Skip to Content
ComponentsInput

Input

Basic text field for capturing user input.

Documentation

"use client"; import type { ComponentPropsWithoutRef } from "react"; import { Field, Input } from "@optiaxiom/react"; export function App({ description, error, label = "Input label", required = false, }: Pick< ComponentPropsWithoutRef<typeof Field>, "description" | "error" | "label" | "required" >) { return ( <Field description={description} error={error} label={label} required={required} > <Input placeholder="Enter text..." /> </Field> ); }

Use the value and defaultValue props to toggle between controlled and uncontrolled usage. And combine it with onValueChange / onChange to listen for changes to the state.

Using onValueChange:

Input value:

"use client"; import { Group, Input, Text } from "@optiaxiom/react"; import { useState } from "react"; export function App() { const [value, setValue] = useState(""); return ( <Group flexDirection="column" gap="16"> <Input onValueChange={setValue} value={value} /> <Text fontSize="md">Input value: {value}</Text> </Group> ); }

Using onChange:

Input value:

"use client"; import { Group, Input, Text } from "@optiaxiom/react"; import { useState } from "react"; export function App() { const [value, setValue] = useState(""); return ( <Group flexDirection="column" gap="16"> <Input onChange={(event) => setValue(event.target.value)} value={value} /> <Text fontSize="md">Input value: {value}</Text> </Group> ); }

Use the type prop to specify the type of data the input should accept. Common types include email, password, tel, url, and number.

import { Field, Group, Input } from "@optiaxiom/react"; export function App() { return ( <Group flexDirection="column" gap="16"> <Field label="Email"> <Input placeholder="name@example.com" type="email" /> </Field> <Field label="Password"> <Input placeholder="Enter password" type="password" /> </Field> <Field label="Phone number"> <Input placeholder="+1 (555) 000-0000" type="tel" /> </Field> <Field label="Website"> <Input placeholder="https://example.com" type="url" /> </Field> <Field label="Number"> <Input placeholder="0" type="number" /> </Field> </Group> ); }

Use the required prop on the Field component to mark an input as required. This adds a visual indicator and sets the appropriate ARIA attributes.

import { Field, Input } from "@optiaxiom/react"; export function App() { return ( <Field label="Email address" required> <Input placeholder="name@example.com" type="email" /> </Field> ); }

Use the size prop to control the size of the input field.

"use client"; import type { ComponentPropsWithRef } from "react"; import { Input } from "@optiaxiom/react"; export function App({ size, }: Pick<ComponentPropsWithRef<typeof Input>, "size">) { return <Input placeholder="Enter text..." size={size} />; }

Use the error prop on the Field component to display validation errors. The error message will be shown below the input and the input will be styled accordingly.

import { Field, Input } from "@optiaxiom/react"; export function App() { return ( <Field error="Please enter a valid email address" label="Email"> <Input defaultValue="invalid-email" type="email" /> </Field> ); }

Enable the disabled prop to toggle the disabled state of the input field.

import { Input } from "@optiaxiom/react"; export function App() { return <Input defaultValue="Some disabled value" disabled />; }

Enable the readOnly prop to display the read-only state of the input field.

import { Input } from "@optiaxiom/react"; export function App() { return <Input defaultValue="Some read-only value" readOnly />; }

Use the addonBefore and addonAfter props to add text labels like currency symbols, units, or prefixes to your inputs.

$
%
kg
https://
@
import { Field, Group, Input } from "@optiaxiom/react"; export function App() { return ( <Group flexDirection="column" gap="16"> <Field label="Price"> <Input addonBefore="$" placeholder="0.00" type="number" /> </Field> <Field label="Discount"> <Input addonAfter="%" placeholder="0" type="number" /> </Field> <Field label="Weight"> <Input addonAfter="kg" placeholder="0" type="number" /> </Field> <Field label="Website"> <Input addonBefore="https://" placeholder="example.com" type="url" /> </Field> <Field label="Username"> <Input addonBefore="@" placeholder="username" /> </Field> </Group> ); }

You can also provide icons, buttons, or any other interactive element as addons.

"use client"; import { Button, Input } from "@optiaxiom/react"; import { IconEye, IconEyeOff } from "@tabler/icons-react"; import { useState } from "react"; export function App() { const [hidden, setHidden] = useState(true); return ( <Input addonAfter={ <Button appearance="subtle" icon={hidden ? <IconEye /> : <IconEyeOff />} onClick={() => setHidden((flag) => !flag)} rounded="full" size="sm" /> } placeholder="Password" type={hidden ? "password" : "text"} /> ); }

Use the addonPointerEvents prop to control whether clicking the addons focuses the input or not.

@
"use client"; import { Input } from "@optiaxiom/react"; import { type ComponentPropsWithoutRef } from "react"; export function App({ addonPointerEvents = "none", }: Pick<ComponentPropsWithoutRef<typeof Input>, "addonPointerEvents">) { return ( <Input addonBefore="@" addonPointerEvents={addonPointerEvents} placeholder="Email" /> ); }

Use the appearance prop to select between the different input appearances.

"use client"; import { Group, Input } from "@optiaxiom/react"; export function App() { return ( <Group gap="16"> <Input defaultValue="Text value" /> <Input appearance="number" defaultValue="23.50" /> </Group> ); }

Use the maxLength prop to limit the number of characters users can enter. Combine with a character counter in the Field description for better UX.

0/50
"use client"; import { Field, Input } from "@optiaxiom/react"; import { useState } from "react"; export function App() { const [value, setValue] = useState(""); const maxLength = 50; return ( <Field description={`${value.length}/${maxLength}`} label="Project description" > <Input maxLength={maxLength} onValueChange={setValue} placeholder="Enter description..." value={value} /> </Field> ); }

SearchInput

Basic search input field with clear button.

Textarea

Multi-line text field for capturing user input.

Props

Supports all Box props in addition to its own. Renders a <div> element but forwards all props to an inner <input> element.

Prop

addonAfter

Display content inside the input at the end.

ReactNode

addonBefore

Display content inside the input at the start.

ReactNode

addonPointerEvents

When this prop is set to none clicking empty space inside the addon will focus the input box.

"none" | "auto"

appearance

Control the appearance of the input.

"number" | "default"

Default: default

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

disabled

Whether the input is disabled.

false | true

error

Whether to show the input error state. Automatically set when used inside a Field component with an error prop.

false | true

htmlSize

Control the native input size attribute.

number

onValueChange

Handler that is called when the value changes.

(value: string) => void

size

Control the size of the input.

"md" | "lg" | "xl"

Default: md

Changelog

  • Added component
Last updated on