import { RadioGroup as KRadioGroup } from "@kobalte/core/radio-group"; import { splitProps, type ComponentProps, For, Show } from "solid-js"; import { tv, type VariantProps } from "tailwind-variants"; const radioStyles = tv( { slots: { root: "flex flex-col gap-3 antialiased", label: "text-sm font-semibold text-main mb-1", item: "group flex items-center gap-3 cursor-pointer disabled:cursor-not-allowed", control: [ "flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-slate-300 bg-app transition-all shadow-sm", "group-hover:border-light group-data-[checked]:border-primary group-data-[checked]:bg-primary", "group-focus-visible:ring-2 group-focus-visible:ring-blue-500/20", ], indicator: "h-2 w-2 rounded-full bg-app shadow-sm", itemLabel: "text-sm font-medium text-main group-data-[disabled]:opacity-50", }, variants: { orientation: { horizontal: { root: "flex-row flex-wrap gap-6" }, vertical: { root: "flex-col" }, }, }, defaultVariants: { orientation: "vertical", }, }, { twMerge: true, }, ); type RadioVariants = VariantProps; export interface RadioOption { label: string; value: string; disabled?: boolean; } export interface RadioGroupProps extends Omit, "children" | "class">, RadioVariants { label?: string; options: RadioOption[]; class?: string; } /** * RadioGroup 高度封装版 * 自动处理循环渲染、选中指示器以及水平/垂直布局 */ export const RadioGroup = (props: RadioGroupProps) => { const [local, variantProps, others] = splitProps( props, ["label", "options", "class"], ["orientation"] ); const s = () => radioStyles({ orientation: variantProps.orientation }); return ( {local.label} {(option) => ( {option.label} )} ); };