This repository contains a small form-builder app built with React, TypeScript and Vite. The app renders forms from JSON schemas and includes schema-driven validation, accessible error UI, and modular field components.
Key tech:
- React 19 + TypeScript
- Vite (dev server + build)
- TanStack Router for routing
- Vitest for tests
Recommended package manager: pnpm
Open a PowerShell terminal in the project root and run:
pnpm install
pnpm devThe dev server runs via Vite (default port configured in package.json is 3000). To build for production:
pnpm build
pnpm serve # preview the production build (vite preview)Run tests with:
pnpm testFormatting and linting:
pnpm format
pnpm lint
pnpm checkNote: scripts are defined in package.json (dev, build, serve, test, lint, format, check).
src/main.tsx— application entrysrc/routes/— file-based routes (TanStack Router)src/components/form/FormBuilder.tsx— main dynamic form renderersrc/components/form/index.module.css— form stylessrc/components/fields/— individual field components (text, textarea, select, radio, checkbox, switch, multiselect)src/Types/formSchemas.ts— example form schemas and rule examplessrc/utils/andsrc/validators/— helpers and schema-driven validation logic
If you're looking to add or modify fields, check src/components/fields and the FieldRenderer that decides which field component to render.
Forms are defined by JSON-like schemas (see src/Types/formSchemas.ts). Individual fields may include a rules object for validation. The validator module reads field.rules and applies registered validators, returning messages defined in the schema when available.
Examples:
required,minLength,maxLength,pattern,min,max, andcustomvalidators are supported.
Validation messages are shown inline and include an accessible error icon and role="alert" for screen readers.
Error UI and labels are implemented with accessibility in mind:
- Field-level errors are rendered in a container with
role="alert"andaria-live="assertive". - Checkbox, radio and other input labels are associated with inputs using
id/htmlForso clicking the label toggles the control.
This project uses file-based routing. Add a new file under src/routes/ and export a route as shown in the project examples. See TanStack Router docs for details.
- Create a new field component in
src/components/fields/. - Export it from
src/components/fields/index.ts. - Update
FieldRenderer.tsxto handle the new renderer type (or extend the factory mapping).
- If the dev server port is already in use, either stop the process using it or run Vite with a different port:
pnpm dev -- --port 4000- If TypeScript complains about missing types after adding libraries, run
pnpm add -D @types/your-librarywhen available or updatetsconfig.jsonpaths.
Small, focused PRs are easiest to review. If you plan larger changes (new validation features, async validators, or a visual redesign), open an issue first so we can discuss the approach.