import { default as React } from 'react';
/**
 * Capability profile for a single tab. Consumed by tooling that needs
 * to reason about what each tab supports (e.g. the auto-CRUD test
 * scaffolder gates create/update/delete phase tests on these flags
 * instead of inferring from JSX patterns).
 *
 * All fields optional — tabs that don't declare capabilities are
 * treated as "unknown" by tooling and fall back to heuristic detection.
 */
export interface TabsItemCapabilities {
    /** Tab supports creating entities (Create button visible). */
    create?: boolean;
    /** Tab supports updating entities (Edit button visible). */
    update?: boolean;
    /** Tab supports deleting entities (Delete button visible). */
    delete?: boolean;
}
export interface TabsItem {
    /**
     * Title / label may be a ReactNode (allows status dots or other
     * inline glyphs alongside the text — see account-information tabs).
     * When a non-string is supplied the auto-CRUD scaffolder can no
     * longer fall back to kebabing it for a `data-tab-id`; pass the
     * stable `id` field explicitly in that case.
     */
    title?: string | React.ReactNode;
    label?: string | React.ReactNode;
    route?: string;
    trigger?: 'route' | 'onClick';
    onClick?: () => void;
    /**
     * Stable identifier surfaced as `data-tab-id` on the rendered button
     * AND on the corresponding panel (when a `<TabPanel>` is used).
     * Tests target tabs by this id rather than by visible label so
     * label-text changes don't break the test contract:
     *   `page.locator('[data-tab-id="categories"]').click()`
     *   `expect(page.locator('[data-tab-active="true"][data-tab-id="categories"]')).toBeVisible()`
     *
     * Falls back to a kebab-cased `label`/`title` when omitted.
     */
    id?: string;
    /**
     * Singular entity noun for THIS tab — `"category"` not `"contract"`
     * for the Categories tab on a contracts route. Read by the auto-CRUD
     * scaffolder to build per-tab fixtures
     * (`Audit Test ${capitalize(subject)}`) so tests in nested
     * describe.serial blocks bind to the right entity.
     */
    subject?: string;
    /** Per-tab CRUD capability flags — see `TabsItemCapabilities`. */
    capabilities?: TabsItemCapabilities;
    /**
     * Actual labels rendered in this tab's metric strip, if the tab has
     * its own metrics. The scaffolder's `verifyStatus` template reads
     * this to build a permissive regex (e.g.
     * `/(Contracts|With Docs|Employees|Customers|Categories)/i`)
     * instead of hardcoding `"Total"`.
     */
    metricLabels?: string[];
    /** Optional count badge rendered after the label (matches the
     *  pattern most workspaces hand-rolled before adopting the shared
     *  shell). Hidden when undefined or null. */
    count?: number | null;
    /**
     * Optional leading glyph / icon node rendered before the label. Use
     * for hand-rolled tab strips migrating to goobs that previously
     * embedded an icon character in their label text (e.g. `"☰ Inbox"`).
     * Pass either a string glyph (rendered with `aria-hidden`) or a
     * ReactNode for full control.
     */
    icon?: React.ReactNode;
}
export interface TabsProps {
    items: TabsItem[];
    activeTab?: number;
    onChange?: (index: number) => void;
    alignment?: 'left' | 'center' | 'right' | 'justify';
    /**
     * Visual treatment of the tab strip. `'underline'` (default) is the
     * classic bottom-border tab row; `'chips'` renders each tab as a rounded
     * pill (bordered, tonal fill when active) and drops the strip's bottom
     * border. Purely cosmetic — `role="tab"`/`role="tablist"` semantics, the
     * count badge, keyboard roving nav, and every `data-*` selector are
     * identical in both appearances, so existing tests and AT are unaffected.
     */
    appearance?: 'underline' | 'chips';
    /**
     * `aria-label` on the tablist. Defaults to `"Workspace sections"`.
     * Override when several `<Tabs>` render on the same page.
     */
    ariaLabel?: string;
    styles?: {
        theme?: string;
        padding?: string;
        gap?: string;
        borderBottom?: string;
        height?: string;
        tabLeftBorder?: string | boolean;
        tabRightBorder?: string | boolean;
        backgroundColor?: string;
    };
}
/**
 * Accessible WAI-ARIA tablist that renders a set of tab items with full
 * keyboard navigation, optional count badges and leading icons, and route- or
 * click-based activation. Emits `nav.change` diagnostics and stable
 * `data-tab-id`/`data-tab-subject` selectors; pairs with the exported `Tab` and
 * `TabPanel`.
 */
declare const Tabs: React.FC<TabsProps>;
/**
 * Compute the panel id that matches a given tab id. This is the SINGLE
 * source of truth for the tab↔panel ARIA pairing: `<Tabs>` uses it for
 * each tab's `aria-controls` and `<TabPanel>` uses it for its `id`, so
 * the two link by construction. Call it directly when hand-rolling a
 * panel element instead of using `<TabPanel>`.
 *
 * Ids are derived purely from the tab id (`tabpanel-${tabId}`), matching
 * the unscoped `tab-${tabId}` button ids. When several `<Tabs>` render
 * on the same page, give their items distinct `id`s (the same contract
 * the tab button ids already require — see `TabsProps.ariaLabel`).
 */
export declare function tabPanelId(tabId: string): string;
export interface TabProps {
    /**
     * Tab content. String when the caller passed plain text; ReactNode
     * when they need inline status glyphs / icons alongside the text.
     * The rendered `<button>` includes the node directly. Tests should
     * locate tabs by `data-tab-id` / `data-tab-subject` rather than
     * label text, since rich-node labels can't be matched with a
     * simple text selector.
     */
    label: string | React.ReactNode;
    isActive: boolean;
    onClick: () => void;
    disabled?: boolean;
    /**
     * Visual theme — surfaced as `data-theme` on the rendered `<button>` so
     * the CSS module's light/dark overrides apply. Defaults to `'sacred'`
     * (the historical hardcoded sacred-gold look). Forwarded by `<Tabs>`
     * from `styles.theme`.
     */
    theme?: string;
    /** Stable identifier surfaced as `data-tab-id`. Forwarded by the
     *  parent `<Tabs>` from `TabsItem.id` (or its kebab-cased label). */
    tabId?: string;
    /** `id` of the corresponding `<TabPanel>` for `aria-controls`. The
     *  parent `<Tabs>` computes this via `tabPanelId(tabId)` and hands it
     *  down so screenreader navigation lands on the right region. */
    panelId?: string;
    /** Singular entity noun for THIS tab — emitted as `data-tab-subject`
     *  so tests can locate a tab by the entity it manages even when its
     *  visible label changes. Forwarded from `TabsItem.subject`. */
    subject?: string;
    /** Optional count badge rendered after the label. */
    count?: number | null | undefined;
    /** Optional leading glyph / icon — see TabsItem.icon. */
    icon?: React.ReactNode;
    /** Forwarded ref to the underlying `<button>` so the parent can
     *  programmatically focus a tab on keyboard nav. */
    buttonRef?: (el: HTMLButtonElement | null) => void;
    /** Forwarded keyboard handler — parent owns the arrow-key/home/end
     *  routing across the tablist. */
    onKeyDown?: (event: React.KeyboardEvent<HTMLButtonElement>) => void;
}
export declare const Tab: React.FC<TabProps>;
/**
 * Optional companion to `<Tabs>` — wraps tab content with the right
 * ARIA wiring (`role="tabpanel"`, `id` linked to the active tab's
 * `aria-controls`, and `data-tab-id` so tests can wait for the
 * correct panel to mount).
 *
 * Use it directly under `<Tabs>` and conditionally render whichever
 * panel matches the active tab. Tests can wait for the panel to
 * become visible:
 *   `await expect(page.locator('[role="tabpanel"][data-tab-id="categories"]')).toBeVisible()`
 */
export interface TabPanelProps {
    /** Must match the corresponding `<TabsItem>.id` so ARIA wiring lines up. */
    tabId: string;
    /** True when this is the currently-active tab; the panel mounts but
     *  the parent component should still gate its rendering. The flag is
     *  used to drive `data-tab-active` and `tabIndex`. */
    isActive?: boolean;
    children: React.ReactNode;
    style?: React.CSSProperties;
}
export declare const TabPanel: React.FC<TabPanelProps>;
export default Tabs;
//# sourceMappingURL=index.d.ts.map