import { type ColorTokens, type StyleProp, type ViewStyle, type TextStyle } from "../../style/index.js";
import { type IconName } from "../../atoms/icon/icon.js";
import { type Variant } from "./tabs.styles.js";
export interface TabsSkin {
/** iOS/web dim the trigger on press; Android uses a ripple instead (null). */
pressedOpacity: number | null;
/** Android ripple over a pressed trigger; null on iOS/web. */
ripple: ((t: ColorTokens) => {
color: string;
borderless: boolean;
}) | null;
/**
* Where the keyboard focus ring sits on the trigger Pressables: INSET_FOCUS_RING draws
* it just inside a trigger that a clipping track or scroller would otherwise cut. The
* ring itself is the kit Pressable's (the palette's `ring`). No-op natively.
*/
focusRing?: ViewStyle;
/** The opacity of a disabled trigger. */
disabledOpacity: number;
/** The vertical rail's width (capped at 40% of its container) and the gap between its rows. */
railWidth: number;
railGap: number;
/** The label of a resting underline tab under the pointer (the web only); null where there is none. */
hoverLabel: ((t: ColorTokens) => TextStyle) | null;
/** The track behind the triggers; `wrap` is the multi-line row (TabsProps.wrap),
* where a capsule track squares off to the corner concentric with its pills, and
* `block` the row of equal columns. */
underlineRow: (t: ColorTokens, wrap: boolean, block?: boolean) => ViewStyle;
underlineTrigger: (t: ColorTokens, selected: boolean, dark: boolean) => ViewStyle;
underlineIndicator: (t: ColorTokens, selected: boolean) => ViewStyle;
underlineLabel: (t: ColorTokens, selected: boolean) => TextStyle;
pillsRow: (t: ColorTokens, wrap: boolean) => ViewStyle;
pillsTrigger: (t: ColorTokens, selected: boolean) => ViewStyle;
pillsFill: (t: ColorTokens, selected: boolean, dark: boolean) => ViewStyle;
pillsLabel: (t: ColorTokens, selected: boolean) => TextStyle;
verticalTrigger: (t: ColorTokens, selected: boolean) => ViewStyle;
verticalFill: (t: ColorTokens, selected: boolean) => ViewStyle;
verticalLabel: (t: ColorTokens, selected: boolean) => TextStyle;
countBadgeBox: (t: ColorTokens) => ViewStyle;
countBadgeLabel: (t: ColorTokens, muted: boolean) => TextStyle;
/** The count's numerals take their tab label's ink (the web renderer's badge sets no
* colour of its own) instead of `countBadgeLabel`'s. */
badgeTakesLabelInk?: boolean;
/** The size of a tab's leading glyph (`{ icon }`), drawn in its label's ink. */
iconSize: number;
}
/** A tab is either a bare label or a label paired with a count badge and/or an
* individual disabled flag (a disabled trigger dims, ignores presses, and is
* skipped by keyboard navigation). */
export type TabItem = string | {
label: string;
badge?: string;
disabled?: boolean;
/** A leading Canvas glyph before the label, in the label's ink (a settings rail's section icons). */
icon?: IconName;
};
export interface TabsProps {
/** Triggers, left to right. Strings, or `{ label, badge }` for a count. */
tabs?: TabItem[];
/** Index of the active trigger; omit for uncontrolled use. */
active?: number;
/** Initial active index for uncontrolled use (a bare switches out of the box). */
defaultActive?: number;
/** Called with the pressed trigger's index (both modes). Matches TabBar and
* ButtonGroup, which also fire `onSelect` for the active-index change. */
onSelect?: (index: number) => void;
/** E2E hook forwarded to the tablist row. */
testID?: string;
pills?: boolean;
vertical?: boolean;
underline?: boolean;
block?: boolean;
/**
* Layout (the underline and pills rows): a row longer than its container wraps
* onto further lines inside one track instead of panning in the overflow
* scroller, so every tab stays on screen at once. The track fills its container
* and grows taller, its corners concentric with the pills. `block` never
* overflows and wins; a `responsive` vertical rail honors it once it flattens.
*/
wrap?: boolean;
/**
* Responsive (vertical look only): render the EXISTING horizontal underline
* look when the component's own CONTAINER is at or below `sm` (640), where a
* side rail would starve the panel beside it. Container-measured with a
* viewport seed. `pills` and `underline` are unaffected.
*/
responsive?: boolean;
disabled?: boolean;
/** Outer layout composition only (width/flex within a parent), never a restyle hook. */
style?: StyleProp;
}
export declare function variantOf(p: TabsProps): Variant;
export declare function wrapsOf(p: Pick, variant: Variant): boolean;
/**
* The offset that brings an activated trigger fully into a horizontal scroller's
* view, or null when no scroll is needed (row fits, trigger already visible, or
* the correction is subpixel). `rect.x` is relative to the scroll content, and
* the result is clamped to the scrollable range. Pure so the math is unit-testable
* without layout events (the board-logic/chart-math precedent).
*/
export declare function tabScrollTarget(rect: {
x: number;
width: number;
}, viewport: number, content: number, offset: number, pad?: number): number | null;
/** Build a Tabs component from a platform skin. */
export declare function createTabs(skin: TabsSkin): (props: TabsProps) => import("react").JSX.Element;
//# sourceMappingURL=tabs.shared.d.ts.map