Radio button group

A native single-select fieldset with typed choices and required selection semantics.

Source
app/components/nitro_kit/radio_button_group.rb
API
NitroKit::RadioButtonGroup.new(legend:, options:, name:, value:, required:)

Selection groups

One fieldset owns the legend, description, same-name controls, and selected value.

Default member role

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/radio_button_group_page.rb
render NitroKit::RadioButtonGroup.new(
  legend: "Default member role",
  description: "New invitations use this role unless an administrator chooses another.",
  id: "gallery-radio-button-group-role",
  name: "workspace[default_role]",
  value: "member",
  required: true,
  options: [
    [ "Administrator", "admin" ],
    { label: "Member", value: "member", id: "gallery-role-member" },
    NitroKit::Choice.new(
      label: "Viewer",
      value: "viewer",
      disabled: true,
      id: "gallery-role-viewer"
    )
  ]
)

Boundary counts

One choice
No selection
Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/radio_button_group_page.rb
sample("One choice", slug: "one") do
  render NitroKit::RadioButtonGroup.new(
    legend: "Deployment target",
    id: "gallery-radio-button-group-one",
    name: "deployment[target]",
    value: "production",
    options: [ [ "Production", "production" ] ]
  )
end
sample("No selection", slug: "none") do
  render NitroKit::RadioButtonGroup.new(
    legend: "Export format",
    id: "gallery-radio-button-group-none",
    name: "export[format]",
    value: nil,
    options: [ [ "CSV", "csv" ], [ "JSON", "json" ], [ "PDF", "pdf" ] ]
  )
end

Availability and pressure

Sizes, disabled groups, many options, and long labels retain the same deterministic structure.

Large retention policies

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/radio_button_group_page.rb
render NitroKit::RadioButtonGroup.new(
  legend: "Workspace retention policy for audit events, credential activity, and deployment metadata",
  description: "Changing the policy affects future retention and never shortens an active legal hold.",
  id: "gallery-radio-button-group-many",
  name: "workspace[retention_policy]",
  value: "regulated",
  size: :lg,
  options: [
    [ "Standard ninety-day retention", "standard" ],
    [ "Extended one-year retention", "extended" ],
    [ "Regulated seven-year retention with immutable audit exports", "regulated" ],
    [ "Legacy indefinite retention", "legacy", true ]
  ]
)

Disabled group

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/radio_button_group_page.rb
render NitroKit::RadioButtonGroup.new(
  legend: "Billing currency",
  description: "Contact support before the next renewal date to change currency.",
  id: "gallery-radio-button-group-disabled",
  name: "billing[currency]",
  value: "USD",
  disabled: true,
  options: [ [ "United States dollar", "USD" ], [ "Euro", "EUR" ] ]
)

Rails form builder

A builder field derives the selected model value, names, IDs, descriptions, and errors.

Invalid invitation role

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/radio_button_group_page.rb
invitation = Gallery::FormExamples.team_invitation(:invalid)

form_with(
  model: invitation,
  scope: :invitation,
  url: "#invitation-role-group",
  builder: NitroKit::FormBuilder,
  id: "gallery-radio-button-group-invitation-form"
) do |form|
  form.field(
    :role,
    as: :radio_group,
    id: "gallery-radio-button-group-invitation-role",
    label: "Invitation role",
    description: "Choose the least privileged role that supports the member's work.",
    options: [ [ "Administrator", "admin" ], [ "Member", "member" ], [ "Viewer", "viewer" ] ],
    required: true
  )
  form.submit("Send invitation", id: "gallery-radio-button-group-invitation-save")
end