Fieldset

A semantic form section with legend, guidance, grouped fields, and disabled state.

Source
app/components/nitro_kit/fieldset.rb
API
NitroKit::Fieldset.new(legend:, description:, disabled:) { fields }

Semantic boundaries

A native fieldset owns one legend, optional guidance, and an explicit fields region.

Boundary states

Empty
Disabled
Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/fieldset_page.rb
sample("Empty", slug: "empty") do
  render NitroKit::Fieldset.new(
    legend: "Optional advanced settings",
    description: "No advanced settings are available for this plan.",
    html: { id: "gallery-fieldset-empty" }
  ) { nil }
end
sample("Disabled", slug: "disabled") do
  render NitroKit::Fieldset.new(
    legend: "Legacy synchronization",
    description: "Locked while migration is in progress.",
    disabled: true,
    name: "legacy-sync",
    html: { id: "gallery-fieldset-disabled" }
  ) do
    render NitroKit::Field.new(
      nil,
      :destination,
      id: "gallery-fieldset-disabled-destination",
      name: "legacy[destination]",
      value: "Compliance archive",
      label: "Destination"
    )
  end
end

Long policy section

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/fieldset_page.rb
render NitroKit::Fieldset.new(
  legend: "Production credential rotation and revocation policy for deployment targets",
  description: "Replacement credentials are distributed before the current credential expires. Revocation begins only after every target confirms receipt.",
  html: { id: "gallery-fieldset-long" }
) do
  render NitroKit::FieldGroup.new(html: { id: "gallery-fieldset-long-fields" }) do
    render NitroKit::Field.new(
      nil,
      :rotation_window,
      as: :number,
      id: "gallery-fieldset-rotation-window",
      name: "credential_policy[rotation_window]",
      value: 14,
      label: "Rotation window in days",
      min: 1,
      max: 90,
      required: true
    )
    render NitroKit::Field.new(
      nil,
      :automatic_rotation,
      as: :switch,
      id: "gallery-fieldset-automatic-rotation",
      name: "credential_policy[automatic_rotation]",
      label: "Generate replacement credentials automatically",
      checked: true
    )
  end
end

Rails form builder

A real model-backed multipart form composes builder fieldsets, groups, errors, choices, and actions.

Registration details

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/fieldset_page.rb
registration = Registration.new(email: "not-an-email", role: "", terms: false, source: "gallery")
registration.validate

form_with(
  model: registration,
  scope: :registration,
  url: "#registration-details",
  builder: NitroKit::FormBuilder,
  id: "gallery-fieldset-registration-form"
) do |form|
  form.hidden_field(:source, id: "gallery-fieldset-registration-source")
  form.fieldset(
    legend: "Registration details",
    description: "Required fields preserve Rails validation and submission behavior.",
    html: { id: "gallery-fieldset-registration" }
  ) do
    form.group(html: { id: "gallery-fieldset-registration-fields" }) do
      form.field(
        :email,
        as: :email,
        id: "gallery-fieldset-registration-email",
        description: "Used only for the registration receipt.",
        required: true
      )
      form.field(
        :role,
        as: :select,
        id: "gallery-fieldset-registration-role",
        label: "Role",
        prompt: "Choose a role",
        options: [ [ "Developer", "developer" ], [ "Designer", "designer" ] ],
        required: true
      )
      form.field(
        :terms,
        as: :checkbox,
        id: "gallery-fieldset-registration-terms",
        label: "I accept the workspace terms",
        required: true
      )
      form.field(
        :attachment,
        as: :file,
        id: "gallery-fieldset-registration-attachment",
        label: "Supporting note",
        accept: "text/plain"
      )
    end
  end
  form.submit("Register", id: "gallery-fieldset-registration-save")
end