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

@inlayphp/forms-react

v0.3.11

Published

React renderer for Inlay PHP-first forms.

Readme

Inlay Forms for React

npm License

React renderer for Inlay PHP-first forms

@inlayphp/forms-react renders the inlay.forms.v1 contract produced by inlayphp/forms. It manages defaults, nested state, conditional visibility, errors, live events, optional Precognition validation and Inertia submission.

Install

pnpm add @inlayphp/forms-react @inlayphp/core @inertiajs/react react react-dom
composer require inlayphp/forms

Peer support targets Inertia React 3 and React 19.

Basic use

import { Form } from '@inlayphp/forms-react'
import type { FormErrors, FormResource } from '@inlayphp/forms-react'

type Props = { userForm: FormResource; errors: FormErrors }

export default function CreateUser({ userForm, errors }: Props) {
  return <Form resource={userForm} errors={errors} />
}

Without onSubmit, the component calls router.visit(resource.action) using the serialized method and current data. Submission does nothing when the action is null. Pass processing to disable the button and show “Saving…”.

Controlled application behavior

<Form
  resource={userForm}
  errors={errors}
  processing={saving}
  onChange={(data) => setDraft(data)}
  onSubmit={(data) => saveThroughApi(data)}
  onLiveChange={({ path, value, data, config }) => {
    updatePreview(path, value, data)
  }}
  onValidationError={(error) => report(error)}
/>

Providing onSubmit gives the application complete submission ownership. Initial data is computed by merging field defaults with resource.data; changing the resource resets local values and live-validation state.

Live validation

When PHP serializes a validation class and precognitive() configuration, the default validateWithPrecognition transport sends field-aware requests to the form action. Requests are cancelled when newer validation supersedes them, errors render inline, and the form exposes an accessible validating state.

Override the transport when necessary:

import type { FormValidator } from '@inlayphp/forms-react'

const validator: FormValidator = async ({ path, data, signal }) => {
  const response = await validateDraft({ path, data, signal })
  return response.errors
}

<Form resource={userForm} validator={validator} />

The validator returns Record<string, string>. PHP still owns the final authoritative validation.

Custom renderers

Wire component type values are renderer keys. Local renderers take precedence over Core registries and built-ins:

import type { SchemaComponentRenderer } from '@inlayphp/forms-react'

const CurrencyField: SchemaComponentRenderer = ({ component, path, value, update }) => (
  <label>
    {component.label}
    <input
      name={path}
      type="number"
      value={String(value ?? '')}
      onChange={(event) => update(path, Number(event.target.value))}
    />
  </label>
)

<Form
  resource={userForm}
  renderers={{ 'vendor-currency': CurrencyField }}
  registries={appRendererRegistries}
/>

Community payloads should set rendererCategory: "schema", "field", or "layout". Registry sets expose separate schema.get(type), field.get(type), and layout.get(type) lookups. Schema content does not receive a form state path. Custom renderers receive the same values, errors, update/live functions and nested renderer context.

SchemaRenderer is exported for advanced composition. evaluateCondition, validateWithPrecognition, all wire-resource types and renderer context types are public exports.

Theme and styling

<Form
  resource={userForm}
  className="max-w-3xl"
  theme={{
    accent: '#7c3aed',
    radius: '0.75rem',
    surface: '#ffffff',
    surfaceMuted: '#f4f4f5',
    foreground: '#18181b',
    muted: '#71717a',
    border: 'rgb(24 24 27 / 0.12)',
    danger: '#dc2626',
  }}
/>

Theme values become inherited --inlay-* variables and otherwise fall back to panel/default variables. Markup includes stable data-contract, data-slot, and data-field attributes. Safe PHP extraAttributes are applied to wrappers; event handlers, raw HTML, style, refs and React internals are filtered.

For Tailwind CSS 4, make package source discoverable when it is outside normal application scanning:

@import 'tailwindcss';
@source '../../node_modules/@inlayphp/*/src/**/*.{ts,tsx,vue}';

The path is relative to the application stylesheet. The full Inlay installer adds this rule automatically.

Payload expectations

FormResource contains contract, name, action, method, columns, submitLabel, validation metadata, data and schema. Built-ins render every current PHP field and the shared Section/Grid/Group/Tabs/Wizard/Fieldset/Callout layouts.

Builder and Repeater rows receive opaque React-only keys so moving a row keeps its local editor, select, upload, and collapse state. These keys are renderer metadata, never form data: onSubmit receives the unchanged { type, data } item shape. Do not persist or validate a React key in application code.

Test, typecheck and build

pnpm test -- --run
pnpm typecheck
pnpm build

The build emits side-effect-free ESM and TypeScript declarations.

Related packages

  • inlayphp/forms: PHP builder and payload.
  • @inlayphp/forms-vue: Vue adapter for the same contract.
  • @inlayphp/core: renderer registries and URL utilities.
  • inlayphp/validation: centralized Laravel validation.