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

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/onChange API 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 strong ring-ring focus.
  • 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

  1. The field works standalone and in the repository's established form pattern.
  2. Help text is replaced or accompanied by a useful validation message.
  3. Layout does not jump unexpectedly when validation appears.
  4. Autofill, focus, disabled, and dark-mode styles remain readable.
  5. The component contains no domain API or submission logic.

Run focused linting allowed by the repository instructions and finish with a simple TL;DR.