Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ out/
build
dist
*.tsbuildinfo
.svelte-kit/


# Debug
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,9 @@ pnpm dev
- http://react-email-demo.json-render.localhost:1355 - React Email Example
- http://remotion-demo.json-render.localhost:1355 - Remotion Video Example
- Chat Example: run `pnpm dev` in `examples/chat`
- Svelte Example: run `pnpm dev` in `examples/svelte` or `examples/svelte-chat`
- Vue Example: run `pnpm dev` in `examples/vue`
- Vite Renderers (React + Vue): run `pnpm dev` in `examples/vite-renderers`
- Vite Renderers (React + Vue + Svelte): run `pnpm dev` in `examples/vite-renderers`
- React Native example: run `npx expo start` in `examples/react-native`

## How It Works
Expand Down
126 changes: 126 additions & 0 deletions apps/web/app/(main)/docs/api/svelte/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("docs/api/svelte")

# @json-render/svelte

Svelte 5 components, providers, and helpers for rendering json-render specs.

## Installation

<PackageInstall packages="@json-render/core @json-render/svelte" />

Peer dependencies: `svelte ^5.0.0` and `zod ^4.0.0`.

<PackageInstall packages="svelte zod" />

## Components

### Renderer

```svelte
<Renderer
spec={spec} // Spec | null
registry={registry}
loading={false}
/>
```

Renders a spec with your component registry. If `spec` is `null`, it renders nothing.

### JsonUIProvider

Convenience wrapper around `StateProvider`, `VisibilityProvider`, `ValidationProvider`, and `ActionProvider`.

```svelte
<JsonUIProvider
initialState={{}}
handlers={handlers}
validationFunctions={validationFunctions}
>
<Renderer {spec} {registry} />
</JsonUIProvider>
```

## defineRegistry

Create a typed component registry and action handlers from a catalog.

```typescript
import { defineRegistry } from "@json-render/svelte";

const { registry, handlers, executeAction } = defineRegistry(catalog, {
components: {
Card,
Button,
},
actions: {
submit: async (params, setState, state) => {
// custom action logic
},
},
});
```

`handlers` is designed for `JsonUIProvider`/`ActionProvider`. `executeAction` is an imperative helper.

## Component Props

Registry components receive `BaseComponentProps<TProps>`:

```typescript
interface BaseComponentProps<TProps> {
props: TProps;
children?: Snippet;
emit: (event: string) => void;
bindings?: Record<string, string>;
loading?: boolean;
}
```

Use `emit("eventName")` to trigger handlers declared in the spec `on` bindings.

## Context Helpers

Use these helpers inside Svelte components:

- `getStateValue(path)` - read/write state via `.current`
- `getBoundProp(() => value, () => bindingPath)` - write back resolved `$bindState` / `$bindItem` values
- `isVisible(condition)` - evaluate visibility via `.current`
- `getAction(name)` - read a registered action handler via `.current`
- `getFieldValidation(ctx, path, config)` - get field validation state + actions

For advanced usage, access full contexts:

- `getStateContext()`
- `getActionContext()`
- `getVisibilityContext()`
- `getValidationContext()`
- `getOptionalValidationContext()`

## Streaming

### createUIStream

```typescript
const stream = createUIStream({
api: "/api/generate-ui",
onComplete: (spec) => console.log(spec),
});

await stream.send("Create a login form");

console.log(stream.spec);
console.log(stream.isStreaming);
```

### createChatUI

```typescript
const chat = createChatUI({ api: "/api/chat-ui" });
await chat.send("Build a settings panel");
console.log(chat.messages, chat.isStreaming);
```

## Schema Export

Use `schema` from `@json-render/svelte` when defining catalogs for Svelte specs.
8 changes: 8 additions & 0 deletions apps/web/app/(main)/docs/installation/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ Peer dependencies: `vue ^3.5.0` and `zod ^4.0.0`.

<PackageInstall packages="vue zod" />

## For Svelte

<PackageInstall packages="@json-render/core @json-render/svelte" />

Peer dependencies: `svelte ^5.0.0` and `zod ^4.0.0`.

<PackageInstall packages="svelte zod" />

## For React UI with shadcn/ui

Pre-built components for fast prototyping and production use:
Expand Down
8 changes: 7 additions & 1 deletion apps/web/lib/docs-navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,18 @@ export const docsNavigation: NavSection[] = [
href: "https://github.com/vercel-labs/json-render/tree/main/examples/image",
external: true,
},
{
title: "Svelte",
href: "https://github.com/vercel-labs/json-render/tree/main/examples/svelte",
external: true,
},
{
title: "Vue",
href: "https://github.com/vercel-labs/json-render/tree/main/examples/vue",
external: true,
},
{
title: "Renders with Vite (Vue / React)",
title: "Renders with Vite (Vue / React / Svelte)",
href: "https://github.com/vercel-labs/json-render/tree/main/examples/vite-renderers",
external: true,
},
Expand Down Expand Up @@ -121,6 +126,7 @@ export const docsNavigation: NavSection[] = [
{ title: "@json-render/image", href: "/docs/api/image" },
{ title: "@json-render/remotion", href: "/docs/api/remotion" },
{ title: "@json-render/vue", href: "/docs/api/vue" },
{ title: "@json-render/svelte", href: "/docs/api/svelte" },
{ title: "@json-render/codegen", href: "/docs/api/codegen" },
],
},
Expand Down
1 change: 1 addition & 0 deletions apps/web/lib/page-titles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const PAGE_TITLES: Record<string, string> = {
"docs/api/react-pdf": "@json-render/react-pdf API",
"docs/api/react-email": "@json-render/react-email API",
"docs/api/react-native": "@json-render/react-native API",
"docs/api/svelte": "@json-render/svelte API",
"docs/api/codegen": "@json-render/codegen API",
"docs/api/image": "@json-render/image API",
"docs/api/remotion": "@json-render/remotion API",
Expand Down
2 changes: 1 addition & 1 deletion examples/react-email/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"react-resizable-panels": "^4.4.1",
"tailwind-merge": "^3.5.0",
"tailwindcss": "^4.1.18",
"zod": "4.3.5"
"zod": "4.3.6"
},
"devDependencies": {
"@internal/typescript-config": "workspace:*",
Expand Down
23 changes: 23 additions & 0 deletions examples/svelte-chat/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
node_modules

# Output
.output
.vercel
.netlify
.wrangler
/.svelte-kit
/build

# OS
.DS_Store
Thumbs.db

# Env
.env
.env.*
!.env.example
!.env.test

# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
1 change: 1 addition & 0 deletions examples/svelte-chat/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
engine-strict=true
42 changes: 42 additions & 0 deletions examples/svelte-chat/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# sv

Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).

## Creating a project

If you're seeing this, you've probably already done this step. Congrats!

```sh
# create a new project
npx sv create my-app
```

To recreate this project with the same configuration:

```sh
# recreate this project
npx sv create --template minimal --types ts --no-install svelte-chat
```

## Developing

Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:

```sh
npm run dev

# or start the server and open the app in a new browser tab
npm run dev -- --open
```

## Building

To create a production version of your app:

```sh
npm run build
```

You can preview the production build with `npm run preview`.

> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
16 changes: 16 additions & 0 deletions examples/svelte-chat/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "https://shadcn-svelte.com/schema.json",
"tailwind": {
"css": "src/app.css",
"baseColor": "zinc"
},
"aliases": {
"components": "$lib/components",
"utils": "$lib/utils",
"ui": "$lib/components/ui",
"hooks": "$lib/hooks",
"lib": "$lib"
},
"typescript": true,
"registry": "https://shadcn-svelte.com/registry"
}
39 changes: 39 additions & 0 deletions examples/svelte-chat/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "svelte-chat",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"prepare": "svelte-kit sync || echo ''",
"check-types": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"@internationalized/date": "^3.10.0",
"@lucide/svelte": "^0.561.0",
"@sveltejs/adapter-auto": "^7.0.0",
"@sveltejs/kit": "^2.50.2",
"@sveltejs/vite-plugin-svelte": "^6.2.4",
"@tailwindcss/vite": "^4.0.0",
"bits-ui": "^2.14.4",
"svelte": "^5.49.2",
"svelte-check": "^4.3.6",
"tailwind-variants": "^3.2.2",
"tailwindcss": "^4.0.0",
"typescript": "^5.9.3",
"vite": "^7.3.1"
},
"dependencies": {
"@ai-sdk/gateway": "^3.0.46",
"@ai-sdk/svelte": "^4.0.96",
"@json-render/core": "workspace:*",
"@json-render/svelte": "workspace:*",
"ai": "^6.0.86",
"clsx": "^2.1.1",
"lucide-svelte": "^0.500.0",
"tailwind-merge": "^3.2.0",
"zod": "4.3.6"
}
}
Loading