Inputs that don’t fight you.
Every state covered — default, hover, focus, disabled, error, success. Every label visible. Every error announced. Every interaction reachable by keyboard.
One input, six states.
The same email field across every required state. Validate on blur, surface errors with role=alert, never remove the focus ring without a replacement.
- default
We'll send a confirmation link.
Resting state — neutral border, surface bg.
- hover
Border darkens as the cursor enters.
Hover — border darkens one step (no fill change).
- focus
Brand ring while focused; never outline:none without a replacement.
Focus — 2px brand ring, brand-tinted border.
- disabled
Locked while the parent step is in flight.
Disabled — opacity 0.6, cursor not-allowed.
- error
Validate on blur, then live-update as the user fixes it.
Looks like that email is missing a domain.
Error — token-mixed red border, message announced via role=alert.
- success
Confirmed — debounced after blur, never on every keystroke.
Email looks good.
Success — token-mixed green border, leading check icon.
Every input type the plugin produces.
Toggles, checkboxes, radios, sliders — hand-rolled with semantic <input> underneath. The combobox, multi-select, tag input, and date picker are vanilla React and ~30 lines each.
Text input
Single-line free text.
Search
Leading icon, clear button on input.
Textarea
84/280
Auto-grows; live character counter.
Number
Stepper buttons; tabular numerals.
Select
Native select with custom chevron.
Date
Visual-only popover with hand-rolled calendar.
Combobox
Filterable autocomplete.
Multi-select chips
ReactSvelteAdd multiple values; remove via chip × or Backspace.
Tag input
#designPress Enter or comma to commit a tag.
File upload
Drag-drop zone; native input under the hood.
Toggle switch
aria-checked is the source of truth.
Checkbox group
Pick any combination.
Radio group
Pick exactly one.
Slider
Range with live tooltip.
A real, polished signup form.
Five input types composed into a coherent flow. Stacked layout, helper text, error summary at the top, primary submit + secondary cancel. Submit shows a 1.5s loading state then confirms.
Built with shipit-ui-design.