Checkbox

Submittable boolean controls with explicit checked, unchecked, and mixed state.

Source
app/components/nitro_kit/checkbox.rb
API
NitroKit::Checkbox.new(label:, id:, name:, value:, checked:)

Submission states

Checked, unchecked, and native indeterminate state stay synchronized as the control changes.

Boolean states

Unchecked
Checked
Indeterminate
Disabled
Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/checkbox_page.rb
sample("Unchecked", slug: "unchecked") do
  render NitroKit::Checkbox.new(
    label: "Email summaries",
    id: "gallery-checkbox-unchecked-control",
    name: "preferences[email_summaries]",
    value: "enabled",
    unchecked_value: "disabled",
    html: { id: "gallery-checkbox-unchecked" }
  )
end
sample("Checked", slug: "checked") do
  render NitroKit::Checkbox.new(
    label: "Security notices",
    id: "gallery-checkbox-checked-control",
    name: "preferences[security_notices]",
    checked: true,
    required: true,
    html: { id: "gallery-checkbox-checked" }
  )
end
sample("Indeterminate", slug: "indeterminate") do
  render NitroKit::Checkbox.new(
    label: "Select visible members",
    id: "gallery-checkbox-indeterminate-control",
    name: "members[visible]",
    indeterminate: true,
    include_hidden: false,
    html: { id: "gallery-checkbox-indeterminate" }
  )
end
sample("Disabled", slug: "disabled") do
  render NitroKit::Checkbox.new(
    label: "Legacy synchronization",
    id: "gallery-checkbox-disabled-control",
    name: "preferences[legacy_sync]",
    checked: true,
    disabled: true,
    html: { id: "gallery-checkbox-disabled" }
  )
end

Label boundaries

Standalone controls need an explicit accessible name; block labels and long agreement text remain native.

Label pressure

Standalone
Block label
Long agreement
Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/checkbox_page.rb
sample("Standalone", slug: "standalone") do
  render NitroKit::Checkbox.new(
    id: "gallery-checkbox-standalone-control",
    name: "rows[selected]",
    include_hidden: false,
    control_aria: { label: "Select deployment row" },
    html: { id: "gallery-checkbox-standalone" }
  )
end
sample("Block label", slug: "block") do
  render NitroKit::Checkbox.new(
    id: "gallery-checkbox-block-control",
    name: "preferences[activity]",
    checked: true,
    html: { id: "gallery-checkbox-block" }
  ) do
    strong { "Activity reports" }
    plain(" every Monday morning")
  end
end
sample("Long agreement", slug: "long") do
  render NitroKit::Checkbox.new(
    label: "I understand that rotating this production credential immediately invalidates every existing deployment token",
    id: "gallery-checkbox-long-control",
    name: "credential[confirm_rotation]",
    required: true,
    html: { id: "gallery-checkbox-long" }
  )
end

Rails form builder

The builder keeps model truthiness, hidden unchecked values, errors, and Rails names together.

Terms validation

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/checkbox_page.rb
registration = Registration.new(email: "[email protected]", role: "developer", terms: false)
registration.validate

form_with(
  model: registration,
  scope: :registration,
  url: "#registration-terms",
  builder: NitroKit::FormBuilder,
  id: "gallery-checkbox-registration-form"
) do |form|
  form.field(
    :terms,
    as: :checkbox,
    id: "gallery-checkbox-registration-terms",
    label: "I accept the workspace terms",
    description: "Required before the invitation can be accepted.",
    checked_value: "yes",
    unchecked_value: "no",
    required: true
  )
  form.submit("Accept invitation", id: "gallery-checkbox-registration-save")
end