import { type ReactNode } from "react"; import { type GestureResponderEvent } from "react-native"; import { type ColorTokens, type ViewStyle, type TextStyle, type LayoutStyle, type MeasureProps } from "../../style/index.js"; import { type IconName } from "../icon/icon.js"; export type Kind = "segmented" | "split" | "stepper" | "spaced" | "attached"; export type Size = "small" | "default" | "large"; /** * The segmented row's density: `compact` keeps each segment at its size's height and * gives it the small label on a tighter inset, the v4 hand-off component page's platform * switch (Component.dc.html line 153: the default track around 28 px buttons of * `padding:0 12px;...;font:500 12px/1`). A skin without a compact segment draws the * default density (the iOS and Android skins, whose platforms ship the control). */ export type Density = "compact" | "default"; /** A segment: a bare label, or a label paired with a kit icon glyph rendered * before it (or alone, under the group-level `iconsOnly`, where the label * becomes the segment's accessible name), or a label shown as a node of its * own (`display`: a styled glyph, such as a bold B in a text-style picker). * Strings stay fully supported. */ export type ButtonGroupItem = string | { label: string; icon?: IconName; /** * What the segment shows in place of its label text (a `Typography` glyph). The * `label` stays the segment's accessible name and the item `onSelect` reports. */ display?: ReactNode; }; /** * The `attached` kind's parts (one hairline box of full-height cells divided by rules), * drawn by every skin: no platform ships this control, so each draws the hand-off's on * its own control corner. */ export interface AttachedParts { /** The box: its edge, corner, fill and lit top edge, clipping its cells. */ wrap: (t: ColorTokens) => ViewStyle; /** A cell's surface: the rule before every cell after the first, and the selected fill. */ segment: (t: ColorTokens, selected: boolean, leading: boolean) => ViewStyle; /** A cell's hover wash. */ hover: (t: ColorTokens) => ViewStyle; /** A cell's height and inset per size. */ cell: Record; /** A cell's label type per size. */ type: Record; /** A cell's label ink. */ label: (t: ColorTokens) => TextStyle; } export type IconColor = "primary" | "primaryForeground" | "muted" | "foreground"; export interface ButtonGroupSkin { /** Optional gray track wrapping the segmented row (iOS); null = bare row. */ segmentedWrap: (t: ColorTokens) => ViewStyle | null; /** Capsule segmented track with a translating selection, where the skin offers it. */ roundedSegmented?: { wrap: ViewStyle; cell: Record; thumb: (index: number, count: number, reduced: boolean) => ViewStyle; }; /** Border width on each segment cell (0 on iOS/Android, 1 on web). */ segmentBorderWidth: number; /** Corner radii for an attached segment given its position in the row. */ joinCorners: (index: number, count: number) => ViewStyle; /** Corner radii for a detached (spaced) peer. */ spacedCorners: ViewStyle; /** Shared-border overlap applied to every non-leading segment; null = none. */ overlap: ViewStyle | null; /** Optional leading divider on every non-leading segment (Android stadium). */ segmentDivider?: (t: ColorTokens) => ViewStyle; /** Selected vs. unselected segment fill/border. */ segmentSurface: (t: ColorTokens, selected: boolean) => ViewStyle; /** Segment label color/weight for selected vs. unselected. */ segmentLabel: (t: ColorTokens, selected: boolean) => TextStyle; /** Segment icon glyph color (the semantic Icon boolean axis) for selected vs. * unselected, tracking each skin's segmentLabel treatment. */ segmentIconColor: (selected: boolean) => IconColor; /** Show a leading check glyph on the selected segment (Android M3). */ showSelectedCheck: boolean; /** A segment glyph's size (`items[].icon`); omit for the size's chevron size. */ segmentIconSize?: number; /** The `attached` kind's box and cells. */ attached: AttachedParts; splitPrimary: (t: ColorTokens) => ViewStyle; splitPrimaryLabel: (t: ColorTokens) => TextStyle; splitDivider: (t: ColorTokens, height: number) => ViewStyle; splitTrigger: (t: ColorTokens, height: number) => ViewStyle; splitMenu: (t: ColorTokens) => ViewStyle; splitMenuItemPressed: (t: ColorTokens) => ViewStyle; splitMenuText: (t: ColorTokens) => TextStyle; /** The split's primary half per size (its height and inset); omit for `cellSize`. */ splitCell?: Record; /** The split's primary label type per size; omit for `cellType`. */ splitCellType?: Record; /** The chevron half's width per size, a square of the segmented height; omit to pad the chevron instead. */ splitTriggerWidth?: Record; /** The split's glyph sizes: the primary's leading icon and the chevron; omit for the size's chevron size. */ splitIconSize?: { icon: number; chevron: number; }; stepperArrow: (t: ColorTokens, height: number) => ViewStyle; stepperArrowLeft: ViewStyle; stepperArrowRight: ViewStyle; stepperMiddle: (t: ColorTokens) => ViewStyle; stepperLabel: (t: ColorTokens) => TextStyle; stepperChevronColor: IconColor; /** * The stepper as ONE box (its edge, corner, fill and clip) around square end cells, at * this height per size; omit for three cells with edges of their own. */ stepperBox?: { box: (t: ColorTokens) => ViewStyle; height: Record; }; /** The stepper's value cell per size, in place of `cellSize` (its inset). */ stepperValueCell?: Record; /** The stepper's built-in end glyphs: minus and plus at this size, in place of the chevrons. */ stepperSigns?: number; /** Height and padding of a segment inside the segmented row (the web's sit in a padded track). */ segmentSize?: Record; /** Label type of a segment inside the segmented row. */ segmentType?: Record; /** A segment's horizontal padding when it shows its icon alone (`iconsOnly`); omit to keep the size's. */ segmentIconOnlyPadding?: number; /** * A `compact` segment's inset and label type over its size's (the hand-off page's * platform switch); omit where the platform's control has one density. */ compactSegment?: { size: ViewStyle; type: TextStyle; }; /** Height and padding of the split, stepper and spaced cells (the web's match its Button). */ cellSize?: Record; /** Label type of the split, stepper and spaced cells. */ cellType?: Record; /** A spaced peer's own surface and label, where the unselected segment's would vanish without a track. */ spacedSurface?: (t: ColorTokens) => ViewStyle; spacedLabel?: (t: ColorTokens) => TextStyle; /** iOS/web dim the cell on press; Android uses a ripple instead (null). */ pressedOpacity: number | null; /** Android ripple over a pressed cell; null on iOS/web. */ ripple?: (t: ColorTokens) => { color: string; borderless: boolean; }; } export interface ButtonGroupProps extends MeasureProps { /** Segments for segmented/spaced: a label string, or `{ label, icon }` for a * leading kit glyph. The stepper cycles the labels (icons ignored there). */ items?: ButtonGroupItem[]; /** Selected segment index (segmented, CONTROLLED), or the stepper's initial index. Omit for uncontrolled use. */ active?: number; /** Initial selected segment index for uncontrolled use (a bare segmented control selects on press). */ defaultActive?: number; /** Called with the pressed/selected index and item (and, for the stepper, the new index). */ onSelect?: (index: number, item: string, event: GestureResponderEvent) => void; segmented?: boolean; split?: boolean; stepper?: boolean; spaced?: boolean; /** * Buttons joined in one hairline box on the raised fill, divided by full-height rules, * the selected one on the raised step (an alignment or a view picker drawn as buttons * rather than a track and thumb). It selects as `segmented` does and takes `active`, * `defaultActive` and `block`. */ attached?: boolean; /** * The stepper's decrement end, in place of its built-in glyph (a `zoomOut` Icon for a * zoom control). The stepper kind only. */ decrementIcon?: ReactNode; /** The stepper's increment end, in place of its built-in glyph (a `zoomIn` Icon). */ incrementIcon?: ReactNode; /** Related actions shown in the split kind's chevron dropdown. */ menu?: string[]; small?: boolean; large?: boolean; /** * Density of the segmented row: the segments keep their size's height and take the * small label on a 12 px inset (the hand-off component page's platform switch, a * default-height track of 12 px labels). On the web only: a platform that ships the * control keeps its one density. The split, stepper and spaced kinds ignore it. */ compact?: boolean; /** A capsule segmented track with equal cells and a sliding selection thumb. */ rounded?: boolean; /** * Segmented/spaced only: each segment renders its `icon` alone and the item's * `label` becomes the segment's ACCESSIBLE name (an icon-only view or * form-factor switcher). An item without an icon keeps its visible label, * with a dev-only warning. Split and stepper ignore it (dev-only warning). */ iconsOnly?: boolean; /** Keep segmented and spaced cells at their resting opacity during a press. */ steadyPress?: boolean; /** Accessible name for the segmented row (the `tablist`), announcing what * the group switches (e.g. "Preview form factor"). Segmented kind only: * spaced peers are independent buttons with no group role. */ accessibilityLabel?: string; /** * Stretch the group to the container width, the segments sharing the space * equally. An orthogonal layout modifier for the segmented and spaced kinds; * split and stepper ignore it (their cells are fixed-width chrome) with a * dev-only warning. A measure step (`sm`, `lg`, …) does the same up to that * width of the scale. */ block?: boolean; disabled?: boolean; /** E2E hook forwarded to the root element. */ testID?: string; /** Composition within a parent only, never a restyle hook and never a width: the parent layout container provides the bounds. */ style?: LayoutStyle; } export declare function kindOf(p: ButtonGroupProps): Kind; export declare function sizeOf(p: ButtonGroupProps): Size; /** The segmented row's density: `compact`, or the default. */ export declare function densityOf(p: ButtonGroupProps): Density; /** Build a ButtonGroup component from a platform skin. */ export declare function createButtonGroup(skin: ButtonGroupSkin): (props: ButtonGroupProps) => import("react").JSX.Element; //# sourceMappingURL=button-group.shared.d.ts.map