Skip to content

HyTab

A tab component designed to work within a tab group to control associated tab panels. Provides keyboard navigation, accessibility features, and customizable styling. Supports both horizontal and vertical orientations and can include icons alongside text labels.

Hybrid SSR/CSR Icon Visibility System

The tab works seamlessly in both SSR and CSR-only (SPAs, Storybook) environments using a hybrid visibility approach:

In SSR environments:

  1. The host framework detects icon slot presence at render time via its own slot API
  2. Passes boolean attribute (has-icon) to the Lit component
  3. CSS uses this attribute for immediate icon wrapper visibility during initial render
  4. After hydration, HasSlotController confirms slot content and adds .has-content class

In CSR-only environments (SPAs, Storybook):

  1. Icon wrapper renders to DOM (no has-icon attribute)
  2. Wrapper is hidden by default via CSS (display: none)
  3. firstUpdated() runs and hideIconWrapperWithoutContent() detects actual content
  4. Adds .has-content class which triggers CSS visibility rules

This approach ensures consistent behavior across all rendering environments while optimizing for SSR performance and preventing layout shifts from flex gap.

Usage Guidelines

Tabs should be used within an hy-tab-group component for proper state management and keyboard navigation. Each tab controls a corresponding hy-tab-panel via the panel attribute.

Orientations

  • horizontal (default): Tabs displayed in a row with bottom indicator
  • vertical-left: Tabs displayed in a column with left-side indicator
  • vertical-right: Tabs displayed in a column with right-side indicator

States

  • default: Inactive tab state
  • active: Selected tab that controls the visible panel
  • disabled: Non-interactive tab state

Keyboard Navigation

When used within hy-tab-group:

  • Arrow Right/Down: Move to next tab
  • Arrow Left/Up: Move to previous tab
  • Home: Move to first tab
  • End: Move to last tab
  • Enter/Space: Activate focused tab

Examples

Basic usage

html
<hy-tab-group>
  <hy-tab slot="tab" label="Dashboard" panel="dashboard-panel"></hy-tab>
  <hy-tab slot="tab" label="Settings" panel="settings-panel"></hy-tab>

  <hy-tab-panel slot="panel" name="dashboard-panel"> Dashboard content </hy-tab-panel>
  <hy-tab-panel slot="panel" name="settings-panel"> Settings content </hy-tab-panel>
</hy-tab-group>

With active state

html
<hy-tab-group>
  <hy-tab slot="tab" label="Overview" panel="overview-panel" active></hy-tab>
  <hy-tab slot="tab" label="Analytics" panel="analytics-panel"></hy-tab>
  <hy-tab slot="tab" label="Reports" panel="reports-panel"></hy-tab>
</hy-tab-group>

With icons

html
<hy-tab-group>
  <hy-tab slot="tab" label="Home" panel="home-panel">
    <hy-icon slot="icon" name="home"></hy-icon>
  </hy-tab>
  <hy-tab slot="tab" label="Settings" panel="settings-panel">
    <hy-icon slot="icon" name="settings"></hy-icon>
  </hy-tab>
  <hy-tab slot="tab" label="Profile" panel="profile-panel">
    <hy-icon slot="icon" name="user"></hy-icon>
  </hy-tab>
</hy-tab-group>

Disabled tab

html
<hy-tab-group>
  <hy-tab slot="tab" label="Available" panel="available-panel" active></hy-tab>
  <hy-tab slot="tab" label="Premium" panel="premium-panel" disabled>
    <hy-icon slot="icon" name="lock"></hy-icon>
  </hy-tab>
</hy-tab-group>

Vertical orientation with left indicator

html
<hy-tab-group orientation="vertical-left">
  <hy-tab slot="tab" label="Profile" panel="profile-panel" orientation="vertical-left">
    <hy-icon slot="icon" name="user"></hy-icon>
  </hy-tab>
  <hy-tab slot="tab" label="Security" panel="security-panel" orientation="vertical-left">
    <hy-icon slot="icon" name="shield"></hy-icon>
  </hy-tab>
  <hy-tab slot="tab" label="Billing" panel="billing-panel" orientation="vertical-left">
    <hy-icon slot="icon" name="credit-card"></hy-icon>
  </hy-tab>
</hy-tab-group>

Vertical orientation with right indicator

html
<hy-tab-group orientation="vertical-right">
  <hy-tab slot="tab" label="Profile" panel="profile-panel" orientation="vertical-right">
    <hy-icon slot="icon" name="user"></hy-icon>
  </hy-tab>
  <hy-tab slot="tab" label="Security" panel="security-panel" orientation="vertical-right">
    <hy-icon slot="icon" name="shield"></hy-icon>
  </hy-tab>
  <hy-tab slot="tab" label="Billing" panel="billing-panel" orientation="vertical-right">
    <hy-icon slot="icon" name="credit-card"></hy-icon>
  </hy-tab>
</hy-tab-group>

Complete tabbed interface

html
<div>
  <hy-tab-group>
    <hy-tab slot="tab" label="Home" panel="home-content" active>
      <hy-icon slot="icon" name="home"></hy-icon>
    </hy-tab>
    <hy-tab slot="tab" label="Products" panel="products-content">
      <hy-icon slot="icon" name="package"></hy-icon>
    </hy-tab>
    <hy-tab slot="tab" label="Support" panel="support-content">
      <hy-icon slot="icon" name="help-circle"></hy-icon>
    </hy-tab>
  </hy-tab-group>

  <hy-tab-panel name="home-content">
    <h2>Welcome Home</h2>
    <p>This is the home content area.</p>
  </hy-tab-panel>

  <hy-tab-panel name="products-content">
    <h2>Our Products</h2>
    <p>Browse our product catalog.</p>
  </hy-tab-panel>

  <hy-tab-panel name="support-content">
    <h2>Support Center</h2>
    <p>Get help and support.</p>
  </hy-tab-panel>
</div>

Programmatic Methods

javascript
const tab = document.querySelector('hy-tab');

// Set active state
tab.active = true;

// Focus the tab
tab.focus();

// Blur the tab
tab.blur();

// Check if disabled
console.log(tab.disabled);

Events

  • select - Fired when the tab is clicked or activated, includes panel ID and tab reference

Slots

  • icon - Icon content to display before the tab label

Methods

focus()

Sets focus on the tab.

Parameters:

  • options - Optional focus options
javascript
const tab = document.querySelector('hy-tab');
tab.focus();

blur()

Removes focus from the tab.

javascript
const tab = document.querySelector('hy-tab');
tab.blur();

Built with Lit. Documented with VitePress.