Reference

Escape hatches

When field's one-call convenience isn't enough: bare components, wrapped inputs, and the custom-widget recipe.

The component API#

Every control field composes is also callable directly, with stable signatures — a bare input, no label/control wrapper, still fully model-bound:

f.Input(:name, :primary, :lg)     # bare input, variants stacked
f.Select(:role, choices: roles)   # native <select>
f.Textarea(:bio, :ghost)
f.Checkbox(:terms)
f.Toggle(:notify)
f.Radio(:size, "large")
f.FileInput(:avatar)
f.Hidden(:token)
f.Label(:email)
f.Control(:email, label: "Email") { f.Input(:email) }

PascalCase marks the component layer; lowercase field/row/group/ submit are the composed verbs. Both apply the model's value, error state, and client-validation data the same way.

The custom-widget recipe#

A bespoke widget — date picker, tag field, remote select — wraps in Control and binds through the three public helpers. This is the supported path, not a fork reason:

f.Control(:starts_at, label: "Starts") do
  render MyDatePicker.new(
    name: f.field_name(:starts_at),
    id: f.field_id(:starts_at),
    value: f.field_value(:starts_at)
  )
end

The control contributes the label, error/hint slot, and layout; your widget owns the input. Errors on the attribute render exactly like any other field's.

Icons inside the field#

wrapped_input renders the daisyUI v5 <label class="input"> pattern — leading content (an icon, a prefix), the bare input, optional trailing content:

f.field_object(:search).wrapped_input(:primary) do
  LucideIcon("search", class: "opacity-50")
end

Icons default to a bundled inline SVG so the gem is self-contained; see Configuration for the glyphs renderer.

Specialised controls#

  • f.Select(:tags, choices:, searchable: true, multiple: true) — a choices.js-backed searchable/multi select (needs the choices.js peer).
  • f.rich_textarea(:body) — the rich-text editor binding (ActionText-compatible value handling).
  • f.time_zone_select(:time_zone) — grouped time zones with a sensible selected default.