Skip to Content

Input

A versatile Input component that provides form-friendly input fields with integrated labels, error handling, and optional left/right sections. Built with accessibility and customization in mind.


Props

NameTypeDefaultDescription
labelstringLabel text displayed above the input.
errors`string[]stringReactNode`
requiredbooleanfalseShows a required indicator (asterisk) next to the label.
leftSectionReactNodeContent displayed on the left side inside the input.
rightSectionReactNodeContent displayed on the right side inside the input.
labelPropsComponentPropsWithoutRef<"label">Props passed to the label element.
labelPosition`“x""y”`"y"
...restComponentPropsWithoutRef<"input">Any native <input> props are forwarded.

Note The component automatically applies number pattern validation for type="number" inputs.


Usage

Basic Input

The most basic usage includes a label and placeholder.

import { Input } from "@kousta-ui/components";
export default function Example() {
return <Input label="Email" placeholder="you@example.com" type="email" />;
}

Input with Errors

Pass an array of strings to the errors prop to display validation messages. The component will automatically apply error styling.

import { Input } from "@kousta-ui/components";
export default function Example() {
return (
<Input
label="Email"
placeholder="you@example.com"
defaultValue="not-an-email"
errors={["Please enter a valid email"]}
/>
);
}
Please enter a valid email

Input with Sections (Prefix/Suffix)

Use leftSection and rightSection to add prefixes, suffixes, icons, or buttons inside the input.

import { Input } from "@kousta-ui/components";
export default function Example() {
return (
<Input
label="Amount"
placeholder="0.00"
type="number"
leftSection={<span style={{ padding: "0 8px", opacity: 0.7 }}>$</span>}
rightSection={<span style={{ padding: "0 8px", opacity: 0.7 }}>USD</span>}
/>
);
}
$USD

Password Input with Show/Hide

You can use the rightSection to create a toggle for password visibility.

import React, { useState } from "react";
import { Input } from "@kousta-ui/components";
export default function Example() {
const [visible, setVisible] = useState(false);
return (
<Input
label="Password"
placeholder="Enter password"
type={visible ? "text" : "password"}
rightSection={
<button
type="button"
onClick={() => setVisible((v) => !v)}
style={{
border: "none",
background: "transparent",
cursor: "pointer",
padding: "0 8px",
}}
aria-label={visible ? "Hide password" : "Show password"}
>
{visible ? "🙈" : "👁️"}
</button>
}
required
/>
);
}

Horizontal Label Layout

Set labelPosition="x" to align the label and input horizontally. You may need to provide a minWidth to the label via labelProps for alignment.

import { Input } from "@kousta-ui/components";
export default function Example() {
return (
<Input
label="Username"
placeholder="john_doe"
labelPosition="x"
labelProps={{ style: { minWidth: 100 } }}
/>
);
}

Disabled Input

Pass the native disabled prop to disable interaction and apply disabled styles.

import { Input } from "@kousta-ui/components";
export default function Example() {
return (
<Input
label="Read-only Field"
placeholder="Cannot edit"
disabled
defaultValue="Some read-only value"
/>
);
}

Accessibility

  • Semantics: Renders a proper <label> element linked to the input via htmlFor.
  • Error states: Errors are announced to screen readers via the data-error attribute.
  • Required fields: Visual indicator (asterisk) and semantic required attribute.
  • Keyboard navigation: Full keyboard support inherited from native input.

Tip Always provide descriptive labels and error messages for screen reader users.


Styles & customization

Runtime classes

  • kui-input-container: The main wrapper for the label, input, and error message.
  • kui-input-inner: The direct wrapper around the input field and its sections.
  • kui-input: The <input> element itself.
  • kui-input-label: The <label> element.
  • kui-input-error-message: The <span> that displays the error message.

Tokens used by the default styles

  • Colors: --kui-neutral-*, --kui-primary-*, --kui-danger-*
  • Spacing: --kui-spacing-2xs, --kui-spacing-xs, --kui-spacing-sm
  • Typography: --kui-text-base, --kui-text-sm
  • Rounding: --kui-rounded

Types (reference)

import { ComponentPropsWithoutRef, ReactNode } from "react"; type LabelPositionBase = "x" | "y"; export type InputProps = ComponentPropsWithoutRef<"input"> & { label?: string; labelProps?: ComponentPropsWithoutRef<"label">; errors?: string[] | string | ReactNode; required?: boolean; leftSection?: ReactNode; rightSection?: ReactNode; labelPosition?: LabelPositionBase; };

Component Props Provider

You can set default input behavior for a subtree using ComponentPropsProvider. This is especially useful to standardize label layout, icons/sections, or label props.

import { ComponentPropsProvider, Input } from "@kousta-ui/components"; export default function Example() { return ( <ComponentPropsProvider input={{ labelPosition: "y", labelProps: { style: { fontWeight: 600 } }, }} > <Input label="Email" placeholder="you@example.com" /> <Input label="Password" type="password" /> </ComponentPropsProvider> ); }
Last updated on