Skip to content

DaisyUI v5 Integration

The Maho Storefront uses DaisyUI v5 as its component CSS library, integrated via UnoCSS preflights rather than Tailwind.

Architecture

Why UnoCSS Instead of Tailwind?

DaisyUI v5 is designed for Tailwind CSS v4. The storefront uses UnoCSS instead because:

  • Faster builds — UnoCSS is significantly faster than Tailwind
  • More flexible — Custom preflights, rules, and shortcuts
  • Smaller output — Only generates used utility classes

CSS Processing

The processDaisyCSS() function in uno.config.ts handles DaisyUI's CSS:

  1. Reads the full DaisyUI CSS from node_modules/daisyui/daisyui.css
  2. Strips @layer directives (UnoCSS manages layers differently)
  3. Flattens bare &{...} blocks using stack-based phantom brace tracking
  4. Preserves meaningful nesting (&:hover, &>.child, &:focus-visible)
  5. Outputs clean CSS as a UnoCSS preflight

Theme Variable Mapping

DaisyUI uses its own CSS variable naming. uno.config.ts maps theme.json tokens to DaisyUI's system:

theme.json TokenDaisyUI VariableUsed By
accent--color-primarybtn-primary, bg-primary, text-primary
primary--color-secondarybtn-secondary, bg-secondary
bg--color-base-100bg-base-100
bgSubtle--color-base-200bg-base-200
bgMuted--color-base-300bg-base-300
text--color-base-contentDefault text color
success--color-successalert-success, badge-success
warning--color-warningalert-warning
error--color-erroralert-error, text-error
info--color-infoalert-info

Important

DaisyUI's primary is the storefront's accent color. This reversal is intentional — the most visually prominent elements (buttons, links, badges) should use the accent/CTA color.

DaisyUI v5 Component Patterns

Forms

DaisyUI v5 uses a different form pattern than v4:

html
<!-- v5 Pattern: fieldset + fieldset-legend -->
<fieldset class="fieldset">
  <legend class="fieldset-legend">Email</legend>
  <label class="input w-full">
    <input type="email" class="grow" placeholder="you@example.com" />
  </label>
</fieldset>

<!-- Select -->
<select class="select w-full">
  <option>Choose one</option>
</select>

WARNING

Do NOT use DaisyUI v4 patterns (form-control, label-text). These don't exist in v5.

Buttons

html
<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-outline">Outline</button>
<button class="btn btn-ghost">Ghost</button>

Tabs

DaisyUI v5 uses tabs-border (not v4's tabs-bordered), and tab-active (not just active):

html
<div class="tabs tabs-border">
  <button class="tab tab-active">Tab 1</button>
  <button class="tab">Tab 2</button>
</div>

Cards

html
<div class="card bg-base-100 shadow-md">
  <figure><img src="..." alt="..." /></figure>
  <div class="card-body">
    <h2 class="card-title">Title</h2>
    <p>Description</p>
    <div class="card-actions justify-end">
      <button class="btn btn-primary">Action</button>
    </div>
  </div>
</div>

Base Reset Gotchas

The UnoCSS base reset must exclude DaisyUI's button classes from generic button resets:

css
button:not(.btn):not(.tab):not([class*="join-item"]) {
  /* Reset styles only for non-DaisyUI buttons */
}

This prevents DaisyUI's styled buttons from being stripped of their styles.

Source: uno.config.ts