Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/json-render/src/catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@ const componentDescriptions: Record<keyof typeof basePropSchemas, string> = {
CodeBlock: 'Preformatted code block with a filename and language label.',
Progress: 'Determinate progress bar.',
Tree: 'Recursive object/array viewer with expandable nodes.',
Tabs: 'Tabbed container; each child renders under the positionally-matching tab.',
Link: 'Hyperlink to a safe-scheme URL with an optional icon.',
Select: 'Single-select dropdown bound to a state value, with optional search.',
}

/**
* The Devframes base catalog (catalog v1): the fourteen canonical components
* The Devframes base catalog (catalog v1): the seventeen canonical components
* with their Devframes-authored Zod prop schemas and descriptions, and an
* empty action set (actions are dispatched dynamically via the bridge, they
* are not declared here). Reference frontend libraries implement this set.
Expand Down
3 changes: 3 additions & 0 deletions packages/json-render/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ export {
DividerPropsSchema,
IconPropsSchema,
KeyValueTablePropsSchema,
LinkPropsSchema,
ProgressPropsSchema,
SelectPropsSchema,
StackPropsSchema,
SwitchPropsSchema,
TabsPropsSchema,
TextInputPropsSchema,
TextPropsSchema,
TreePropsSchema,
Expand Down
44 changes: 43 additions & 1 deletion packages/json-render/src/prop-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,48 @@ export const TreePropsSchema = z.object({
defaultExpanded: bool.optional(),
})

export const TabsPropsSchema = z.object({
// `children[i]` renders under `tabs[i]` — the two arrays are positional.
tabs: scalar(z.array(z.looseObject({
value: z.string(),
label: z.string(),
icon: z.string().optional(),
badge: z.string().optional(),
badgeVariant: z.enum(['default', 'info', 'success', 'warning', 'danger']).optional(),
}))).optional(),
value: str.optional(),
defaultValue: str.optional(),
orientation: z.enum(['horizontal', 'vertical']).optional(),
})

export const LinkPropsSchema = z.object({
href: str.optional(),
label: str.optional(),
icon: str.optional(),
external: bool.optional(),
})

export const SelectPropsSchema = z.object({
value: str.optional(),
options: scalar(z.array(z.union([
z.string(),
z.looseObject({
value: z.string(),
label: z.string().optional(),
icon: z.string().optional(),
description: z.string().optional(),
}),
]))).optional(),
placeholder: str.optional(),
label: str.optional(),
disabled: bool.optional(),
searchable: bool.optional(),
})

/**
* Map of base-catalog component name → Zod prop schema. The keys are the
* canonical component set (catalog v1).
* canonical component set (catalog v1: the original fourteen plus the
* additive Tabs/Link/Select).
*/
export const basePropSchemas = {
Stack: StackPropsSchema,
Expand All @@ -143,6 +182,9 @@ export const basePropSchemas = {
CodeBlock: CodeBlockPropsSchema,
Progress: ProgressPropsSchema,
Tree: TreePropsSchema,
Tabs: TabsPropsSchema,
Link: LinkPropsSchema,
Select: SelectPropsSchema,
} as const satisfies Record<string, z.ZodType>

/** Canonical base-catalog component name. */
Expand Down
7 changes: 5 additions & 2 deletions packages/json-render/test/catalog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { describe, expect, it } from 'vitest'
import { baseCatalog, baseComponentNames, basePropSchemas } from '../src/index'

describe('base catalog', () => {
it('exposes the fourteen catalog-v1 components', () => {
expect(baseComponentNames).toHaveLength(14)
it('exposes the seventeen catalog-v1 components', () => {
expect(baseComponentNames).toHaveLength(17)
expect(baseComponentNames).toEqual([
'Stack',
'Card',
Expand All @@ -19,6 +19,9 @@ describe('base catalog', () => {
'CodeBlock',
'Progress',
'Tree',
'Tabs',
'Link',
'Select',
])
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,46 @@ export declare const basePropSchemas: {
data: z.ZodOptional<z.ZodUnknown>;
defaultExpanded: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
}, z.core.$strip>;
readonly Tabs: z.ZodObject<{
tabs: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodObject<{
value: z.ZodString;
label: z.ZodString;
icon: z.ZodOptional<z.ZodString>;
badge: z.ZodOptional<z.ZodString>;
badgeVariant: z.ZodOptional<z.ZodEnum<{
success: "success";
default: "default";
warning: "warning";
danger: "danger";
info: "info";
}>>;
}, z.core.$loose>>, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
defaultValue: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
orientation: z.ZodOptional<z.ZodEnum<{
horizontal: "horizontal";
vertical: "vertical";
}>>;
}, z.core.$strip>;
readonly Link: z.ZodObject<{
href: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
icon: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
external: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
}, z.core.$strip>;
readonly Select: z.ZodObject<{
value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
options: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
value: z.ZodString;
label: z.ZodOptional<z.ZodString>;
icon: z.ZodOptional<z.ZodString>;
description: z.ZodOptional<z.ZodString>;
}, z.core.$loose>]>>, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
placeholder: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
disabled: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
searchable: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
}, z.core.$strip>;
};
export declare const baseSchema: import("@json-render/core").Schema<{
spec: import("@json-render/core").SchemaType<"object", {
Expand Down Expand Up @@ -268,11 +308,30 @@ export declare const KeyValueTablePropsSchema: z.ZodObject<{
data: z.ZodOptional<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
loading: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
}, z.core.$strip>;
export declare const LinkPropsSchema: z.ZodObject<{
href: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
icon: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
external: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
}, z.core.$strip>;
export declare const ProgressPropsSchema: z.ZodObject<{
value: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
max: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
}, z.core.$strip>;
export declare const SelectPropsSchema: z.ZodObject<{
value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
options: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
value: z.ZodString;
label: z.ZodOptional<z.ZodString>;
icon: z.ZodOptional<z.ZodString>;
description: z.ZodOptional<z.ZodString>;
}, z.core.$loose>]>>, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
placeholder: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
disabled: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
searchable: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
}, z.core.$strip>;
export declare const StackPropsSchema: z.ZodObject<{
direction: z.ZodOptional<z.ZodEnum<{
row: "row";
Expand Down Expand Up @@ -301,6 +360,27 @@ export declare const SwitchPropsSchema: z.ZodObject<{
label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
disabled: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
}, z.core.$strip>;
export declare const TabsPropsSchema: z.ZodObject<{
tabs: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodObject<{
value: z.ZodString;
label: z.ZodString;
icon: z.ZodOptional<z.ZodString>;
badge: z.ZodOptional<z.ZodString>;
badgeVariant: z.ZodOptional<z.ZodEnum<{
success: "success";
default: "default";
warning: "warning";
danger: "danger";
info: "info";
}>>;
}, z.core.$loose>>, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
defaultValue: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
orientation: z.ZodOptional<z.ZodEnum<{
horizontal: "horizontal";
vertical: "vertical";
}>>;
}, z.core.$strip>;
export declare const TextInputPropsSchema: z.ZodObject<{
value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
placeholder: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ export var DividerPropsSchema /* const */
export var IconPropsSchema /* const */
export var JSON_RENDER_INDEX_KEY /* const */
export var KeyValueTablePropsSchema /* const */
export var LinkPropsSchema /* const */
export var ProgressPropsSchema /* const */
export var SelectPropsSchema /* const */
export var StackPropsSchema /* const */
export var SwitchPropsSchema /* const */
export var TabsPropsSchema /* const */
export var TextInputPropsSchema /* const */
export var TextPropsSchema /* const */
export var TreePropsSchema /* const */
Expand Down
Loading