Data Input Components
When to Use
Form elements: text fields, selections, toggles, and form structure.
Decision: Which Input Component
| Component | Class | Use for |
|---|---|---|
| Text input | .input |
Single-line text, email, search |
| Form group | .fieldset |
Label + input + help text grouping (v5) |
| Select | .select |
Dropdown selection |
| Multi-line | .textarea |
Long-form text |
| Boolean | .checkbox |
True/false selection |
| On/off | .toggle |
Styled boolean switch |
| Radio | .radio |
Single-select from group |
| Range | .range |
Numeric slider |
| Rating | .rating |
Star rating input |
| File picker | .file-input |
Styled file upload field |
| Animated label | .floating-label |
Placeholder-style label that animates on focus (v5) |
| CSS validation | .validator |
Show/hide hints using native :valid/:invalid state |
| Calendar styling | .calendar |
Skin for third-party datepicker libraries |
| Filter chips | .filter |
Radio/checkbox inputs styled as selectable pill chips |
.input — Text Input
Modifiers: input-primary through input-error (border color on focus) + input-ghost + sizes input-xs through input-xl
<!-- Wrapper pattern (supports prefix/suffix icons) -->
<label class="input input-primary flex items-center gap-2">
<svg .../><!-- prefix icon -->
<input type="text" class="grow" placeholder="Search" />
</label>
<!-- Direct input (simpler) -->
<input type="text" class="input w-full" placeholder="Email" />
Gotchas:
- v5 changed the primary pattern to a wrapper
<label class="input">containing<input>— this enables icon prefix/suffix without extra CSS input-borderedis no longer in v5 — borders are now default. Useinput-ghostto remove them- Mobile iOS: DaisyUI adds
font-size: max(0.875rem, 1rem)on focus on coarse-pointer devices to prevent iOS zoom on small inputs
.fieldset — Form Group Container
v5 addition. Groups label, input, and help text:
<fieldset class="fieldset">
<legend class="fieldset-legend">Account Details</legend>
<label class="fieldset-label">Email</label>
<input type="email" class="input w-full" placeholder="you@example.com" />
<p class="fieldset-label text-error">Enter a valid email address</p>
</fieldset>
Gotchas: .fieldset replaces the old form-control class from v4. Do not use form-control in v5.
.select — Select Dropdown
Same modifier pattern as .input: select-primary through select-error + select-ghost + sizes.
<label class="select">
<select>
<option disabled selected>Pick a color</option>
<option>Red</option>
<option>Blue</option>
</select>
</label>
.textarea — Text Area
Same modifier pattern. No fixed height by default — use Tailwind min-h-* or rows attribute.
<textarea class="textarea textarea-primary w-full" placeholder="Message" rows="4"></textarea>
.checkbox — Checkbox
<input type="checkbox" class="checkbox checkbox-primary" />
<input type="checkbox" class="checkbox checkbox-success checkbox-lg" checked />
Modifiers: semantic colors + sizes checkbox-xs through checkbox-xl
Gotchas: DaisyUI checkbox uses CSS ::before for the checkmark animation — the native appearance is suppressed via appearance: none. This means browser built-in checkbox styling is completely replaced, including high-contrast mode (handled via forced-colors media query in the CSS).
.radio — Radio Button
Same modifier pattern as checkbox. Always wrap related radios with a <fieldset> and provide <legend>.
<input type="radio" name="plan" class="radio radio-primary" />
.toggle — Toggle Switch
<input type="checkbox" class="toggle toggle-primary" />
<input type="checkbox" class="toggle toggle-success toggle-lg" checked />
The toggle is a styled <input type="checkbox"> — same semantics, different visual.
.range — Range Slider
<input type="range" min="0" max="100" value="40" class="range range-primary" />
.rating — Star Rating
<div class="rating rating-lg">
<input type="radio" name="rating-1" class="mask mask-star-2 bg-orange-400" aria-label="1 star" />
<input type="radio" name="rating-1" class="mask mask-star-2 bg-orange-400" checked aria-label="2 stars" />
<!-- etc -->
</div>
Gotchas: Rating uses radio inputs with the .mask utility to clip to star shape. Requires aria-label on each input for accessibility.
.file-input — File Upload Input
Description: Styled file picker input. Follows the same modifier pattern as .input.
Modifiers: file-input-primary through file-input-error + sizes file-input-xs through file-input-xl
<label class="form-control w-full max-w-xs">
<div class="label"><span class="label-text">Pick a file</span></div>
<input type="file" class="file-input file-input-primary w-full" />
</label>
<!-- Ghost variant (minimal border) -->
<input type="file" class="file-input file-input-ghost w-full" />
Gotchas:
- The browser's native file picker UI is not replaceable — DaisyUI only styles the surrounding element
- On Safari/iOS, the "Choose File" button text is browser-controlled and cannot be changed via CSS
- Always pair with a
<label>for accessibility —<input type="file">without an accessible label is non-compliant
.label — Form Label with Floating Variant
Description: Wrapper for form field labels. v5 supports floating labels (placeholder-style labels that animate on focus).
Required structure — Standard label:
<fieldset class="fieldset">
<label class="fieldset-label">Email address</label>
<input type="email" class="input w-full" />
</fieldset>
Required structure — Floating label:
<label class="floating-label">
<span>Email address</span>
<input type="email" class="input" placeholder="Email address" />
</label>
Gotchas:
- Floating labels require the
placeholderattribute to be set to the same text as the label — the placeholder is used to detect the empty state via CSS:placeholder-shown floating-labelis a v5 addition — not available in v4- For error state text, use a second
<span class="fieldset-label text-error">after the input, not inside the floating label wrapper
.validator — Inline Validation Display
Description: Validates input values and shows contextual success/error messages without JavaScript. Uses CSS :valid / :invalid pseudo-classes on the native input.
Required structure:
<input
type="email"
class="input validator"
required
placeholder="user@example.com"
/>
<p class="validator-hint">Must be a valid email address</p>
With fieldset:
<fieldset class="fieldset">
<label class="fieldset-label">Email</label>
<input type="email" class="input validator w-full" required />
<p class="validator-hint">Enter a valid email address</p>
</fieldset>
Gotchas:
.validatorrelies on native HTML validation — the input must haverequired,type="email",pattern,min/max, or other native validation attributes. Without them,:valid/:invalidnever trigger- Validation state only shows after the user interacts with the field (
:user-invalidin modern browsers) — the error does not display on initial page load .validator-hintis hidden by default and shown only on:invalidstate — the text should describe the validation rule, not the error- For custom validation logic (e.g., async username availability),
.validatorcannot help — use JS to add/remove error classes manually
.calendar — Calendar Date Picker Styling
Description: CSS styles for third-party calendar/datepicker libraries. DaisyUI provides the visual theme; the calendar interaction logic must come from a JS library (e.g., Pikaday, Cally web component).
Note: .calendar is a styling skin, not a standalone component. It does not ship with calendar logic.
Recommended pairing — Cally web component:
<!-- Install: npm install cally -->
<script type="module" src="node_modules/cally/src/index.js"></script>
<calendar-date class="calendar">
<svg slot="previous"><!-- left arrow icon --></svg>
<svg slot="next"><!-- right arrow icon --></svg>
</calendar-date>
Gotchas:
- Without a JS library,
.calendarrenders nothing meaningful — the component is a CSS skin only - DaisyUI's calendar CSS targets Cally web component element selectors — compatibility with other datepicker libraries is not guaranteed
- Theme colors apply automatically via CSS variable inheritance — no extra config needed
.filter — Toggleable Filter Chips
Description: A group of radio or checkbox inputs styled as filter chips/pills. CSS-only selection state management.
Required structure:
<div class="filter">
<input class="btn filter-reset" type="radio" name="category" aria-label="All" checked />
<input class="btn btn-sm" type="radio" name="category" aria-label="Electronics" />
<input class="btn btn-sm" type="radio" name="category" aria-label="Clothing" />
<input class="btn btn-sm" type="radio" name="category" aria-label="Books" />
</div>
Gotchas:
- Filter chip labels come from
aria-labelattribute — DaisyUI renders them via CSScontent: attr(aria-label), soaria-labelis both the visible text and the accessible label filter-resetstyles the "All" / reset option distinctly — include one reset chip at the start- Use
type="radio"for single-select filters,type="checkbox"for multi-select - For filtering actual content, add JavaScript to listen for change events and filter DOM elements — DaisyUI provides no filtering logic
Common Mistakes
- Using old
form-controlwrapper class (v4) in v5 projects — replaced byfieldset - Not providing
<label>oraria-labelfor checkbox/radio/toggle — these are<input>elements; screen readers need explicit labels - Setting
input-borderedin v5 — this class no longer exists; borders are on by default - Using
.validatorwithout native HTML validation attributes — norequired/type/patternmeans:invalidnever fires
See Also
- Customization Patterns
- Security and Accessibility
- Reference:
react-design-system.mdSection 8 — react-hook-form integration - Reference:
node_modules/daisyui/components/input/object.js - Reference:
node_modules/daisyui/components/fieldset/object.js