-
Notifications
You must be signed in to change notification settings - Fork 0
LayrzTextAreaInput
Multiline text entry field for longer prose, notes, and descriptions.
Specification Status: Derived from multiline mode of
layrz_theme.ThemedTextInput. This documentation reflects the current layrz_theme API and is NOT YET CONFIRMED as the design for layrz_ui. Team review and design sign-off are required before implementation.
| Property | Value |
|---|---|
| Mirror |
ThemedTextInput with maxLines > 1
|
| Phase | M3 Inputs |
| Domain | Inputs |
| SDK Primitive |
EditableText with custom TextSelectionControls
|
Architectural question: LayrzTextAreaInput is distinct from picker-style inputs because it needs an EDITABLE text field, not a read-only one. Unlike LayrzSelectInput, LayrzDateInput, etc., it cannot follow the "compose a read-only LayrzTextInput, open a dialog" pattern.
Should LayrzTextAreaInput:
- Inherit the Input Contract's standard API (label, prefix, suffix, help affordances, focus, etc.)?
- Or is it a separate implementation that reuses the Input Contract's visual chrome but not the composition pattern?
-
Value type:
String— multiline text content - Interaction pattern: A resizable text box with scrolling support
- Summary display: Shows text directly (not summarized into a single line)
-
Line count: Configurable via
minLines,maxLines, and expandable height
// Design sketch — illustrative only
class LayrzTextAreaInput extends StatefulWidget {
/// The current text content.
final String? value;
/// Callback invoked when the text changes.
final void Function(String)? onChanged;
/// Callback invoked when the user submits (if applicable).
final void Function(String)? onSubmit;
/// Minimum number of lines displayed (expands if content exceeds this).
final int minLines;
/// Maximum number of lines before scrolling is enabled.
final int maxLines;
/// Maximum number of characters allowed (if any).
final int? maxLength;
/// Placeholder text shown when empty.
final String? placeholder;
/// Keyboard type (multiline text, numbers, punctuation, etc.).
final TextInputType keyboardType;
/// Text input action (e.g., TextInputAction.newline for Enter behavior).
final TextInputAction textInputAction;
/// Input formatters to apply (e.g., length limits, character filters).
final List<TextInputFormatter> inputFormatters;
const LayrzTextAreaInput({
required this.value,
this.onChanged,
this.onSubmit,
this.minLines = 3,
this.maxLines = 10,
this.maxLength,
this.placeholder,
this.keyboardType = .multiline,
this.textInputAction = .newline,
this.inputFormatters = const [],
// ... shared contract parameters (label, prefix, suffix, help, errors, etc.)
});
}Inherits the full Input Contract chrome:
// Design sketch — shared with LayrzTextInput:
class LayrzTextAreaInput {
/// Label displayed above the field.
final String? labelText;
/// Custom label widget (mutually exclusive with labelText).
final Widget? label;
/// Placeholder/hint text (shown when empty).
final String? placeholder;
/// Icon in the prefix slot.
final IconData? prefixIcon;
/// Custom widget in the prefix slot (mutually exclusive with prefixIcon).
final Widget? prefixWidget;
/// Callback when prefix is tapped.
final VoidCallback? onPrefixTap;
/// Icon in the suffix slot.
final IconData? suffixIcon;
/// Custom widget in the suffix slot (mutually exclusive with suffixIcon).
final Widget? suffixWidget;
/// Callback when suffix is tapped.
final VoidCallback? onSuffixTap;
/// Help title for tooltip.
final String? helpTitleText;
/// Help content for tooltip.
final String? helpContentText;
/// Padding inside the field.
final EdgeInsets? padding;
/// Error messages to display below the field.
final List<String> errors;
/// Whether to display errors and help text.
final bool hideDetails;
/// Focus node for managing focus.
final FocusNode? focusNode;
/// Text controller for external value management.
final TextEditingController? controller;
/// Whether the field is disabled.
final bool disabled;
/// Whether the field is read-only (editing not allowed).
final bool readOnly;
/// Character count display (optional).
final bool showCharacterCount;
}Same disposal contract as LayrzTextInput:
- If
focusNodeis null, the widget creates one and disposes it when the widget is disposed. - If
focusNodeis provided by the caller, the widget does NOT dispose it. - If
controlleris null, the widget creates one and disposes it. - If
controlleris provided by the caller, the widget does NOT dispose it.
ThemedTextInput with maxLines > 1 (source: lib/src/inputs/src/general/text_input.dart):
| Parameter | Type | Notes |
|---|---|---|
value |
String? |
Current text content |
onChanged |
void Function(String)? |
Text change callback |
onSubmitted |
VoidCallback? |
Submitted callback (Enter on desktop) |
controller |
TextEditingController? |
Text controller |
labelText |
String? |
Label text |
label |
Widget? |
Label widget |
placeholder |
String? |
Placeholder text |
maxLines |
int |
Max lines before scrolling (default: 1; >1 for textarea) |
minLines |
Not exposed | (Inferred from current layrz_theme; may need to be explicit in layrz_ui) |
prefixIcon |
IconData? |
Icon in prefix slot |
prefixWidget |
Widget? |
Custom prefix widget |
onPrefixTap |
VoidCallback? |
Prefix tap handler |
suffixIcon |
IconData? |
Icon in suffix slot |
suffixWidget |
Widget? |
Custom suffix widget |
onSuffixTap |
VoidCallback? |
Suffix tap handler |
errors |
List<String> |
Error messages |
hideDetails |
bool |
Hide errors/help text |
padding |
EdgeInsets? |
Field padding |
disabled |
bool |
Disable the field |
readonly |
bool |
Read-only (no editing) |
focusNode |
FocusNode? |
Focus node |
keyboardType |
TextInputType |
Keyboard type (default: text) |
textInputAction |
TextInputAction? |
Enter key behavior |
inputFormatters |
List<TextInputFormatter> |
Input formatters |
autofillHints |
List<String> |
Autofill hints |
autocorrect |
bool |
Spell check (default: true) |
enableSuggestions |
bool |
Suggestions (default: true) |
autofocus |
bool |
Auto-focus on mount |
obscureText |
bool |
Mask text (for password-like fields) |
-
Material-free TextSelectionControls — CRITICAL BLOCKER. The SDK's
EditableTextrequires a concreteTextSelectionControlsimplementation. Material's version must be replaced with a hand-rolled Material Design Free version that provides:- Text selection (tap and drag to select)
- Copy/paste (long-press or keyboard shortcuts)
- Cut operations
- Selection toolbar with context menu (desktop)
- Mobile selection handles with magnifier
- Undo/redo if desired
This is the same blocker as for LayrzTextInput and the entire input family.
-
Multiline detection:
maxLines > 1enables multiline mode. When maxLines is 1 (the default), the field is single-line. -
Line-limited scrolling: If content exceeds
maxLines, the field becomes vertically scrollable. - Enter key: In multiline mode, Enter inserts a newline (does not submit by default).
-
Character limit: If
maxLengthis set, the field is limited to that many characters. Some input formatters can enforce this.
-
Separate component or factory?: Should LayrzTextAreaInput be:
- A distinct widget class (recommended for clarity)?
- A factory constructor of LayrzTextInput (e.g.,
LayrzTextInput.multiline())? - Or a parameter-driven variant (e.g.,
LayrzTextInput(isMultiline: true))?
-
Minimum line count: Should there be an explicit
minLinesparameter to control the initial height, or is it inferred frommaxLines? -
Character count display: Should the field optionally show "123 / 500" character count below the field? Is this built-in or handled via suffix widget?
-
Resizability: Can the user resize the textarea by dragging a corner handle, or is height fixed by
maxLines? -
Word wrap and overflow: Is text always wrapped within the field width, or can it overflow horizontally?
-
Undo/redo support: Should undo/redo be built-in or depend on the caller's controller?
-
Spell-check and suggestions: On mobile, should there be platform-specific spell-check overlays? Should
autocorrectandenableSuggestionsbe exposed in layrz_ui? -
Material-free TextSelectionControls: This is a CRITICAL BLOCKER. What is the implementation plan for copy/paste, selection toolbar, and mobile selection handles?
Last updated: 2026-08-13
Related documents: Input Contract, Flutter 347 Audit, Component Catalog, Design Tokens
Made with ❤️ by Golden M, Inc.
- LayrzTextInput
- LayrzSelectableAction
- LayrzSelectionToolbar
- LayrzTextSelectionControls
- LayrzSelectionMagnifier
- LayrzSelectionHandlePainter
- LayrzTextAreaInput
- LayrzComboBoxInput
- LayrzNumberInput
- LayrzPasswordInput
- LayrzCheckboxInput
- LayrzRadioInput
- LayrzSelectInput
- LayrzMultiSelectInput
- LayrzSearchInput
- LayrzDualListInput
- LayrzDurationInput