diff --git a/lib/src/common/utils/directionality.dart b/lib/src/common/utils/directionality.dart new file mode 100644 index 00000000..a39c1b20 --- /dev/null +++ b/lib/src/common/utils/directionality.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +bool isRTLLanguage(Locale locale) { + final rtlLanguages = [ + 'ar', // Arabic + 'dv', // Divehi (Maldivian) + 'fa', // Persian (Farsi) + 'ha', // Hausa (in Ajami script) + 'he', // Hebrew + 'khw', // Khowar (in Arabic script) + 'ks', // Kashmiri (in Arabic script) + 'ku', // Kurdish (Sorani) + 'ps', // Pashto + 'ur', // Urdu + 'yi', // Yiddish + 'sd', // Sindhi + 'ug', // Uyghur + ]; + return rtlLanguages.contains(locale.languageCode); +} + +bool isRTL(BuildContext context) { + return isRTLLanguage(Localizations.localeOf(context)); +} diff --git a/lib/src/editor/raw_editor/raw_editor_state.dart b/lib/src/editor/raw_editor/raw_editor_state.dart index ff90998b..b0e2174d 100644 --- a/lib/src/editor/raw_editor/raw_editor_state.dart +++ b/lib/src/editor/raw_editor/raw_editor_state.dart @@ -23,6 +23,7 @@ import '../../common/structs/horizontal_spacing.dart'; import '../../common/structs/offset_value.dart'; import '../../common/structs/vertical_spacing.dart'; import '../../common/utils/cast.dart'; +import '../../common/utils/directionality.dart'; import '../../common/utils/platform.dart'; import '../../controller/quill_controller.dart'; import '../../delta/delta_diff.dart'; @@ -975,16 +976,23 @@ class QuillRawEditorState extends EditorState } prevNodeOl = attrs[Attribute.list.key] == Attribute.ol; - + var nodeTextDirection = getDirectionOfNode(node); + // verify if the direction from nodeTextDirection is the default direction + // and watch if the system language is a RTL language and avoid putting + // to the edge of the left side any checkbox or list point/number if is a + // RTL language + if (nodeTextDirection == TextDirection.ltr && isRTL(context)) { + nodeTextDirection = TextDirection.rtl; + } if (node is Line) { final editableTextLine = _getEditableTextLineFromNode(node, context); result.add(Directionality( - textDirection: getDirectionOfNode(node), child: editableTextLine)); + textDirection: nodeTextDirection, child: editableTextLine)); } else if (node is Block) { final editableTextBlock = EditableTextBlock( block: node, controller: controller, - textDirection: getDirectionOfNode(node), + textDirection: nodeTextDirection, scrollBottomInset: widget.configurations.scrollBottomInset, horizontalSpacing: _getHorizontalSpacingForBlock(node, _styles), verticalSpacing: _getVerticalSpacingForBlock(node, _styles), @@ -1011,7 +1019,7 @@ class QuillRawEditorState extends EditorState ); result.add( Directionality( - textDirection: getDirectionOfNode(node), + textDirection: nodeTextDirection, child: editableTextBlock, ), ); diff --git a/lib/src/editor/widgets/text/text_block.dart b/lib/src/editor/widgets/text/text_block.dart index 406561a9..8d8c0a5b 100644 --- a/lib/src/editor/widgets/text/text_block.dart +++ b/lib/src/editor/widgets/text/text_block.dart @@ -3,6 +3,7 @@ import 'package:flutter/rendering.dart'; import '../../../common/structs/horizontal_spacing.dart'; import '../../../common/structs/vertical_spacing.dart'; +import '../../../common/utils/directionality.dart'; import '../../../common/utils/font.dart'; import '../../../controller/quill_controller.dart'; import '../../../delta/delta_diff.dart'; @@ -134,6 +135,15 @@ class EditableTextBlock extends StatelessWidget { Block node, DefaultStyles? defaultStyles) { final attrs = block.style.attributes; if (attrs.containsKey(Attribute.blockQuote.key)) { + // Verify if the direction is RTL and avoid passing the decoration + // to the left when need to be on right side + if (textDirection == TextDirection.rtl) { + return defaultStyles!.quote!.decoration?.copyWith( + border: Border( + right: BorderSide(width: 4, color: Colors.grey.shade300), + ), + ); + } return defaultStyles!.quote!.decoration; } if (attrs.containsKey(Attribute.codeBlock.key)) { @@ -184,7 +194,14 @@ class EditableTextBlock extends StatelessWidget { MediaQuery.devicePixelRatioOf(context), cursorCont, ); - final nodeTextDirection = getDirectionOfNode(line); + var nodeTextDirection = getDirectionOfNode(line); + // verify if the direction from nodeTextDirection is the default direction + // and watch if the system language is a RTL language and avoid putting + // to the edge of the left side any checkbox or list point/number if is a + // RTL language + if (nodeTextDirection == TextDirection.ltr && isRTL(context)) { + nodeTextDirection = TextDirection.rtl; + } children.add( Directionality( textDirection: nodeTextDirection,