import { forwardRef } from 'react'; import { Pressable, View } from 'react-native'; import { mergeDataAttributes, type IUseSwitchReturn } from '@cdx-ui/primitives'; import { cn, composeEventHandlers } from '@cdx-ui/utils'; import { switchThumbVariants, switchTrackVariants, switchWebTrackColorVariants, type SwitchVariantProps, } from './styles'; export interface BaseSwitchProps { switchState: IUseSwitchReturn; className?: string; size?: SwitchVariantProps['size']; accessibilityLabel?: string; onFocus?: () => void; onBlur?: () => void; } /** * Web host for `Switch`. Renders a custom `Pressable` + `View` toggle (preserving * the existing visual contract) wired to the resolved state in `switchState`. * * `role="switch"` + `aria-checked` + keyboard semantics satisfy the same a11y * contract that an `` would provide, without * the visual rework an input swap would require (see spike notes in PR). */ export const BaseSwitch = forwardRef( ({ switchState, className, size = 'md', accessibilityLabel, onFocus, onBlur, ...props }, ref) => { return ( switchState.setChecked(!switchState.checked)} onFocus={composeEventHandlers(onFocus, switchState.focusProps.onFocus as () => void)} onBlur={composeEventHandlers(onBlur, switchState.focusProps.onBlur as () => void)} onHoverIn={switchState.hoverProps.onHoverIn as () => void} onHoverOut={switchState.hoverProps.onHoverOut as () => void} tabIndex={0} className={cn( switchTrackVariants({ size }), switchWebTrackColorVariants({ isChecked: switchState.checked, isInvalid: switchState.isInvalid, }), className, )} {...props} {...mergeDataAttributes(props, switchState.dataAttrs)} > ); }, ); BaseSwitch.displayName = 'BaseSwitch';