"use client"; import { motion, MotionConfig, useReducedMotion } from "motion/react"; import { createContext, useCallback, useContext, useId, useMemo, useState, type ReactNode, } from "react"; import { SPRING_LAYOUT, SPRING_PRESS } from "@/lib/ease"; import { cn } from "@/lib/utils"; type RadioCtx = { value: string; setValue: (value: string) => void; layoutId: string; }; const RadioCtx = createContext(null); function useRadioGroup() { const ctx = useContext(RadioCtx); if (!ctx) { throw new Error("RadioGroupItem must be used inside "); } return ctx; } export interface RadioGroupProps { value?: string; defaultValue?: string; onValueChange?: (value: string) => void; children: ReactNode; className?: string; orientation?: "vertical" | "horizontal"; } export function RadioGroup({ value, defaultValue = "", onValueChange, children, className, orientation = "vertical", }: RadioGroupProps) { const [internal, setInternal] = useState(defaultValue); const layoutId = useId(); const reduce = useReducedMotion(); const controlled = value !== undefined; const current = controlled ? value : internal; const setValue = useCallback( (next: string) => { if (!controlled) setInternal(next); onValueChange?.(next); }, [controlled, onValueChange], ); const contextValue = useMemo( () => ({ value: current, setValue, layoutId }), [current, layoutId, setValue], ); return (
{children}
); } export interface RadioGroupItemProps { value: string; label?: string; disabled?: boolean; className?: string; id?: string; } export function RadioGroupItem({ value, label, disabled, className, id: idProp, }: RadioGroupItemProps) { const { value: groupValue, setValue, layoutId } = useRadioGroup(); const autoId = useId(); const id = idProp ?? autoId; const reduce = useReducedMotion(); const selected = groupValue === value; return ( ); }