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
- A box that does not change. The box's width is its style's least width or the one its caller gave it; a text that grows longer does not widen it, but gets as small as it takes to fit.
- The largest size.
textStyleis the style of the text at its largest: a role of the theme's typography, such asheadlinefor an amount. It isbodyunless given. A box too short for the style grows to hold a line of it. - The smallest size.
minFontSizeis the smallest the text gets: a size in sp, or one in em, which is a share of the style's size. It is the theme'sfootnotesize unless given. A text that still does not fit at that size scrolls, as the text of any field does. - Several lines. With
lineLimits = TextFieldLineLimits.MultiLine(...)the text wraps, and the box grows with it from the least of its lines to the most. From there the box keeps its height, and the text is set smaller, its line spacing with it. - A given height. A height the field is given comes before its lines: the box fills it, and the text is fitted to that height.
- What is fitted is the text as it is shown. The thousands separators that an
outputTransformationadds only for display count too, and so does what the keyboard is still composing. The placeholder is in the text's style, and where it is long it shrinks too. - It is the text's size that gets smaller. Nothing is drawn smaller than it is: the caret, a selection and its handles are those of the size the text is in.
- Three overloads. In the one that takes a
statethe text is read from the state. The one that takes avalueand anonValueChangekeeps the text with its caller, and takes its lines assingleLine,minLinesandmaxLines. The one that takes afieldis bound to a form's field. - What comes from the text field.
label,placeholder,supportingText,error, the icons,showClearButton,maxLength, the keyboard and the transformations are as they are in the text field. - Automation. With
tagKeythe field is namedAutoResizeTextField_<tagKey>, and its clear buttonAutoResizeTextFieldClear_<tagKey>. The field reports that it took the focus and that it was cleared, and never its text.
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.
| 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, and a height is one the text is fitted to as it is to the width. |
enabled | Boolean | true | whether the field can be typed into. One that cannot takes no focus, is drawn in the disabled colours 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, in the text's own style. |
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. |
leadingIcon | (@Composable () -> Unit)? | null | what 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)? | null | what stands after the text, and after the clear button: a currency's sign after an amount. |
showClearButton | Boolean | false | shows 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. |
maxLength | Int? | null | the 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. |
showCharacterCount | Boolean | true | shows count/maxLength under the box while maxLength is set. |
textStyle | TextStyle? | null | the 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. |
minFontSize | TextUnit | PantrixTheme.typography.footnote.fontSize | the 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. |
lineLimits | TextFieldLineLimits | TextFieldLineLimits.SingleLine | one 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. |
keyboardOptions | KeyboardOptions | KeyboardOptions.Default | the keyboard's type, its capitals, its corrections and its action key. |
onKeyboardAction | KeyboardActionHandler? | null | called 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. |
inputTransformation | InputTransformation? | null | what is done to the text as the user types it. With maxLength, it comes first and the limit applies to what it lets through. |
outputTransformation | OutputTransformation? | null | how the text is shown, without changing it: an amount's separators. The text is fitted as it is shown. |
contentType | ContentType? | null | what the field holds, for the platform to fill it in: ContentType.CreditCardNumber and the like. |
style | TextFieldStyle? | null | this call's own style: 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, 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. |
tagKey | String? | null | the 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. |
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 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.
| 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. |
enabled | Boolean | true | whether the field can be typed into. |
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, in the text's own style. |
supportingText | String? | null | help under the box. With error it is the message that says what to put right. |
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. |
leadingIcon | (@Composable () -> Unit)? | null | what stands before the text. A slot does not size what is put in it. |
trailingIcon | (@Composable () -> Unit)? | null | what stands after the text, and after the clear button. |
showClearButton | Boolean | false | shows a button that asks for an empty text, while the field can be typed into and is not empty. |
maxLength | Int? | null | the 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. |
showCharacterCount | Boolean | true | shows count/maxLength under the box while maxLength is set. |
textStyle | TextStyle? | null | the style of the text at its largest. What it leaves unset is the body's. |
minFontSize | TextUnit | PantrixTheme.typography.footnote.fontSize | the 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. |
singleLine | Boolean | true | whether 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. |
minLines | Int | 1 | the least lines the box is tall, in a field of several, counted at the text's largest size. |
maxLines | Int | if (singleLine) 1 else Int.MAX_VALUE | the most lines the box grows to, in a field of several, before its text is set smaller. |
keyboardOptions | KeyboardOptions | KeyboardOptions.Default | the keyboard's type, its capitals, its corrections and its action key. |
keyboardActions | KeyboardActions | KeyboardActions.Default | what the keyboard's action key does, for the action keyboardOptions names. |
visualTransformation | VisualTransformation | VisualTransformation.None | how the text is shown, without changing it: an amount's separators. The text is fitted as it is shown. |
contentType | ContentType? | null | what the field holds, for the platform to fill it in. |
style | TextFieldStyle? | null | this call's own style: 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, 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. |
tagKey | String? | null | the field's automation key: the field is AutoResizeTextField_<tagKey>, and its clear button AutoResizeTextFieldClear_<tagKey>. |
interactionSource | MutableInteractionSource? | null | the 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.
| Parameter | Type | Default | What it is |
|---|---|---|---|
field | FormField<String> | the field the text field shows and changes. | |
modifier | Modifier | Modifier | the modifier of the whole field. |
form | FormState? | null | given, 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. |
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, in the text's own style. |
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. |
trailingIcon | (@Composable () -> Unit)? | null | what stands after the text, 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. |
maxLength | Int? | null | the most characters the user can enter. It has to be positive. |
showCharacterCount | Boolean | true | shows count/maxLength under the box while maxLength is set. |
textStyle | TextStyle? | null | the style of the text at its largest. What it leaves unset is the body's. |
minFontSize | TextUnit | PantrixTheme.typography.footnote.fontSize | the smallest the text gets, in sp or in em: the theme's footnote size unless told. |
lineLimits | TextFieldLineLimits | TextFieldLineLimits.SingleLine | one line, or TextFieldLineLimits.MultiLine, whose text is set smaller past the most of its lines. Tab moves the focus on from either. |
keyboardOptions | KeyboardOptions | KeyboardOptions.Default | the keyboard's type, its capitals, its corrections and its action key. |
onKeyboardAction | KeyboardActionHandler? | null | called for the keyboard's action key, in place of the form's submit. |
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. The text is fitted as it is shown. |
contentType | ContentType? | null | what the field holds, for the platform to fill it in. |
style | TextFieldStyle? | null | this call's own style: 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, 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 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. |