Tabs

A set of layered sections of content, known as tab panels, that are displayed one at a time.

Requires JavaScript

Installation

Add the component to your project:

rails generate shadcn:component tabs

Usage

<%= render Shadcn::TabsComponent.new(default_value: "account") do |tabs| %>
  <% tabs.with_list do |list| %>
    <% list.with_trigger(value: "account") { "Account" } %>
    <% list.with_trigger(value: "password") { "Password" } %>
  <% end %>
  <% tabs.with_panel(value: "account") do %>
    Account content here.
  <% end %>
  <% tabs.with_panel(value: "password") do %>
    Password content here.
  <% end %>
<% end %>

Examples

Basic

<%= render Shadcn::TabsComponent.new(default_value: "tab1") do |tabs| %>
  <% tabs.with_list do |list| %>
    <% list.with_trigger(value: "tab1") { "Tab 1" } %>
    <% list.with_trigger(value: "tab2") { "Tab 2" } %>
    <% list.with_trigger(value: "tab3") { "Tab 3" } %>
  <% end %>
  <% tabs.with_panel(value: "tab1") do %>
    Content for Tab 1
  <% end %>
  <% tabs.with_panel(value: "tab2") do %>
    Content for Tab 2
  <% end %>
  <% tabs.with_panel(value: "tab3") do %>
    Content for Tab 3
  <% end %>
<% end %>

URL Sync

Sync the active tab with the URL using the url_param option. This is useful for shareable links and browser back/forward navigation.

<%= render Shadcn::TabsComponent.new(default_value: "account", url_param: "tab") do |tabs| %>
  <% tabs.with_list do |list| %>
    <% list.with_trigger(value: "account") { "Account" } %>
    <% list.with_trigger(value: "settings") { "Settings" } %>
  <% end %>
  ...
<% end %>

<%# URL will update to ?tab=account or ?tab=settings when tabs are clicked %>

Disabled Tab

<% list.with_trigger(value: "disabled", disabled: true) { "Disabled" } %>

API Reference

TabsComponent

API Reference

Prop Type Default Description
default_value String nil The value of the initially active tab
orientation Symbol :horizontal Tab orientation (:horizontal or :vertical)
url_param String nil Query parameter name to sync active tab with URL

Slots

Slot Description
with_list Container for tab triggers (yields TabsListComponent)
with_panel(value:) Tab panel content, matched by value to trigger

TabsListComponent Slots

Slot Props Description
with_trigger value:, disabled: Tab trigger button

Stimulus Controller

This component requires JavaScript. The Stimulus controller shadcn--tabs provides interactivity.

Manages tab switching, keyboard navigation, and URL synchronization.

Installation

Add to your config/importmap.rb:

pin "shadcn-rails", to: "shadcn/index.js"

Then in your app/javascript/controllers/index.js:

import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"

const application = Application.start()
registerShadcnControllers(application)

Or import just this controller:

import TabsController from "shadcn-rails/controllers/tabs_controller"

application.register("shadcn--tabs", TabsController)

Targets

Name Description
trigger Tab trigger buttons
content Tab content panels

Values

Name Type Default Description
value String "" Currently active tab value
defaultValue String "" Initial tab value
urlParam String null URL parameter name for syncing

Actions

Action Description
selectTab Switches to a specific tab (triggered by click)

TypeScript

Type definitions are included. Import types as needed:

import type { TabsController } from "shadcn-rails"

Accessibility

  • Uses role="tablist", role="tab", and role="tabpanel"
  • Sets aria-selected on active tab
  • Links tabs to panels via aria-controls and aria-labelledby
  • Keyboard navigation: Arrow Left/Arrow Right to navigate between tabs
  • Home/End to jump to first/last tab