import type { ViewProps } from 'react-native'; import type { AnimatedProps, SharedValue, WithSpringConfig, WithTimingConfig, } from 'react-native-reanimated'; import type { Animation, AnimationRoot, AnimationValue, } from '../../helpers/internal/types'; import * as SwitchPrimitivesTypes from '../../primitives/switch/switch.types'; /** * Render function props for switch children */ export interface SwitchRenderProps { /** Whether the switch is selected */ isSelected?: boolean; /** Whether the switch is disabled */ isDisabled: boolean; } /** * Animation configuration for switch root component */ export type SwitchRootAnimation = AnimationRoot<{ scale?: AnimationValue<{ /** * Scale values [unpressed, pressed] * @default [1, 0.95] */ value?: [number, number]; /** * Animation timing configuration * @default { duration: 150 } */ timingConfig?: WithTimingConfig; }>; backgroundColor?: AnimationValue<{ /** * Background color values [unselected, selected] * @default Uses theme colors (default, accent) */ value?: [string, string]; /** * Animation timing configuration * @default { duration: 175, easing: Easing.bezier(0.25, 0.1, 0.25, 1) } */ timingConfig?: WithTimingConfig; }>; }>; /** * Props for the main Switch component */ export interface SwitchProps extends Omit { /** Content to render inside the switch, or a render function */ children?: React.ReactNode | ((props: SwitchRenderProps) => React.ReactNode); /** Whether the switch is disabled @default false */ isDisabled?: boolean; /** Custom class name for the switch * * @note The following style properties are occupied by animations and cannot be set via className: * - `backgroundColor` - Animated for selection transitions (unselected: default, selected: accent) * - `transform` (specifically `scale`) - Animated for press feedback transitions (unpressed: 1, pressed: 0.96) * * To customize these properties, use the `animation` prop: * ```tsx * * ``` * * To completely disable animated styles and use your own via className or style prop, set `isAnimatedStyleActive={false}`. */ className?: string; /** * Animation configuration for switch * - `false` or `"disabled"`: Disable only root animations * - `"disable-all"`: Disable all animations including children * - `true` or `undefined`: Use default animations * - `object`: Custom animation configuration */ animation?: SwitchRootAnimation; /** * Whether animated styles (react-native-reanimated) are active * When `false`, the animated style is removed and you can implement custom logic * This prop should only be used when you want to write custom styling logic instead of the default animated styles * @default true */ isAnimatedStyleActive?: boolean; /** * Background layer rendered behind the switch content. * - `undefined` (default): renders `Switch.Background` while unselected * (selection paints its own accent color) when the active library theme * registers default background content (e.g. `glass`); otherwise no layer * - custom node: replaces the default layer entirely (wrap content in * `Switch.Background` to keep the absolute-fill and clipping) * - `null`: removes the background layer */ background?: React.ReactNode; } /** * Props for the Switch.Background sub-component. * Generic absolute-fill container behind the switch content. When no * `children` are given, the active library theme decides the default * content (e.g. a frosted-glass blur layer when the theme is `glass`). */ export type SwitchBackgroundProps = ViewProps & { /** Additional CSS classes */ className?: string; }; /** * Animation configuration for switch thumb component */ export type SwitchThumbAnimation = Animation<{ /** * Animates the thumb position between the leading and trailing edges. * Applied to the Yoga-logical `start` property, so the travel direction * automatically flips in right-to-left layouts. * When you provide a single value (e.g., `value: 2`), it applies the same offset * to both sides: `2px` from the leading edge when unselected, and `2px` from the * trailing edge when selected. */ left?: AnimationValue<{ /** * Offset value from the edges (leading when unselected, trailing when selected) * @default 2 * @example value: 4 // 4px offset from both edges */ value?: number; /** * Spring animation configuration for thumb position * @default { damping: 120, stiffness: 1600, mass: 2 } */ springConfig?: WithSpringConfig; }>; backgroundColor?: AnimationValue<{ /** * Background color values [unselected, selected] * @default ['white', theme accent-foreground color] */ value?: [string, string]; /** * Animation timing configuration * @default { duration: 175, easing: Easing.bezier(0.25, 0.1, 0.25, 1) } */ timingConfig?: WithTimingConfig; }>; }>; /** * Props for the SwitchThumb component */ export interface SwitchThumbProps extends Omit, 'children'> { /** Content to render inside the thumb, or a render function */ children?: React.ReactNode | ((props: SwitchRenderProps) => React.ReactNode); /** Custom class name for the thumb element * * @note The following style properties are occupied by animations and cannot be set via className: * - `left` - Animated for thumb position transitions (unselected: left edge offset, selected: right edge offset) * - `backgroundColor` - Animated for selection transitions (unselected: white, selected: accent-foreground) * * To customize these properties, use the `animation` prop: * ```tsx * * ``` * * To completely disable animated styles and use your own via className or style prop, set `isAnimatedStyleActive={false}`. */ className?: string; /** * Animation configuration for thumb * - `false` or `"disabled"`: Disable all animations * - `true` or `undefined`: Use default animations * - `object`: Custom animation configuration */ animation?: SwitchThumbAnimation; /** * Whether animated styles (react-native-reanimated) are active * When `false`, the animated style is removed and you can implement custom logic * This prop should only be used when you want to write custom styling logic instead of the default animated styles * @default true */ isAnimatedStyleActive?: boolean; } /** * Props for the SwitchContent component */ export interface SwitchContentProps { /** Content to render inside the switch content */ children?: React.ReactNode; /** Custom class name for the content element */ className?: string; } /** * Context value for switch components */ export interface SwitchContextValue extends Pick {} /** * Context value for switch animation state */ export interface SwitchAnimationContextValue { /** Shared value tracking if the switch is pressed */ isSwitchPressed: SharedValue; /** Width of the content container */ contentContainerWidth: SharedValue; }