Input

A single-line text field in a hairline HUD frame. It accepts icons or keyboard hints on either side, comes in two sizes and has an invalid state for validation errors.

import { Input } from 'jarvis-react-ui';

Basic

Input passes every native <input> attribute through (value, onChange, type, name, placeholder, ...). The ref points at the native <input>.

import { Input } from 'jarvis-react-ui';

export default function Basic() {
    return <Input aria-label="Callsign" placeholder="Enter callsign" />;
}

Adornments

startAdornment and endAdornment render inside the frame, before and after the text. Use them for an icon, a keyboard hint built with Hint.Key, a unit or a small action.

import { Search } from 'lucide-react';
import { Hint, Input } from 'jarvis-react-ui';

export default function WithAdornments() {
    return (
        <Input
            aria-label="Search docs"
            placeholder="Search docs…"
            startAdornment={<Search size={12} aria-hidden="true" />}
            endAdornment={<Hint.Key>CTRL K</Hint.Key>}
        />
    );
}

Sizes

sm is 26px high, md (the default) is 32px. The field is 220px wide; set fullWidth to fill its container instead.

import { Input } from 'jarvis-react-ui';

export default function Sizes() {
    return (
        <>
            <Input aria-label="Small" size="sm" placeholder="size sm" />
            <Input aria-label="Medium" size="md" placeholder="size md" />
        </>
    );
}

Invalid

invalid switches the frame to the error color and sets aria-invalid on the input. The component renders no helper text itself: place the message next to it and link it with aria-describedby.

import { useId } from 'react';
import { Input } from 'jarvis-react-ui';

export default function Invalid() {
    const helpId = useId();

    return (
        <div className="flex flex-col gap-[6px]">
            <Input
                aria-label="Accent color"
                aria-describedby={helpId}
                defaultValue="#zz00ff"
                invalid
            />
            <span id={helpId} className="text-[10px] text-error">
                Use a hex color such as #4ca8e8.
            </span>
        </div>
    );
}

Controlled

Drive the field with value and onChange like a native input. Here a clear button appears in the end adornment once there is text.

import { useState } from 'react';
import { Search, X } from 'lucide-react';
import { IconButton, Input } from 'jarvis-react-ui';

export default function Controlled() {
    const [query, setQuery] = useState('');

    return (
        <Input
            aria-label="Filter systems"
            placeholder="Filter systems…"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            startAdornment={<Search size={12} aria-hidden="true" />}
            endAdornment={
                query === '' ? undefined : (
                    <IconButton icon={X} label="Clear" size="sm" onClick={() => setQuery('')} />
                )
            }
        />
    );
}

Disabled

disabled is forwarded to the native input; the frame dims and hover sounds stop.

import { Input } from 'jarvis-react-ui';

export default function Disabled() {
    return <Input aria-label="Uplink" placeholder="Uplink offline" disabled />;
}

Styling

className goes to the outer frame (border, size, width); inputClassName goes to the native <input> element.

Sound

Hovering the frame plays hover_button through the nearest SfxProvider (not while disabled). Typing is silent. See Sound effects.

Accessibility

  • Renders a native <input>; all keyboard behavior is the browser's.
  • There is no built-in label. Provide a visible <label htmlFor> or an aria-label; a placeholder is not a label.
  • invalid sets aria-invalid="true". Reference the error message with aria-describedby.
  • Adornments are decorative by default: mark icons aria-hidden. Interactive adornments (such as a clear IconButton) need their own accessible name.

API

Prop Type Default Description
className string Additional class names for the outer frame <div> that holds input and adornments.
endAdornment ReactNode Content rendered after the text, e.g. a keyboard hint or a clear button.
fullWidth boolean false Stretches the field to the width of its container.
inputClassName string Additional class names for the native <input> element.
invalid boolean false Marks the field as invalid: error border and aria-invalid.
size 'sm' | 'md' 'md' Height and font size of the field.
startAdornment ReactNode Content rendered before the text, e.g. an Icon.

Also accepts inherited props from InputHTMLAttributes (30), HTMLAttributes (54), AriaAttributes (53), DOMAttributes (169), RefAttributes (1), Attributes (1).