Tangible Design System · @tangible/ui 0.2.29 · Interactive version · Markdown

Sidebar

import { Sidebar } from '@tangible/ui';

Interactive docs and examples: Sidebar in Storybook.

Sidebar props

Prop Type Default Description
children ReactNode Sidebar content (Header, Nav, etc.).
aria-label? string Accessible label for the sidebar landmark (static) or dialog (drawer). When a page has multiple sidebars, each must have a unique label so screen reader users can distinguish between landmarks (e.g. "Course navigation", "Lesson settings").
className? string Additional CSS class names.
collapsed? boolean Collapsed state (controlled). Pair with onCollapsedChange. Leave undefined to let the sidebar own the state.
collapsible? boolean false Opt into the collapsed rail: the sidebar can shrink to --tui-sidebar-collapsed-width, hiding Header, Nav and Footer while leaving any other child — a Sidebar.Toggle, an icon rail — visible. Deliberately absent from drawer mode: a drawer is already a show/hide overlay, and a rail inside one has nothing to sit beside.
defaultCollapsed? boolean false Initial collapsed state when uncontrolled.
drawer? boolean false Enable drawer mode (mobile overlay).
onClose? () => void Callback to close the drawer. Required when drawer={true}. Called when ESC is pressed or backdrop is clicked. Omitting this in drawer mode means the user cannot dismiss the overlay, which is a WCAG 2.1.1 (Keyboard) failure.
onCollapsedChange? (collapsed: boolean) => void Called with the next collapsed state whenever Sidebar.Toggle is pressed — in both controlled and uncontrolled mode.
open? boolean Drawer open state.
position? "left" | "right" 'left' Sidebar position. Affects border placement and drawer slide direction.

Sidebar.Header

Prop Type Default Description
children ReactNode Header content (back button, title, progress, CTAs).
className? string Additional CSS class names.

Sidebar.Footer

Prop Type Default Description
children ReactNode Footer content (CTAs, user info, etc.). Sticks to the bottom of the sidebar.
className? string Additional CSS class names.

Sidebar.Nav

Prop Type Default Description
children ReactNode Nav content (typically Accordion with StepList).
aria-label? string Accessible label for the nav landmark. Use this for the primary label since nav is the actionable region.
aria-labelledby? string ID of a visible heading that labels the navigation.
className? string Additional CSS class names.

Sidebar.Toggle

Prop Type Default Description
className? string Additional CSS class names.
disabled? boolean Disabled state.
href? never
labels? SidebarToggleLabels Accessible names for the two states. Defaults are English and are exported as defaultSidebarToggleLabels; a partial object overrides only the keys it names.
loading? boolean Loading state: shows a spinner and blocks activation while keeping the button focusable (aria-disabled, not native disabled), so a keyboard user who triggered it keeps their place. Only onClick is guarded: put the action there, not in onKeyDown/onPointerDown. The start and end of loading aren't announced; confirm completion through your own status message (a Toast, say).
loadingLabel? string `${label}, loading` (English) Accessible label override during loading state. For i18n support.
shape? "circle" | "square" 'square' Button shape. Use 'circle' for avatar-adjacent actions, FABs, or anywhere a round affordance is expected.
showTooltip? boolean false Show the label as a tooltip on hover. Since icon-only buttons have no visible text, enabling this helps sighted users discover what the button does. Recommended for most standalone icon buttons. Can be omitted in toolbars where a shared Tooltip provider handles it, or where adjacent visible text already communicates the action.
size? "lg" | "md" | "sm" | "xs" 'sm' Size of the button. 'xs': 24px — below WCAG 2.5.8 minimum target size (24×24 CSS px). Use only in dense, mouse-first UIs (toolbars, table rows) where touch is not expected. Consider pairing with adequate spacing or a larger touch target via padding/margin. 'sm': 32px (default); 'md': 40px; 'lg': 48px
theme? "danger" | "info" | "primary" | "secondary" | "success" | "warning" 'secondary' Semantic color theme. Note: Defaults to 'secondary' (unlike Button which defaults to 'primary') because IconButtons are typically used for toolbar/utility actions.
tooltipSide? "bottom" | "left" | "right" | "top" 'top' Tooltip placement side.
variant? "ghost" | "outline" | "solid" 'ghost' Visual style variant. 'solid': Filled background; 'outline': Border only, transparent background; 'ghost': No border or background, icon only — has no at-rest visual affordance. Best suited for toolbar groups, icon bars, or other contexts where surrounding UI makes the interactive nature obvious.

Also accepts the standard attributes of ButtonHTMLAttributes (data-*, aria-*, event handlers), passed to the element it renders.

Other exports

Examples

Other stories: Static, With Header and Nav Slots, With Footer, Right Position, Drawer Mode, Drawer (Right Position), Drawer Keyboard Interaction, Course Viewer (Full Integration) (interactive page).

Component API tokens

Read via fallback, never declared. Set one on an ancestor to restyle every instance under it.