Form components provide accessible, styled inputs for user interaction.
A text input component with icon and reset functionality.
Usage
import { Input } from "@/components/form/Input";
import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons";
function SearchForm() {
const [query, setQuery] = useState("");
return (
<Input
value={query}
onChange={setQuery}
icon={faMagnifyingGlass}
resettable={true}
inputProps={{
placeholder: "Search anime...",
autoComplete: "off"
}}
/>
);
}
Props
onChange
(value: string) => void
required
Callback when value changes
Shows reset button (X) when value is not empty
FontAwesome icon to display at the start of input
inputProps
ComponentPropsWithRef<'input'>
Additional props passed to the underlying input element
Styling
padding
string
default:"0.5rem 1rem"
Input padding
Rounded corners for pill shape
Uses theme.colors["solid-on-card"]
Focus State
From /src/components/form/Input.tsx:24:
&:focus-within {
box-shadow: ${theme.shadows.low};
// Dark theme focus ring
box-shadow: 0 0 0 2px ${theme.colors["text-primary"]};
}
Source
Defined in /src/components/form/Input.tsx:52
TextArea
A multi-line text input with vertical resizing.
Usage
import { TextArea } from "@/components/form/TextArea";
function CommentForm() {
return (
<TextArea
placeholder="Enter your comment..."
rows={4}
/>
);
}
Props
TextArea extends the standard HTML textarea element and accepts all standard textarea attributes.
Styling
Only allow vertical resizing
Uses theme.colors["solid-on-card"]
Custom scrollbar colors: theme.colors["gray-800"] on transparent
Source
Defined in /src/components/form/TextArea.tsx:6
Switch
A toggle switch built with Radix UI Switch primitive.
Usage
import Switch from "@/components/form/Switch";
function Settings() {
const [enabled, setEnabled] = useState(false);
return (
<label>
<Switch
isChecked={enabled}
onCheckedChange={setEnabled}
/>
<span>Enable notifications</span>
</label>
);
}
Props
onCheckedChange
(isChecked: boolean) => void
required
Callback when checked state changes
Also accepts all RadixSwitch.SwitchProps.
Styling
Uses theme.colors["solid-on-card"] when unchecked
Switch States
From /src/components/form/Switch.tsx:26:
const StyledSwitchThumb = styled(RadixSwitch.Thumb)`
width: 25px;
height: 25px;
background-color: ${theme.colors["text-disabled"]};
&[data-state="checked"] {
transform: translateX(25px);
background-color: ${theme.colors["text-primary"]};
}
`;
Source
Defined in /src/components/form/Switch.tsx:48
Slider
A range slider built with Radix UI Slider primitive.
Usage
import { Slider } from "@/components/slider/Slider";
function VolumeControl() {
const [volume, setVolume] = useState(0.5);
return (
<Slider
value={[volume]}
onValueChange={([value]) => setVolume(value)}
min={0}
max={1}
step={0.01}
/>
);
}
Props
onValueChange
(value: number[]) => void
Callback when value changes
Also accepts all RadixSlider.SliderProps.
Styling
Example from VolumeControl
From /src/components/video-player/VolumeControl.tsx:47:
<StyledSlider
value={[volume]}
onValueChange={([volume]) => {
setVolume(volume);
setMuted(false);
}}
min={0}
max={1}
step={0.01}
/>
Source
Defined in /src/components/slider/Slider.tsx:53
Combining form components:
import { Column } from "@/components/box/Flex";
import { Input } from "@/components/form/Input";
import { TextArea } from "@/components/form/TextArea";
import Switch from "@/components/form/Switch";
import { Button } from "@/components/button/Button";
function PlaylistForm() {
return (
<Column style={{ "--gap": "16px" }}>
<Input
value={name}
onChange={setName}
inputProps={{ placeholder: "Playlist name" }}
/>
<TextArea
placeholder="Description"
rows={3}
/>
<label>
<Switch isChecked={isPublic} onCheckedChange={setIsPublic} />
Make playlist public
</label>
<Button variant="primary">Save Playlist</Button>
</Column>
);
}
Accessibility
- All inputs support keyboard navigation
- Focus states use theme colors
- Radix UI primitives include ARIA attributes
- Custom scrollbar styles maintain accessibility