Skip to content

Commit

Permalink
[SuperEditor][SuperTextField] - Improve RTL support (Resolves #2472) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
angelosilvestre authored and web-flow committed Jan 25, 2025
1 parent c7f6db4 commit 175465f
Show file tree
Hide file tree
Showing 36 changed files with 626 additions and 291 deletions.
138 changes: 86 additions & 52 deletions super_editor/lib/src/default_editor/list_items.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:super_editor/src/core/editor.dart';
import 'package:super_editor/src/core/styles.dart';
import 'package:super_editor/src/default_editor/attributions.dart';
import 'package:super_editor/src/default_editor/blocks/indentation.dart';
import 'package:super_editor/src/default_editor/text_tools.dart';
import 'package:super_editor/src/infrastructure/_logging.dart';
import 'package:super_editor/src/infrastructure/attributed_text_styles.dart';
import 'package:super_editor/src/infrastructure/keyboard.dart';
Expand Down Expand Up @@ -161,11 +162,16 @@ class ListItemComponentBuilder implements ComponentBuilder {
ordinalValue = computeListItemOrdinalValue(node, document);
}

final textDirection = getParagraphDirection(node.text.toPlainText());
final textAlignment = textDirection == TextDirection.ltr ? TextAlign.left : TextAlign.right;

return switch (node.type) {
ListItemType.unordered => UnorderedListItemComponentViewModel(
nodeId: node.id,
indent: node.indent,
text: node.text,
textDirection: textDirection,
textAlignment: textAlignment,
textStyleBuilder: noStyleBuilder,
selectionColor: const Color(0x00000000),
),
Expand All @@ -174,6 +180,8 @@ class ListItemComponentBuilder implements ComponentBuilder {
indent: node.indent,
ordinalValue: ordinalValue,
text: node.text,
textDirection: textDirection,
textAlignment: textAlignment,
textStyleBuilder: noStyleBuilder,
selectionColor: const Color(0x00000000),
),
Expand All @@ -196,6 +204,8 @@ class ListItemComponentBuilder implements ComponentBuilder {
indent: componentViewModel.indent,
dotStyle: componentViewModel.dotStyle,
textSelection: componentViewModel.selection,
textDirection: componentViewModel.textDirection,
textAlignment: componentViewModel.textAlignment,
selectionColor: componentViewModel.selectionColor,
highlightWhenEmpty: componentViewModel.highlightWhenEmpty,
underlines: componentViewModel.createUnderlines(),
Expand All @@ -206,6 +216,8 @@ class ListItemComponentBuilder implements ComponentBuilder {
indent: componentViewModel.indent,
listIndex: componentViewModel.ordinalValue!,
text: componentViewModel.text,
textDirection: componentViewModel.textDirection,
textAlignment: componentViewModel.textAlignment,
styleBuilder: componentViewModel.textStyleBuilder,
numeralStyle: componentViewModel.numeralStyle,
textSelection: componentViewModel.selection,
Expand Down Expand Up @@ -281,6 +293,7 @@ abstract class ListItemComponentViewModel extends SingleColumnLayoutComponentVie
indent == other.indent &&
text == other.text &&
textDirection == other.textDirection &&
textAlignment == other.textAlignment &&
selection == other.selection &&
selectionColor == other.selectionColor &&
highlightWhenEmpty == other.highlightWhenEmpty &&
Expand All @@ -298,6 +311,7 @@ abstract class ListItemComponentViewModel extends SingleColumnLayoutComponentVie
indent.hashCode ^
text.hashCode ^
textDirection.hashCode ^
textAlignment.hashCode ^
selection.hashCode ^
selectionColor.hashCode ^
highlightWhenEmpty.hashCode ^
Expand Down Expand Up @@ -355,6 +369,7 @@ class UnorderedListItemComponentViewModel extends ListItemComponentViewModel {
textStyleBuilder: textStyleBuilder,
dotStyle: dotStyle,
textDirection: textDirection,
textAlignment: textAlignment,
selection: selection,
selectionColor: selectionColor,
composingRegion: composingRegion,
Expand Down Expand Up @@ -423,6 +438,7 @@ class OrderedListItemComponentViewModel extends ListItemComponentViewModel {
text: text,
textStyleBuilder: textStyleBuilder,
textDirection: textDirection,
textAlignment: textAlignment,
selection: selection,
selectionColor: selectionColor,
composingRegion: composingRegion,
Expand Down Expand Up @@ -493,6 +509,8 @@ class UnorderedListItemComponent extends StatefulWidget {
Key? key,
required this.componentKey,
required this.text,
this.textDirection = TextDirection.ltr,
this.textAlignment = TextAlign.left,
required this.styleBuilder,
this.inlineWidgetBuilders = const [],
this.dotBuilder = _defaultUnorderedListItemDotBuilder,
Expand All @@ -510,6 +528,8 @@ class UnorderedListItemComponent extends StatefulWidget {

final GlobalKey componentKey;
final AttributedText text;
final TextDirection textDirection;
final TextAlign textAlignment;
final AttributionStyleBuilder styleBuilder;
final InlineWidgetBuilderChain inlineWidgetBuilders;
final UnorderedListItemDotBuilder dotBuilder;
Expand Down Expand Up @@ -558,34 +578,39 @@ class _UnorderedListItemComponentState extends State<UnorderedListItemComponent>
return ProxyTextDocumentComponent(
key: widget.componentKey,
textComponentKey: _innerTextComponentKey,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: indentSpace,
decoration: BoxDecoration(
border: widget.showDebugPaint ? Border.all(width: 1, color: Colors.grey) : null,
),
child: SizedBox(
height: lineHeight,
child: widget.dotBuilder(context, widget),
child: Directionality(
textDirection: widget.textDirection,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: indentSpace,
decoration: BoxDecoration(
border: widget.showDebugPaint ? Border.all(width: 1, color: Colors.grey) : null,
),
child: SizedBox(
height: lineHeight,
child: widget.dotBuilder(context, widget),
),
),
),
Expanded(
child: TextComponent(
key: _innerTextComponentKey,
text: widget.text,
textStyleBuilder: widget.styleBuilder,
inlineWidgetBuilders: widget.inlineWidgetBuilders,
textSelection: widget.textSelection,
textScaler: textScaler,
selectionColor: widget.selectionColor,
highlightWhenEmpty: widget.highlightWhenEmpty,
underlines: widget.underlines,
showDebugPaint: widget.showDebugPaint,
Expanded(
child: TextComponent(
key: _innerTextComponentKey,
text: widget.text,
textDirection: widget.textDirection,
textAlign: widget.textAlignment,
textStyleBuilder: widget.styleBuilder,
inlineWidgetBuilders: widget.inlineWidgetBuilders,
textSelection: widget.textSelection,
textScaler: textScaler,
selectionColor: widget.selectionColor,
highlightWhenEmpty: widget.highlightWhenEmpty,
underlines: widget.underlines,
showDebugPaint: widget.showDebugPaint,
),
),
),
],
],
),
),
);
}
Expand Down Expand Up @@ -659,6 +684,8 @@ class OrderedListItemComponent extends StatefulWidget {
required this.componentKey,
required this.listIndex,
required this.text,
this.textDirection = TextDirection.ltr,
this.textAlignment = TextAlign.left,
required this.styleBuilder,
this.inlineWidgetBuilders = const [],
this.numeralBuilder = _defaultOrderedListItemNumeralBuilder,
Expand All @@ -677,6 +704,8 @@ class OrderedListItemComponent extends StatefulWidget {
final GlobalKey componentKey;
final int listIndex;
final AttributedText text;
final TextDirection textDirection;
final TextAlign textAlignment;
final AttributionStyleBuilder styleBuilder;
final InlineWidgetBuilderChain inlineWidgetBuilders;
final OrderedListItemNumeralBuilder numeralBuilder;
Expand Down Expand Up @@ -725,35 +754,40 @@ class _OrderedListItemComponentState extends State<OrderedListItemComponent> {
return ProxyTextDocumentComponent(
key: widget.componentKey,
textComponentKey: _innerTextComponentKey,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: indentSpace,
height: lineHeight,
decoration: BoxDecoration(
border: widget.showDebugPaint ? Border.all(width: 1, color: Colors.grey) : null,
),
child: SizedBox(
child: Directionality(
textDirection: widget.textDirection,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: indentSpace,
height: lineHeight,
child: widget.numeralBuilder(context, widget),
decoration: BoxDecoration(
border: widget.showDebugPaint ? Border.all(width: 1, color: Colors.grey) : null,
),
child: SizedBox(
height: lineHeight,
child: widget.numeralBuilder(context, widget),
),
),
),
Expanded(
child: TextComponent(
key: _innerTextComponentKey,
text: widget.text,
textStyleBuilder: widget.styleBuilder,
inlineWidgetBuilders: widget.inlineWidgetBuilders,
textSelection: widget.textSelection,
textScaler: textScaler,
selectionColor: widget.selectionColor,
highlightWhenEmpty: widget.highlightWhenEmpty,
underlines: widget.underlines,
showDebugPaint: widget.showDebugPaint,
Expanded(
child: TextComponent(
key: _innerTextComponentKey,
text: widget.text,
textDirection: widget.textDirection,
textAlign: widget.textAlignment,
textStyleBuilder: widget.styleBuilder,
inlineWidgetBuilders: widget.inlineWidgetBuilders,
textSelection: widget.textSelection,
textScaler: textScaler,
selectionColor: widget.selectionColor,
highlightWhenEmpty: widget.highlightWhenEmpty,
underlines: widget.underlines,
showDebugPaint: widget.showDebugPaint,
),
),
),
],
],
),
),
);
}
Expand Down
64 changes: 34 additions & 30 deletions super_editor/lib/src/default_editor/paragraph.dart
Original file line number Diff line number Diff line change
Expand Up @@ -331,38 +331,42 @@ class _ParagraphComponentState extends State<ParagraphComponent>

@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Indent spacing on left.
SizedBox(
width: widget.viewModel.indentCalculator(
widget.viewModel.textStyleBuilder({}),
widget.viewModel.indent,
return Directionality(
textDirection: widget.viewModel.textDirection,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Indent spacing on left.
SizedBox(
width: widget.viewModel.indentCalculator(
widget.viewModel.textStyleBuilder({}),
widget.viewModel.indent,
),
),
),
// The actual paragraph UI.
Expanded(
child: TextComponent(
key: _textKey,
text: widget.viewModel.text,
textAlign: widget.viewModel.textAlignment,
textScaler: widget.viewModel.textScaler,
textStyleBuilder: widget.viewModel.textStyleBuilder,
inlineWidgetBuilders: widget.viewModel.inlineWidgetBuilders,
metadata: widget.viewModel.blockType != null
? {
'blockType': widget.viewModel.blockType,
}
: {},
textSelection: widget.viewModel.selection,
selectionColor: widget.viewModel.selectionColor,
highlightWhenEmpty: widget.viewModel.highlightWhenEmpty,
underlines: widget.viewModel.createUnderlines(),
showDebugPaint: widget.showDebugPaint,
// The actual paragraph UI.
Expanded(
child: TextComponent(
key: _textKey,
text: widget.viewModel.text,
textDirection: widget.viewModel.textDirection,
textAlign: widget.viewModel.textAlignment,
textScaler: widget.viewModel.textScaler,
textStyleBuilder: widget.viewModel.textStyleBuilder,
inlineWidgetBuilders: widget.viewModel.inlineWidgetBuilders,
metadata: widget.viewModel.blockType != null
? {
'blockType': widget.viewModel.blockType,
}
: {},
textSelection: widget.viewModel.selection,
selectionColor: widget.viewModel.selectionColor,
highlightWhenEmpty: widget.viewModel.highlightWhenEmpty,
underlines: widget.viewModel.createUnderlines(),
showDebugPaint: widget.showDebugPaint,
),
),
),
],
],
),
);
}
}
Expand Down
Loading

0 comments on commit 175465f

Please sign in to comment.