"use client"; import { cloneElement, forwardRef, useId, useState, type InputHTMLAttributes, type TextareaHTMLAttributes, type SelectHTMLAttributes, type ReactElement, type ReactNode, } from "react"; type FieldLabel = { label: string; hint?: ReactNode; error?: string }; export function FormField({ label, hint, error, children, className = "", }: FieldLabel & { children: ReactElement<{ id?: string; "aria-describedby"?: string; "aria-invalid"?: boolean; }>; className?: string; }) { const generated = useId(), id = children.props.id ?? generated; const helpId = `${id}-help`, errorId = `${id}-error`; const described = [ children.props["aria-describedby"], hint && helpId, error && errorId, ] .filter(Boolean) .join(" "); return (
{cloneElement(children, { id, "aria-describedby": described || undefined, "aria-invalid": error ? true : children.props["aria-invalid"], })} {hint && (
{hint}
)} {error && ( )}
); } export type TextFieldProps = InputHTMLAttributes & FieldLabel; export const TextField = forwardRef( function TextField({ label, hint, error, className = "", ...props }, ref) { return ( ); }, ); export const TextArea = forwardRef< HTMLTextAreaElement, TextareaHTMLAttributes & FieldLabel >(function TextArea( { label, hint, error, className = "", rows = 4, ...props }, ref, ) { return (