import { type JSX, For, Show, createSignal } from 'solid-js'; import { cn } from '../utils/cn'; import { Textarea } from '../ui/textarea'; import { Star } from 'lucide-solid'; import type { FormField } from './form'; /** The shared prop shape every leaf widget receives from FieldRow. */ export interface WidgetProps { id: string; value: unknown; field: FormField; disabled: boolean; placeholder?: string; required: boolean; invalid: boolean; describedBy?: string; label: string; onInput: (value: unknown) => void; onBlur: () => void; } const inputBase = 'w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:pointer-events-none'; function ariaProps(p: WidgetProps) { return { 'aria-required': p.required || undefined, 'aria-invalid': p.invalid || undefined, 'aria-describedby': p.describedBy, }; } /** text / email / url / date / datetime / time / password — all variants. */ export function TextWidget( props: WidgetProps & { variant: 'text' | 'email' | 'url' | 'date' | 'datetime' | 'time' | 'password' }, ): JSX.Element { const inputType = () => { switch (props.variant) { case 'email': return 'email'; case 'url': return 'url'; case 'date': return 'date'; case 'datetime': return 'datetime-local'; case 'time': return 'time'; case 'password': return 'password'; default: return 'text'; } }; return ( props.onInput(e.currentTarget.value)} onBlur={props.onBlur} /> ); } export function TextareaWidget(props: WidgetProps): JSX.Element { const len = () => ((props.value as string) ?? '').length; return (