import { Platform } from 'react-native'; import { cva } from 'class-variance-authority'; import { DISABLED_CURSOR, TRANSITION_COLORS } from '../../styles/constants'; export const radioRootVariants = cva([ 'flex-row items-center gap-2', 'data-[disabled=true]:opacity-[var(--opacity-disabled)]', DISABLED_CURSOR, ]); export const radioIndicatorVariants = cva([ 'items-center justify-center', 'rounded-[var(--border-radius-round)]', 'border-[length:var(--border-width-selected)]', 'h-5 w-5', 'bg-surface-primary', 'data-[checked=false]:border-content-secondary', 'data-[checked=true]:border-stroke-action', 'data-[invalid=true]:border-stroke-danger', Platform.select({ web: [ TRANSITION_COLORS, 'group', // Hover — unchecked (Figma: border unchanged, bg overlay at opacity/hover) 'data-[hover=true]:data-[checked=false]:bg-content-secondary/[0.08]', // Hover — unchecked + invalid (overlay uses danger token) 'data-[hover=true]:data-[invalid=true]:data-[checked=false]:bg-surface-danger-strong/[0.08]', 'data-[hover=true]:data-[checked=true]:border-surface-action-strong-hover', 'data-[hover=true]:data-[invalid=true]:border-surface-danger-strong-hover', // Active — CSS :active (web root does not track press via data-active). // data-[hover=true] guard ensures active beats hover by specificity (0,3,0 > 0,2,0). 'web:active:data-[hover=true]:data-[checked=false]:border-stroke-hover', 'web:active:data-[hover=true]:data-[invalid=true]:data-[checked=false]:border-surface-danger-strong-active', 'web:active:data-[hover=true]:data-[checked=true]:border-surface-action-strong-active', 'web:active:data-[hover=true]:data-[checked=true]:data-[invalid=true]:border-surface-danger-strong-active', 'web:data-[focus-visible=true]:outline-none', 'web:data-[focus-visible=true]:ring-2 web:data-[focus-visible=true]:ring-stroke-focus web:data-[focus-visible=true]:ring-offset-2', ].join(' '), default: [ // Native: Uniwind only evaluates the last data-[] condition in a compound chain. // Use single-condition data-[field-state=...] selectors (emitted by RadioIndicator). 'data-[field-state=active]:border-stroke-hover', 'data-[field-state=invalid-active]:border-surface-danger-strong-active', 'data-[field-state=checked-active]:border-surface-action-strong-active', 'data-[field-state=checked-invalid-active]:border-surface-danger-strong-active', ].join(' '), }), ]); export const radioInnerDotVariants = cva([ 'rounded-[var(--border-radius-round)]', 'h-2.5 w-2.5', 'scale-0', 'data-[checked=true]:scale-100', 'bg-surface-action-strong', 'data-[invalid=true]:bg-surface-danger-strong', Platform.select({ web: [ 'data-[hover=true]:bg-surface-action-strong-hover', 'data-[hover=true]:data-[invalid=true]:bg-surface-danger-strong-hover', // Active via group-active on indicator (inner dot is not the :active target). 'web:group-active:data-[hover=true]:data-[checked=true]:bg-surface-action-strong-active', 'web:group-active:data-[hover=true]:data-[checked=true]:data-[invalid=true]:bg-surface-danger-strong-active', ].join(' '), default: [ 'data-[field-state=checked-active]:bg-surface-action-strong-active', 'data-[field-state=checked-invalid-active]:bg-surface-danger-strong-active', ].join(' '), }), ]); export const radioLabelVariants = cva(['body-md', 'text-content-primary']); export const radioGroupVariants = cva([], { variants: { direction: { column: 'gap-2', row: 'flex-row gap-4', }, }, defaultVariants: { direction: 'column' }, });