page.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import Link from "next/link";
  2. import { Button } from "@/components/ui/button";
  3. import { Demo } from "@/components/demo";
  4. export default function Home() {
  5. return (
  6. <>
  7. {/* Hero */}
  8. <section className="max-w-5xl mx-auto px-6 pt-24 pb-16 text-center">
  9. <h1 className="text-5xl md:text-7xl font-bold tracking-tighter mb-6">
  10. JSON becomes UI
  11. </h1>
  12. <p className="text-lg text-muted-foreground max-w-2xl mx-auto mb-12 leading-relaxed">
  13. Define a catalog. AI generates JSON. Your components render natively.
  14. </p>
  15. <Demo />
  16. <div className="flex gap-3 justify-center mt-12">
  17. <Button size="lg" asChild>
  18. <Link href="/docs">Get Started</Link>
  19. </Button>
  20. <Button size="lg" variant="outline" asChild>
  21. <a
  22. href="https://github.com/vercel-labs/json-render"
  23. target="_blank"
  24. rel="noopener noreferrer"
  25. >
  26. GitHub
  27. </a>
  28. </Button>
  29. </div>
  30. </section>
  31. {/* How it works */}
  32. <section className="border-t border-border">
  33. <div className="max-w-5xl mx-auto px-6 py-24">
  34. <div className="grid md:grid-cols-3 gap-12">
  35. <div>
  36. <div className="text-xs text-muted-foreground font-mono mb-3">01</div>
  37. <h3 className="text-lg font-semibold mb-2">Define Catalog</h3>
  38. <p className="text-sm text-muted-foreground leading-relaxed">
  39. Specify which components AI can use with Zod schemas. Full type safety and validation.
  40. </p>
  41. </div>
  42. <div>
  43. <div className="text-xs text-muted-foreground font-mono mb-3">02</div>
  44. <h3 className="text-lg font-semibold mb-2">Register Components</h3>
  45. <p className="text-sm text-muted-foreground leading-relaxed">
  46. Map catalog types to your React components. Use your own design system.
  47. </p>
  48. </div>
  49. <div>
  50. <div className="text-xs text-muted-foreground font-mono mb-3">03</div>
  51. <h3 className="text-lg font-semibold mb-2">Let AI Generate</h3>
  52. <p className="text-sm text-muted-foreground leading-relaxed">
  53. AI outputs JSON matching your schema. Stream it. Render progressively.
  54. </p>
  55. </div>
  56. </div>
  57. </div>
  58. </section>
  59. {/* Code example */}
  60. <section className="border-t border-border">
  61. <div className="max-w-5xl mx-auto px-6 py-24">
  62. <div className="grid lg:grid-cols-2 gap-12">
  63. <div>
  64. <h2 className="text-2xl font-semibold mb-4">Define your catalog</h2>
  65. <p className="text-muted-foreground mb-6">
  66. Components, actions, and validation functions. All type-safe with Zod.
  67. </p>
  68. <pre className="text-xs">
  69. <code>{`import { createCatalog } from '@json-render/core';
  70. import { z } from 'zod';
  71. export const catalog = createCatalog({
  72. components: {
  73. Card: {
  74. props: z.object({
  75. title: z.string(),
  76. description: z.string().nullable(),
  77. }),
  78. hasChildren: true,
  79. },
  80. Metric: {
  81. props: z.object({
  82. label: z.string(),
  83. valuePath: z.string(),
  84. format: z.enum(['currency', 'percent']),
  85. }),
  86. },
  87. },
  88. actions: {
  89. export: { params: z.object({ format: z.string() }) },
  90. },
  91. });`}</code>
  92. </pre>
  93. </div>
  94. <div>
  95. <h2 className="text-2xl font-semibold mb-4">AI generates JSON</h2>
  96. <p className="text-muted-foreground mb-6">
  97. Constrained output that your components render natively.
  98. </p>
  99. <pre className="text-xs">
  100. <code>{`{
  101. "key": "dashboard",
  102. "type": "Card",
  103. "props": {
  104. "title": "Revenue Dashboard",
  105. "description": null
  106. },
  107. "children": [
  108. {
  109. "key": "revenue",
  110. "type": "Metric",
  111. "props": {
  112. "label": "Total Revenue",
  113. "valuePath": "/metrics/revenue",
  114. "format": "currency"
  115. }
  116. }
  117. ]
  118. }`}</code>
  119. </pre>
  120. </div>
  121. </div>
  122. </div>
  123. </section>
  124. {/* Features */}
  125. <section className="border-t border-border">
  126. <div className="max-w-5xl mx-auto px-6 py-24">
  127. <h2 className="text-2xl font-semibold mb-12 text-center">Features</h2>
  128. <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-8">
  129. {[
  130. { title: "Guardrails", desc: "AI can only use components you define in the catalog" },
  131. { title: "Streaming", desc: "Progressive rendering as JSON streams from the model" },
  132. { title: "Data Binding", desc: "Two-way binding with JSON Pointer paths" },
  133. { title: "Actions", desc: "Named actions handled by your application" },
  134. { title: "Visibility", desc: "Conditional show/hide based on data or auth" },
  135. { title: "Validation", desc: "Built-in and custom validation functions" },
  136. ].map((feature) => (
  137. <div key={feature.title}>
  138. <h3 className="font-semibold mb-2">{feature.title}</h3>
  139. <p className="text-sm text-muted-foreground">{feature.desc}</p>
  140. </div>
  141. ))}
  142. </div>
  143. </div>
  144. </section>
  145. {/* CTA */}
  146. <section className="border-t border-border">
  147. <div className="max-w-4xl mx-auto px-6 py-24 text-center">
  148. <h2 className="text-2xl font-semibold mb-4">Get started</h2>
  149. <pre className="inline-block text-left mb-8 text-sm">
  150. <code>npm install @json-render/core @json-render/react</code>
  151. </pre>
  152. <Button asChild>
  153. <Link href="/docs">Documentation</Link>
  154. </Button>
  155. </div>
  156. </section>
  157. </>
  158. );
  159. }