Skip to content

TextInput

A single-line editable text field. Read or set its text through a TextEditingController, or react to edits with onChanged and onSubmit.

See also: TextArea for multiline text · CompletionTextInput for inline suggestions.

Learn more: Forms & validation

Import: package:fleury/fleury.dart, or package:fleury/fleury_core.dart in browser code.

TextInput(
placeholder: 'Command',
onChanged: (text) => updateDraft(text),
onSubmit: (text) => runCommand(text),
)
// To read or set the text from code, pass a controller your State creates
// once and disposes:
TextInput(controller: controller, onSubmit: (text) => runCommand(text))

While focused, the field takes typed characters, so a binding in an enclosing KeyBindings whose first key is one, such as q, doesn’t fire. A typed character that continues a sequence already under way still reaches its binding: the b of Ctrl+X b completes it. Other keys the field doesn’t use, such as Ctrl+S, pass on to enclosing widgets. With the default keymap (TextEditingKeymap.defaultSingleLine):

  • Left and Right move the caret. At either end of the text, with nothing selected, an unmodified press passes on instead, so arrow-key focus traversal can move on. Ctrl+Left and Ctrl+Right (or Alt+Left and Alt+Right) move by word, and Home and End jump to the start and end. Add Shift to any of these to extend the selection.
  • Backspace and Delete delete a character; Ctrl+Backspace or Alt+Backspace deletes the word before the caret.
  • Ctrl+A selects all. Ctrl+C copies and Ctrl+X cuts the selection; with nothing selected they pass on, so an unhandled Ctrl+C still quits a terminal app.
  • Ctrl+Z undoes. The field consumes Ctrl+Z even with nothing to undo, so a terminal app doesn’t suspend on it while the field has focus. Ctrl+Y redoes, as does Ctrl+Shift+Z where the terminal can report it.
  • Up and Down move through an open completion list (see completionController); without one, they step through historyController’s entries. Otherwise they pass on.
  • Tab accepts the selected completion; without an open completion list, it passes on.
  • Enter calls onSubmit. The field consumes Enter even when onSubmit is null.
  • Escape closes an open completion list; otherwise it calls onEscape, or passes on when onEscape is null.

Where the terminal or browser reports the Super key (Cmd on macOS), Super+A, Super+C, Super+X, Super+Z, and Super+Shift+Z do the same as their Ctrl forms. TextEditingKeymap.emacsSingleLine adds Emacs-style keys and takes over Ctrl+A and Ctrl+Y: among others, Ctrl+A and Ctrl+E jump to the start and end; Ctrl+K, Ctrl+U, and Ctrl+W cut text into a kill ring shared by all fields; and Ctrl+Y pastes it back.

Unless the controller opts into preserving text, input is canonicalized before it reaches the model: control bytes are replaced and escape sequences are collapsed, so the field’s content is exactly what it draws. See TextEditingController for the rules and what an app reads back.

ParameterTypeDefaultDescription
controller:TextEditingController?—External controller for the text. If null, the widget creates its own and disposes it on unmount.
focusNode:FocusNode?—External FocusNode. Provide one when a parent needs to drive focus (e.g. Tab cycling between panes). If null, the widget creates its own and disposes it on unmount.
autofocus:boolfalseWhether to request focus on first mount.
onChanged:void Function(String text)?—Called after typing, deletion, paste, history navigation, completion, or a semantic edit changes the text. Programmatic controller writes do not call this; use controller listeners to observe changes from any origin. Cursor-only moves and rejected edits do not call this callback.
onSubmit:void Function(String text)?—Called with the current text when the user presses Enter. The field consumes Enter even when this is null.
onEscape:void Function()?—Called when the user presses Escape while no completion list is open (Escape closes an open one first). If null, Escape passes on to enclosing widgets.
placeholder:String''Hint text shown when the field is empty. Cleared as soon as the user types.
placeholderStyle:CellStyleconst CellStyle(dim: true)Style for the placeholder text. Defaults to dim.
style:CellStyleCellStyle.noneStyle for the rendered text and its interactive states. More
cursorStyle:CellStyleconst CellStyle(inverse: true)Style merged on top of style at the cursor cell. Defaults to inverse: true — a block cursor.
blinkInterval:Durationconst Duration(milliseconds: 500)On/off cadence for the blinking cursor. Default matches native terminal conventions (~500 ms).
enableBlink:booltrueWhen true (default), the cursor blinks while the widget is focused. When false, the cursor is rendered solid whenever the widget is focused. The cursor is always suppressed when the widget is unfocused.
obscureText:boolfalseWhen true, each grapheme of the field’s text is replaced with obscuringCharacter at paint time. The controller still holds the real text — only the displayed glyphs are masked. Use for password / secret entry.
obscuringCharacter:String'•'The glyph used to replace each character when obscureText is true. Defaults to •.
enabled:booltrueWhether the field can receive focus and handle input.
readOnly:boolfalseWhether the field can receive focus but refuses text mutations. More
validationError:String?—Validation error attached directly to this input’s current value. More
semanticLabel:String?—Label exposed through the semantic app graph. More
semanticState:SemanticStateSemanticState.emptyExtra semantic state merged into the text-field node. More
clipboardPolicy:TextClipboardPolicy?—How copy, cut, and the kill ring treat this field’s text. Null (the default) means TextClipboardPolicy.redacted when obscureText is true and TextClipboardPolicy.allowed otherwise. More
historyController:TextHistoryController?—Optional command/submission history for Up/Down navigation. More
commitHistoryOnSubmit:booltrueWhether Enter adds the submitted text to historyController before calling onSubmit. Has no effect when onSubmit is null.
completionController:TextCompletionController?—Completion state for this field: while its list is open, Up and Down move the selected option, Tab accepts it, and Escape closes the list. More
onCompletionAccepted:void Function(TextCompletionOption option)?—Called after a selected completion option is applied.
keymap:TextEditingKeymapTextEditingKeymap.defaultSingleLineWhich keys trigger which editing actions. Defaults to TextEditingKeymap.defaultSingleLine; TextEditingKeymap.emacsSingleLine adds Emacs-style keys such as Ctrl+A, Ctrl+E, and Ctrl+K.
pastePolicy:TextPastePolicyconst TextPastePolicy()Policy for chunking large bracketed paste payloads.
  • style: Pass a plain CellStyle for the common case. Use CellStyle.interactive only when focus, hover, disabled, or invalid should look different locally.
  • readOnly: Cursor movement and submit/escape callbacks still work while read-only.
  • validationError: Use this when the input is not inside a FormField. An enclosing FormField supplies its current error automatically.
  • semanticLabel: When omitted, placeholder is used as the field label when non-empty. Use this when a visible form label sits outside the field or the placeholder is example text rather than the durable field name.
  • semanticState: Specialized fields can use this to expose stable domain facts such as numeric bounds while keeping the core text editing role and actions.
  • clipboardPolicy: An explicit value applies whether or not the text is obscured: setting TextClipboardPolicy.allowed on an obscureText field deliberately lets its plain text reach both the clipboard (copy and cut) and the kill ring that all fields share. Leave it null, or set TextClipboardPolicy.redacted, to keep a password field’s content out of both.
  • historyController: History is opt-in so fields embedded in palettes, autocompletes, and other parent-owned navigation surfaces keep bubbling Up/Down by default.
  • completionController: The field doesn’t draw the list or produce suggestions; a widget such as the bundled CompletionTextInput does that around it.

TextInput is defined in packages/fleury/lib/src/widgets/text_input.dart.

Category: Inputs & controls · All widgets