Tabs & Breadcrumbs
Tabbed navigation with JS and Turbo modes, plus breadcrumb navigation with multiple separators and sizes.
JS Mode Tabs - Underline
Client-side tab switching with underline style. All panel content is in the DOM.
Overview
BetterUi is a comprehensive ViewComponent library for Rails applications. It provides ready-to-use, accessible UI components styled with Tailwind CSS v4.
<%= bui_tabs(mode: :js, style: :underline, variant: :primary, default_tab: "tab1") do |tabs| %>
<% tabs.with_tab(id: "tab1", label: "First Tab", active: true) %>
<% tabs.with_tab(id: "tab2", label: "Second Tab") %>
<% tabs.with_panel(id: "tab1", active: true) do %>
<p class="p-4">Content for the first tab.</p>
<% end %>
<% tabs.with_panel(id: "tab2") do %>
<p class="p-4">Content for the second tab.</p>
<% end %>
<% end %>
JS Mode Tabs - Pills
Pill-styled tabs with a rounded button appearance.
Dashboard view with key metrics and recent activity.
<%= bui_tabs(mode: :js, style: :pills, variant: :accent) do |tabs| %>
<% tabs.with_tab(id: "tab1", label: "Dashboard", active: true) %>
<% tabs.with_tab(id: "tab2", label: "Analytics") %>
<% tabs.with_panel(id: "tab1", active: true) do %>
<p class="p-4">Dashboard content.</p>
<% end %>
<% tabs.with_panel(id: "tab2") do %>
<p class="p-4">Analytics content.</p>
<% end %>
<% end %>
JS Mode Tabs - Bordered
Bordered tabs with a card-like appearance for the active tab.
Profile information and personal details.
<%= bui_tabs(mode: :js, style: :bordered, variant: :success) do |tabs| %>
<% tabs.with_tab(id: "tab1", label: "Profile", active: true) %>
<% tabs.with_tab(id: "tab2", label: "Settings") %>
<% tabs.with_panel(id: "tab1", active: true) do %>
<p class="p-4">Profile content.</p>
<% end %>
<% tabs.with_panel(id: "tab2") do %>
<p class="p-4">Settings content.</p>
<% end %>
<% end %>
Tab Sizes
Tabs are available in sm, md, and lg sizes.
Size: sm
Content for the first tab (sm size).
Size: md
Content for the first tab (md size).
Size: lg
Content for the first tab (lg size).
<%= bui_tabs(mode: :js, style: :underline, variant: :primary, size: :sm) do |tabs| %>
<%# ... %>
<% end %>
<%= bui_tabs(mode: :js, style: :underline, variant: :primary, size: :lg) do |tabs| %>
<%# ... %>
<% end %>
Tab Alignment
Tabs can be aligned to start, center, end, or stretched to fill the container.
Alignment: start
Content aligned to start.
Alignment: center
Content aligned to center.
Alignment: end
Content aligned to end.
Alignment: stretch
Content aligned to stretch.
<%= bui_tabs(mode: :js, alignment: :start) do |tabs| %>
<%# ... (default, left-aligned) %>
<% end %>
<%= bui_tabs(mode: :js, alignment: :center) do |tabs| %>
<%# ... (centered) %>
<% end %>
<%= bui_tabs(mode: :js, alignment: :end) do |tabs| %>
<%# ... (right-aligned) %>
<% end %>
<%= bui_tabs(mode: :js, alignment: :stretch) do |tabs| %>
<%# ... (full-width) %>
<% end %>
Turbo Mode Tabs
Turbo mode loads tab content via Turbo Frames, enabling server-rendered tab panels without full page reloads.
Turbo mode tabs use Turbo Frames to load content from the server when a tab is clicked. This is ideal for tabs with heavy content or when you want to lazy-load tab panels.
See the full Turbo tabs demo: Turbo Tabs Demo
<%= bui_tabs(mode: :turbo, frame_id: "tab-content", style: :underline, variant: :primary) do |tabs| %>
<% tabs.with_tab(id: "overview", label: "Overview", href: overview_path, active: true) %>
<% tabs.with_tab(id: "features", label: "Features", href: features_path) %>
<% tabs.with_tab(id: "settings", label: "Settings", href: settings_path) %>
<% end %>
<%= turbo_frame_tag "tab-content" do %>
<%= yield %>
<% end %>
Breadcrumbs
Navigation breadcrumbs with different separators (slash, chevron, dot) and sizes (sm, md, lg).
Separators
Slash
Chevron
Dot
Sizes
SM
MD
LG
Longer Path
<%# Chevron separator %>
<%= bui_breadcrumb(separator: :chevron, size: :md) do |bc| %>
<% bc.with_item(label: "Home", href: root_path) %>
<% bc.with_item(label: "Products", href: products_path) %>
<% bc.with_item(label: "Widget") %>
<% end %>
<%# Dot separator, small size %>
<%= bui_breadcrumb(separator: :dot, size: :sm) do |bc| %>
<% bc.with_item(label: "Home", href: root_path) %>
<% bc.with_item(label: "Current Page") %>
<% end %>