Text Area
A text area: a field for text of several lines, a comment, a message or a note, that grows with what is typed and then scrolls, under a label, with help or an error's message below it and a count of its characters.
import com.pantrixui.components.inputs.textarea.PantrixTextArea
- Three overloads. The one that takes a
statekeeps the text in aTextFieldState. The one that takes avalueand anonValueChangekeeps the text in its caller; the text field underneath does not tell how far it is scrolled, so its box has no bar. The one that takes afieldtakes its value, its error and its name from the form's field. - Lines.
minLines(3 by default) says how many lines the box is at the least, andmaxLines(8 by default) at the most. AModifier.heightgiven to the field takes the place of the lines, and the text scrolls inside the box. - Enter is a new line. The keyboard's action key is always the new line: on Android another action would take the place of the key for a new line. Sending is
onSubmit's: Ctrl+Enter or Cmd+Enter on a hardware keyboard. A software keyboard has no such keys; the screen gives a send button as well. Tab moves the focus on and types no tab. - A soft limit.
maxLengthcan be passed (TextLimit.Allow): past it the count says how far past in words ("12 over the limit"), and the count and the border turn to the error's colour. A paste that does not fit is taken whole, and the user cuts it where they choose. A form is not submitted with a bound field's text past the limit.TextLimit.Blockturns an edit past the limit down whole, as a text field's limit does. - Icons and the clear button.
leadingIcon,trailingIconandshowClearButtonstand at the first line, not in the middle of the box. - The handle that resizes. On the platforms used with a pointer, a desktop and the web, the handle in the box's bottom corner drags the box taller and shorter. A dragged box does not grow with its text, and is never shorter than its least lines. A phone has no handle: a finger on the box scrolls the text.
resizable = falsetakes the handle away. - Style, colours and direction.
style(TextFieldStyle) andcolors(TextFieldColors) are the text field's; the handle takes the icon's colour and the bar thescrollBarcolour. In a right-to-left layout the handle is in the bottom corner at the left.
Examples
A comment that grows
A comment field: three lines while it is empty, it grows a line at a time as it is typed in, and at eight lines the text scrolls inside the box. The thin bar at the box's end shows how far the text is scrolled. A sentence starts with a capital: the keyboard opens that way.
maxLength = 500 writes the count under the box. The line below reads comment.text as it is typed.
val comment = rememberTextFieldState()
PantrixTextArea(
state = comment,
modifier = Modifier.fillMaxWidth(),
label = "Comment",
placeholder = "What did you think of the product?",
supportingText = "Your comment is public",
maxLength = 500,
tagKey = "comment"
)
PantrixText(
text = "Lines: ${comment.text.lines().size}",
color = PantrixTheme.colors.textSecondary
)
A field given a height
A height given to the field is the whole field's: Modifier.height(200.dp). The box fills what the label and the count leave of it; that height takes the place of the lines, and a text that does not fit scrolls inside the box.
The second field is given heightIn: the handle drags the box only within that range. A fixed height leaves the handle nothing to move.
PantrixTextArea(
state = rememberTextFieldState(DELIVERY_NOTES),
modifier = Modifier.fillMaxWidth().height(200.dp),
label = "Delivery instructions",
showClearButton = true,
maxLength = 400,
tagKey = "instructions"
)
PantrixTextArea(
state = rememberTextFieldState(),
modifier = Modifier.fillMaxWidth().heightIn(max = 320.dp),
label = "Extra note",
supportingText = "The handle makes it 320dp tall at the most",
tagKey = "extra_note"
)
private const val DELIVERY_NOTES =
"Use the back door of the building; the bell on the front door does not work. The lift is serviced on Fridays, " +
"take the stairs to the third floor. If I am out, leave the parcel with the porter, Mr Hasan. Thank you!"
A soft limit and the count
The limit is soft: the text may pass 140 characters. Past it the count says how far past in words ("6 over the limit"), the count and the border turn to the error's colour, and a screen reader is told the field's error, "Too long". Paste a long text: it is taken whole, and you can cut it where you choose.
Type and stop with a screen reader on: the count is told once, after typing stops.
PantrixTextArea(
state = rememberTextFieldState(ALMOST_A_POST),
modifier = Modifier.fillMaxWidth(),
label = "Post",
supportingText = "140 characters at the most",
minLines = 2,
maxLength = 140,
// The default: the text may pass the limit.
overLimit = TextLimit.Allow,
tagKey = "post"
)
private const val ALMOST_A_POST =
"The new version is out! A dark theme, faster search and an offline mode are here. Tell us what you think; " +
"your comments guide us."
A limit that blocks, on a field whose text is a String
overLimit = TextLimit.Block turns down an edit past the limit whole: typing stops at the limit, and a paste that does not fit is not put in at all.
This field holds its text as a String: value and onValueChange. An edit past the limit is never asked of onValueChange. The text field underneath does not tell how far it is scrolled, so this overload's box has no bar.
var reason by remember { mutableStateOf("") }
PantrixTextArea(
value = reason,
onValueChange = { reason = it },
modifier = Modifier.fillMaxWidth(),
label = "Reason for the return",
placeholder = "In a few words",
minLines = 2,
maxLines = 4,
maxLength = 80,
overLimit = TextLimit.Block,
tagKey = "return_reason"
)
Sending with Ctrl/Cmd+Enter
onSubmit is called by Ctrl+Enter or Cmd+Enter on a hardware keyboard; Enter alone starts a new line. A software keyboard has no such keys, so a "Send" button stands beside it as well. Type a message and press Ctrl+Enter: the app's snackbar says the message was sent, and the field is emptied.
The send is reported as an event (submit); what was typed never is.
val snackbars = LocalPantrixSnackbars.current
val scope = rememberCoroutineScope()
val message = rememberTextFieldState()
val send = {
if (message.text.isNotBlank()) {
scope.launch { snackbars?.show(message = "Message sent", tagKey = "message_sent") }
message.clearText()
}
}
PantrixTextArea(
state = message,
modifier = Modifier.fillMaxWidth(),
label = "Message",
placeholder = "Send with Ctrl+Enter or Cmd+Enter",
minLines = 2,
maxLines = 6,
onSubmit = send,
tagKey = "message"
)
PantrixButton(text = "Send", onClick = send, tagKey = "send_message")
Bound to a form's field
The PantrixTextArea that takes a field takes its value, its error and its name from the form's field: no tagKey is given, the field's id is the automation key (TextArea_<id>). With form given, Ctrl+Enter or Cmd+Enter submits the form through the "Save" button.
The limit is soft, but the form is not submitted with a text past it: the field is in error with "Too long", the count says how far past, and the focus goes to the field. Leave the field empty, or go past 160 characters, and press "Save".
val snackbars = LocalPantrixSnackbars.current
val scope = rememberCoroutineScope()
val form = rememberFormState()
PantrixTextArea(
field = form.field("bio", initial = "", Rules.notBlank("Tell us about yourself in a few sentences")),
modifier = Modifier.fillMaxWidth(),
form = form,
label = "About me",
supportingText = "Shown on your profile",
maxLength = 160
)
PantrixButton(
text = "Save",
onClick = {
scope.launch { form.submit { snackbars?.show(message = "Profile saved", tagKey = "bio_saved") } }
},
form = form,
tagKey = "save_bio"
)
Disabled and read-only
enabled = false draws the field in the theme's disabled colours: it takes no focus, cannot be typed into, has no handle, and a screen reader is told it is disabled.
readOnly = true only stops changes: the field is focused, its text selected, copied and scrolled; it can be made taller with the handle and read.
PantrixTextArea(
state = rememberTextFieldState("Your order has shipped; no note can be added."),
modifier = Modifier.fillMaxWidth(),
enabled = false,
label = "Shipping note",
minLines = 2,
tagKey = "shipping_note"
)
PantrixTextArea(
state = rememberTextFieldState(RETURN_POLICY),
modifier = Modifier.fillMaxWidth(),
readOnly = true,
label = "Return policy",
maxLines = 4,
tagKey = "return_policy"
)
private const val RETURN_POLICY =
"You can return the product within 14 days of the day you received it. It must be unused, with its labels " +
"still on and in its original packaging. We pay for the return shipping. Your money goes back to the card you " +
"paid with within 3 working days of the product reaching our warehouse."
Its own colours and style
colors and style are the text field's: TextFieldColors and TextFieldStyle. The colours that are given are used, and the rest stay the theme's roles. The first field's border, caret and scroll bar are the app's own purple; the handle and the clear button take the icon's colour.
The second field's style draws the box rounder with ShapeRole.Large and gives it more padding.
val own = ownColors()
PantrixTextArea(
state = rememberTextFieldState(DELIVERY_NOTES),
modifier = Modifier.fillMaxWidth(),
label = "Note",
showClearButton = true,
maxLines = 4,
colors = TextFieldColors(
focusedBorder = own.color,
cursor = own.color,
icon = own.color,
scrollBar = own.color
),
tagKey = "own_colors"
)
PantrixTextArea(
state = rememberTextFieldState(),
modifier = Modifier.fillMaxWidth(),
label = "Description",
style = TextFieldStyle(shape = ShapeRole.Large, horizontalPadding = 20.dp, verticalPadding = 16.dp),
tagKey = "own_style"
)
private const val DELIVERY_NOTES =
"Use the back door of the building; the bell on the front door does not work. The lift is serviced on Fridays, " +
"take the stairs to the third floor. If I am out, leave the parcel with the porter, Mr Hasan. Thank you!"
The handle that resizes
On a desktop and on the web, drag the handle in the box's bottom corner: the box gets taller or shorter, and the pointer turns to an up-and-down resize arrow. A dragged box keeps that height and does not grow with its text; nor is it ever shorter than its least lines. A phone has no handle.
The second field has resizable = false: no handle, and the box grows with its text alone.
PantrixTextArea(
state = rememberTextFieldState(),
modifier = Modifier.fillMaxWidth(),
label = "Meeting notes",
supportingText = "Make it taller with the handle in the bottom corner",
tagKey = "meeting_notes"
)
PantrixTextArea(
state = rememberTextFieldState(),
modifier = Modifier.fillMaxWidth(),
label = "Short note",
minLines = 2,
maxLines = 4,
resizable = false,
tagKey = "short_note"
)
Right to left
In a right-to-left layout the icon and the clear button swap places, the handle moves to the bottom corner at the left, and the scroll bar stands at the box's left: that is where a line ends. Each paragraph takes its direction from its own first letter.
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
PantrixTextArea(
state = rememberTextFieldState(ARABIC_NOTE),
modifier = Modifier.fillMaxWidth(),
label = "ملاحظة",
leadingIcon = {
PantrixIcon(
imageVector = PantrixIcons.Person,
contentDescription = null,
size = PantrixTheme.style(TextFieldStyle).iconSize
)
},
showClearButton = true,
maxLines = 3,
maxLength = 200,
tagKey = "arabic_note"
)
}
private const val ARABIC_NOTE = "يرجى ترك الطرد عند البواب إذا لم أكن في المنزل. شكراً لكم!"
A tap outside puts the keyboard away
On iOS the keyboard of a field of several lines has no key that puts it away. Modifier.clearFocusOnTap() clears the focus when an empty part of this column is tapped, and the keyboard goes. A tap on the field or on a button is theirs: the caret moves, the button does its work. A scroll is no tap.
The app's root does the same: in this catalogue a tap on any empty part of the page puts the keyboard away.
Column(
modifier = Modifier.fillMaxWidth().clearFocusOnTap(),
verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)
) {
PantrixTextArea(
state = rememberTextFieldState(),
modifier = Modifier.fillMaxWidth(),
label = "Feedback",
minLines = 2,
tagKey = "feedback"
)
PantrixText(
text = "Tap here to put the keyboard away",
color = PantrixTheme.colors.textSecondary
)
}
API
state
A text area: a field for text of several lines, a comment, a message or a note, that grows with what is typed and then scrolls, under a label, with help or an error's message below it and a count of its characters.
| Parameter | Type | Default | What it is |
|---|---|---|---|
state | TextFieldState | the text and the selection. Create it with rememberTextFieldState(), and read what was typed from it: state.text where the text is used, or snapshotFlow { state.text.toString() } to follow it as it changes. | |
modifier | Modifier | Modifier | the modifier of the whole field: its label, its box and what is under it. fillMaxWidth() makes the box as wide as its parent. A height is the whole field's as well, in place of its lines: the box fills what the label and the supporting text leave of it, and its text scrolls in it. The handle moves the box only within such a height, so a field that is to be dragged is given heightIn and not height. |
enabled | Boolean | true | whether the field can be typed into. One that cannot takes no focus, is drawn in the disabled colours, has no handle and says so. |
readOnly | Boolean | false | whether the text can only be read: it can still be focused, selected, copied, scrolled and dragged taller. |
label | String? | null | what the field is for, written above the box: the field's name for a screen reader. |
placeholder | String? | null | shown in the box while it is empty. It is no label: it goes as soon as the user types. |
supportingText | String? | null | help under the box, in a smaller type. With error it is the message that says what to put right, which a screen reader announces as the error. |
error | Boolean | false | whether the text is wrong: the border, the label, the supporting text and the caret turn to the danger role, and a screen reader is told. A text past a soft maxLength is drawn in error as well. |
leadingIcon | (@Composable () -> Unit)? | null | what stands before the text, at its first line, in the secondary text colour. A slot does not size what is put in it: PantrixIcon(size = PantrixTheme.style(TextFieldStyle).iconSize) is the platform's size. |
trailingIcon | (@Composable () -> Unit)? | null | what stands after the text at its first line, and after the clear button. |
showClearButton | Boolean | false | shows a button at the first line that empties the field, while the field can be typed into and is not empty. It leaves the caret in the field. It is no stop for Tab, and a screen reader still reaches it as a button. |
minLines | Int | 3 | how many lines tall the box is at the least: while it is empty, and when it is dragged its shortest. At least one. |
maxLines | Int | 8 | how many lines tall the box grows to with its text before the text scrolls in it. No fewer than minLines: the two the same give a box that keeps its height. |
resizable | Boolean | true | whether a handle in the box's bottom corner drags it taller or shorter. Only where the platform is used with a pointer, a desktop's or a browser's: on a phone a finger on the box scrolls its text. |
maxLength | Int? | null | the most characters the text should hold, counted as String.length counts them, so that an emoji can count as two. What an edit past it does is overLimit's. It has to be positive. |
overLimit | TextLimit | TextLimit.Allow | what an edit past maxLength does: TextLimit.Allow takes it and shows that the text is too long, and TextLimit.Block turns it down whole. |
showCharacterCount | Boolean | true | shows the count under the box while maxLength is set: 120/500, and past the limit how far past it, 12 over the limit. A screen reader is told it once typing pauses, at the limit and past it. |
onSubmit | (() -> Unit)? | null | called for Ctrl and Enter, or Cmd and Enter, on a hardware keyboard: the text is sent. Null leaves both keys to the field. It is reported, and the text never is. |
keyboardOptions | KeyboardOptions | KeyboardOptions(capitalization = KeyboardCapitalization.Sentences) | the keyboard's type, its capitals and its corrections: a sentence starts with a capital unless told otherwise. The keyboard's action is always the new line, whatever is named here. |
inputTransformation | InputTransformation? | null | what is done to the text as the user types it. With a maxLength that blocks, it comes first and the limit applies to what it lets through. |
outputTransformation | OutputTransformation? | null | how the text is shown, without changing it. |
style | TextFieldStyle? | null | this call's own style, the text field's: over every enclosing one and under the density. Only the fields it sets change, on every platform. |
colors | TextFieldColors? | null | this call's own colours, the text field's, in place of the theme's roles: the ones it sets are used, and the rest stay the theme's. A disabled field is drawn in the theme's disabled colours whatever is given. |
contentDescription | String? | null | what a screen reader says for the field: its name where it has no label. A placeholder that says the same is then left to the eye, so that the field is not named twice while it is empty. |
tagKey | String? | null | the field's automation key: the field is TextArea_<tagKey>, its clear button TextAreaClear_<tagKey> and its handle TextAreaResize_<tagKey>. The field reports that it took the focus, that it was cleared and that it was submitted, and never its text. |
interactionSource | MutableInteractionSource? | null | the field's interactions, hoisted: its focus, its hover and its presses. It keeps a source of its own when this is null. |
value
A text area whose text is a String its caller holds: value is what it shows, and onValueChange is asked for every change the user makes.
| Parameter | Type | Default | What it is |
|---|---|---|---|
value | String | the text the field shows. | |
onValueChange | (String) -> Unit | asked for each change the user makes, with the whole new text, and by the clear button with an empty one. | |
modifier | Modifier | Modifier | the modifier of the whole field: its label, its box and what is under it. A height is the whole field's, in place of its lines. |
enabled | Boolean | true | whether the field can be typed into. One that cannot takes no focus, is drawn in the disabled colours, has no handle and says so. |
readOnly | Boolean | false | whether the text can only be read: it can still be focused, selected and copied. |
label | String? | null | what the field is for, written above the box: the field's name for a screen reader. |
placeholder | String? | null | shown in the box while it is empty. |
supportingText | String? | null | help under the box. With error it is the message that says what to put right, which a screen reader announces as the error. |
error | Boolean | false | whether the text is wrong: the border, the label, the supporting text and the caret turn to the danger role, and a screen reader is told. A text past a soft maxLength is drawn in error as well. |
leadingIcon | (@Composable () -> Unit)? | null | what stands before the text, at its first line. |
trailingIcon | (@Composable () -> Unit)? | null | what stands after the text at its first line, and after the clear button. |
showClearButton | Boolean | false | shows a button at the first line that asks for an empty text, while the field can be typed into and is not empty. It leaves the caret in the field, and is no stop for Tab. |
minLines | Int | 3 | how many lines tall the box is at the least. At least one. |
maxLines | Int | 8 | how many lines tall the box grows to with its text before the text scrolls in it. No fewer than minLines. |
resizable | Boolean | true | whether a handle in the box's bottom corner drags it taller or shorter, where the platform is used with a pointer. |
maxLength | Int? | null | the most characters the text should hold, counted as String.length counts them. What an edit past it does is overLimit's. It has to be positive. |
overLimit | TextLimit | TextLimit.Allow | what an edit past maxLength does: TextLimit.Allow asks for it and shows that the text is too long, and TextLimit.Block turns it down before onValueChange is asked. |
showCharacterCount | Boolean | true | shows the count under the box while maxLength is set, and past the limit how far past it. |
onSubmit | (() -> Unit)? | null | called for Ctrl and Enter, or Cmd and Enter, on a hardware keyboard. Null leaves both keys to the field. |
keyboardOptions | KeyboardOptions | KeyboardOptions(capitalization = KeyboardCapitalization.Sentences) | the keyboard's type, its capitals and its corrections. The keyboard's action is always the new line, whatever is named here. |
style | TextFieldStyle? | null | this call's own style, the text field's: over every enclosing one and under the density. |
colors | TextFieldColors? | null | this call's own colours, the text field's, in place of the theme's roles. A disabled field is drawn in the theme's disabled colours whatever is given. |
contentDescription | String? | null | what a screen reader says for the field where it has no label. |
tagKey | String? | null | the field's automation key: the field is TextArea_<tagKey>, its clear button TextAreaClear_<tagKey> and its handle TextAreaResize_<tagKey>. The field reports that it took the focus, that it was cleared and that it was submitted, and never its text. |
interactionSource | MutableInteractionSource? | null | the field's interactions, hoisted. It keeps a source of its own when this is null. |
field
A text area bound to a form's field: its text, its error and its name come from field.
| Parameter | Type | Default | What it is |
|---|---|---|---|
field | FormField<String> | the field the text area shows and changes. | |
modifier | Modifier | Modifier | the modifier of the whole field. |
form | FormState? | null | given, Ctrl and Enter, or Cmd and Enter, submit the form through the button registered with it: the form is checked, and then submitted or the focus sent to its first field in error. Enter alone starts a new line. An onSubmit of the caller's own takes the place of the form's submit. |
enabled | Boolean | true | whether the field can be typed into. |
readOnly | Boolean | false | whether the text can only be read. |
label | String? | null | what the field is for, written above the box: the field's name for a screen reader. |
placeholder | String? | null | shown in the box while it is empty. |
supportingText | String? | null | help under the box, while the field has no error to show there. |
leadingIcon | (@Composable () -> Unit)? | null | what stands before the text, at its first line. |
trailingIcon | (@Composable () -> Unit)? | null | what stands after the text at its first line, and after the clear button. |
showClearButton | Boolean | false | shows a button that empties the field, while it can be typed into and is not empty. |
minLines | Int | 3 | how many lines tall the box is at the least. At least one. |
maxLines | Int | 8 | how many lines tall the box grows to with its text before the text scrolls in it. No fewer than minLines. |
resizable | Boolean | true | whether a handle in the box's bottom corner drags it taller or shorter, where the platform is used with a pointer. |
maxLength | Int? | null | the most characters the text should hold. It has to be positive. |
overLimit | TextLimit | TextLimit.Allow | what an edit past maxLength does: TextLimit.Allow takes it and puts the field in error, and TextLimit.Block turns it down whole. |
showCharacterCount | Boolean | true | shows the count under the box while maxLength is set, and past the limit how far past it. |
onSubmit | (() -> Unit)? | null | called for Ctrl and Enter, or Cmd and Enter, on a hardware keyboard, in place of the form's submit. |
keyboardOptions | KeyboardOptions | KeyboardOptions(capitalization = KeyboardCapitalization.Sentences) | the keyboard's type, its capitals and its corrections. The keyboard's action is always the new line, whatever is named here. |
inputTransformation | InputTransformation? | null | what is done to the text as the user types it. |
outputTransformation | OutputTransformation? | null | how the text is shown, without changing it. |
style | TextFieldStyle? | null | this call's own style, the text field's: over every enclosing one and under the density. |
colors | TextFieldColors? | null | this call's own colours, the text field's, in place of the theme's roles. A disabled field is drawn in the theme's disabled colours whatever is given. |
contentDescription | String? | null | what a screen reader says for the field where it has no label. |
interactionSource | MutableInteractionSource? | null | the field's interactions, hoisted. It keeps a source of its own when this is null. |
TextFieldStyle
PantrixTextField's box: its shape, how tall and how wide it is at the least, the room around its text, its icons and its border.
| Parameter | Type | Default | What it is |
|---|---|---|---|
shape | ShapeSpec | ShapeSpec.Unspecified | The box's shape. A fully round one, ShapeRole.Full, is a pill only while the field holds one line: a field of several lines takes ShapeRole.Large instead, since a capsule's curve runs into the first line of its text. |
height | Dp | Dp.Unspecified | The least the box is tall. |
minWidth | Dp | Dp.Unspecified | The least the box is wide, which keeps an empty field from growing as the user types into it. |
horizontalPadding | Dp | Dp.Unspecified | The room between the box's edge and its text, where no icon is. |
verticalPadding | Dp | Dp.Unspecified | The room above the first line of the text and below the last. |
iconPadding | Dp | Dp.Unspecified | The room around an icon in its slot. |
iconSize | Dp | Dp.Unspecified | The size an icon in a slot should take. A slot does not size what is put in it. |
borderWidth | Dp | Dp.Unspecified | How thick the box's border is. |
focusedBorderWidth | Dp | Dp.Unspecified | How thick the border is while the field has the focus: the border is what shows it. |
textRole | TypeRole? | null | The role of the type scale the text is typed in, and its placeholder set in: the body's, 16sp, on Android and iOS, as Material 3 and iOS type a field, and the label's, 14sp, on the desktop and the web, as a page under a pointer does. A select's box and the fields made on this style take it as well. |
TextFieldColors
What PantrixTextField is painted with, for a field that does not take the theme's: a colour that is set is used, and one that is left out stays the theme's role. A product gives the colours it changes and no others:
| Parameter | Type | Default | What it is |
|---|---|---|---|
container | Color | Color.Unspecified | The box's fill. The theme's surface. |
border | Color | Color.Unspecified | The box's border at rest. The theme's border. |
hoveredBorder | Color | Color.Unspecified | The border under a pointer. The theme's borderHover, a notch stronger than border. |
focusedBorder | Color | Color.Unspecified | The border while the field has the focus. The theme's primary. |
error | Color | Color.Unspecified | What says the text is wrong: the border, the label, the message under the box, the caret, and the count once it is past its limit. The theme's danger. |
text | Color | Color.Unspecified | The typed text. The theme's textPrimary. |
label | Color | Color.Unspecified | The label above the box. Left out, it is drawn as any text is where the field stands, since it is outside the box on whatever the field is put on: in textPrimary on the theme's own ground, and in the content colour of a fill. |
placeholder | Color | Color.Unspecified | The placeholder. The theme's textSecondary. |
supportingText | Color | Color.Unspecified | The help under the box, and the count. The theme's textSecondary. |
icon | Color | Color.Unspecified | What an icon in a slot is drawn in unless it sets a tint of its own, and the clear button's cross. The theme's textSecondary. |
cursor | Color | Color.Unspecified | The caret, and with it the handles and the highlight of a selection. The theme's primary. |
scrollBar | Color | Color.Unspecified | The bar that shows how far the text of a box of several lines is scrolled. The theme's borderStrong: it is a mark beside the text, and the box's soft edge would not be seen there. |
Accessibility
- The count and a screen reader. Up to the limit the count writes "120/500". A screen reader is told it once typing stops, at the limit and past it: told at every key, it would talk over the keyboard's own echo of each letter.
- Putting the keyboard away. On iOS the keyboard of a field of several lines has no key that puts it away.
Modifier.clearFocusOnTap()on the screen's root clears the focus on a tap outside the field, and the keyboard goes; this catalogue does so too.