@trevelabs/formwire-react
v0.1.2
Published
Drop-in, accessible React form component for Formwire forms.
Maintainers
Readme
@trevelabs/formwire-react
Drop-in, accessible React form component for Formwire. It fetches a form's public schema at runtime and renders a validated, submittable form — no codegen, no build step.
npm install @trevelabs/formwire-reactimport { FormwireForm } from "@trevelabs/formwire-react";
export function Contact() {
return (
<FormwireForm formId="<FORM_ID>" baseUrl="https://your-formwire-host" />
);
}Prefer to own and edit the markup instead? Use the formwire CLI
(npx formwire-cli add <id>) to generate a shadcn/ui component into your project.
Features
- Schema-driven — renders text, email, tel, number, textarea, select, radio, and checkbox fields from the form definition.
- Validation — builds a Zod schema (required, email, option membership) and validates with React Hook Form.
- Accessible — associated labels,
aria-invalid,aria-describedby, androle="alert"errors. - Spam protection — includes the configured honeypot field and renders a Cloudflare Turnstile widget when the form requires it.
- Server errors — surfaces
422validationdetailsback onto fields. - Unstyled by default — semantic markup with
data-formwire-*hooks and aclassNamesAPI, so you can style it with Tailwind, CSS, or your design system. - Next.js ready — ships the
"use client"directive and dual ESM/CJS builds.
Props
| Prop | Type | Description |
| --------------- | ---------------------- | ---------------------------------------------- |
| formId | string | The Formwire form ID (required). |
| baseUrl | string | Formwire submissions host. Default https://api.formwire.dev. |
| className | string | Class for the <form> element. |
| classNames | FormwireClassNames | Per-part class overrides. |
| onSuccess | (values) => void | Called after a successful submission. |
| onError | (error) => void | Called on load/submit failure. |
| renderLoading | () => ReactNode | Custom loading node. |
| renderError | (error) => ReactNode | Custom load-error node. |
Styling
The markup is unstyled. Target the data attributes:
[data-formwire-form] {
display: flex;
flex-direction: column;
gap: 1rem;
}
[data-formwire-error] {
color: crimson;
}…or pass class names per part:
<FormwireForm
formId="<FORM_ID>"
classNames={{
field: "flex flex-col gap-1.5",
label: "text-sm font-medium",
control: "rounded-md border px-3 py-2",
error: "text-sm text-red-600",
submit: "rounded-md bg-black px-4 py-2 text-white",
}}
/>Parts: form, field, label, requiredMark, control, help, error,
radioGroup, radioOption, checkboxField, checkboxLabel, submit,
success, formError.
Development
pnpm install
pnpm build # dual ESM/CJS + types via tsup
pnpm typecheck
pnpm test
pnpm lint:package # publint + are-the-types-wrong