Guide

# Variants

daisyUI variants stack positionally on any field — with defaults per form, per class, or globally.

## Positional variants

Any positional symbol that isn't a type override is a daisyUI variant, stacked onto the inner input exactly as the [daisyui gem](https://github.com/mhenrixon/daisyui) stacks them:

```ruby
f.field :email, :primary, :sm       # input input-primary input-sm
f.field :bio, :ghost                # textarea textarea-ghost
f.Input(:name, :primary, :lg)       # escape hatch: same stacking
f.submit "Save", :primary, :wide    # btn btn-primary btn-wide
```

An invalid field appends the error variant automatically (unless you already passed a color), so server-side errors restyle the control with no extra code.

## Form-level and global defaults

Real apps repeat the same variants on nearly every field. Set them once:

```ruby
# per form (inline)
Form(model: @user, field_variants: [:primary, :sm]) { |f| f.field :email }

# per form class — inherited down the subclass chain
class ApplicationForm < Forms::Base
  form_options field_variants: [:primary]
end

# global
PhlexForms.configure { |c| c.field_variants = [:sm] }
```

Defaults apply to every `field`'s inner input (never labels or hints), and `fields_for` builders inherit the parent form's.

## Precedence

Variants concatenate **global → form-level → call-site**, so the most local wins the class stack:

```ruby
PhlexForms.configure { |c| c.field_variants = [:sm] }

Form(model: @user, field_variants: [:primary]) do |f|
  f.field :email          # input-sm input-primary
  f.field :name, :lg      # input-sm input-primary input-lg — :lg wins
end
```

> **Tip:** Under the Plain theme, variants are accepted and ignored — the same form class renders unstyled without touching a call site.