Skip to content
Liquidify
HomeDocsComponentsExamplesPlayground
⌘K
(opens in new tab)
Liquidify

Accessible React controls with a CSS and SVG material engine.

Product

ComponentsExamplesPlaygroundPackages

Learn

DocumentationGetting startedConceptsAI resources

Project

CommunityShowcaseVersionsGitHub

Independent open-source software. Not affiliated with or endorsed by Apple Inc.

LicenseBrand

Component catalog

Browse the public controls by interaction purpose. Every result links to generated API facts, accessibility behavior, source, and exhaustive stories.

Tabs

A control that presents several mutually-exclusive views and lets the user switch between them by tapping a labelled tab — the canonical glass tab bar.

import { Tabs } from "@liquidify/react/tabs"

Overview

Basic Tabs

A focused starting point showing Tabs with its essential configuration.

API

PropTypeDefaultDescription
aria-labelstring | undefined—Accessible name for the `role="tablist"` bar — required (no default text).
aria-labelledbystring | undefined—Accessible name reference for the `role="tablist"` bar.
children
required
ReactNode—The tabs, rendered in order — 1..N {@link Tabs.Item} children (children role: `items`). Only `Tabs.Item` children are read; any non-`Item` node (a `Fragment`, a wrapper, stray text) is a **dev-mode `console.error`** and is filtered in production.
classNamestring | undefined—Optional additional CSS class merged into the glass surface class. The supported per-instance customisation seam: override any `--lq-*` custom property from this class's CSS — the token cascade the engine reads (ADR-0004). No raw inline style is involved, so this stays ADR-0003 clean.
contentPlacement"top" | "bottom" | undefinedtopWhich side of the tab bar the active tab's content (the `Tabs.Item` children) is rendered on. `"top"` — the reference iOS arrangement: the panel sits **above** a bottom tab bar. `"bottom"` — the bar leads and the panel sits **below** it, the familiar web/macOS arrangement. The two regions are reordered in the DOM, not merely visually, so the reading and focus order always match what is on screen (APG Tabs). The root also stamps `data-content-placement` for styling. Invalid in navigation mode (no panel exists) — a dev-mode `console.error`, and the prop is ignored.
defaultValuestring | undefinedthe first `Tabs.Item`'s `value` (tab mode only)Uncontrolled seed for the internal selection (ignored once {@link TabsProps.value} is supplied).
disabledboolean | undefined—When `true`, the whole control is dimmed, removed from the tab order, and all interaction is suppressed.
onChange((value: string) => void) | undefined—Fires with the newly selected tab's `value` on activation. A same-value activation is dropped (no-op policy, ADR-0015).
orientation"horizontal" | "vertical" | undefinedhorizontalLayout axis of the tab bar. Only `"horizontal"` is implemented in v1 (spec `## Out of scope`); the root still stamps `data-orientation`.
refRef<HTMLDivElement> | undefined—Forwarded ref to the rendered element — the component's native root (or the merged child element on a component that opts into {@link SlottableProps}). Generic over `E` (charter `docs/api-conventions.md` §4 rule 1, default `HTMLElement`) so a component with a polymorphic root (Link's navigation / action mode union, Text's `as`) can instantiate the concrete element per variant instead of leaving every consumer with a widened `Ref<HTMLElement>`. A component that does not narrow simply inherits the `HTMLElement` default — source-compatible with every pre-existing non-generic `extends ControlProps`.
tintLiquidTintValue | undefined—System-accent of the control — drawn from the RESTRICTED {@link LIQUID_COLORS} palette (the thirteen Apple system colours). **Orthogonal to a component's `variant`**: it recolours the accent the surface draws from (focus ring, tinted fill, selection) without changing its variant. Resolved via `data-tint` attribute selectors in CSS (tokens-only, ADR-0003).
valuestring | undefined—Controlled selected-tab key. Passing this switches Tabs to controlled mode: the rendered selection always reflects this value and the consumer owns it via {@link TabsProps.onChange}.

Guidelines

Do
  • Use Tabs when its semantics match the content or action.
  • Keep labels concise, specific, and consistent with the surrounding interface.
  • Test the component with keyboard navigation, zoom, and both color schemes.
Don't
  • Do not use Tabs as a visual substitute for a different semantic element.
  • Do not rely on color or an icon alone to communicate essential meaning.
  • Do not override the component tokens with fixed values unless the product theme requires it.

Accessibility

Tabs supports the documented keyboard interactions below.

Keyboard
  • Press Tab to move focus to the control.
  • Use the control's documented activation keys without trapping focus.
  • Provide an accessible name whenever the visible label is absent.

Tokens

NameValue
--lq-color-accent#007aff
--lq-color-bg-primary#ffffff
--lq-color-labelComponent-defined value
--lq-color-on-accentComponent-defined value
--lq-color-system-red-default-dark#ff4245
--lq-color-system-red-default-light#ff383c
--lq-font-caption-Component-defined value
--lq-glass-440.71.15var(--lq-segmented-control-indicator-blur)calc(var(--lq-glass-material-blur) * 8)var(--lq-shadow-presentational)
--lq-hit-target-touch2.75rem
--lq-lens-progressResolved by the active Liquidify theme
--lq-lens-stretchResolved by the active Liquidify theme
--lq-lens-xResolved by the active Liquidify theme
--lq-radius-pill9999rem
--lq-shadow-ambient-0 0.125rem 0.375rem rgba(0, 0, 0, 0.10)0 0.5rem 1.375rem rgba(0, 0, 0, 0.20)0 0.75rem 1.75rem rgba(0, 0, 0, 0.14)
--lq-space-0.0625rem0.125rem0.25rem0.5rem0.75rem1rem1.25rem1.5rem2rem2.5rem3rem3.5rem
--lq-tabs-badge-offsetvar(--lq-space-4)
--lq-tabs-badge-sizevar(--lq-space-16)
--lq-tabs-cell-gapvar(--lq-space-2)
--lq-tabs-chip-contract0.5
--lq-tabs-chip-lens-deltacalc(var(--lq-tabs-chip-lens-h) - var(--lq-tabs-chip-rest-h))
--lq-tabs-coat-idle-opacity0.4
--lq-tabs-gapvar(--lq-space-4)
--lq-tabs-icon-sizevar(--lq-space-24)
--lq-tabs-padvar(--lq-space-8)

Key features

  • Liquid material

    Uses Liquidify surfaces and theme-aware design tokens.

  • Typed API

    Provides a typed React API with generated prop documentation.

  • Accessible by default

    Preserves semantic structure, focus visibility, and assistive-technology state.

Resources

  • Source
  • Markdown
  • JSON
  • Storybook
Components