feat: improve outline block (#4722)

This commit is contained in:
Lucas.Xu 2024-02-24 20:54:21 +07:00 committed by GitHub
parent 2abb396467
commit cea1c17b76
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 92 additions and 70 deletions

View File

@ -114,9 +114,12 @@ enum OptionAlignType {
}
enum OptionDepthType {
h1(1, "H1"),
h2(2, "H2"),
h3(3, "H3");
h1(1, 'H1'),
h2(2, 'H2'),
h3(3, 'H3'),
h4(4, 'H4'),
h5(5, 'H5'),
h6(6, 'H6');
const OptionDepthType(this.level, this.description);

View File

@ -32,6 +32,12 @@ Node outlineBlockNode() {
);
}
enum _OutlineBlockStatus {
noHeadings,
noMatchHeadings,
success;
}
class OutlineBlockComponentBuilder extends BlockComponentBuilder {
OutlineBlockComponentBuilder({
super.configuration,
@ -75,7 +81,7 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
BlockComponentTextDirectionMixin,
BlockComponentBackgroundColorMixin {
// Change the value if the heading block type supports heading levels greater than '3'
static const finalHeadingLevel = 3;
static const maxVisibleDepth = 6;
@override
BlockComponentConfiguration get configuration => widget.configuration;
@ -120,8 +126,29 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
final textDirection = calculateTextDirection(
layoutDirection: Directionality.maybeOf(context),
);
final (status, headings) = getHeadingNodes();
final children = getHeadingNodes()
Widget child;
switch (status) {
case _OutlineBlockStatus.noHeadings:
child = Align(
alignment: Alignment.centerLeft,
child: Text(
LocaleKeys.document_plugins_outline_addHeadingToCreateOutline.tr(),
style: configuration.placeholderTextStyle(node),
),
);
case _OutlineBlockStatus.noMatchHeadings:
child = Align(
alignment: Alignment.centerLeft,
child: Text(
LocaleKeys.document_plugins_outline_noMatchHeadings.tr(),
style: configuration.placeholderTextStyle(node),
),
);
case _OutlineBlockStatus.success:
final children = headings
.map(
(e) => Container(
padding: const EdgeInsets.only(
@ -135,17 +162,20 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
),
)
.toList();
final child = children.isEmpty
? Align(
alignment: Alignment.centerLeft,
child: Text(
LocaleKeys.document_plugins_outline_addHeadingToCreateOutline
.tr(),
style: configuration.placeholderTextStyle(node),
child = Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Column(
children: children,
),
)
: Container(
);
}
return Container(
constraints: const BoxConstraints(
minHeight: 40.0,
),
padding: padding,
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 2.0,
horizontal: 5.0,
@ -155,7 +185,6 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
color: backgroundColor,
),
child: Column(
key: ValueKey(children.hashCode),
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
textDirection: textDirection,
@ -165,36 +194,29 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
style: Theme.of(context).textTheme.titleLarge,
),
const VSpace(8.0),
Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Column(
children: children,
),
),
child,
],
),
);
return Container(
constraints: const BoxConstraints(
minHeight: 40.0,
),
padding: padding,
child: child,
);
}
Iterable<Node> getHeadingNodes() {
(_OutlineBlockStatus, Iterable<Node>) getHeadingNodes() {
final children = editorState.document.root.children;
final int level =
node.attributes[OutlineBlockKeys.depth] ?? finalHeadingLevel;
return children.where(
(element) =>
element.type == HeadingBlockKeys.type &&
element.delta?.isNotEmpty == true &&
element.attributes[HeadingBlockKeys.level] <= level,
node.attributes[OutlineBlockKeys.depth] ?? maxVisibleDepth;
var headings = children.where(
(e) => e.type == HeadingBlockKeys.type && e.delta?.isNotEmpty == true,
);
if (headings.isEmpty) {
return (_OutlineBlockStatus.noHeadings, []);
}
headings =
headings.where((e) => e.attributes[HeadingBlockKeys.level] <= level);
if (headings.isEmpty) {
return (_OutlineBlockStatus.noMatchHeadings, []);
}
return (_OutlineBlockStatus.success, headings);
}
}
@ -263,12 +285,8 @@ extension on Node {
return 0.0;
}
final level = attributes[HeadingBlockKeys.level];
if (level == 2) {
return 20;
} else if (level == 3) {
return 40;
}
return 0;
final indent = (level - 1) * 15.0 + 10.0;
return indent;
}
String get outlineItemText {

View File

@ -793,7 +793,8 @@
"copiedToPasteBoard": "The link has been copied to the clipboard"
},
"outline": {
"addHeadingToCreateOutline": "Add headings to create a table of contents."
"addHeadingToCreateOutline": "Add headings to create a table of contents.",
"noMatchHeadings": "No matching headings found."
},
"table": {
"addAfter": "Add after",