@modyra/preact
v0.8.0
Published
Preact binding for the Modyra form engine — a thin variant of the React adapter on preact/hooks.
Maintainers
Readme
@modyra/preact
Preact binding for the Modyra form
engine — a thin variant of @modyra/react: same vanillaReactivity() +
useSyncExternalStore pattern, ported to preact/hooks and
preact/compat.
Headless. This package renders no markup — you bring your own. Modyra's DOM conformance suites (anatomy, state matrix, renderer equivalence) check the three adapters that do render; they do not apply here, because there is no part to find and no rendered state to compare. What this package promises — value, validation, error and lifecycle semantics — is checked by its own suites and the shared reactivity capability tests. Accessibility and theming are yours;
@modyra/widgetsexports the same projections, id policy and class vocabulary the rendering adapters use, so your markup can be built from the contract rather than guessed.
npm install @modyra/preactimport { useMdyForm, useMdyField } from "@modyra/preact";
import { field, required } from "@modyra/core";
function SignupForm() {
const form = useMdyForm(() => ({ email: field("", [required()]) }));
const email = useMdyField(form.f.email);
return (
<input
value={email.value}
onChange={(e) => form.f.email.set(e.currentTarget.value)}
onBlur={email.markAsTouched}
/>
);
}What's included
useMdyForm(schemaFn, options?)— one typed form per component instance, destroyed on unmount.useMdyField(handle)— subscribes to a single field viauseSyncExternalStore(frompreact/compat).createStore/createFieldStore— the framework-free store the hooks wrap, directly testable in Node with no Preact renderer.- The headless widgets bridge —
useMdyTextField/useMdySelect/useMdyCommandQueuefrom@modyra/widgets' controllers, same shape as the React adapter's (only the hook import source differs:preact/hooksinstead ofreact). - The full core API —
field,group,array,serverValidator,crossField, drafts, undo/redo… re-exported from@modyra/core.
Headless recipes
The shadcn/Radix prop-mapper recipes in
docs/guides/headless-recipes.md
work unchanged: they only touch the framework-agnostic field handle, never
a React/Preact API. packages/preact/test/headless-recipes.test.mjs is the
React adapter's suite ported verbatim, proving the claim rather than just
asserting it.
License
MIT © Lorenzo Muscherà
