BidiSelectableText class

A selectable text widget that automatically detects and sets text direction based on content.

BidiSelectableText wraps Flutter's standard SelectableText widget but automatically determines whether the text should be displayed in right-to-left (RTL) or left-to-right (LTR) direction based on the content of the text itself.

This is particularly useful for applications that support multiple languages with different text directions and need selectable read-only content (e.g., article bodies, user profiles, chat messages in read mode).

Use the primary constructor for plain strings and BidiSelectableText.rich for styled TextSpan trees (mirrors SelectableText.rich).

Example:

// Automatically selectable with LTR direction
BidiSelectableText('Hello world!')

// Automatically selectable with RTL direction
BidiSelectableText('مرحبا بالعالم!')

// Styled selectable text (mirrors SelectableText.rich):
BidiSelectableText.rich(
  TextSpan(children: [
    TextSpan(text: 'مرحبا ', style: TextStyle(fontWeight: FontWeight.bold)),
    TextSpan(text: 'world'),
  ]),
)
Inheritance

Constructors

BidiSelectableText(String data, {Key? key, FocusNode? focusNode, TextStyle? style, StrutStyle? strutStyle, TextAlign? textAlign, TextScaler? textScaler, bool showCursor = false, bool autofocus = false, int? minLines, int? maxLines, double cursorWidth = 2.0, double? cursorHeight, Radius? cursorRadius, Color? cursorColor, BoxHeightStyle selectionHeightStyle = ui.BoxHeightStyle.tight, BoxWidthStyle selectionWidthStyle = ui.BoxWidthStyle.tight, bool enableInteractiveSelection = true, TextSelectionControls? selectionControls, GestureTapCallback? onTap, ScrollPhysics? scrollPhysics, String? semanticsLabel, TextHeightBehavior? textHeightBehavior, TextWidthBasis? textWidthBasis, SelectionChangedCallback? onSelectionChanged, EditableTextContextMenuBuilder? contextMenuBuilder, TextMagnifierConfiguration? magnifierConfiguration, int? sampleLength = 50})
Creates a BidiSelectableText widget with a plain string.
const
BidiSelectableText.rich(TextSpan textSpan, {Key? key, FocusNode? focusNode, TextStyle? style, StrutStyle? strutStyle, TextAlign? textAlign, TextScaler? textScaler, bool showCursor = false, bool autofocus = false, int? minLines, int? maxLines, double cursorWidth = 2.0, double? cursorHeight, Radius? cursorRadius, Color? cursorColor, BoxHeightStyle selectionHeightStyle = ui.BoxHeightStyle.tight, BoxWidthStyle selectionWidthStyle = ui.BoxWidthStyle.tight, bool enableInteractiveSelection = true, TextSelectionControls? selectionControls, GestureTapCallback? onTap, ScrollPhysics? scrollPhysics, String? semanticsLabel, TextHeightBehavior? textHeightBehavior, TextWidthBasis? textWidthBasis, SelectionChangedCallback? onSelectionChanged, EditableTextContextMenuBuilder? contextMenuBuilder, TextMagnifierConfiguration? magnifierConfiguration, int? sampleLength = 50})
Creates a BidiSelectableText widget with a TextSpan — a drop-in replacement for SelectableText.rich.
const

Properties

autofocus bool
Whether this text field should focus itself if nothing else is already focused.
final
contextMenuBuilder EditableTextContextMenuBuilder?
Builds the text selection context menu. Defaults to the platform adaptive toolbar.
final
cursorColor Color?
The color of the cursor. Defaults to the theme's ThemeData.colorScheme.
final
cursorHeight double?
How tall the cursor will be.
final
cursorRadius Radius?
How rounded the corners of the cursor should be.
final
cursorWidth double
How thick the cursor will be.
final
data String?
The plain text string. Non-null only when using the primary constructor.
final
enableInteractiveSelection bool
Whether to enable user interface affordances for changing the text selection.
final
focusNode FocusNode?
final
hashCode int
The hash code for this object.
no setterinherited
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
magnifierConfiguration TextMagnifierConfiguration?
final
maxLines int?
The maximum number of lines. See SelectableText.maxLines.
final
minLines int?
The minimum number of lines to occupy. See SelectableText.minLines.
final
onSelectionChanged SelectionChangedCallback?
Called when the user changes the selection (including cursor position).
final
onTap GestureTapCallback?
Called when the user taps on the text.
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
sampleLength int?
Maximum number of characters to sample for direction detection.
final
scrollPhysics ScrollPhysics?
The ScrollPhysics to use when vertically scrolling the input.
final
selectionControls TextSelectionControls?
Optional delegate for building the text selection controls.
final
selectionHeightStyle BoxHeightStyle
Controls how tall the selection highlight boxes are. See SelectableText.
final
selectionWidthStyle BoxWidthStyle
Controls how wide the selection highlight boxes are. See SelectableText.
final
semanticsLabel String?
An optional semantics label for this widget. See SelectableText.semanticsLabel.
final
showCursor bool
Whether to show cursor.
final
strutStyle StrutStyle?
The strut style used for the vertical layout.
final
style TextStyle?
The text style to apply. If null, inherits from the ambient DefaultTextStyle.
final
textAlign TextAlign?
How the text should be aligned horizontally.
final
textHeightBehavior TextHeightBehavior?
final
textScaler TextScaler?
final
textSpan TextSpan?
The TextSpan for rich text. Non-null only when using BidiSelectableText.rich.
final
textWidthBasis TextWidthBasis?
Defines how to measure the width of the rendered text.
final

Methods

build(BuildContext context) Widget
Describes the part of the user interface represented by this widget.
override
createElement() StatelessElement
Creates a StatelessElement to manage this widget's location in the tree.
inherited
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a one-line detailed description of the object.
inherited
toStringShort() String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited