npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@marktiderman/genesis-forms-react

v0.3.3

Published

React bindings for Genesis Forms: useForm, useField with one-field re-renders, a ranked renderer registry and a headless FormRuntime. Works in React DOM and React Native. Part of the Genesis framework.

Readme

@marktiderman/genesis-forms-react

React bindings for Genesis Forms. Headless: no markup, no styles. Works in React DOM and React Native.

| Export | What it does | | --- | --- | | useForm(form, options) | Creates an engine, and a new one when the definition changes identity (keep it stable: module scope or useMemo). options are read when an engine is created. | | useField(engine, id) | Value, error, visibility and recalled label for one field. Typing in one field re-renders that field only. | | useFormSelector(engine, select) | Subscribe to any slice of the form state. | | useChoiceOptions(engine, id) | The options a choice question shows now: all of them, or the ones its filter keeps given another answer (visibleOptions in genesis-forms). Re-renders only when that list changes. | | useRespondentPath(engine) | The blocks to render and count: the path without questions a link prefilled and hides (respondentPath in genesis-forms). | | createRendererRegistry(entries) | Field renderers by type or test, ranked: a higher rank overrides a built-in without forking. extend() returns a new registry; register() mutates this one in place. | | <FormRuntime>, <FieldRenderer id> | Provide the engine, the registry and a per-form id prefix (useId, so two forms on a page never share ids); render one field with whatever the registry resolves. A renderer gets inputId and, in a one-at-a-time layout, onAdvance, which it should call only for a deliberate pick (click, tap, Space or Enter), never for an arrow-key change. | | useFormController(engine, options) | The headless controller a renderer draws: the step on screen and the path, errors, Next and Back, sending with retry, auto-advance, saving progress, what to announce and where focus goes. <Form> in genesis-forms-web renders it; a native renderer renders the same one. See below. | | formEngineOptions(options, { hostOptions, linkParams }) | The engine options for a form that takes the host's option lists and the link's parameters beside its own. |

useFormController

const engine = useForm(form, formEngineOptions(options, { hostOptions, linkParams }));
const c = useFormController(engine, {
  layout,            // "focus" | "classic"; default: the definition's, else "classic"
  onSubmit,          // (engine) => void | Promise<void>; a rejection keeps the answers, phase "failed"
  onChange,          // (state, engine) => void, on every state change
  onProgress,        // with settings.saveProgress: (engine, formProgress) after each step
  autoAdvance,       // default true: c.onAdvance moves on after a single pick
  waitFor,           // () => message | null: hold Next and Send (an upload in flight)
  focus,             // (target) => void: move focus; the controller says when and to what
});

It returns:

| Field | | | --- | --- | | engine, definition, layout | What it runs. | | status, current, path, errors, errorList | The state to draw: the block on screen, the blocks to render (respondentPath), errors by id, and the invalid answers in order ({ id, label, message }). | | step, total, isLast, canGoBack, historyLength | Progress and the navigation's state. | | description, ending | The introduction with recall resolved; the Ending reached (or the first). | | phase, busy, failed, locked, showEnding | Sending: "idle", "sending", "sent" or "failed"; completed answers are locked; the ending shows once onSubmit resolved. | | saveProgress, announcement, direction | Whether answers save as they go; the latest live-region message; which way the last step went. | | advance(), submit(), back() | The controls. submit is what Enter, OK or Send does: advance in focus layout, send in classic. | | onAdvance, cancelAdvance() | For a field renderer's single pick (focus layout with autoAdvance), and to cancel it. | | flushProgress(), announce(message) | Send a pending save now (the page or app is going away); say something in the live region. |

focus gets { kind: "step", id } when a new question is on screen (focus layout; never on the first render), { kind: "ending" }, { kind: "errorSummary" } after a failed classic submit, and { kind: "submit" } after a failed send. Actions and options are read when they run, so passing new functions each render is fine and an action from an old render acts on the current one. A different engine starts the controller over.

For the ready-made web UI, use @marktiderman/genesis-forms-web.

License

MIT