Accordion

Keyed disclosure sections with native buttons and visible state.

Source
app/components/nitro_kit/accordion.rb
API
NitroKit::Accordion.new(id:, mode:) { |accordion| accordion.item }

Account questions

Native details and summary elements work before JavaScript and keep stable keyed IDs.

Billing questions

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/accordion_page.rb
render NitroKit::Accordion.new(id: "gallery-accordion-billing", mode: :single) do |accordion|
  accordion.item(:invoices, title: "Where can I find invoices?", expanded: true) do
    "Invoices are available from Billing settings."
  end
  accordion.item(:currency, title: "Can I change billing currency?") do
    "Contact support before the next renewal date."
  end
  accordion.item(:legacy, title: "What happens to a legacy plan?") do
    "Legacy plans retain their current limits until an owner chooses a new plan."
  end
end

Modes and item counts

Single and multiple expansion modes remain useful from one disclosure through a dense set.

Boundary counts

One closed item
One open item
Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/accordion_page.rb
sample("One closed item", slug: "one-closed") do
  render NitroKit::Accordion.new(id: "gallery-accordion-one", mode: :multiple) do |accordion|
    accordion.item(:summary, title: "Workspace summary") do
      "Mothership is on the Team plan with twelve active members."
    end
  end
end

sample("One open item", slug: "one-open") do
  render NitroKit::Accordion.new(id: "gallery-accordion-one-open", mode: :single) do |accordion|
    accordion.item(:summary, title: "Workspace summary", expanded: true) do
      "Mothership is on the Team plan with twelve active members."
    end
  end
end

Multiple open items

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/accordion_page.rb
render NitroKit::Accordion.new(id: "gallery-accordion-multiple", mode: :multiple) do |accordion|
  accordion.item(:general, title: "General", expanded: true) do
    "Workspace name, locale, and time zone."
  end
  accordion.item(:members, title: "Members and access", expanded: true) do
    "Roles, pending invitations, and session policies."
  end
  accordion.item(:billing, title: "Billing") do
    "Plan, payment method, and invoice history."
  end
  accordion.item(:advanced, title: "Advanced controls") do
    "Advanced controls are managed by the organization owner."
  end
end

Content pressure

Long labels, long copy, nested markup, and many items use the same keyed declaration API.

Long and nested content

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/accordion_page.rb
render NitroKit::Accordion.new(id: "gallery-accordion-pressure", mode: :multiple) do |accordion|
  accordion.item(
    :retention,
    title: "How does workspace data retention change when a long-running organization changes plans?",
    expanded: true
  ) do
    p do
      "Workspace records remain available throughout the current billing period. Exported audit events " \
        "continue to use their original timestamps and actor identifiers."
    end
    ul do
      li { "Active members keep their existing access until the renewal date." }
      li { "Pending invitations can be revoked before the plan changes." }
      li { "Invoice and audit exports remain available to workspace owners." }
    end
  end
  accordion.item(:exports, title: "Exports") { "Exports are prepared as UTF-8 CSV files." }
  accordion.item(:regions, title: "Data regions") { "The workspace currently uses the EU region." }
  accordion.item(:sessions, title: "Active sessions") { "Owners can revoke individual sessions." }
  accordion.item(:webhooks, title: "Webhook delivery") { "Failed deliveries retry with backoff." }
  accordion.item(:legacy, title: "Legacy retention controls") do
    "Legacy controls remain visible while owners plan their replacement."
  end
end

Detail composition

An operational detail view composes cards, status, tables, and grouped actions inside panels.

Deployment detail

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/accordion_page.rb
render NitroKit::Accordion.new(id: "gallery-accordion-deployment", mode: :single) do |accordion|
  accordion.item(:overview, title: "Deployment overview", expanded: true) do
    render NitroKit::Card.new(id: "gallery-accordion-deployment-card") do |card|
      card.title("Billing portal · release 1842", level: 3)
      card.body do
        render NitroKit::Badge.new(
          "Operational",
          id: "gallery-accordion-deployment-status",
          color: :success,
          size: :sm
        )
        p { "Deployed by Grace Hopper on July 13, 2026 at 08:42 UTC." }
      end
      card.footer do
        render NitroKit::ButtonGroup.new(
          id: "gallery-accordion-deployment-actions",
          label: "Deployment actions"
        ) do |group|
          group.button(
            "View logs",
            id: "gallery-accordion-deployment-logs",
            href: "#deployment-logs",
            size: :sm
          )
          group.button(
            "Roll back",
            id: "gallery-accordion-deployment-rollback",
            variant: :destructive,
            size: :sm
          )
        end
      end
    end
  end

  accordion.item(:checks, title: "Health checks") do
    render_health_checks
  end

  accordion.item(:environment, title: "Environment and access") do
    render NitroKit::Card.new(id: "gallery-accordion-environment-card") do |card|
      card.title("Production environment", level: 3)
      card.body do
        p { "EU region · protected branch · owner approval required" }
      end
      card.footer do
        render NitroKit::Badge.new(
          "Protected",
          id: "gallery-accordion-environment-status",
          variant: :outline,
          color: :info
        )
      end
    end
  end
end