/**
* TabBar — a floating-pill bar of page-level navigation tabs.
*
* Each tab is an icon + label (+ optional count badge); the active tab is
* marked with `aria-current="page"` and an `--accent` underline. The bar is a
* glassy `--card` pill that floats on whatever canvas the consumer provides
* (the strip area itself is transparent, so it blends with the surrounding
* surface).
*
* Two layouts:
* - default (`fill` off): content-width tabs that **centre** when they fit and
* scroll from the inline-start (`safe center`) when they overflow, with a
* gutter preserved at both ends. The label stacks under the icon below `sm`.
* Use this when the tab set is open-ended (e.g. a marketplace app's routes).
* - `fill`: equal-width tabs that fill the bar and always stack the label under
* the icon — a fixed, always-visible set that fits any column width without
* scrolling (e.g. a patient portal's handful of sections).
*
* Tabs render as links when given an `href` (real navigation) or as buttons
* otherwise (in-app view switching via `onSelect`). Use it as a header (top,
* default) for section navigation; `position="bottom"` floats it from the
* bottom edge for a footer.
*
* With `collapseToMenu`, the strip folds into a single DropdownMenu whenever the
* tabs don't fit — below the `sm` breakpoint OR when they overflow their
* container at any width (a narrow column on a wide screen, e.g. a page squeezed
* between two sidebars, clips the tabs just the same as a small viewport).
*
* SPA / consumer-router links: pass `renderLink` and TabBar hands each `href`
* tab off to your router's `` instead of rendering its own `` — the
* embedded MarketplaceAppShell strip uses this so a tab click is a client-side
* route change, not a full page navigation. The kit forwards the same
* `className` + `aria-current` so the accent-underline active styling and the
* `aria-current="page"` marker survive in both modes. With `renderLink`
* omitted the output is the plain `` exactly as before.
*/
import { type MouseEvent, type ReactNode } from 'react';
export interface TabBarItem {
/** Stable id; also the value handed to `onSelect` for button tabs. */
id: string;
/** Pre-translated label — consumers localise their own nav copy. */
label: string;
/** Optional leading icon (a lucide-react element or equivalent), tinted with `--accent`. */
icon?: ReactNode;
/** Optional unseen-item count rendered as a pill badge. */
badgeCount?: number;
/** Mark the tab as the current page (`aria-current='page'` + accent underline). */
isActive?: boolean;
/** When set, the tab renders as a link to this href; otherwise it's a button. */
href?: string;
/**
* Optional click handler threaded onto the link tab's `` (or, when
* `renderLink` is supplied, available to the consumer's router element). Use
* it to intercept a same-origin click and route client-side without a full
* navigation. Only applies to `href` (link) tabs — button tabs use `onSelect`.
*/
onClick?: (event: MouseEvent) => void;
}
/**
* Props the kit hands to `renderLink` for each `href` tab. The consumer returns
* their router's `` carrying the same `className` (the active
* accent-underline styling) and `aria-current` (`'page'` on the active tab).
*/
export interface TabBarRenderLinkProps {
/** The tab's destination — feed it to your router's `to` / `href`. */
href: string;
/** The kit's tab classes (CVA output) — apply verbatim to the link element. */
className: string;
/** Icon + label + badge — render as the link's children. */
children: ReactNode;
/** `'page'` on the active tab, otherwise omitted — forward to the link. */
'aria-current'?: 'page';
/**
* The tab's stable `TabBarItem.id`, as the agent / automation DOM hook.
* Spread it onto your router link (`{...rest}`) so the tab stays addressable
* by `[data-tab-id]` the same way the kit's own `` / `