Rich text editor for Flutter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

128 lines
3.7 KiB

import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart' hide Text;
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
import '../universal_ui/universal_ui.dart';
import '../widgets/demo_scaffold.dart';
class CustomAttrPage extends StatefulWidget {
CustomAttrPage() {
// should probably be called when the app first starts but since the
// registry is a hashmap then it won't really matter for this example
Attribute.addCustomAttribute(const RandomColorAttribute(true));
}
@override
_CustomAttrPageState createState() => _CustomAttrPageState();
}
class _CustomAttrPageState extends State<CustomAttrPage> {
final FocusNode _focusNode = FocusNode();
QuillController? _controller;
@override
Widget build(BuildContext context) {
return DemoScaffold(
documentFilename: 'sample_data_nomedia.json',
builder: _buildContent,
customButtons: [
QuillCustomButton(
icon: Icons.smart_toy_sharp,
onTap: () {
if (_controller != null) {
if (_controller!
.getSelectionStyle()
.attributes
.keys
.contains(RandomColorAttribute.KEY)) {
_controller!
.formatSelection(const RandomColorAttribute(null));
} else {
_controller!
.formatSelection(const RandomColorAttribute(true));
}
}
},
isToggled: () {
return _controller != null &&
_controller!
.getSelectionStyle()
.attributes
.containsKey(RandomColorAttribute.KEY);
})
],
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
// update ui and randomize the colors
});
},
child: const Icon(Icons.refresh),
),
title: 'Custom attribute demo',
);
}
Widget _buildContent(BuildContext context, QuillController? controller) {
_controller = controller;
var quillEditor = QuillEditor(
controller: controller!,
scrollController: ScrollController(),
scrollable: true,
focusNode: _focusNode,
autoFocus: true,
readOnly: false,
expands: false,
padding: EdgeInsets.zero,
embedBuilders: FlutterQuillEmbeds.builders(),
customStyleBuilder: _customStyleBuilder,
);
if (kIsWeb) {
quillEditor = QuillEditor(
controller: controller,
scrollController: ScrollController(),
scrollable: true,
focusNode: _focusNode,
autoFocus: true,
readOnly: false,
expands: false,
padding: EdgeInsets.zero,
embedBuilders: defaultEmbedBuildersWeb,
customStyleBuilder: _customStyleBuilder,
);
}
return Padding(
padding: const EdgeInsets.all(8),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey.shade200),
),
child: quillEditor,
),
);
}
TextStyle _customStyleBuilder(Attribute attr) {
if (attr.key == RandomColorAttribute.KEY) {
// generate a random text color
return TextStyle(
color:
Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1));
}
return const TextStyle();
}
}
// custom inline attribute
class RandomColorAttribute extends Attribute<bool?> {
const RandomColorAttribute(bool? val)
: super(KEY, AttributeScope.INLINE, val);
static const String KEY = 'random-color';
}