ui · Primitive
Input
@devalok/shilp-sutra/ui/inputView in Storybook Hand-curated previews ship in rolling waves. See it live in Storybook →
Reference
Props
size: "xs" | "sm" | "md" | "lg"
state: InputState
startSection: ReactNode (icon or content in the leading slot)
endSection: ReactNode (icon or content in the trailing slot)
startSectionClickable: boolean (enables pointer events on start section)
endSectionClickable: boolean (enables pointer events on end section)
startSectionType: 'icon' | 'label' (section display type — auto-inferred from content)
endSectionType: 'icon' | 'label' (section display type — auto-inferred from content)
wrapperClassName: string (classes for the wrapper div — border, bg, ring)
(plus all standard HTML input attributes except native "size")
Types
InputState = 'default' | 'error' | 'warning' | 'success'
Defaults
size: "md"
Example
<Input type="email" placeholder="[email protected]" state="error" startSection={<Icon icon={IconMail} />} />
<Input size="xs" placeholder="Quick search" startSection={<Icon icon={IconSearch} />} />
<Input startSection="https://" startSectionType="label" placeholder="example.com" />
<Input endSection=".00" endSectionType="label" startSection={<Icon icon={IconCurrencyDollar} />} placeholder="0" />
Composability
- FormField auto-consumption: Inside a
<FormField>, Input auto-inheritsstate,aria-describedby(linked to FormHelperText),aria-invalid(when state="error"),aria-required. Explicit props on Input override context. - IconProvider cascade: Icons in
startSection/endSectionare auto-sized via IconProvider per the input'ssize(xs → sm icon, sm → sm icon, md → md icon, lg → md icon). Don't pass explicit size to nested<Icon>. - Container-first architecture (v0.29.0+): Border, background, focus ring all live on the wrapper div (accessed via
wrapperClassName). The raw<input>inside is transparent.classNamegoes to the input element;wrapperClassNamegoes to the wrapper. - Section types: Strings in startSection/endSection auto-render as
label(tinted bg + border separator); React elements auto-render asicon(fixed-width centered cell). Override viastartSectionType/endSectionType. - Label pairing: Always pair with
<Label htmlFor="x" />+<Input id="x" />or wrap both in a<label>— FormField doesn't auto-wire the visual label to the input.
Gotchas
- HTML native "size" attribute is excluded — use CSS width instead
- state="error" sets aria-invalid automatically
- Inside FormField: auto-inherits state, aria-describedby, aria-required from context (explicit props override)
classNametargets the<input>element; usewrapperClassNamefor border/bg/ring overrides- Focus ring is on the wrapper container (focus-within), not the input itself
- Icons in startSection/endSection are auto-sized via IconProvider per input size
- Sections are
pointer-events-noneby default — setstartSectionClickable/endSectionClickablefor interactive sections - Section type is auto-inferred: strings default to
'label'(tinted bg + border), React elements default to'icon'(fixed-width centered). Override withstartSectionType/endSectionType.
Changes
v0.38.0
- Removed (BREAKING) deprecated
startIcon/endIconprops. UsestartSection/endSection. - Removed (BREAKING) deprecated
inputVariantsexport. UseinputWrapperVariants.
v0.29.0
- Changed v2 rewrite: container-first architecture with wrapper div holding focus ring
- Added
xssize (28px height) - Added
startSection/endSectionprops replacingstartIcon/endIcon(deprecated but still work) - Added
startSectionClickable/endSectionClickableprops for interactive sections - Added
wrapperClassNameprop for styling the wrapper div (border, bg, ring) - Changed Focus ring now on wrapper via
focus-within(container-level ring, not input-level) - Changed Icons auto-sized via
IconProvidercontext per input size - Deprecated
startIcon/endIcon— usestartSection/endSection - Added
startSectionType/endSectionTypeprops —'icon'(fixed-width centered cell) or'label'(tinted background with border separator). Auto-inferred from content type (strings → label, React elements → icon). - Changed Sections use flexbox layout for consistent alignment
- Deprecated
inputVariantsexport — useinputWrapperVariants(semantics changed to target wrapper)
v0.15.0
- Changed
lgsize font changed fromtext-ds-lg(18px) totext-ds-md(14px) — all input sizes now use 14px for consistency - Changed
mdsize font standardized totext-ds-md(14px) from mixed values
v0.12.0
- Changed Softer resting border (
border-border-subtleinstead ofborder-border), subtler focus ring (ring-1 ring-focus/50instead ofring-2 ring-focus) - Changed Reverted split
pl-*/pr-*size variants back topx-*; icon padding usespl-ds-07/pr-ds-07
v0.8.0
- Fixed Now consumes FormField context automatically (
aria-describedby,aria-invalid,aria-required)
v0.4.2
- Added
inputVariantsexport
v0.1.0
- Added Initial release