Input
Inputs are used to collect data from the user. They can be used to collect text, numbers, dates, and more.
Preview
Installation
Copy and paste the following code into your project.
"use client";
import * as React from "react";
import {
TextField as AriaTextField,
type TextFieldProps as AriaTextFieldProps,
} from "react-aria-components";
import { tv, type VariantProps } from "tailwind-variants";
import { Input, type inputStyles } from "./input";
import { Field, FieldProps } from "./field";
const textFieldStyles = tv({
base: "flex flex-col gap-2 items-start",
});
type TextFieldProps = TextFieldRootProps &
Omit<FieldProps, "children"> &
VariantProps<typeof inputStyles> & {
leftSection?: React.ReactNode;
rightSection?: React.ReactNode;
isLoading?: boolean;
loaderPosition?: "left" | "right";
placeholder?: string;
};
const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(
(
{
className,
size,
placeholder,
label,
description,
errorMessage,
leftSection,
rightSection,
isLoading,
loaderPosition = "right",
withAsterisk,
contextualHelp,
...props
},
ref
) => {
return (
<TextFieldRoot className={className} {...props}>
{({ isRequired }) => (
<Field
label={label}
description={description}
errorMessage={errorMessage}
isRequired={isRequired}
withAsterisk={withAsterisk}
contextualHelp={contextualHelp}
descriptionPosition={props.descriptionPosition}
>
<Input
size={size}
leftSection={leftSection}
rightSection={rightSection}
isLoading={isLoading}
loaderPosition={loaderPosition}
ref={ref}
placeholder={placeholder}
disabled={props.isDisabled}
aria-invalid={props.isInvalid}
/>
</Field>
)}
</TextFieldRoot>
);
}
);
TextField.displayName = "TextField";
type TextFieldRootProps = Omit<AriaTextFieldProps, "className"> & {
className?: string;
};
const TextFieldRoot = React.forwardRef<
React.ElementRef<typeof AriaTextField>,
TextFieldRootProps
>(({ className, ...props }, ref) => {
return (
<AriaTextField
ref={ref}
className={textFieldStyles({ className })}
{...props}
/>
);
});
TextFieldRoot.displayName = "TextFieldRoot";
export type { TextFieldProps, TextFieldRootProps };
export { TextField, TextFieldRoot };
Update the import paths to match your project setup.
Usage
Text fields consist of an input element and a label. TextField automatically manages the relationship between the two elements using the for attribute on the <label>
element and the aria-labelledby attribute on the <input>
element.
TextField also supports optional description and error message elements, which can be used to provide more context about the field, and any validation messages. These are linked with the input via the aria-describedby attribute.
Props
Label
The label
prop is used to set the label of the input field.
and you can use aria-label
to set label but it will be not visible to the user.
Description
The description
prop is used to set the description of the input field.
and you can set descriptionPosition
to top
or bottom
to set the position of the description, the default position is top
.
Required
The isRequired
prop is used to set the input field as required.
Use withAsterisk
to show an asterisk next to the label.
Error
The isInvalid
prop is used to set the error message of the input field.
use errorDescription
to set the error description.
Loading
Use the isLoading
prop to show a loading spinner inside the input field.
use loadingPosition
to set the position of the loading spinner, the default position is right
.
Disabled
Use the isDisabled
prop to disable the input field.
Readonly
Use the isReadonly
prop to set the input field as readonly. Unlike disabled, readonly fields can still be selected and copied.
Sections
Use the rightSection
or leftSection
prop to add an icon to the button.
type of rightSection
or leftSection
is ReactNode
.
Sizes
Use the size
prop to change the size of the input field. The default size is md
.
Input Composition
If you want more control over the input you can import all the components individually. This component allows you to compose the input field with other components like buttons, icons, and more.
TextField Props
Name | Type | Default | Description |
---|---|---|---|
leftSection | ReactNode | — | The element to render on the left side of the input. |
rightSection | ReactNode | — | The element to render on the right side of the input. |
label | string | — | The label for the input. |
description | string | — | The description for the input. |
descriptionPosition | 'top' | 'bottom' | 'top' | The position of the description relative to the input. |
isLoading | boolean | — | Whether the input is in a loading state. |
loadingPosition | 'left' | 'right' | 'right' | The position of the loading spinner relative to the input. |
size | 'sm' | 'md' | 'lg' | 'xl' | 'md' | The size of the input. |
isReadOnly | boolean | — | Whether the input can be selected but not changed by the user. |
errorDescription | string | — | The error description for the input. |
isInvalid | boolean | — | Whether the value is invalid. |
isDisabled | boolean | — | Whether the input is disabled. |
isReadOnly | boolean | — | Whether the input can be selected but not changed by the user. |
isRequired | boolean | — | Whether user input is required on the input before form submission. |
withAsterisk | boolean | — | Whether to show an asterisk next to the label. |
validate | (value: string) => ValidationError | true | null | undefined | — | A function that returns an error message if a given value is invalid. Validation errors are displayed to the user when the form is submitted if validationBehavior="native" . For real-time validation, use the isInvalid prop instead. |
autoFocus | boolean | — | Whether the element should receive focus on render. |
value | string | — | The current value (controlled). |
defaultValue | string | — | The default value (uncontrolled). |
autoComplete | string | — | Describes the type of autocomplete functionality the input should provide if any. See MDN. |
maxLength | number | — | The maximum number of characters supported by the input. See MDN. |
minLength | number | — | The minimum number of characters required by the input. See MDN. |
pattern | string | — | Regex pattern that the value of the input must match to be valid. See MDN. |
type | 'text' | 'search' | 'url' | 'tel' | 'email' | 'password' | string & {} | — | The type of input to render. See MDN. |
inputMode | 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search' | — | Hints at the type of data that might be entered by the user while editing the element or its contents. See MDN. |
name | string | — | The name of the input element, used when submitting an HTML form. See MDN. |
validationBehavior | 'native' | 'aria' | 'native' | Whether to use native HTML form validation to prevent form submission when the value is missing or invalid, or mark the field as required or invalid via ARIA. |
children | ReactNode | (values: TextFieldRenderProps & { defaultChildren: ReactNode | undefined }) => ReactNode | — | The children of the component. A function may be provided to alter the children based on component state. |
className | string | (values: TextFieldRenderProps & { defaultClassName: string | undefined }) => string | — | The CSS className for the element. A function may be provided to compute the class based on component state. |
style | CSSProperties | (values: TextFieldRenderProps & { defaultStyle: CSSProperties }) => CSSProperties | — | The CSS style for the element. A function may be provided to compute the style based on component state. |
TextField Events
Name | Type | Description |
---|---|---|
onFocus | (e: FocusEvent<Target>) => void | Handler that is called when the element receives focus. |
onBlur | (e: FocusEvent<Target>) => void | Handler that is called when the element loses focus. |
onFocusChange | (isFocused: boolean) => void | Handler that is called when the element's focus status changes. |
onKeyDown | (e: KeyboardEvent) => void | Handler that is called when a key is pressed. |
onKeyUp | (e: KeyboardEvent) => void | Handler that is called when a key is released. |
onChange | (value: T) => void | Handler that is called when the value changes. |
onCopy | ClipboardEventHandler<HTMLInputElement> | Handler that is called when the user copies text. See MDN. |
onCut | ClipboardEventHandler<HTMLInputElement> | Handler that is called when the user cuts text. See MDN. |
onPaste | ClipboardEventHandler<HTMLInputElement> | Handler that is called when the user pastes text. See MDN. |
onCompositionStart | CompositionEventHandler<HTMLInputElement> | Handler that is called when a text composition system starts a new text composition session. See MDN. |
onCompositionEnd | CompositionEventHandler<HTMLInputElement> | Handler that is called when a text composition system completes or cancels the current text composition session. See MDN. |
onCompositionUpdate | CompositionEventHandler<HTMLInputElement> | Handler that is called when a new character is received in the current text composition session. See MDN. |
onSelect | ReactEventHandler<HTMLInputElement> | Handler that is called when text in the input is selected. See MDN. |
onBeforeInput | FormEventHandler<HTMLInputElement> | Handler that is called when the input value is about to be modified. See MDN. |
onInput | FormEventHandler<HTMLInputElement> | Handler that is called when the input value is modified. See MDN. |
TextField Accessibility Props
Name | Type | Description |
---|---|---|
id | string | The element's unique identifier. See MDN. |
excludeFromTabOrder | boolean | Whether to exclude the element from the sequential tab order. If true, the element will not be focusable via the keyboard by tabbing. This should be avoided except in rare scenarios where an alternative means of accessing the element or its functionality via the keyboard is available. |
aria-activedescendant | string | Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application. |
aria-autocomplete | 'none' | 'inline' | 'list' | 'both' | Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be presented if they are made. |
aria-haspopup | boolean | 'false' | 'true' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog' | Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element. |
aria-label | string | Defines a string value that labels the current element. |
aria-labelledby | string | Identifies the element (or elements) that labels the current element. |
aria-describedby | string | Identifies the element (or elements) that describes the object. |
aria-details | string | Identifies the element (or elements) that provide a detailed, extended description for the object. |
aria-errormessage | string | Identifies the element that provides an error message for the object. |