import { type ReactNode } from "react"; import { type GestureResponderEvent } from "react-native"; import { type ColorTokens, type StyleProp, type ViewStyle, type TextStyle } from "../../style/index.js"; export interface RadioProps { /** * This option's value within a RadioGroup. When the radio sits inside a * ``, its checked state and selection are driven by the group * matching this value; ignored for a standalone radio. */ value?: string | number; /** Whether this control is the selected option (controlled; standalone use). */ checked?: boolean; /** Alias for `checked`, for callers that think in terms of "selected". */ selected?: boolean; /** Fired on press with the next checked value (always true for a radio). */ onChange?: (checked: boolean, event: GestureResponderEvent) => void; /** E2E hook forwarded to the pressable row. */ testID?: string; /** Label text (the option's title) shown beside the control. */ children?: ReactNode; /** * Optional muted secondary line rendered under the label, for the common * title-plus-description option (a plan picker, a settings choice). Supplying it * builds the stacked title/description layout inside the control, so the caller * never hand-composes a Row + Column + two Typography nodes per option. */ description?: ReactNode; /** * Render the whole control as a selectable option CARD: the ring plus the title and * description sit inside Card chrome (bordered, padded), and the ENTIRE card is the * tap target. When this radio is the chosen option, the card takes Card's own * `selected` treatment (a primary border and a soft primary tint), so the whole tile * reads as chosen, not just the dot. Pairs with `description` for a plan/tier picker, * and is still group-wired through `value` inside a ``. */ card?: boolean; small?: boolean; large?: boolean; /** Dim the control and block presses. */ disabled?: boolean; /** Outer layout composition only (width/flex within a parent), never a restyle hook. */ style?: StyleProp; } export type Size = "small" | "default" | "large"; export interface RadioSkin { /** The circular control. `checked` swaps the neutral border for primary. `nudge` aligns the ring to a label's first line. */ ring: (tokens: ColorTokens, size: Size, checked: boolean, nudge: boolean) => ViewStyle; /** The centered fill dot, rendered only when checked. */ dot: (tokens: ColorTokens, size: Size) => ViewStyle; /** The label text to the right of the ring. */ label: (tokens: ColorTokens, size: Size, disabled: boolean) => TextStyle; /** The muted secondary description line, rendered under the label when present. */ description: (tokens: ColorTokens, size: Size, disabled: boolean) => TextStyle; /** * The `card` mode chrome: the whole control wrapped as a selectable Card surface * (bordered + padded, per-OS radius/curve), derived from the kit Card skin. When * `checked`, it applies Card's own `selected` treatment (primary border + soft tint). */ card: (tokens: ColorTokens, checked: boolean) => ViewStyle; /** Opacity applied to the row when disabled. */ disabledOpacity: number; /** iOS/web dim the row on press; Android uses a ripple instead (null). */ pressedOpacity: number | null; /** Android ripple over the ring; null on iOS/web. */ ripple: ((tokens: ColorTokens) => { color: string; borderless: boolean; radius?: number; }) | null; } /** Build a Radio component from a platform skin. */ export declare function createRadio(skin: RadioSkin): (props: RadioProps) => import("react").JSX.Element; //# sourceMappingURL=radio.shared.d.ts.map