"use client"; import { useId, type CSSProperties } from "react"; export type Choice = { value: string; label: string; description?: string; disabled?: boolean; }; type ChoiceProps = { label: string; options: readonly Choice[]; value: string; onValueChange: (value: string) => void; name?: string; disabled?: boolean; className?: string; }; export function RadioGroup({ label, options, value, onValueChange, name, disabled, className = "", }: ChoiceProps) { const id = useId(); return (
{label} {options.map((option) => ( ))}
); } export function SegmentedControl({ label, options, value, onValueChange, name, disabled, className = "", }: ChoiceProps) { const id = useId(); return (
{label} {options.map((option) => ( ))}
); } export function NumberField({ label, value, onValueChange, min = -Infinity, max = Infinity, step = 1, disabled = false, className = "", }: { label: string; value: number; onValueChange: (value: number) => void; min?: number; max?: number; step?: number; disabled?: boolean; className?: string; }) { const id = useId(); const update = (n: number) => { if (Number.isFinite(n)) onValueChange(Math.min(max, Math.max(min, n))); }; const increment = Math.max(Number.EPSILON, Math.abs(step)); return (
update(e.target.valueAsNumber)} />
); } export function Rating({ label, value, onValueChange, max = 5, disabled, className = "", }: { label: string; value: number; onValueChange: (value: number) => void; max?: number; disabled?: boolean; className?: string; }) { const id = useId(), count = Math.min(10, Math.max(1, Math.floor(max))); return (
{label} {Array.from({ length: count }, (_, i) => ( ))}
); } export function ColorPicker({ label, value, onValueChange, swatches = ["#ff4d1c", "#2f6bff", "#2e8b70", "#f4f0e8"], disabled, className = "", }: { label: string; value: string; onValueChange: (value: string) => void; swatches?: readonly string[]; disabled?: boolean; className?: string; }) { const valid = /^#[\da-f]{6}$/i.test(value); return (
{label}
{swatches .filter((s) => /^#[\da-f]{6}$/i.test(s)) .map((color) => (
); }