thesoftwarehouse/copilot-collections/tsh-implementing-forms

Claude Code and agent skill by thesoftwarehouse/copilot-collections

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Form architecture, schema-based validation, field composition, error handling, multi-step form flows, and accessible form patterns. Use when building forms, implementing validation, creating multi-step wizards, or integrating form fields with a component library.

Install

npx vskill@latest install thesoftwarehouse/copilot-collections/tsh-implementing-forms

SKILL.md

Implementing Forms

Provides patterns and workflows for building robust, accessible forms with schema-based validation, composable field components, and multi-step form flows.

<principles>

<schema-first-validation> Define validation rules as a separate schema, co-located with but decoupled from UI code. The schema is the single source of truth for what constitutes valid data. Infer TypeScript types from schemas to eliminate drift between validation rules and form types. Never duplicate type definitions manually — derive them from the schema. </schema-first-validation>

<progressive-disclosure-of-errors> Show validation errors at the right moment: on field blur or form submission, not on every keystroke. Help users fix errors rather than frustrate them with premature feedback. After the first validation pass, switch to on-change validation so users see errors clear as they correct them. </progressive-disclosure-of-errors>

<accessible-by-default> Every form field must have a visible label. Error messages must be announced to screen readers via role="alert" or aria-live regions. The form must be fully navigable by keyboard alone — Tab through fields, Enter to submit, Escape to cancel where applicable. Associate error messages with their fields using aria-describedby. </accessible-by-default>

</principles>

Form Implementation Process

Use the checklist below and track progress:

Progress:
- [ ] Step 1: Define the data model
- [ ] Step 2: Build field components
- [ ] Step 3: Compose the form
- [ ] Step 4: Handle multi-step flows (if applicable)
- [ ] Step 5: Verify accessibility

Step 1: Define the data model

  • Identify all fields: names, types, required vs. optional, default values.
  • Define a validation schema in a co-located file (*.schema.ts or validation/ directory). The schema declares every constraint: required fields, min/max lengths, patterns, custom rules, cross-field dependencies.
  • Infer the form's TypeScript type directly from the schema — do not write a separate interface that duplicates the schema's structure.
  • Document any async validation rules (e.g., "check if username is available") — these run on blur or submit, never on every keystroke.

Step 2: Build field components

Create composable field wrapper components that connect the form library's state to the component library's inputs. Each field wrapper:

  • Receives the field name (and optionally the form context) as props.
  • Renders a visible <label>, the input element, and an error message container.
  • Reads touched/dirty/error state from the form library and reflects it in the UI.
  • Sets accessibility attributes:
  • aria-invalid="true" when the field has an error.
  • aria-describedby pointing to the error message element's id.
  • aria-required="true" for required fields.
  • Supports all relevant input types: text, select, checkbox, radio, textarea, date, file upload.
  • For file inputs: hide the native <input type="file"> visually and use a styled trigger button with aria-label. Display selected file name(s), size, and a remove action. Validate file type and size in the schema — reject invalid files before upload begins.
  • Keeps the wrapper generic — the same field component works for different forms by accepting the field name as a parameter.

Step 3: Compose the form

Assemble field components into a form:

  • Wrap field components with the form library's provider/context so fields can access form state.
  • Add novalidate attribute to the <form> element when using custom validation — this disables browser-native validation bubbles that conflict with the form library's error display. The schema-based validation from Step 1 replaces the browser's built-in constraints.
  • Handle submission flow:
  1. Validate all fields against the schema.
  2. If invalid — display errors and focus the first invalid field.
  3. If valid — transform data if needed (trim strings, format dates), then call the submit handler.
  4. During async submission: disable the submit button and show a loading indicator.
  5. On success — navigate, show confirmation, or reset form as appropriate.
  6. On server error — map API error responses to specific form fields where possible. Display unmapped errors as a form-level message.
  • Prevent double submission by disabling the submit button while a submission is in flight.
  • Ensure the form is submittable via the Enter key (native <form> behavior — do not break it with preventDefault on the wrong element).

Step 4: Handle multi-step flows (if applicable)

When a form spans multiple steps or pages:

  • Split the form into discrete steps, each with its own validation schema. Only validate the fields visible in the current step.
  • Persist state across steps using form-level state (component state or a store) — not URL parameters. Users must not lose data when navigating between steps.
  • Validate the current step before allowing navigation to the next step. Show errors on the current step, do not allow skipping ahead past invalid steps.
  • Allow back-navigation without losing previously entered data.
  • Show a progress indicator (stepper, progress bar, or step labels) so users know where they are and how many steps remain.
  • On the final step, submit all accumulated data from all steps together.

Step 5: Verify accessibility

Use the tsh-ensuring-accessibility skill for a thorough audit. At minimum, verify:

  • Every <input>, <select>, and <textarea> has an associated <label> element (via for/id pairing or wrapping).
  • Error messages use role="alert" or are in an aria-live="polite" region so screen readers announce them.
  • Tab order follows the visual layout — no unexpected focus jumps.
  • The form can be submitted by pressing Enter in a text field.
  • Focus moves to the first invalid field after a failed submission attempt.
  • Required fields are indicated both visually (e.g., asterisk) and programmatically (aria-required).

Validation Timing

Validation modeWhen to useBehavior
On submitSimple forms, few fieldsValidate all fields on submit, show all errors at once
On blurComplex forms, many required fieldsValidate each field when the user leaves it
On change (with debounce)Real-time feedback needed (password strength, username availability)Validate as user types, debounced to avoid excessive checks
MixedBest UX for most formsValidate on blur initially; after the first error, switch to on-change so errors clear immediately when corrected

Error Display Patterns

PatternDescription
Inline below fieldError message directly under the invalid field — most common, recommended default
Summary at topList of all errors at the top of the form — useful for long forms, aids screen readers
Inline + summaryBoth inline and summary — best accessibility (screen reader reads summary, sighted users see inline)
Toast/notificationOnly for server-side submission errors, never for field-level validation

Form Checklist

Form:
- [ ] Validation schema defined separately from UI
- [ ] TypeScript type inferred from schema (no manual duplication)
- [ ] Every field has a visible label
- [ ] Error messages shown inline below fields
- [ ] Errors announced to screen readers (role="alert" or aria-live)
- [ ] Submit button disabled during submission
- [ ] Server-side errors mapped to specific fields
- [ ] Tab order follows visual layout
- [ ] Form submittable via Enter key
- [ ] Loading state during async submission

Anti-Patterns

Anti-PatternInstead Do
Manual validation in event handlersUse a schema-based validation library
Duplicating types between schema and formInfer types from the schema
Showing errors on every keystrokeUse blur or mixed-mode validation
Unlabeled inputs (placeholder as label)Always use visible <label> elements
Generic "Form has errors" messageSpecific per-field error messages
Losing form data on back-navigationPersist state across steps
Ignoring server-side errorsMap API errors to specific form fields
Submit button without loading stateDisable button + show spinner during submission

Connected Skills

  • tsh-implementing-frontend — for component composition patterns and framework-specific references (form library integration, validation library choice)
  • tsh-ensuring-accessibility — for WCAG compliance in form fields, labels, and error announcements
  • tsh-writing-hooks — for custom form-related hooks/composables (useFormField, useMultiStepForm)
  • tsh-reviewing-frontend — for form-specific review criteria during code review

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
266
Repository forks
18
7-day trend score
28

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/thesoftwarehouse/copilot-collections/tsh-implementing-forms/badge)](https://verified-skill.com/skills/thesoftwarehouse/copilot-collections/tsh-implementing-forms)

Something wrong with this skill or its page? Tell us.