Tabs
Keyed tab and panel pairs with automatic or manual keyboard activation.
- Source
app/components/nitro_kit/tabs.rb- API
NitroKit::Tabs.new(id:, default:) { |tabs| tabs.tab(key, label) { panel } }
Anatomy
Each declaration owns its panel; all panels remain readable until Stimulus enhances the APG tab behavior, and inactive content remains available to find in page.
Settings sections
test/dummy/app/components/gallery/components/tabs_page.rbrender NitroKit::Tabs.new(
id: "gallery-tabs-settings",
default: :members,
label: "Workspace settings"
) do |tabs|
tabs.tab(:general, "General") { "Workspace name and regional preferences." }
tabs.tab(:members, "Members") { "Manage roles, invitations, and access." }
tabs.tab(:billing, "Billing") { "Review plan, payment method, and invoices." }
endOrientation and activation
Horizontal and vertical tablists expose automatic or manual keyboard activation after enhancement.
Vertical manual tabs
test/dummy/app/components/gallery/components/tabs_page.rbrender NitroKit::Tabs.new(
id: "gallery-tabs-vertical-manual",
default: :security,
label: "Account controls",
orientation: :vertical,
activation: :manual
) do |tabs|
tabs.tab(:profile, "Profile") { "Name, photo, and public account details." }
tabs.tab(:security, "Security") { "Password, recovery codes, and active sessions." }
tabs.tab(:notifications, "Notifications") { "Email and workspace notification preferences." }
tabs.tab(:legacy, "Legacy authentication", disabled: true) do
"Legacy authentication is unavailable for new workspaces."
end
endHorizontal manual tabs
test/dummy/app/components/gallery/components/tabs_page.rbrender NitroKit::Tabs.new(
id: "gallery-tabs-horizontal-manual",
default: :usage,
label: "Plan usage",
activation: :manual
) do |tabs|
tabs.tab(:usage, "Usage") { "Seats, storage, and API request volume." }
tabs.tab(:limits, "Limits") { "Plan limits and overage behavior." }
tabs.tab(:history, "History") { "Monthly usage totals for the past year." }
endSingle tab
test/dummy/app/components/gallery/components/tabs_page.rbrender NitroKit::Tabs.new(id: "gallery-tabs-one", label: "Release information") do |tabs|
tabs.tab(:summary, "Summary") { "Release 1842 is operational in the EU region." }
endContent pressure
Many tabs, long labels, long panel copy, and disabled choices retain deterministic relationships.
Many long tabs
Dates use the workspace locale while audit timestamps retain their original UTC value. Individual members may choose a different display time zone without changing stored events.
test/dummy/app/components/gallery/components/tabs_page.rbrender NitroKit::Tabs.new(
id: "gallery-tabs-pressure",
default: :regional_preferences,
label: "Extended workspace administration"
) do |tabs|
tabs.tab(:general, "General") { "Workspace identity and ownership." }
tabs.tab(:regional_preferences, "Regional preferences and time-zone behavior") do
p do
"Dates use the workspace locale while audit timestamps retain their original UTC value. " \
"Individual members may choose a different display time zone without changing stored events."
end
end
tabs.tab(:members, "Members") { "Roles, invitations, and deactivation." }
tabs.tab(:security, "Security") { "Sessions, recovery, and authentication policies." }
tabs.tab(:integrations, "Integrations") { "Connected services and delivery status." }
tabs.tab(:billing, "Billing") { "Plan, payment method, and invoice history." }
tabs.tab(:legacy, "Legacy provisioning", disabled: true) do
"Legacy provisioning is no longer available."
end
endSettings composition
A complete settings surface nests forms, cards, status, tables, and grouped actions in panels.
Workspace administration
Members
| Member | Role | Status |
|---|---|---|
| Ada Lovelace | Owner | Active |
| Grace Hopper | Admin | Active |
| Katherine Johnson | Member | Invited |
Team plan
USD 49.00 monthly · renews August 1, 2026
test/dummy/app/components/gallery/components/tabs_page.rbrender NitroKit::Tabs.new(
id: "gallery-tabs-administration",
default: :profile,
label: "Workspace administration",
orientation: :vertical,
activation: :manual
) do |tabs|
tabs.tab(:profile, "Profile") { render_profile_settings }
tabs.tab(:members, "Members") { render_member_settings }
tabs.tab(:billing, "Billing") { render_billing_settings }
endComponent contract
Constructor options, rendered root, closed vocabularies, and compound boundary for this component, exactly as shipped.
docs/component_contracts.md · NitroKit::Tabs
- Constructor-specific options
- required
id: default: nil,label:defaulting toI18n.t("nitro_kit.tabs.label"),orientation: :horizontal,activation: :automatic
- required
- Root and closed vocabulary
div[data-nk=tabs]; orientationshorizontal vertical; activationsautomatic manual- Compound contract
- Requires one or more uniquely keyed tabs with content and at least one enabled tab. An explicit default must be declared and enabled. Every panel remains available in the no-JavaScript baseline; Stimulus adds APG selection,
hidden="until-found"inactive panels, find-in-page activation, roving focus, and keyboard activation after enhancement.
System rules for coding agents
Instructions for coding agents, repeated on every component page so one fetched page has enough context. Humans can usually skip this section.
test/dummy/app/components/gallery/agent_rules.rb
View agent instructions
- Nitro Kit 2.0 is a gem-owned, Phlex-only UI system for Rails. Render components directly:
render NitroKit::Button.new("Save", variant: :primary). - Compose Nitro components inside application-owned Phlex classes. Public initializers and declared slots are the component API; private methods are not.
- Public options are explicit keywords, and enumerated options are closed vocabularies. Invalid names or values raise
ArgumentError; this component's accepted options are in the contract above. - Pass native attributes through their typed boundary:
html:for HTML,aria:for ARIA, anddata:for application data.classandstyleare forbidden, including insidehtml:. - Nitro owns
NitroKit::Component::RESERVED_DATA_ATTRIBUTES:data-nk,data-slot,data-variant,data-size,data-nk-escape,data-enhanced,data-state,data-disabled,data-required,data-orientation,data-presentation,data-placement,data-layout,data-side,data-field-type,data-dir,data-gap,data-align,data-justify,data-wrap,data-cols,data-mode,data-key. Do not pass them throughdata:.data-action,data-controllerare additive and compose with Nitro behavior. - If an integration truly requires a class, use
desperately_need_a_class:. It requires a non-blank String and marks the exception withdata-nk-escape="class". - Every root emits
data-nk; owned parts emit component-qualifieddata-slotvalues such asfield-controlorcard-title. Select on those attributes, never on classes. - Customize components with documented
--nk-*custom properties in an application stylesheet. Variables beginning with--_nk-*are private component mechanics. - Use
NitroKit::FlexandNitroKit::Gridfor layout. Parents own external placement and available width; components own their intrinsic geometry. - Preserve native elements and accessibility semantics. State is exposed through native semantics and ARIA first, and through
data-statewhen styling or behavior also needs it.