feat: display number in latin or roman format (#595)
This commit is contained in:
parent
ec3ecf58a0
commit
c63d664513
3 changed files with 101 additions and 3 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:appflowy_editor/src/editor/block_component/base_component/block_icon_builder.dart';
|
import 'package:appflowy_editor/src/editor/block_component/base_component/block_icon_builder.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:numerus/roman/roman.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class NumberedListBlockKeys {
|
class NumberedListBlockKeys {
|
||||||
|
|
@ -207,7 +208,6 @@ class _NumberedListIcon extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final editorState = context.read<EditorState>();
|
final editorState = context.read<EditorState>();
|
||||||
final text = editorState.editorStyle.textStyleConfiguration.text;
|
final text = editorState.editorStyle.textStyleConfiguration.text;
|
||||||
final level = _NumberedListIconBuilder(node: node).level;
|
|
||||||
return Container(
|
return Container(
|
||||||
constraints: const BoxConstraints(minWidth: 26, minHeight: 22),
|
constraints: const BoxConstraints(minWidth: 26, minHeight: 22),
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
padding: const EdgeInsets.only(right: 4.0),
|
||||||
|
|
@ -217,7 +217,10 @@ class _NumberedListIcon extends StatelessWidget {
|
||||||
applyHeightToFirstAscent: false,
|
applyHeightToFirstAscent: false,
|
||||||
applyHeightToLastDescent: false,
|
applyHeightToLastDescent: false,
|
||||||
),
|
),
|
||||||
TextSpan(text: '$level.', style: text.combine(textStyle)),
|
TextSpan(
|
||||||
|
text: node.levelString,
|
||||||
|
style: text.combine(textStyle),
|
||||||
|
),
|
||||||
textDirection: direction,
|
textDirection: direction,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -225,6 +228,21 @@ class _NumberedListIcon extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension on Node {
|
||||||
|
String get levelString {
|
||||||
|
final builder = _NumberedListIconBuilder(node: this);
|
||||||
|
final indexInRootLevel = builder.indexInRootLevel;
|
||||||
|
final indexInSameLevel = builder.indexInSameLevel;
|
||||||
|
final level = indexInRootLevel % 3;
|
||||||
|
final levelString = switch (level) {
|
||||||
|
1 => indexInSameLevel.latin,
|
||||||
|
2 => indexInSameLevel.roman,
|
||||||
|
_ => '$indexInSameLevel',
|
||||||
|
};
|
||||||
|
return '$levelString.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _NumberedListIconBuilder {
|
class _NumberedListIconBuilder {
|
||||||
_NumberedListIconBuilder({
|
_NumberedListIconBuilder({
|
||||||
required this.node,
|
required this.node,
|
||||||
|
|
@ -232,7 +250,21 @@ class _NumberedListIconBuilder {
|
||||||
|
|
||||||
final Node node;
|
final Node node;
|
||||||
|
|
||||||
int get level {
|
// the level of the current node
|
||||||
|
int get indexInRootLevel {
|
||||||
|
var level = 0;
|
||||||
|
var parent = node.parent;
|
||||||
|
while (parent != null) {
|
||||||
|
if (parent.type == NumberedListBlockKeys.type) {
|
||||||
|
level++;
|
||||||
|
}
|
||||||
|
parent = parent.parent;
|
||||||
|
}
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the index of the current level
|
||||||
|
int get indexInSameLevel {
|
||||||
int level = 1;
|
int level = 1;
|
||||||
Node? previous = node.previous;
|
Node? previous = node.previous;
|
||||||
|
|
||||||
|
|
@ -253,3 +285,20 @@ class _NumberedListIconBuilder {
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension on int {
|
||||||
|
String get latin {
|
||||||
|
String result = '';
|
||||||
|
int number = this;
|
||||||
|
while (number > 0) {
|
||||||
|
int remainder = (number - 1) % 26;
|
||||||
|
result = String.fromCharCode(remainder + 65) + result;
|
||||||
|
number = (number - 1) ~/ 26;
|
||||||
|
}
|
||||||
|
return result.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
String get roman {
|
||||||
|
return toRomanNumeralString() ?? '$this';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ dependencies:
|
||||||
string_validator: ^1.0.0
|
string_validator: ^1.0.0
|
||||||
universal_html: ^2.2.4
|
universal_html: ^2.2.4
|
||||||
keyboard_height_plugin: ^0.0.4
|
keyboard_height_plugin: ^0.0.4
|
||||||
|
numerus: ^2.1.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
||||||
|
|
@ -124,5 +124,53 @@ void main() async {
|
||||||
|
|
||||||
await editor.dispose();
|
await editor.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('number, latin and roman', (tester) async {
|
||||||
|
final delta = Delta()..insert(text);
|
||||||
|
final editor = tester.editor
|
||||||
|
..addNode(
|
||||||
|
// 1.
|
||||||
|
numberedListNode(
|
||||||
|
delta: delta,
|
||||||
|
children: [
|
||||||
|
// a.
|
||||||
|
numberedListNode(
|
||||||
|
delta: delta,
|
||||||
|
children: [
|
||||||
|
numberedListNode(delta: delta), // Ⅰ.
|
||||||
|
numberedListNode(delta: delta), // ⅠⅠ.
|
||||||
|
numberedListNode(delta: delta), // ⅠⅠⅠ.
|
||||||
|
],
|
||||||
|
),
|
||||||
|
// b.
|
||||||
|
numberedListNode(
|
||||||
|
delta: delta,
|
||||||
|
children: [
|
||||||
|
numberedListNode(delta: delta), // Ⅰ.
|
||||||
|
numberedListNode(delta: delta), // ⅠⅠ.
|
||||||
|
numberedListNode(delta: delta), // ⅠⅠⅠ.
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
..addNode(
|
||||||
|
// 2.
|
||||||
|
numberedListNode(
|
||||||
|
delta: delta,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await editor.startTesting();
|
||||||
|
for (final number in ['1.', '2.']) {
|
||||||
|
expect(find.text(number, findRichText: true), findsOneWidget);
|
||||||
|
}
|
||||||
|
for (final latin in ['a.', 'b.']) {
|
||||||
|
expect(find.text(latin, findRichText: true), findsOneWidget);
|
||||||
|
}
|
||||||
|
for (final roman in ['I.', 'II.', 'III.']) {
|
||||||
|
expect(find.text(roman, findRichText: true), findsNWidgets(2));
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue