Pantrix UI

Auto-resize Text Field

A text field whose text gets smaller to stay in view: an amount, a card's number, a short note, anything that is read whole.

import com.pantrixui.components.inputs.autoresizetextfield.PantrixAutoResizeTextField

Examples

At its plainest

The least it takes: a TextFieldState and a label. The field is given no width: the box has its style's least width, and does not grow wider with its text. The address is too long for that box, so it is drawn in a smaller size.

Keep typing: the text shrinks down to its smallest size, the theme's footnote size; there it stops shrinking and scrolls, as the text of any field does. Delete: the text grows back, but not past its style's size, here body.

PantrixAutoResizeTextField(
    state = rememberTextFieldState("Atatürk Bulvarı No: 125, Daire 14, Çankaya"),
    label = "Address",
    tagKey = "plain_address"
)

An amount set large

The amount of a money transfer, in the theme's largest style: textStyle = PantrixTheme.typography.display. A few digits fill the box; with the ones that follow, the digits get as small as it takes to fit, and the box keeps both its width and its height. The box is tall enough to hold a line of this style.

Its keyboard is the decimal one, an input transformation turns down what is not an amount, and an output transformation puts in the dots between the thousands only for display. What is fitted is the text as it is drawn: the dots count too.

The text is read from the state at the moment it is used: amount.text when the button is pressed. What is read is the text that was typed; the dots added for display are no part of it.

val snackbars = LocalPantrixSnackbars.current
val scope = rememberCoroutineScope()
val amount = rememberTextFieldState()
PantrixAutoResizeTextField(
    state = amount,
    modifier = Modifier.fillMaxWidth(),
    label = "Amount",
    placeholder = "0",
    supportingText = "Shrinks as you type, grows back as you delete",
    trailingIcon = { PantrixText(text = "TL") },
    showClearButton = true,
    textStyle = PantrixTheme.typography.display,
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
    inputTransformation = AnAmount,
    outputTransformation = GroupedInThousands,
    tagKey = "transfer_amount"
)
PantrixButton(
    text = "Send",
    onClick = {
        val entered = amount.text.toString()
        val message = if (entered.isEmpty()) "Enter an amount" else "$entered TL will be sent"
        scope.launch { snackbars?.show(message = message, tagKey = "amount_read") }
    },
    tagKey = "send_amount"
)

private val AnAmount = InputTransformation {
    val typed = asCharSequence().toString()
    val amount = typed.replace('.', ',')
    when {
        !AMOUNT.matches(amount) -> revertAllChanges()
        amount != typed -> replace(0, length, amount)
    }
}

private val AMOUNT = Regex("""\d{0,12}(,\d{0,2})?""")

private val GroupedInThousands = OutputTransformation {
    val whole = asCharSequence().indexOf(',').let { comma -> if (comma < 0) length else comma }
    // From right to left: each dot added later lies to the left of those added before it, and does not shift them.
    var at = whole - 3
    while (at > 0) {
        insert(at, ".")
        at -= 3
    }
}

The smallest size

All three fields hold the same address in the title style. The address fits none of their boxes, so each is down to its own smallest size. The first is given no minFontSize: the text shrinks down to the theme's footnote size. In the second the smallest size is 14 sp. In the third it is given in em: 0.8.em, eight tenths of the style's own size.

A text that still does not fit at its smallest size stops shrinking and scrolls, as the text of any field does. With a minFontSize at the style's own size or above it, the text never shrinks.

val address = "Atatürk Bulvarı No: 125, Daire 14, Kızılay Mahallesi, Çankaya, Ankara"
PantrixAutoResizeTextField(
    state = rememberTextFieldState(address),
    label = "Not given: footnote size",
    textStyle = PantrixTheme.typography.title,
    tagKey = "smallest_default"
)
PantrixAutoResizeTextField(
    state = rememberTextFieldState(address),
    label = "Smallest 14 sp",
    textStyle = PantrixTheme.typography.title,
    minFontSize = 14.sp,
    tagKey = "smallest_sp"
)
PantrixAutoResizeTextField(
    state = rememberTextFieldState(address),
    label = "Smallest 0.8 em",
    textStyle = PantrixTheme.typography.title,
    minFontSize = 0.8.em,
    tagKey = "smallest_em"
)

A field whose text is held as a String

A card number of sixteen digits. The caller holds the number as a String: the field shows it and asks for every change, and since a change that is not all digits is not taken, it is not shown either. The supporting text is made from that String. This overload takes its lines as singleLine, minLines and maxLines.

The text is in the title style, and shrinks in a box it does not fit. Its smallest size is the label size (minFontSize = PantrixTheme.typography.label.fontSize): the number is never set smaller than that. The placeholder is in the text's style too.

var number by rememberSaveable { mutableStateOf("") }
val missing = 16 - number.length
PantrixAutoResizeTextField(
    value = number,
    onValueChange = { if (it.all(Char::isDigit)) number = it },
    modifier = Modifier.fillMaxWidth(),
    label = "Card number",
    placeholder = "0000000000000000",
    supportingText = if (missing == 0) "Number complete" else "Digits to go: $missing",
    maxLength = 16,
    showCharacterCount = false,
    textStyle = PantrixTheme.typography.title,
    minFontSize = PantrixTheme.typography.label.fontSize,
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
    contentType = ContentType.CreditCardNumber,
    tagKey = "card_number"
)

An IBAN bound to a form

The overload that takes a field gets its value, its error and its name from its field in the form: if the focus leaves while the IBAN is incomplete, the rule's message takes the place of the supporting text. In a field that is given form, the keyboard's action key submits the form through the "Save IBAN" button. The text of a field bound to a form is the value of the form's field: it does not have to be read separately.

Twenty-six characters in the callout style do not fit a narrow box: the text shrinks, and the whole IBAN stays in view.

val snackbars = LocalPantrixSnackbars.current
val scope = rememberCoroutineScope()
val form = rememberFormState()
PantrixAutoResizeTextField(
    field = form.field("iban", initial = "", Rules.matches(IBAN, "Enter a 26-character IBAN that starts with TR")),
    modifier = Modifier.fillMaxWidth(),
    form = form,
    label = "IBAN",
    placeholder = "TR000000000000000000000000",
    supportingText = "Long as it is, all of it stays in view",
    showClearButton = true,
    maxLength = 26,
    textStyle = PantrixTheme.typography.callout,
    keyboardOptions = KeyboardOptions(capitalization = KeyboardCapitalization.Characters)
)
PantrixButton(
    text = "Save IBAN",
    onClick = {
        scope.launch { form.submit { snackbars?.show(message = "IBAN saved", tagKey = "iban_saved") } }
    },
    form = form,
    tagKey = "save_iban"
)

private val IBAN = Regex("""TR\d{24}""")

A note of several lines

With lineLimits = TextFieldLineLimits.MultiLine(minHeightInLines = 2, maxHeightInLines = 4) the text wraps: the box is two lines tall, and grows with the text to four lines. Once the note passes four lines the box stays as it is, and the text gets as small as it takes to fit, its line spacing with it. Enter starts a new line.

The text is read from the state at the moment it is used: note.text when the button is pressed.

val snackbars = LocalPantrixSnackbars.current
val scope = rememberCoroutineScope()
val note = rememberTextFieldState()
PantrixAutoResizeTextField(
    state = note,
    modifier = Modifier.fillMaxWidth(),
    label = "Note for the courier",
    placeholder = "Don't ring the bell, leave it at the door",
    supportingText = "Grows to four lines, then the text shrinks",
    showClearButton = true,
    maxLength = 280,
    lineLimits = TextFieldLineLimits.MultiLine(minHeightInLines = 2, maxHeightInLines = 4),
    tagKey = "courier_note"
)
PantrixButton(
    text = "Save note",
    onClick = {
        val written = note.text.toString()
        val message = if (written.isBlank()) "Write a note" else "Note saved. Characters: ${written.length}"
        scope.launch { snackbars?.show(message = message, tagKey = "note_saved") }
    },
    tagKey = "save_note"
)

A field given a height

A message written on a gift card, in a field that is given a height: Modifier.height(180.dp). The height is the whole field's: the box fills what the label and the supporting text leave of it, and is just as tall while the message is short. The text starts in the title style; when it does not fit the box it goes down to the largest size in which all of it is in view, and it grows back as it is deleted.

No line limit is given (TextFieldLineLimits.MultiLine()): the room the text is fitted to is the field's height.

PantrixAutoResizeTextField(
    state = rememberTextFieldState(CARD_MESSAGE),
    modifier = Modifier.fillMaxWidth().height(180.dp),
    label = "Card message",
    supportingText = "The field's height is fixed: the text shrinks to fit",
    showClearButton = true,
    maxLength = 280,
    textStyle = PantrixTheme.typography.title,
    lineLimits = TextFieldLineLimits.MultiLine(),
    tagKey = "card_message"
)

private const val CARD_MESSAGE = "Happy birthday! May the year ahead bring you health, happiness and plenty of joy. " +
    "Here's to many more good years together."

Supporting text and error

supportingText stands under the box. error = true turns the border, the label, the supporting text and the caret to the danger role, and the message is announced to a screen reader as an error. The field starts in error: 75.000 is over the daily limit. Delete a digit: the error goes.

It is the caller that works out the error, not the field; here by reading amount.text. What is read is the digits that were typed: the dots between the thousands are only drawn.

val amount = rememberTextFieldState("75000")
val typed = amount.text.toString().toLongOrNull() ?: 0L
val overLimit = typed > 50_000
PantrixAutoResizeTextField(
    state = amount,
    modifier = Modifier.fillMaxWidth(),
    label = "Amount to withdraw",
    supportingText = if (overLimit) "Over the daily limit: 50.000 TL at most" else "Daily limit 50.000 TL",
    error = overLimit,
    trailingIcon = { PantrixText(text = "TL") },
    showClearButton = true,
    maxLength = 9,
    showCharacterCount = false,
    textStyle = PantrixTheme.typography.headline,
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
    inputTransformation = DigitsOnly,
    outputTransformation = GroupedInThousands,
    tagKey = "withdrawal"
)

private val DigitsOnly = InputTransformation {
    if (!asCharSequence().all(Char::isDigit)) revertAllChanges()
}

private val GroupedInThousands = OutputTransformation {
    val whole = asCharSequence().indexOf(',').let { comma -> if (comma < 0) length else comma }
    // From right to left: each dot added later lies to the left of those added before it, and does not shift them.
    var at = whole - 3
    while (at > 0) {
        insert(at, ".")
        at -= 3
    }
}

Read-only and disabled

A field with readOnly = true cannot be changed, but it can be focused, and its text selected and copied. The balance is in the headline style and is shown with the dots between its thousands; in a box it does not fit, it shrinks as it does in a field that can be typed into.

A field with enabled = false is drawn in the theme's disabled colours and takes no focus. Its text is still fitted to its box.

PantrixAutoResizeTextField(
    state = rememberTextFieldState("125000000000000,00"),
    modifier = Modifier.fillMaxWidth(),
    readOnly = true,
    label = "Balance",
    supportingText = "Read-only: in the headline style, shrunk to fit",
    trailingIcon = { PantrixText(text = "TL") },
    textStyle = PantrixTheme.typography.headline,
    outputTransformation = GroupedInThousands,
    tagKey = "balance"
)
PantrixAutoResizeTextField(
    state = rememberTextFieldState("4543 60** **** 0719"),
    modifier = Modifier.fillMaxWidth(),
    enabled = false,
    label = "Saved card",
    supportingText = "Disabled: cannot be changed for this payment",
    textStyle = PantrixTheme.typography.title,
    tagKey = "saved_card"
)

private val GroupedInThousands = OutputTransformation {
    val whole = asCharSequence().indexOf(',').let { comma -> if (comma < 0) length else comma }
    // From right to left: each dot added later lies to the left of those added before it, and does not shift them.
    var at = whole - 3
    while (at > 0) {
        insert(at, ".")
        at -= 3
    }
}

Its own colours and style

This field has no style or colour class of its own: it takes the TextFieldColors and the TextFieldStyle of PantrixTextField. A product that restyles its text fields restyles this one with them.

In the first field the text, the focused border and the caret are the app's own purple. The second field's box is fully round: TextFieldStyle(shape = ShapeRole.Full). textStyle and style are two different things: the first is the text's style, the second the box's.

val own = ownColors()
PantrixAutoResizeTextField(
    state = rememberTextFieldState("2026 Spring Campaign"),
    modifier = Modifier.fillMaxWidth(),
    label = "Campaign name",
    textStyle = PantrixTheme.typography.title,
    colors = TextFieldColors(focusedBorder = own.color, text = own.color, cursor = own.color),
    tagKey = "own_colors"
)
PantrixAutoResizeTextField(
    state = rememberTextFieldState("PX-2026-0914"),
    modifier = Modifier.fillMaxWidth(),
    label = "Tracking number",
    textStyle = PantrixTheme.typography.title,
    style = TextFieldStyle(shape = ShapeRole.Full),
    tagKey = "pill"
)

API

state

A text field whose text gets smaller to stay in view: an amount, a card's number, a short note, anything that is read whole.

ParameterTypeDefaultWhat it is
stateTextFieldStatethe 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.
modifierModifierModifierthe modifier of the whole field: its label, its box and what is under it. fillMaxWidth() makes the box as wide as its parent, and a height is one the text is fitted to as it is to the width.
enabledBooleantruewhether the field can be typed into. One that cannot takes no focus, is drawn in the disabled colours and says so.
readOnlyBooleanfalsewhether the text can only be read: it can still be focused, selected and copied.
labelString?nullwhat the field is for, written above the box: the field's name for a screen reader.
placeholderString?nullshown in the box while it is empty, in the text's own style.
supportingTextString?nullhelp 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.
errorBooleanfalsewhether 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.
leadingIcon(@Composable () -> Unit)?nullwhat stands before the text, 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)?nullwhat stands after the text, and after the clear button: a currency's sign after an amount.
showClearButtonBooleanfalseshows a button that empties the field, while the field can be typed into and is not empty. It leaves the caret in the field, and is no stop for Tab.
maxLengthInt?nullthe most characters the user can enter, counted as String.length counts them. An edit that would pass the limit is turned down whole. Text set in code is not cut, and the user can still make it shorter. It has to be positive.
showCharacterCountBooleantrueshows count/maxLength under the box while maxLength is set.
textStyleTextStyle?nullthe style of the text at its largest: a role of the theme's typography, such as PantrixTheme.typography.headline for an amount. What it leaves unset is the body's, which is what the text is set in without it. A box too short for the style grows to hold a line of it.
minFontSizeTextUnitPantrixTheme.typography.footnote.fontSizethe smallest the text gets: a size in sp, or one in em, which is a share of the style's own. It is the theme's footnote size unless told. A text that does not fit at this size scrolls, and at the style's own size or above it the text never shrinks.
lineLimitsTextFieldLineLimitsTextFieldLineLimits.SingleLineone line, or TextFieldLineLimits.MultiLine, in which the text wraps and Enter starts a new line. The box is as tall as its lines are at the text's largest size: it grows from minHeightInLines to maxHeightInLines, and past the most of them the text is set smaller. With no most lines the box grows with its text for as long as it may, and the text is set smaller only where the field is given a height. Tab moves the focus on from either.
keyboardOptionsKeyboardOptionsKeyboardOptions.Defaultthe keyboard's type, its capitals, its corrections and its action key.
onKeyboardActionKeyboardActionHandler?nullcalled for the keyboard's action key, for the action keyboardOptions names. Null keeps what the platform does: Next moves the focus on, and Done closes the keyboard.
inputTransformationInputTransformation?nullwhat is done to the text as the user types it. With maxLength, it comes first and the limit applies to what it lets through.
outputTransformationOutputTransformation?nullhow the text is shown, without changing it: an amount's separators. The text is fitted as it is shown.
contentTypeContentType?nullwhat the field holds, for the platform to fill it in: ContentType.CreditCardNumber and the like.
styleTextFieldStyle?nullthis call's own style: over every enclosing one and under the density. Only the fields it sets change, on every platform.
colorsTextFieldColors?nullthis call's own colours, 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.
contentDescriptionString?nullwhat 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.
tagKeyString?nullthe field's automation key: the field is AutoResizeTextField_<tagKey>, and its clear button AutoResizeTextFieldClear_<tagKey>. The field reports that it took the focus and that it was cleared, and never its text.
interactionSourceMutableInteractionSource?nullthe 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 field whose text shrinks to fit, and whose text is a String its caller holds: value is what it shows, and onValueChange is asked for every change the user makes.

ParameterTypeDefaultWhat it is
valueStringthe text the field shows.
onValueChange(String) -> Unitasked for each change the user makes, with the whole new text, and by the clear button with an empty one.
modifierModifierModifierthe modifier of the whole field: its label, its box and what is under it.
enabledBooleantruewhether the field can be typed into.
readOnlyBooleanfalsewhether the text can only be read: it can still be focused, selected and copied.
labelString?nullwhat the field is for, written above the box: the field's name for a screen reader.
placeholderString?nullshown in the box while it is empty, in the text's own style.
supportingTextString?nullhelp under the box. With error it is the message that says what to put right.
errorBooleanfalsewhether 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.
leadingIcon(@Composable () -> Unit)?nullwhat stands before the text. A slot does not size what is put in it.
trailingIcon(@Composable () -> Unit)?nullwhat stands after the text, and after the clear button.
showClearButtonBooleanfalseshows a button that asks for an empty text, while the field can be typed into and is not empty.
maxLengthInt?nullthe most characters the user can enter. An edit that would pass the limit is turned down whole, before onValueChange is asked. A value over the limit is shown as it is, and the user can still make it shorter. It has to be positive.
showCharacterCountBooleantrueshows count/maxLength under the box while maxLength is set.
textStyleTextStyle?nullthe style of the text at its largest. What it leaves unset is the body's.
minFontSizeTextUnitPantrixTheme.typography.footnote.fontSizethe smallest the text gets, in sp or in em: the theme's footnote size unless told. A text that does not fit at this size scrolls.
singleLineBooleantruewhether the field holds one line, which is fitted to the box's width. It does unless told. A line break in value is then shown as a space, and value keeps it.
minLinesInt1the least lines the box is tall, in a field of several, counted at the text's largest size.
maxLinesIntif (singleLine) 1 else Int.MAX_VALUEthe most lines the box grows to, in a field of several, before its text is set smaller.
keyboardOptionsKeyboardOptionsKeyboardOptions.Defaultthe keyboard's type, its capitals, its corrections and its action key.
keyboardActionsKeyboardActionsKeyboardActions.Defaultwhat the keyboard's action key does, for the action keyboardOptions names.
visualTransformationVisualTransformationVisualTransformation.Nonehow the text is shown, without changing it: an amount's separators. The text is fitted as it is shown.
contentTypeContentType?nullwhat the field holds, for the platform to fill it in.
styleTextFieldStyle?nullthis call's own style: over every enclosing one and under the density. Only the fields it sets change, on every platform.
colorsTextFieldColors?nullthis call's own colours, 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.
contentDescriptionString?nullwhat a screen reader says for the field: its name where it has no label.
tagKeyString?nullthe field's automation key: the field is AutoResizeTextField_<tagKey>, and its clear button AutoResizeTextFieldClear_<tagKey>.
interactionSourceMutableInteractionSource?nullthe field's interactions, hoisted. It keeps a source of its own when this is null.

field

A text field whose text shrinks to fit, bound to a form's field: its text, its error and its name come from field.

ParameterTypeDefaultWhat it is
fieldFormField<String>the field the text field shows and changes.
modifierModifierModifierthe modifier of the whole field.
formFormState?nullgiven, the keyboard's action key submits the form through the button registered with it. An action of Next or Previous moves the focus as it always does. A field of one line that names no action gets ImeAction.Done, since the default action never reaches a handler. A field of several lines is left alone: there Enter starts a new line. An onKeyboardAction of the caller's own takes the place of the submit.
enabledBooleantruewhether the field can be typed into.
readOnlyBooleanfalsewhether the text can only be read.
labelString?nullwhat the field is for, written above the box: the field's name for a screen reader.
placeholderString?nullshown in the box while it is empty, in the text's own style.
supportingTextString?nullhelp under the box, while the field has no error to show there.
leadingIcon(@Composable () -> Unit)?nullwhat stands before the text.
trailingIcon(@Composable () -> Unit)?nullwhat stands after the text, and after the clear button.
showClearButtonBooleanfalseshows a button that empties the field, while it can be typed into and is not empty.
maxLengthInt?nullthe most characters the user can enter. It has to be positive.
showCharacterCountBooleantrueshows count/maxLength under the box while maxLength is set.
textStyleTextStyle?nullthe style of the text at its largest. What it leaves unset is the body's.
minFontSizeTextUnitPantrixTheme.typography.footnote.fontSizethe smallest the text gets, in sp or in em: the theme's footnote size unless told.
lineLimitsTextFieldLineLimitsTextFieldLineLimits.SingleLineone line, or TextFieldLineLimits.MultiLine, whose text is set smaller past the most of its lines. Tab moves the focus on from either.
keyboardOptionsKeyboardOptionsKeyboardOptions.Defaultthe keyboard's type, its capitals, its corrections and its action key.
onKeyboardActionKeyboardActionHandler?nullcalled for the keyboard's action key, in place of the form's submit.
inputTransformationInputTransformation?nullwhat is done to the text as the user types it.
outputTransformationOutputTransformation?nullhow the text is shown, without changing it. The text is fitted as it is shown.
contentTypeContentType?nullwhat the field holds, for the platform to fill it in.
styleTextFieldStyle?nullthis call's own style: over every enclosing one and under the density. Only the fields it sets change, on every platform.
colorsTextFieldColors?nullthis call's own colours, 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.
contentDescriptionString?nullwhat a screen reader says for the field where it has no label.
interactionSourceMutableInteractionSource?nullthe 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.

ParameterTypeDefaultWhat it is
shapeShapeSpecShapeSpec.UnspecifiedThe 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.
heightDpDp.UnspecifiedThe least the box is tall.
minWidthDpDp.UnspecifiedThe least the box is wide, which keeps an empty field from growing as the user types into it.
horizontalPaddingDpDp.UnspecifiedThe room between the box's edge and its text, where no icon is.
verticalPaddingDpDp.UnspecifiedThe room above the first line of the text and below the last.
iconPaddingDpDp.UnspecifiedThe room around an icon in its slot.
iconSizeDpDp.UnspecifiedThe size an icon in a slot should take. A slot does not size what is put in it.
borderWidthDpDp.UnspecifiedHow thick the box's border is.
focusedBorderWidthDpDp.UnspecifiedHow thick the border is while the field has the focus: the border is what shows it.
textRoleTypeRole?nullThe 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:

ParameterTypeDefaultWhat it is
containerColorColor.UnspecifiedThe box's fill. The theme's surface.
borderColorColor.UnspecifiedThe box's border at rest. The theme's border.
hoveredBorderColorColor.UnspecifiedThe border under a pointer. The theme's borderHover, a notch stronger than border.
focusedBorderColorColor.UnspecifiedThe border while the field has the focus. The theme's primary.
errorColorColor.UnspecifiedWhat 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.
textColorColor.UnspecifiedThe typed text. The theme's textPrimary.
labelColorColor.UnspecifiedThe 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.
placeholderColorColor.UnspecifiedThe placeholder. The theme's textSecondary.
supportingTextColorColor.UnspecifiedThe help under the box, and the count. The theme's textSecondary.
iconColorColor.UnspecifiedWhat 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.
cursorColorColor.UnspecifiedThe caret, and with it the handles and the highlight of a selection. The theme's primary.
scrollBarColorColor.UnspecifiedThe 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.