Skip to main content

A text input that works with Field, with an optional character counter and screen reader announcements.

<primitives:input.root>
    <primitives:input.label />
    <primitives:input.input />
    <primitives:input.wordCount />
</primitives:input.root>
typo3 ui:add input

Read more about installing Components and Primitives.

Nest ui:input.root directly inside ui:field.root. The input takes name, disabled, required, invalid and aria-describedby from the field. Label it with the primitive's own input.label, which targets the input for you. The demo is a required email field with helper and error text.

We'll only use this to send your confirmation.

Pass maxLength and place the wordCount part anywhere inside input.root. The bio in the demo counts up to 140 characters.

0 / 140 characters

Set maxLengthBehavior="{f:constant(name: 'Jramke\FluidPrimitives\Enum\MaxLengthBehavior::Warn')}" to keep maxLength as a target instead of a wall. The browser cuts nothing off, the count switches to "Characters over the limit: 6" and the parts carry data-over-limit, next to data-at-limit for exactly maxLength characters and data-max-length-behavior to style warn apart from invalid. The form still submits. The demo is a meta description that starts over its limit.

Characters over the limit: 15

Enforce the limit that matters on the server. To accept a few characters over, give the template a lower maxLength than the validator, for example StringLength(maximum: 210) behind maxLength="200". The count is the one of the browser's maxlength, in UTF-16 units, so an emoji counts twice. mb_strlen and a VARCHAR(n) column count it once, so the count is never lower than the server's.

MaxLengthBehavior::Invalid works like Warn and also makes the surrounding field invalid with the tooLong validity, so a form does not submit until the text fits. The error shows when the user leaves the field, like any other constraint. Give ui:field.errorText a match of ValidityMatch::TooLong for your own message. Type past the limit in the demo and tab out.

0 / 20 characters

transform runs on every input event and returns the value to write back to the input. A function can't be set from the template, so pass transform where you create Input in your own entry file. Type a coupon code in lowercase and it turns uppercase as you type.

The following tables cover the available props of the Fluid Primitives.

Provides shared input state and wraps all related parts. Renders a <div> element.

NameDescriptionRequiredDefault
typestring
The HTML input type attribute, e.g. text, email, password, search, tel, url.
No
'text'
placeholderstring
Placeholder text shown when the input is empty.
No
-
autocompletestring
Hints for browser autofill, e.g. email, tel, given-name, street-address. See the [HTML spec](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill) for the full list of tokens.
No
-
namestring
The name attribute of the input. Useful for form submission. Inherited from a surrounding field when available.
No
-
disabledboolean
Whether the input is disabled. Inherited from a surrounding field when available.
No
-
invalidboolean
Whether the input value is invalid. Inherited from a surrounding field when available.
No
-
requiredboolean
Whether the input is required. Inherited from a surrounding field when available.
No
-
readOnlyboolean
Whether the input is readonly. Inherited from a surrounding field when available.
No
-
defaultValuestring
The initial value of the input when rendered. Use when you don't need to control the value of the input. Inherited from a surrounding field when available.
No
''
maxLengthinteger
The maximum number of characters allowed, see `maxLengthBehavior` for what happens beyond it. Also drives the wordCount part, e.g. '42 / 250 characters'.
No
-
maxLengthBehaviorEnum\MaxLengthBehavior
What happens when the value is longer than `maxLength`. - `block`: The browser stops the typing and cuts a paste off at the limit. - `warn`: Typing and pasting past the limit is allowed, the word count and `data-over-limit` show it, the form still submits. - `invalid`: Like `warn`, and a surrounding field also becomes invalid with the `tooLong` validity, so the form does not submit.
No
Block
patternstring
A regular expression the input's value is checked against on form submission.
No
-
inputModeEnum\InputMode
Hints at the type of data that might be entered by the user and the keyboard shown on mobile devices, e.g. numeric, email, tel.
No
-
translationsarray
Specifies the localized word count strings, `wordCount` and `wordCountOver`, with `%count%`, `%max%` and `%over%` placeholders. In a client script they are functions of `{ count, max, over }`. Use `f:translate` for per-template localization overrides when needed.
No
-
announceboolean
Whether the word count is announced to assistive tech as the user types. Set to false to stay silent.
No
true
announceDebounceinteger
Milliseconds to debounce word count announcements by, so rapid typing doesn't spam assistive tech. Set to 0 to announce every change immediately.
No
600
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
rootIdstring
The root ID of the component, used for hydration and identification.
No
-
idsarray
The IDs of of the component parts for composition.
No
[]
autoMountboolean
Whether the client initializes the component on its own. Set it to false to mount it yourself with `mount()`
No
true
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-invalidPresent when invalid
data-disabledPresent when disabled
data-readonlyPresent when read-only
data-max-length-behaviorThe `maxLengthBehavior` while there is a `maxLength`: `block`, `warn` or `invalid`. Style the over-limit state of `warn` and `invalid` apart. One of: "invalid", "block", "warn".
data-at-limitPresent while the value is exactly `maxLength` characters long.
data-over-limitPresent while the value is longer than `maxLength` and `maxLengthBehavior` is not `block`.

Labels the input. Renders a <label> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-invalidPresent when invalid
data-disabledPresent when disabled
data-requiredPresent when required

The editable input. Renders an <input> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-max-length-behaviorThe `maxLengthBehavior` while there is a `maxLength`: `block`, `warn` or `invalid`. Style the over-limit state of `warn` and `invalid` apart. One of: "invalid", "block", "warn".
data-at-limitPresent while the value is exactly `maxLength` characters long.
data-over-limitPresent while the value is longer than `maxLength` and `maxLengthBehavior` is not `block`.
data-invalidPresent when invalid
data-disabledPresent when disabled
data-readonlyPresent when read-only

Displays the character count, e.g. '42 / 250 characters'. Renders a <span> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-max-length-behaviorThe `maxLengthBehavior` while there is a `maxLength`: `block`, `warn` or `invalid`. Style the over-limit state of `warn` and `invalid` apart. One of: "invalid", "block", "warn".
data-at-limitPresent while the value is exactly `maxLength` characters long.
data-over-limitPresent while the value is longer than `maxLength` and `maxLengthBehavior` is not `block`.
NameDescriptionDefault
idstring
The unique identifier of the input.
-
idsRecord<string, string> | undefined
The ids of the parts other elements reference: input (the for of its label) and wordCount.
-
namestring | undefined
The name of the input, as it is submitted with the form. Taken from the closest field.
-
disabledboolean | undefined
Whether the input is disabled. Taken from the closest field.
-
readOnlyboolean | undefined
Whether the input is read-only. Taken from the closest field.
-
requiredboolean | undefined
Whether the input is required. Taken from the closest field.
-
invalidboolean | undefined
Whether the input is invalid. Taken from the closest field.
-
defaultValuestring | undefined
The initial value of the input.
-
maxLengthnumber | undefined
The most characters allowed. It also drives the word count, e.g. 42 / 250 characters.
-
maxLengthBehaviorMaxLengthBehavior | undefined
What happens when the value is longer than maxLength. block stops the typing and cuts a paste off, warn allows both and only shows that the value is over the limit, invalid does the same and makes a surrounding field invalid (tooLong).
"block"
patternstring | undefined
A regular expression the value has to match.
-
inputModeJSX.HTMLAttributes<HTMLInputElement>['inputMode'] | undefined
The kind of virtual keyboard to show on devices that have one.
-
translationsInputTranslations | undefined
The localized texts of the input.
-
announceboolean | undefined
Whether the word count is announced to assistive tech. Set to false to stay silent.
true
announceDebouncenumber | undefined
Milliseconds to debounce word count announcements by, so rapid typing doesn't spam assistive tech on every keystroke. Set to 0 to announce every change immediately.
600
transform((value: string, event: Event) => string) | undefined
Runs on every native input event, before the value is committed. Return the value to write back to the input, e.g. uppercased or digits only. The cursor position is kept. It cannot be set from a Fluid template, only by constructing Input in your own entry file.
-
onValueChange((details: { value: string }) => void) | undefined
Called when the value changes.
-
NameTypeDescription
valuestringThe current value of the input.
countnumberThe number of characters in the value.
overnumberThe number of characters over maxLength. It is always 0 for maxLengthBehavior="block".
atLimitbooleanWhether the value is exactly maxLength characters long.
countTextstring | nullThe word count text, e.g. 42 / 250 characters. null without maxLength or when the text is turned off.
disabledbooleanWhether the input is disabled.
readOnlybooleanWhether the input is read-only.
requiredbooleanWhether the input is required.
invalidbooleanWhether the input is invalid.
namestring | undefinedThe name of the input.
maxLengthnumber | undefinedThe most characters allowed.