Skip to content

Commit f376f72

Browse files
feat: Enable BoxDecoration for DefaultTextBlockStyle of header Attribute (#2438)
* feat: Enable BoxDecoration for DefaultTextBlockStyle of header Attribute --------- Co-authored-by: Ellet <[email protected]>
1 parent 693f4ac commit f376f72

File tree

4 files changed

+58
-10
lines changed

4 files changed

+58
-10
lines changed

CHANGELOG.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212

1313
### Fixed
1414

15-
* Remove unicode from `QuillText` element that causes weird caret behavior on empty lines [#2453](https://github.com/singerdmx/flutter-quill/pull/2453).
16-
* Focus and open context menu on right click if unfocused [#2477](https://github.com/singerdmx/flutter-quill/pull/2477).
17-
* Update QuillController `length` extension method deprecation message [#2483](https://github.com/singerdmx/flutter-quill/pull/2483).
15+
- Remove unicode from `QuillText` element that causes weird caret behavior on empty lines [#2453](https://github.com/singerdmx/flutter-quill/pull/2453).
16+
- Focus and open context menu on right click if unfocused [#2477](https://github.com/singerdmx/flutter-quill/pull/2477).
17+
- Update QuillController `length` extension method deprecation message [#2483](https://github.com/singerdmx/flutter-quill/pull/2483).
1818

1919
### Added
2020

21-
* `Rule` is now part of the public API, so that `Document.setCustomRules` can be used.
21+
- `Rule` is now part of the public API, so that `Document.setCustomRules` can be used.
22+
- `decoration` property in `DefaultTextBlockStyle` for the `header` attribute to customize headers with borders, background colors, and other styles using `BoxDecoration` [#2429](https://github.com/singerdmx/flutter-quill/pull/2429).
2223

2324
## [11.0.0] - 2025-02-16
2425

lib/src/editor/raw_editor/raw_editor_state.dart

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,8 @@ class QuillRawEditorState extends EditorState
586586
prevNodeOl = attrs[Attribute.list.key] == Attribute.ol;
587587
final nodeTextDirection = getDirectionOfNode(node, _textDirection);
588588
if (node is Line) {
589-
final editableTextLine = _getEditableTextLineFromNode(node, context);
589+
final editableTextLine =
590+
_getEditableTextLineFromNode(node, context, attrs);
590591
result.add(Directionality(
591592
textDirection: nodeTextDirection, child: editableTextLine));
592593
} else if (node is Block) {
@@ -639,7 +640,7 @@ class QuillRawEditorState extends EditorState
639640
}
640641

641642
EditableTextLine _getEditableTextLineFromNode(
642-
Line node, BuildContext context) {
643+
Line node, BuildContext context, Map<String, Attribute<dynamic>> attrs) {
643644
final textLine = TextLine(
644645
line: node,
645646
textDirection: _textDirection,
@@ -668,7 +669,8 @@ class QuillRawEditorState extends EditorState
668669
_hasFocus,
669670
MediaQuery.devicePixelRatioOf(context),
670671
_cursorCont,
671-
_styles!.inlineCode!);
672+
_styles!.inlineCode!,
673+
_getDecoration(node, _styles, attrs));
672674
return editableTextLine;
673675
}
674676

@@ -772,6 +774,30 @@ class QuillRawEditorState extends EditorState
772774
return VerticalSpacing.zero;
773775
}
774776

777+
BoxDecoration? _getDecoration(Node node, DefaultStyles? defaultStyles,
778+
Map<String, Attribute<dynamic>> attrs) {
779+
if (attrs.containsKey(Attribute.header.key)) {
780+
final level = attrs[Attribute.header.key]!.value;
781+
switch (level) {
782+
case 1:
783+
return defaultStyles!.h1!.decoration;
784+
case 2:
785+
return defaultStyles!.h2!.decoration;
786+
case 3:
787+
return defaultStyles!.h3!.decoration;
788+
case 4:
789+
return defaultStyles!.h4!.decoration;
790+
case 5:
791+
return defaultStyles!.h5!.decoration;
792+
case 6:
793+
return defaultStyles!.h6!.decoration;
794+
default:
795+
throw ArgumentError('Invalid level $level');
796+
}
797+
}
798+
return null;
799+
}
800+
775801
void _didChangeTextEditingValueListener() {
776802
_didChangeTextEditingValue(controller.ignoreFocusOnTextChange);
777803
}

lib/src/editor/widgets/text/text_block.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ class EditableTextBlock extends StatelessWidget {
209209
MediaQuery.devicePixelRatioOf(context),
210210
cursorCont,
211211
styles!.inlineCode!,
212-
);
212+
null);
213213
final nodeTextDirection = getDirectionOfNode(line, textDirection);
214214
children.add(
215215
Directionality(

lib/src/editor/widgets/text/text_line.dart

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,7 @@ class EditableTextLine extends RenderObjectWidget {
736736
this.devicePixelRatio,
737737
this.cursorCont,
738738
this.inlineCodeStyle,
739+
this.decoration,
739740
{super.key});
740741

741742
final Line line;
@@ -751,6 +752,7 @@ class EditableTextLine extends RenderObjectWidget {
751752
final double devicePixelRatio;
752753
final CursorCont cursorCont;
753754
final InlineCodeStyle inlineCodeStyle;
755+
final BoxDecoration? decoration;
754756

755757
@override
756758
RenderObjectElement createElement() {
@@ -769,7 +771,8 @@ class EditableTextLine extends RenderObjectWidget {
769771
_getPadding(),
770772
color,
771773
cursorCont,
772-
inlineCodeStyle);
774+
inlineCodeStyle,
775+
decoration);
773776
}
774777

775778
@override
@@ -785,7 +788,8 @@ class EditableTextLine extends RenderObjectWidget {
785788
..hasFocus = hasFocus
786789
..setDevicePixelRatio(devicePixelRatio)
787790
..setCursorCont(cursorCont)
788-
..setInlineCodeStyle(inlineCodeStyle);
791+
..setInlineCodeStyle(inlineCodeStyle)
792+
..setDecoration(decoration);
789793
}
790794

791795
EdgeInsetsGeometry _getPadding() {
@@ -812,6 +816,7 @@ class RenderEditableTextLine extends RenderEditableBox {
812816
this.color,
813817
this.cursorCont,
814818
this.inlineCodeStyle,
819+
this.decoration,
815820
);
816821

817822
RenderBox? _leading;
@@ -830,6 +835,7 @@ class RenderEditableTextLine extends RenderEditableBox {
830835
List<TextBox>? _selectedRects;
831836
late Rect _caretPrototype;
832837
InlineCodeStyle inlineCodeStyle;
838+
BoxDecoration? decoration;
833839
final Map<TextLineSlot, RenderBox> children = <TextLineSlot, RenderBox>{};
834840

835841
Iterable<RenderBox> get _children sync* {
@@ -945,6 +951,12 @@ class RenderEditableTextLine extends RenderEditableBox {
945951
markNeedsLayout();
946952
}
947953

954+
void setDecoration(BoxDecoration? newDecoration) {
955+
if (decoration == newDecoration) return;
956+
decoration = newDecoration;
957+
markNeedsPaint();
958+
}
959+
948960
// Start selection implementation
949961

950962
bool containsTextSelection() {
@@ -1334,6 +1346,15 @@ class RenderEditableTextLine extends RenderEditableBox {
13341346
);
13351347
}
13361348
}
1349+
final boxDecoration = decoration;
1350+
if (boxDecoration != null) {
1351+
final paintRect = offset & size;
1352+
boxDecoration.createBoxPainter().paint(
1353+
context.canvas,
1354+
paintRect.topLeft,
1355+
ImageConfiguration(size: paintRect.size),
1356+
);
1357+
}
13371358

13381359
if (_body != null) {
13391360
final parentData = _body!.parentData as BoxParentData;

0 commit comments

Comments
 (0)