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