import { useRef, useState, type InputHTMLAttributes, type ReactNode, type Ref, type TextareaHTMLAttributes, } from 'react'; import { cx } from '../utils/cx'; import { describedBy, Field, useFieldControl, type FieldShellProps } from './Field'; import { Icon } from './Icon'; import { IconButton } from './Button'; export interface TextFieldProps extends Omit, 'size'>, FieldShellProps { startIcon?: ReactNode; endAdornment?: ReactNode; ref?: Ref; } export function TextField({ label, description, error, size = 'md', block = true, startIcon, endAdornment, className, id, required, disabled, onChange, onInvalid, 'aria-describedby': ariaDescribedBy, ...rest }: TextFieldProps) { const { ids, validity } = useFieldControl(id, required, error); return (
{startIcon && {startIcon}} { validity.onInvalid(event); onInvalid?.(event); }} onChange={(event) => { validity.reportValue(event.currentTarget.value); onChange?.(event); }} /> {endAdornment && ( {endAdornment} )}
); } export interface TextareaProps extends Omit, 'size'>, FieldShellProps { resize?: 'none' | 'vertical'; ref?: Ref; } export function Textarea({ label, description, error, size = 'md', block = true, resize = 'vertical', rows = 4, className, id, required, disabled, onChange, onInvalid, 'aria-describedby': ariaDescribedBy, ...rest }: TextareaProps) { const { ids, validity } = useFieldControl(id, required, error); return (