## Taffy Tabs (S—002)

A playful tab bar whose indicator stretches toward the next tab and snaps into place.

- URL: https://sundaeui.dev/components/taffy-tabs
- Category: Navigation & menus · Art direction: Playful
- Access: Free (no account needed)
- Stack: React 18+, TypeScript, plain CSS; dependencies: none
- Install: `npx shadcn@latest add https://sundaeui.dev/r/taffy-tabs.json`
- Tags: tabs, animated, react, colorful, navigation, mobile

The indicator is one element whose left and right edges are animated separately. When you switch tabs, the leading edge moves first and the trailing edge follows a beat later, both with a little overshoot. The pill stretches like taffy and settles.
Each tab can bring its own colour, and the indicator blends between them as it travels. Items lean slightly toward the pointer, and press states squash a little, so the bar feels physical without becoming noisy.
Use it for bottom navigation in consumer apps, view switchers and onboarding steps. Anywhere a bit of character is welcome.

### Usage

```tsx
import { TaffyTabs } from '@/components/sundae/taffy-tabs'

<TaffyTabs
  label="App sections"
  defaultValue="home"
  onValueChange={(id) => router.push('/' + id)}
  tabs={[
    { id: 'home', label: 'Home', color: '#ff6b3d', icon: <HomeIcon /> },
    { id: 'explore', label: 'Explore', color: '#2f9e6e', icon: <CompassIcon /> },
    { id: 'saved', label: 'Saved', color: '#e0a100', icon: <BookmarkIcon /> },
  ]}
/>
```

### Props

- `tabs` (`TaffyTab[]`, required): Items: { id, label, icon?, color? }.
- `value` (`string`): Controlled active tab id.
- `defaultValue` (`string`): Initial tab for uncontrolled use. Defaults to the first tab.
- `onValueChange` (`(id: string) => void`): Called when the user picks a tab.
- `label` (`string`, default `'Sections'`): Accessible name of the tab list.
- `magnetic` (`boolean`, default `true`): Items lean slightly toward the pointer.

### Accessibility

- Implements the WAI-ARIA tabs pattern: role="tablist" and role="tab", aria-selected, and roving tabindex.
- Arrow keys, Home and End move between tabs, and focus follows the selection.
- Below 520px, inactive labels are visually hidden but stay readable by screen readers.
