import { pageMetadata } from "@/lib/page-metadata";
export const metadata = pageMetadata("docs/api/solid");
# @json-render/solid
SolidJS components, providers, and hooks for rendering json-render specs.
## Installation
Peer dependencies: `solid-js ^1.9.0` and `zod ^4.0.0`.
## Providers
### StateProvider
```tsx
console.log(changes)}
>
{/* children */}
```
Prop
Type
Description
store
StateStore
External store (controlled mode). When provided,{" "}
initialState and onStateChange are ignored.
initialState
Record<string, unknown>
Initial state model for uncontrolled mode.
onStateChange
{"(changes: Array<{ path: string; value: unknown }>) => void"}
Called for uncontrolled state updates.
### ActionProvider
```tsx
{} }}
navigate={(path) => {}}
>
{/* children */}
```
### VisibilityProvider
```tsx
{/* children */}
```
### ValidationProvider
```tsx
Boolean(value) }}>
{/* children */}
```
### JSONUIProvider
Combined provider wrapper for state, visibility, validation, and actions.
```tsx
```
## defineRegistry
Create a typed component registry and action helpers from a catalog.
```tsx
const { registry, handlers, executeAction } = defineRegistry(catalog, {
components: {
Card: (renderProps) => {renderProps.children}
,
Button: (renderProps) => (
renderProps.emit("press")}>
{renderProps.element.props.label as string}
),
},
actions: {
submit: async (params, setState, state) => {
// custom action logic
},
},
});
```
## Components
### Renderer
```tsx
```
Renders a `Spec` tree using your registry.
### createRenderer
Build an app-level renderer from catalog + components:
```tsx
const AppRenderer = createRenderer(catalog, {
Card: (renderProps) => {renderProps.children}
,
});
{}} />;
```
## Hooks
- `useStateStore()`
- `useStateValue(path)` - returns an accessor
- `useStateBinding(path)` - returns `[Accessor, setValue]`
- `useVisibility()` / `useIsVisible(condition)`
- `useActions()` / `useAction(binding)`
- `useValidation()` / `useOptionalValidation()`
- `useFieldValidation(path, config)` - returns accessor-backed `state`, `errors`, and `isValid`
- `useBoundProp(value, bindingPath)`
- `useUIStream(options)`
- `useChatUI(options)`
## Built-in Actions
`ActionProvider` handles these built-in actions:
- `setState`
- `pushState`
- `removeState`
- `validateForm`
## Component Props
Registry components receive:
```ts
interface ComponentRenderProps> {
element: UIElement;
children?: JSX.Element;
emit: (event: string) => void;
on: (event: string) => EventHandle;
bindings?: Record;
loading?: boolean;
}
```
Use `emit("event")` to dispatch event bindings. Use `on("event")` to access `EventHandle` metadata (`bound`, `shouldPreventDefault`, `emit`).
## Reactivity Notes
- Keep changing reads in JSX expressions, `createMemo`, or `createEffect`.
- Avoid props destructuring in component signatures when you need live updates.
- `StateProvider` and other contexts expose getter-backed values so consumers read live signals.
- `useStateValue`, `useStateBinding`, and `useFieldValidation` expose reactive accessors; call them as functions.