solid

bởi vercel

Trình kết xuất SolidJS cho json-render. Sử dụng khi xây dựng danh mục/registry @json-render/solid, kết nối các nhà cung cấp Renderer, triển khai bindings/actions, hoặc…

npx skills add https://github.com/vercel-labs/json-render --skill solid

@json-render/solid

@json-render/solid renders json-render specs into Solid component trees with fine-grained reactivity.

Quick Start

import { Renderer, JSONUIProvider } from "@json-render/solid";
import type { Spec } from "@json-render/solid";
import { registry } from "./registry";

export function App(props: { spec: Spec | null }) {
  return (
    <JSONUIProvider registry={registry} initialState={{}}>
      <Renderer spec={props.spec} registry={registry} />
    </JSONUIProvider>
  );
}

Create a Catalog

import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/solid/schema";
import { z } from "zod";

export const catalog = defineCatalog(schema, {
  components: {
    Button: {
      props: z.object({
        label: z.string(),
        variant: z.enum(["primary", "secondary"]).nullable(),
      }),
      description: "Clickable button",
    },
    Card: {
      props: z.object({ title: z.string() }),
      description: "Card container",
    },
  },
  actions: {
    submit: { description: "Submit data" },
  },
});

Define Components

Components receive ComponentRenderProps from the renderer:

interface ComponentRenderProps<P = Record<string, unknown>> {
  element: UIElement<string, P>;
  children?: JSX.Element;
  emit: (event: string) => void;
  on: (event: string) => EventHandle;
  bindings?: Record<string, string>;
  loading?: boolean;
}

Example:

import type { BaseComponentProps } from "@json-render/solid";

export function Button(props: BaseComponentProps<{ label: string }>) {
  return (
    <button onClick={() => props.emit("press")}>{props.props.label}</button>
  );
}

Create a Registry

import { defineRegistry } from "@json-render/solid";
import { catalog } from "./catalog";
import { Card } from "./Card";
import { Button } from "./Button";

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

Spec Structure

{
  "root": "card1",
  "elements": {
    "card1": {
      "type": "Card",
      "props": { "title": "Hello" },
      "children": ["btn1"]
    },
    "btn1": {
      "type": "Button",
      "props": { "label": "Click me" },
      "on": {
        "press": { "action": "submit" }
      }
    }
  }
}

Providers

  • StateProvider: state model read/write and controlled mode via store
  • VisibilityProvider: evaluates visible conditions
  • ValidationProvider: field validation + validateForm integration
  • ActionProvider: runs built-in and custom actions
  • JSONUIProvider: combined provider wrapper

Hooks

  • useStateStore, useStateValue, useStateBinding
  • useVisibility, useIsVisible
  • useActions, useAction
  • useValidation, useOptionalValidation, useFieldValidation
  • useBoundProp
  • useUIStream, useChatUI

Built-in Actions

Handled automatically by ActionProvider:

  • setState
  • pushState
  • removeState
  • validateForm

Dynamic Props and Bindings

Supported expression forms include:

  • {"$state": "/path"}
  • {"$bindState": "/path"}
  • {"$bindItem": "field"}
  • {"$template": "Hi ${/user/name}"}
  • {"$computed": "fn", "args": {...}}
  • {"$cond": <condition>, "$then": <value>, "$else": <value>}

Use useBoundProp in components for writable bound values:

import { useBoundProp } from "@json-render/solid";

function Input(props: BaseComponentProps<{ value?: string }>) {
  const [value, setValue] = useBoundProp(
    props.props.value,
    props.bindings?.value,
  );
  return (
    <input
      value={String(value() ?? "")}
      onInput={(e) => setValue(e.currentTarget.value)}
    />
  );
}

useStateValue, useStateBinding, and the state / errors / isValid fields from useFieldValidation are reactive accessors in Solid. Call them as functions inside JSX, createMemo, or createEffect.

Solid Reactivity Rules

  • Do not destructure component props in function signatures when values need to stay reactive.
  • Keep changing reads inside JSX expressions, createMemo, or createEffect.
  • Context values are exposed through getter-based objects so consumers always observe live signals.

Streaming UI

import { useUIStream, Renderer } from "@json-render/solid";

const stream = useUIStream({ api: "/api/generate-ui" });
await stream.send("Create a support dashboard");

<Renderer
  spec={stream.spec}
  registry={registry}
  loading={stream.isStreaming}
/>;

Use useChatUI for chat + UI generation flows.

Thêm skills từ vercel

benchmark-sandbox
vercel
Chạy các kịch bản đánh giá vercel-plugin trong Vercel Sandboxes thay vì các bảng WezTerm cục bộ. Cung cấp các microVM tạm thời với Claude Code và plugin được cài đặt sẵn,…
official
emil-design-eng
vercel
Kỹ năng này mã hóa triết lý của Emil Kowalski về trau chuốt giao diện người dùng, thiết kế thành phần, quyết định hoạt ảnh và những chi tiết vô hình giúp phần mềm mang lại cảm giác tuyệt vời.
official
vercel-react-best-practices
vercel
Hướng dẫn tối ưu hiệu suất React và Next.js từ Vercel Engineering. Kỹ năng này nên được sử dụng khi viết, xem xét hoặc tái cấu trúc mã React/Next.js…
official
vercel-react-best-practices
vercel
Hướng dẫn tối ưu hiệu suất React và Next.js từ Vercel Engineering. Kỹ năng này nên được sử dụng khi viết, xem xét hoặc tái cấu trúc mã React/Next.js…
official
write-guide
vercel
Tạo một hướng dẫn kỹ thuật dạy một trường hợp sử dụng thực tế thông qua các ví dụ tiến dần. Các khái niệm chỉ được giới thiệu khi người đọc cần đến chúng.
official
release
vercel
Phát hành vercel-plugin — chạy các cổng, tăng phiên bản, tạo tạo phẩm, commit và push. Sử dụng khi được yêu cầu "phát hành", "ship", "tăng và push", hoặc "cắt một bản phát hành".
official
deepsec
vercel
Chạy DeepSec trên bản checkout dự án Vercel từ dev3000. Sử dụng để thiết lập DeepSec một chạm, khởi tạo ngữ cảnh dự án, xử lý lần đầu có giới hạn, và…
official
backport-pr
vercel
Backport một pull request Next.js đã được merge từ canary sang một nhánh phát hành trước đó như next-16-2. Sử dụng khi người dùng yêu cầu backport, cherry-pick, hoặc mở một…
official