import { useId, type InputHTMLAttributes, type ReactNode, type TextareaHTMLAttributes, } from 'react'; interface FieldShellProps { label: string; hint?: string | undefined; error?: string | null | undefined; children: (ids: { id: string; describedBy: string | undefined }) => ReactNode; } /** Общая обёртка поля: label, подсказка и сообщение об ошибке. */ function FieldShell({ label, hint, error, children }: FieldShellProps) { const id = useId(); const hintId = `${id}-hint`; const errorId = `${id}-error`; const describedBy = [hint === undefined ? null : hintId, error === null || error === undefined ? null : errorId] .filter((value): value is string => value !== null) .join(' ') || undefined; return (
{children({ id, describedBy })} {hint === undefined ? null : (

{hint}

)} {error === null || error === undefined ? null : ( )}
); } const controlClass = 'w-full rounded-[var(--radius-md)] border border-border/60 bg-surface-2 px-3 py-2 text-fg placeholder:text-fg-muted/70 disabled:opacity-60'; export type InputFieldProps = { label: string; hint?: string | undefined; error?: string | null | undefined; } & InputHTMLAttributes; export function Field({ label, hint, error, className = '', ...rest }: InputFieldProps) { return ( {({ id, describedBy }) => ( )} ); } export type TextAreaFieldProps = { label: string; hint?: string | undefined; error?: string | null | undefined; } & TextareaHTMLAttributes; export function TextAreaField({ label, hint, error, className = '', ...rest }: TextAreaFieldProps) { return ( {({ id, describedBy }) => (