Text input component with Inter font, elevation shadows, and optional clear button. Extends native <input> attributes.
import { DesignInput } from "@/components/ui/design-input"
// Basic
<DesignInput placeholder="Enter text..." />
// Controlled with clear button
<DesignInput
value={value}
onChange={(e) => setValue(e.target.value)}
clearable
onClear={() => setValue("")}
/>
// With label
<DesignInput label="Username" placeholder="Enter username..." />
// Ghost variant (transparent, shows bg on hover/focus)
<DesignInput variant="ghost" placeholder="Click to edit..." />| Prop | Type | Default | Description |
|---|---|---|---|
size | "small" | "default" | "large" | "default" | Height: 28px / 32px / 40px |
variant | "default" | "ghost" | "default" | ghost: transparent bg, shows on hover/focus |
label | string | - | Label text displayed above the input |
clearable | boolean | - | Show clear (x) button when input has value |
onClear | () => void | - | Callback when clear button is clicked (required with clearable) |
startContent | ReactNode | - | Slot before the text input (e.g. search icon) |
endContent | ReactNode | - | Slot after the text input (e.g. eye icon) |
children | ReactNode | - | Replaces the entire <input> element (custom content mode) |
dashed | boolean | - | Dashed border style for empty/placeholder states |
textAlign | "left" | "center" | "right" | "left" | Text alignment inside input |
error | boolean | - | Error visual state |
errorMessage | string | - | Error text inside input (right side, red) |
showCount | boolean | - | Show character count (requires maxLength) |
maxLength | number | - | Max chars (CJK chars count as 2 when showCount enabled) |
disabled | boolean | - | Disabled state (44% opacity, surface-400 bg) |
className | string | - | Applied to the outer wrapper div |
ref | Ref<HTMLInputElement> | - | Forwarded to the native <input> element |
Right-side visibility priority: endContent > error+errorMessage > clearable. Only one shows at a time.
size="small"(no size prop)size="large"Minimal usage
{ placeholder: "Enter text..." }Label text above input
{ label: "Username" }clearable + onClear paired together
{ clearable: true, onClear: "() => setValue('')" }44% opacity, surface-400 bg
{ disabled: true }Red error text inside input (right side)
{ error: true, errorMessage: "Required" }Transparent bg, shows on hover/focus
{ variant: "ghost" }startContent / endContent / children — three slots for custom content
Icon or text before input
{ startContent: "<DesignIcon name="search" />" }Icon or text after input
{ endContent: "<DesignIcon name="eye" />" }startContent + endContent together
{ startContent: "$", endContent: "USD" }Replaces the entire <input> element
{ children: "<custom content>" }showCount + maxLength — CJK characters count as 2
Displays "current/max" on the right
{ maxLength: 30, showCount: true }Combine label with character count
{ label: "Title", maxLength: 50, showCount: true }clearable must always pair with onClear callback to reset controlled statechildren replaces the entire <input> — no typing, no value, no onChangeshowCount requires maxLength — CJK characters are counted as 2className is applied to the outer wrapper div, not the <input> element