import { type ReactNode } from "react";
import { type ColorTokens, type StyleProp, type ViewStyle, type TextStyle } from "../../style/index.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;
/**
* Web-only focus-outline reset for the trigger Pressables. The iOS skin sets
* this so the react-native-web keyboard-focus blue ring (which a real iOS
* device never shows) is suppressed, leaving the press dim as the only
* feedback. Undefined on web/Android, which keep their own focus treatment.
* No-op natively, where `outlineStyle`/`outlineWidth` are not real CSS.
*/
focusOutlineReset?: ViewStyle;
underlineRow: (t: ColorTokens) => ViewStyle;
underlineTrigger: (t: ColorTokens, selected: boolean, dark: boolean) => ViewStyle;
underlineIndicator: (t: ColorTokens, selected: boolean) => ViewStyle;
underlineLabel: (t: ColorTokens, selected: boolean) => TextStyle;
pillsRow: (t: ColorTokens) => 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;
}
/** 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;
};
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;
/**
* 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;
}
/**
* 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) => string | number | bigint | boolean | Iterable | Promise> | Iterable | null | undefined> | import("react").JSX.Element | null | undefined;
//# sourceMappingURL=tabs.shared.d.ts.map