You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2.0 KiB
2.0 KiB
Reusable Form Field Component Prompt
Create a reusable form field for <input/select/date/textarea/custom control>.
Inspect the existing form, label, input, select, and React Hook Form patterns
before implementation.
React contract
- Support a controlled
value/onChangeAPI unless the native primitive and established form adapter require another pattern. - Forward the appropriate control ref.
- Accept
name,label,description,error,required,disabled,className, and relevant native control attributes. - Generate stable IDs with
useId()when an ID is not supplied. - Keep validation rules in the parent/schema; render the resulting message.
- Define React Hook Form integration:
<Controller | register | both>.
Styling theme: clear data entry
- Labels are concise and visually connected to their controls.
- Controls use
bg-background,border-input, and a strongring-ringfocus. - Placeholder and help text use muted foreground, with sufficient contrast.
- Error styling uses destructive semantics plus text/icon—not border color alone.
- Required, disabled, read-only, success, and loading states are visually distinct.
- Spacing remains consistent whether help or error text is present.
Accessibility behavior
- Label and control are programmatically associated.
- Help/error IDs are connected through
aria-describedby. - Invalid controls set
aria-invalid. - Required state is communicated to assistive technology.
- Keyboard behavior follows the native element or selected accessible primitive.
Acceptance criteria
- The field works standalone and in the repository's established form pattern.
- Help text is replaced or accompanied by a useful validation message.
- Layout does not jump unexpectedly when validation appears.
- Autofill, focus, disabled, and dark-mode styles remain readable.
- The component contains no domain API or submission logic.
Run focused linting allowed by the repository instructions and finish with a simple TL;DR.