mirror of
https://github.com/vercel-labs/json-render.git
synced 2026-09-14 13:41:32 +08:00
152 lines
4.4 KiB
TypeScript
152 lines
4.4 KiB
TypeScript
import { defineCatalog } from "@json-render/core";
|
|
import { schema } from "@json-render/react/schema";
|
|
import { z } from "zod";
|
|
|
|
/**
|
|
* A compact, opinionated catalog focused on interactive UI patterns that
|
|
* show up well in the devtools panel: state changes, action dispatches,
|
|
* input bindings, conditional visibility, and repeated lists.
|
|
*/
|
|
export const catalog = defineCatalog(schema, {
|
|
components: {
|
|
Card: {
|
|
props: z.object({
|
|
title: z.string().nullable(),
|
|
subtitle: z.string().nullable(),
|
|
tone: z
|
|
.enum(["default", "accent", "success", "warn", "muted"])
|
|
.nullable(),
|
|
}),
|
|
slots: ["default"],
|
|
description: "Container with optional title/subtitle.",
|
|
},
|
|
Heading: {
|
|
props: z.object({
|
|
text: z.string(),
|
|
level: z.enum(["1", "2", "3"]).nullable(),
|
|
}),
|
|
description: "Section heading. level defaults to 2.",
|
|
},
|
|
Text: {
|
|
props: z.object({
|
|
text: z.string(),
|
|
muted: z.boolean().nullable(),
|
|
weight: z.enum(["regular", "medium", "bold"]).nullable(),
|
|
}),
|
|
description: "Paragraph text.",
|
|
},
|
|
Stack: {
|
|
props: z.object({
|
|
gap: z.enum(["xs", "sm", "md", "lg"]).nullable(),
|
|
}),
|
|
slots: ["default"],
|
|
description: "Vertical stack with gap.",
|
|
},
|
|
Row: {
|
|
props: z.object({
|
|
gap: z.enum(["xs", "sm", "md", "lg"]).nullable(),
|
|
align: z.enum(["start", "center", "end", "between"]).nullable(),
|
|
}),
|
|
slots: ["default"],
|
|
description: "Horizontal row with gap.",
|
|
},
|
|
Grid: {
|
|
props: z.object({
|
|
columns: z.enum(["2", "3", "4"]).nullable(),
|
|
gap: z.enum(["xs", "sm", "md", "lg"]).nullable(),
|
|
}),
|
|
slots: ["default"],
|
|
description: "Multi-column grid layout.",
|
|
},
|
|
Metric: {
|
|
props: z.object({
|
|
label: z.string(),
|
|
value: z.string(),
|
|
delta: z.string().nullable(),
|
|
trend: z.enum(["up", "down", "flat"]).nullable(),
|
|
}),
|
|
description: "Single labelled metric with optional delta + trend.",
|
|
},
|
|
Badge: {
|
|
props: z.object({
|
|
label: z.string(),
|
|
tone: z
|
|
.enum(["default", "accent", "success", "warn", "muted"])
|
|
.nullable(),
|
|
}),
|
|
description: "Small pill-shaped label.",
|
|
},
|
|
Divider: {
|
|
props: z.object({}),
|
|
description: "Horizontal rule.",
|
|
},
|
|
Button: {
|
|
props: z.object({
|
|
label: z.string(),
|
|
variant: z.enum(["primary", "secondary", "ghost"]).nullable(),
|
|
size: z.enum(["sm", "md"]).nullable(),
|
|
disabled: z.boolean().nullable(),
|
|
}),
|
|
description:
|
|
"Clickable button. Use on.press to trigger actions (setState, pushState, removeState).",
|
|
},
|
|
TextInput: {
|
|
props: z.object({
|
|
value: z.string().nullable(),
|
|
placeholder: z.string().nullable(),
|
|
}),
|
|
description:
|
|
"Text input. Use { $bindState: '/path' } on value for two-way binding.",
|
|
},
|
|
Checkbox: {
|
|
props: z.object({
|
|
label: z.string().nullable(),
|
|
checked: z.boolean().nullable(),
|
|
}),
|
|
description:
|
|
"Checkbox. Use { $bindState: '/path' } on checked for two-way binding.",
|
|
},
|
|
ProgressBar: {
|
|
props: z.object({
|
|
value: z.number(),
|
|
max: z.number().nullable(),
|
|
tone: z.enum(["default", "accent", "success", "warn"]).nullable(),
|
|
}),
|
|
description:
|
|
"Horizontal progress bar. value is [0, max]. max defaults to 100.",
|
|
},
|
|
Callout: {
|
|
props: z.object({
|
|
title: z.string().nullable(),
|
|
text: z.string(),
|
|
tone: z.enum(["info", "success", "warn", "tip"]).nullable(),
|
|
}),
|
|
description: "Highlighted note / tip / warning box.",
|
|
},
|
|
List: {
|
|
props: z.object({}),
|
|
slots: ["default"],
|
|
description:
|
|
"Vertical list container. Pair with repeat to iterate an array.",
|
|
},
|
|
ListItem: {
|
|
props: z.object({
|
|
title: z.string(),
|
|
description: z.string().nullable(),
|
|
meta: z.string().nullable(),
|
|
}),
|
|
description: "Single list row.",
|
|
},
|
|
Avatar: {
|
|
props: z.object({
|
|
initials: z.string(),
|
|
tone: z.enum(["default", "accent", "success", "warn"]).nullable(),
|
|
}),
|
|
description: "Circular avatar with 1-2 initials.",
|
|
},
|
|
},
|
|
actions: {},
|
|
});
|
|
|
|
export type DemoCatalog = typeof catalog;
|