'use client' import * as React from 'react' import { Radio as BaseRadio } from '@base-ui/react/radio' import { LazyMotion, domAnimation, m, useAnimate } from 'motion/react' import { useReducedMotion } from '../../hooks/use-reduced-motion' import { cn, useComposedRefs } from '../../internal/utils' const SQUISH_TRANSITION = { duration: 0.3, ease: [0.4, 0, 0.2, 1] satisfies [number, number, number, number], } const INDICATOR_TRANSITION = { duration: 0.3, ease: [0.4, 0, 0.2, 1] satisfies [number, number, number, number], } const ZERO_TRANSITION = { duration: 0 } as const function RadioIndicator({ checked, reduced }: { checked: boolean; reduced: boolean }) { return ( ) } function RadioRoot({ renderProps, state, reduced, }: { renderProps: React.ComponentPropsWithRef<'span'> state: { checked: boolean } reduced: boolean }) { const { checked } = state const { ref, ...htmlProps } = renderProps const [scope, animate] = useAnimate() const composedRef = useComposedRefs(ref, scope) const prevChecked = React.useRef(checked) React.useEffect(() => { const toggled = prevChecked.current !== checked prevChecked.current = checked if (toggled && !reduced) { animate(scope.current, { scale: [1, 0.8, 1.1, 1] }, SQUISH_TRANSITION) } }, [checked, animate, scope, reduced]) return ( ) } type RadioProps = React.ComponentProps function Radio({ className, ...props }: RadioProps) { const reduced = useReducedMotion() const ariaInvalid = props['aria-invalid'] const invalid = ariaInvalid === true || ariaInvalid === 'true' return ( } /> ) } export { Radio } export type { RadioProps }