| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- import { defineCatalog } from "@json-render/core";
- import { schema } from "@json-render/react/schema";
- import { z } from "zod";
- /**
- * Web playground component catalog
- *
- * This defines the components available for AI generation in the playground.
- * Components map to implementations in lib/catalog/components.tsx
- * Actions map to handlers in lib/catalog/actions.ts
- */
- export const playgroundCatalog = defineCatalog(schema, {
- components: {
- // Layout Components
- Card: {
- props: z.object({
- title: z.string().nullable(),
- description: z.string().nullable(),
- maxWidth: z.enum(["sm", "md", "lg", "full"]).nullable(),
- centered: z.boolean().nullable(),
- }),
- slots: ["default"],
- description:
- "Container card for content sections. Use for forms/content boxes, NOT for page headers.",
- },
- Stack: {
- props: z.object({
- direction: z.enum(["horizontal", "vertical"]).nullable(),
- gap: z.enum(["none", "sm", "md", "lg"]).nullable(),
- align: z.enum(["start", "center", "end", "stretch"]).nullable(),
- justify: z
- .enum(["start", "center", "end", "between", "around"])
- .nullable(),
- }),
- slots: ["default"],
- description: "Flex container for layouts",
- },
- Grid: {
- props: z.object({
- columns: z
- .union([
- z.literal(1),
- z.literal(2),
- z.literal(3),
- z.literal(4),
- z.literal(5),
- z.literal(6),
- ])
- .nullable(),
- gap: z.enum(["sm", "md", "lg"]).nullable(),
- }),
- slots: ["default"],
- description: "Grid layout (1-6 columns)",
- },
- Divider: {
- props: z.object({}),
- description: "Horizontal separator line",
- },
- // Form Inputs
- Input: {
- props: z.object({
- label: z.string(),
- name: z.string(),
- type: z.enum(["text", "email", "password", "number"]).nullable(),
- placeholder: z.string().nullable(),
- }),
- description: "Text input field",
- },
- Textarea: {
- props: z.object({
- label: z.string(),
- name: z.string(),
- placeholder: z.string().nullable(),
- rows: z.number().nullable(),
- }),
- description: "Multi-line text input",
- },
- Select: {
- props: z.object({
- label: z.string(),
- name: z.string(),
- options: z.array(z.string()),
- placeholder: z.string().nullable(),
- }),
- description: "Dropdown select input",
- },
- Checkbox: {
- props: z.object({
- label: z.string(),
- name: z.string(),
- checked: z.boolean().nullable(),
- }),
- description: "Checkbox input",
- },
- Radio: {
- props: z.object({
- label: z.string(),
- name: z.string(),
- options: z.array(z.string()),
- }),
- description: "Radio button group",
- },
- Switch: {
- props: z.object({
- label: z.string(),
- name: z.string(),
- checked: z.boolean().nullable(),
- }),
- description: "Toggle switch input",
- },
- // Actions
- Button: {
- props: z.object({
- label: z.string(),
- variant: z.enum(["primary", "secondary", "danger"]).nullable(),
- action: z.string().nullable(),
- actionParams: z.record(z.string(), z.unknown()).nullable(),
- }),
- description:
- "Clickable button. Use action to specify the action name and actionParams for parameters.",
- },
- Link: {
- props: z.object({
- label: z.string(),
- href: z.string(),
- }),
- description: "Anchor link",
- },
- // Typography
- Heading: {
- props: z.object({
- text: z.string(),
- level: z.enum(["h1", "h2", "h3", "h4"]).nullable(),
- }),
- description: "Heading text (h1-h4)",
- },
- Text: {
- props: z.object({
- text: z.string(),
- variant: z.enum(["body", "caption", "muted"]).nullable(),
- }),
- description: "Paragraph text",
- },
- // Data Display
- Image: {
- props: z.object({
- alt: z.string(),
- width: z.number().nullable(),
- height: z.number().nullable(),
- }),
- description: "Placeholder image (displays alt text in a styled box)",
- },
- Avatar: {
- props: z.object({
- src: z.string().nullable(),
- name: z.string(),
- size: z.enum(["sm", "md", "lg"]).nullable(),
- }),
- description: "User avatar with fallback initials",
- },
- Badge: {
- props: z.object({
- text: z.string(),
- variant: z.enum(["default", "success", "warning", "danger"]).nullable(),
- }),
- description: "Status badge",
- },
- Alert: {
- props: z.object({
- title: z.string(),
- message: z.string().nullable(),
- type: z.enum(["info", "success", "warning", "error"]).nullable(),
- }),
- description: "Alert banner",
- },
- Progress: {
- props: z.object({
- value: z.number(),
- max: z.number().nullable(),
- label: z.string().nullable(),
- }),
- description: "Progress bar (value 0-100)",
- },
- Rating: {
- props: z.object({
- value: z.number(),
- max: z.number().nullable(),
- label: z.string().nullable(),
- }),
- description: "Star rating display",
- },
- // Charts
- BarGraph: {
- props: z.object({
- title: z.string().nullable(),
- data: z.array(
- z.object({
- label: z.string(),
- value: z.number(),
- }),
- ),
- }),
- description: "Vertical bar chart",
- },
- LineGraph: {
- props: z.object({
- title: z.string().nullable(),
- data: z.array(
- z.object({
- label: z.string(),
- value: z.number(),
- }),
- ),
- }),
- description: "Line chart with points",
- },
- },
- actions: {
- // Demo actions for the playground
- buttonClick: {
- params: z.object({
- message: z.string().nullable(),
- }),
- description:
- "Triggered when a button is clicked. Shows a toast with the message.",
- },
- formSubmit: {
- params: z.object({
- formName: z.string().nullable(),
- }),
- description:
- "Triggered when a form is submitted. Shows a toast confirming submission.",
- },
- linkClick: {
- params: z.object({
- href: z.string(),
- }),
- description:
- "Triggered when a link is clicked. Shows a toast with the destination.",
- },
- },
- });
|