page.tsx 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. import Link from "next/link";
  2. import { Code } from "@/components/code";
  3. export const metadata = {
  4. title: "Schemas | json-render",
  5. };
  6. export default function SchemasPage() {
  7. return (
  8. <article>
  9. <h1 className="text-3xl font-bold mb-4">Schemas</h1>
  10. <p className="text-muted-foreground mb-8">
  11. Schemas define the structure and validation rules for your UI specs.
  12. </p>
  13. <h2 className="text-xl font-semibold mt-12 mb-4">What is a Schema?</h2>
  14. <p className="text-sm text-muted-foreground mb-4">
  15. A schema defines the JSON structure that describes your UI. It includes:
  16. </p>
  17. <ul className="list-disc list-inside text-sm text-muted-foreground space-y-1 mb-4">
  18. <li>
  19. <strong className="text-foreground">Element structure</strong> — How
  20. components are nested and referenced
  21. </li>
  22. <li>
  23. <strong className="text-foreground">Property types</strong> — What
  24. props each component accepts
  25. </li>
  26. <li>
  27. <strong className="text-foreground">Data binding syntax</strong> — How
  28. to reference dynamic data
  29. </li>
  30. <li>
  31. <strong className="text-foreground">Action format</strong> — How user
  32. interactions are defined
  33. </li>
  34. </ul>
  35. <h2 className="text-xl font-semibold mt-12 mb-4">
  36. Schema-Agnostic by Design
  37. </h2>
  38. <p className="text-sm text-muted-foreground mb-4">
  39. json-render can work with any JSON schema.{" "}
  40. <code className="text-foreground">@json-render/core</code> provides the
  41. primitives to define catalogs and renderers for any format:
  42. </p>
  43. <ul className="list-disc list-inside text-sm text-muted-foreground space-y-1 mb-4">
  44. <li>
  45. <strong className="text-foreground">@json-render/react</strong> — The
  46. built-in flat element tree schema
  47. </li>
  48. <li>
  49. <strong className="text-foreground">
  50. <Link href="/docs/a2ui" className="hover:underline">
  51. A2UI
  52. </Link>
  53. </strong>{" "}
  54. — Google{"'"}s Agent-to-User Interaction protocol
  55. </li>
  56. <li>
  57. <strong className="text-foreground">
  58. <Link href="/docs/adaptive-cards" className="hover:underline">
  59. Adaptive Cards
  60. </Link>
  61. </strong>{" "}
  62. — Microsoft{"'"}s platform-agnostic UI format
  63. </li>
  64. <li>
  65. <strong className="text-foreground">AG-UI</strong> — CopilotKit{"'"}s
  66. Agent User Interaction Protocol
  67. </li>
  68. <li>
  69. <strong className="text-foreground">OpenAPI/Swagger</strong> — API
  70. documentation schemas for dynamic forms
  71. </li>
  72. <li>
  73. <strong className="text-foreground">Custom schemas</strong> — Design
  74. your own format tailored to your domain
  75. </li>
  76. </ul>
  77. <p className="text-sm text-muted-foreground mb-4">
  78. See the{" "}
  79. <Link
  80. href="/docs/custom-schema"
  81. className="text-foreground hover:underline"
  82. >
  83. Custom Schema guide
  84. </Link>{" "}
  85. to learn how to implement support for any schema.
  86. </p>
  87. <h2 className="text-xl font-semibold mt-12 mb-4">Built-in Schema</h2>
  88. <p className="text-sm text-muted-foreground mb-4">
  89. <code className="text-foreground">@json-render/react</code> uses a flat
  90. element tree schema with a root key and elements map:
  91. </p>
  92. <Code lang="json">{`{
  93. "root": "card-1",
  94. "elements": {
  95. "card-1": {
  96. "key": "card-1",
  97. "type": "Card",
  98. "props": { "title": "Dashboard" },
  99. "children": ["text-1", "button-1"],
  100. "parentKey": ""
  101. },
  102. "text-1": {
  103. "key": "text-1",
  104. "type": "Text",
  105. "props": { "content": "Welcome, $data.user.name" },
  106. "children": [],
  107. "parentKey": "card-1"
  108. },
  109. "button-1": {
  110. "key": "button-1",
  111. "type": "Button",
  112. "props": { "label": "Click me" },
  113. "children": [],
  114. "parentKey": "card-1"
  115. }
  116. }
  117. }`}</Code>
  118. <h2 className="text-xl font-semibold mt-12 mb-4">Schema Components</h2>
  119. <h3 className="text-lg font-medium mt-8 mb-3">Element Structure</h3>
  120. <p className="text-sm text-muted-foreground mb-4">
  121. In the built-in schema, each element in the elements map has this
  122. structure:
  123. </p>
  124. <Code lang="typescript">{`interface Element {
  125. key: string; // Unique identifier
  126. type: string; // Component type from catalog
  127. props: Record<string, any>; // Component properties
  128. children: string[]; // Array of child element keys
  129. parentKey: string; // Parent element key (empty for root)
  130. visible?: VisibilityRule; // Conditional display
  131. }`}</Code>
  132. <h3 className="text-lg font-medium mt-8 mb-3">Data Binding Syntax</h3>
  133. <p className="text-sm text-muted-foreground mb-4">
  134. Reference dynamic data using the{" "}
  135. <code className="text-foreground">$data</code> prefix in props:
  136. </p>
  137. <Code lang="json">{`{
  138. "key": "greeting",
  139. "type": "Text",
  140. "props": {
  141. "content": "$data.user.name",
  142. "count": "$data.items.length"
  143. },
  144. "children": [],
  145. "parentKey": "card-1"
  146. }`}</Code>
  147. <h3 className="text-lg font-medium mt-8 mb-3">Action Format</h3>
  148. <p className="text-sm text-muted-foreground mb-4">
  149. Actions are defined in the catalog and referenced from components. The
  150. renderer handles action execution:
  151. </p>
  152. <Code lang="typescript">{`// In your catalog
  153. actions: {
  154. navigate: {
  155. params: z.object({ url: z.string() }),
  156. description: 'Navigate to a URL',
  157. },
  158. apiCall: {
  159. params: z.object({
  160. endpoint: z.string(),
  161. method: z.enum(['GET', 'POST', 'PUT', 'DELETE']),
  162. }),
  163. description: 'Make an API request',
  164. },
  165. }`}</Code>
  166. <h2 className="text-xl font-semibold mt-12 mb-4">Custom Schemas</h2>
  167. <p className="text-sm text-muted-foreground mb-4">
  168. <code className="text-foreground">@json-render/core</code> is
  169. schema-agnostic. You can define any JSON structure:
  170. </p>
  171. <Code lang="typescript">{`import { z } from 'zod';
  172. // Define your own element schema
  173. const MyElementSchema = z.object({
  174. component: z.string(),
  175. settings: z.record(z.unknown()),
  176. nested: z.array(z.lazy(() => MyElementSchema)).optional(),
  177. });
  178. // Define your own data binding format
  179. const BoundValue = z.object({
  180. literal: z.string().optional(),
  181. path: z.string().optional(), // e.g., "/users/0/name"
  182. });
  183. // Define your own action format
  184. const ActionSchema = z.object({
  185. name: z.string(),
  186. context: z.record(z.unknown()).optional(),
  187. });`}</Code>
  188. <h2 className="text-xl font-semibold mt-12 mb-4">Schema vs Catalog</h2>
  189. <p className="text-sm text-muted-foreground mb-4">
  190. The schema and catalog work together but serve different purposes:
  191. </p>
  192. <ul className="list-disc list-inside text-sm text-muted-foreground space-y-1 mb-4">
  193. <li>
  194. <strong className="text-foreground">Schema</strong> — Defines the JSON
  195. structure (how elements are organized)
  196. </li>
  197. <li>
  198. <strong className="text-foreground">Catalog</strong> — Defines
  199. available components and their props (what can be used)
  200. </li>
  201. </ul>
  202. <p className="text-sm text-muted-foreground mb-4">
  203. The schema is the grammar; the catalog is the vocabulary.
  204. </p>
  205. <h2 className="text-xl font-semibold mt-12 mb-4">Next</h2>
  206. <p className="text-sm text-muted-foreground">
  207. Learn about{" "}
  208. <Link href="/docs/specs" className="text-foreground hover:underline">
  209. specs
  210. </Link>{" "}
  211. — the actual JSON documents that describe your UI.
  212. </p>
  213. </article>
  214. );
  215. }