@liveschema/react
v1.1.3
Published
React bindings for liveschema. `useLiveSchema(schema, values)` returns every declared field with an `isReachable` flag and enum options, the reachable subset, and an `isReachableField(key)` predicate for conditional rendering.
Downloads
90
Maintainers
Readme
@liveschema/react
React bindings for @liveschema/core. The useLiveSchema() hook walks a liveschema definition against your form's current values on every render and exposes the live reachable-field set — gate JSX with a predicate or iterate the reachable subset.
Install
pnpm add @liveschema/core @liveschema/react zodDefine a schema
Schemas are plain @liveschema/core definitions — defineSchema() plus .field() / .when() (see core for the full API). A minimal schema.ts:
import { z } from 'zod'
import { defineSchema } from '@liveschema/core'
export const schema = defineSchema()
.field('orderType', z.enum(['pickup', 'delivery']))
.when({ orderType: 'delivery' }, (b) => b.field('paymentMethod', z.enum(['card', 'cash'])))paymentMethod only becomes reachable once orderType is 'delivery' — exactly what the hook gates on below.
Usage
Example with react-hook-form
import { useForm, useWatch } from 'react-hook-form'
import { standardSchemaResolver } from '@hookform/resolvers/standard-schema'
import { toStandardSchema } from '@liveschema/core'
import { useLiveSchema } from '@liveschema/react'
import { schema } from './schema'
export function MyForm() {
const { register, control } = useForm({
resolver: standardSchemaResolver(toStandardSchema(schema)),
})
const values = useWatch({ control })
const { fields, isReachableField } = useLiveSchema(schema, values)
return (
<form>
{fields.orderType.enumOptions?.map((o) => (
<label key={o}>
<input type="radio" value={o} {...register('orderType')} />
{o}
</label>
))}
{isReachableField('paymentMethod') &&
fields.paymentMethod.enumOptions?.map((o) => (
<label key={o}>
<input type="radio" value={o} {...register('paymentMethod')} />
{o}
</label>
))}
</form>
)
}Return shape
| Property | Type | Meaning |
| ------------------ | -------------------------------------------- | --------------------------------------------------------------------- |
| fields | Record<Key, { isReachable; enumOptions? }> | Every declared field, keyed by name, in schema order. |
| reachableFields | Partial<typeof fields> | The currently-reachable subset; unreachable keys are absent. |
| isReachableField | (key) => boolean | Predicate equivalent to key in reachableFields. Use for JSX gating. |
Keys are typed via SchemaKeys<typeof schema>, so isReachableField('typo') is a compile error. enumOptions is only present on enum-like fields — accessing it on a string/boolean field is a compile error rather than undefined.
If you need the underlying validators (e.g. for per-field "Next"-button validation in a wizard), reach for reachableFields(schema, values) from @liveschema/core alongside the hook.
Examples
- examples/tanstack-form-example — React + TanStack Form (single-page)
