kat_html_editor 0.0.5
kat_html_editor: ^0.0.5 copied to clipboard
HTML rich text editor for Android, iOS, and Web, it is built with the powerful Quill Js library. Which is an open source WYSIWYG editor built for the modern web.
example/lib/main.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:kat_html_editor/kat_html_editor.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late QuillEditorController controller;
final customToolBarList = [
ToolBarStyle.bold,
ToolBarStyle.italic,
ToolBarStyle.align,
ToolBarStyle.color,
ToolBarStyle.background,
ToolBarStyle.listBullet,
ToolBarStyle.listOrdered,
ToolBarStyle.clean,
ToolBarStyle.addTable,
ToolBarStyle.editTable,
];
final _toolbarColor = Colors.grey.shade200;
final _backgroundColor = Colors.white70;
final _toolbarIconColor = Colors.black87;
final _editorTextStyle = const TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.normal,
fontFamily: 'Roboto',
);
final _hintTextStyle = const TextStyle(
fontSize: 18,
color: Colors.black38,
fontWeight: FontWeight.normal,
);
bool _hasFocus = false;
@override
void initState() {
controller = QuillEditorController();
controller.onTextChanged((text) {
debugPrint('listening to $text');
});
controller.onEditorLoaded(() {
debugPrint('Editor Loaded :)');
});
super.initState();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(
child: Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomInset: false,
body: Column(
children: [
ToolBar(
toolBarColor: _toolbarColor,
padding: const EdgeInsets.all(8),
iconSize: 25,
iconColor: _toolbarIconColor,
activeIconColor: Colors.greenAccent.shade400,
controller: controller,
crossAxisAlignment: WrapCrossAlignment.start,
direction: Axis.horizontal,
customButtons: [
Container(
width: 25,
height: 25,
decoration: BoxDecoration(
color: _hasFocus ? Colors.green : Colors.grey,
borderRadius: BorderRadius.circular(15),
),
),
InkWell(
onTap: () => unFocusEditor(),
child: const Icon(Icons.favorite, color: Colors.black),
),
InkWell(
onTap: () async {
var selectedText = await controller.getSelectedText();
debugPrint('selectedText $selectedText');
var selectedHtmlText =
await controller.getSelectedHtmlText();
debugPrint('selectedHtmlText $selectedHtmlText');
},
child: const Icon(Icons.add_circle, color: Colors.black),
),
],
),
Expanded(
child: QuillHtmlEditor(
text: "<h1>Hello</h1>This is a quill html editor example 😊",
hintText: 'Hint text goes here',
controller: controller,
isEnabled: true,
ensureVisible: false,
minHeight: 500,
autoFocus: false,
textStyle: _editorTextStyle,
hintTextStyle: _hintTextStyle,
hintTextAlign: TextAlign.start,
padding: const EdgeInsets.only(left: 10, top: 10),
hintTextPadding: const EdgeInsets.only(left: 20),
backgroundColor: _backgroundColor,
inputAction: InputAction.newline,
onEditingComplete: (s) => debugPrint('Editing completed $s'),
loadingBuilder: (context) {
return const Center(
child: CircularProgressIndicator(
strokeWidth: 1,
// color: Colors.red,
),
);
},
onFocusChanged: (focus) {
debugPrint('has focus $focus');
setState(() {
_hasFocus = focus;
});
},
onTextChanged:
(text) => debugPrint('widget text change $text'),
onEditorCreated: () {
debugPrint('Editor has been loaded');
setHtmlText('Testing text on load');
},
onEditorResized:
(height) => debugPrint('Editor resized $height'),
onSelectionChanged:
(sel) =>
debugPrint('index ${sel.index}, range ${sel.length}'),
),
),
],
),
bottomNavigationBar: Container(
width: double.maxFinite,
color: _toolbarColor,
padding: const EdgeInsets.all(8),
child: Wrap(
children: [
textButton(
text: 'Set Text',
onPressed: () {
setHtmlText('This text is set by you 🫵');
},
),
textButton(
text: 'Get Text',
onPressed: () {
getHtmlText();
},
),
textButton(
text: 'Insert Video',
onPressed: () {
insertVideoURL(
'https://www.youtube.com/watch?v=4AoFA19gbLo',
);
insertVideoURL('https://vimeo.com/440421754');
insertVideoURL(
'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
);
},
),
textButton(
text: 'Insert Image',
onPressed: () {
insertNetworkImage('https://i.imgur.com/0DVAOec.gif');
},
),
textButton(
text: 'Insert Index',
onPressed: () {
insertHtmlText(
"This text is set by the insertText method",
index: 10,
);
},
),
textButton(
text: 'Undo',
onPressed: () {
controller.undo();
},
),
textButton(
text: 'Redo',
onPressed: () {
controller.redo();
},
),
textButton(
text: 'Clear History',
onPressed: () async {
controller.clearHistory();
},
),
textButton(
text: 'Clear Editor',
onPressed: () {
controller.clear();
},
),
textButton(
text: 'Get Delta',
onPressed: () async {
var delta = await controller.getDelta();
debugPrint('delta');
debugPrint(jsonEncode(delta));
},
),
textButton(
text: 'Set Delta',
onPressed: () {
final Map<dynamic, dynamic> deltaMap = {
"ops": [
{
"insert": {
"video":
"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
},
},
{
"insert": {
"video":
"https://www.youtube.com/embed/4AoFA19gbLo",
},
},
{"insert": "Hello"},
{
"attributes": {"header": 1},
"insert": "\n",
},
{"insert": "You just set the Delta text 😊\n"},
],
};
controller.setDelta(deltaMap);
},
),
],
),
),
),
),
);
}
Widget textButton({required String text, required VoidCallback onPressed}) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: MaterialButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
color: _toolbarIconColor,
onPressed: onPressed,
child: Text(text, style: TextStyle(color: _toolbarColor)),
),
);
}
void getHtmlText() async {
String? htmlText = await controller.getText();
debugPrint(htmlText);
}
void setHtmlText(String text) async {
await controller.setText(text);
}
void insertNetworkImage(String url) async {
await controller.embedImage(url);
}
void insertVideoURL(String url) async {
await controller.embedVideo(url);
}
void insertHtmlText(String text, {int? index}) async {
await controller.insertText(text, index: index);
}
void clearEditor() => controller.clear();
void enableEditor(bool enable) => controller.enableEditor(enable);
void unFocusEditor() => controller.unFocus();
}