@xgent-ai/showcase
v2.1.0
Published
XGENT.ai React Library Development Helper - Showcase
Readme
@xgent-ai/showcase
XGENT.ai React Library Development Helper - Showcase
A Storybook-like development tool for grafton-based UI libraries. It renders
every component's showcase cases from a grafton-manifest.json, with friendly
props rendering (binding-expression chips, boolean badges, expandable schema
fragments), copyable view schemas, case deep links, fullscreen previews, and
preview background/width switching.
Usage
import { showcase } from '@xgent-ai/showcase';
import * as components from './index';
import * as widgets from './widgets';
import manifest from '../grafton-manifest.json';
import testStore from '../test/stores/test';
const registry = {
...components,
...widgets,
icons: { /* lucide icons referenced via {$type: "Icon", variant: "registry"} */ },
schemas: { /* named schemas referenced via RegistryView / TabsWidget schemaName */ },
};
const deps = { showcaseCardStyle: 'w-full' };
showcase(registry, manifest, deps, { test: testStore }, demoCollection);Parameters
| Param | Description |
|-------|-------------|
| registry | Global view registry for previews: component/widget exports plus optional icons, schemas, hooks, styles groups (prefixed into the registry as icon::name etc.). |
| manifest | The grafton-manifest.json content (array of libraries). Normalized internally via normalizeManifest(), so both legacy and rich formats work. |
| deps | Style hooks for the page skeleton. showcaseCardStyle is applied to each case card. |
| stores | Store factories made available to case previews, e.g. { test: testStoreFactory } feeds @store::test.* bindings. |
| demo | Optional { name: ReactComponent } collection served at /demo/:name for free-form demo pages. |
Routes
| Route | Page |
|-------|------|
| /home | Component overview grid (all libraries) |
| /:lib/:type/:component | Component page: header (description, grafton badges, props table, docs) + one card per showcase case |
| /:lib/:type/:component/preview/:caseIndex | Chrome-less fullscreen preview of a single case |
| /demo/:name | Custom demo page |
Case cards support #anchor deep links (slugified case title; click the title
to copy the link) and per-case preview background/width settings persisted in
the URL query (p{index}bg / p{index}w).
Manifest format
[
{
"name": "shadcn", // library id, used in routes
"description": "Shadcn-based Library",
"package": "@xgent-ai/ui-shadcn/widgets",
"components": [ /* component entries */ ],
"widgets": [ /* component entries */ ]
}
]Component entry
{
"name": "AlertDialog", // must match a registry export
"displayName": "Alert Dialog",
"description": "确认对话框…", // optional, shown under the title
"status": "beta", // optional: stable | beta | deprecated
"docs": "markdown …", // optional, rendered as a Docs section
"props": [ /* see below */ ],
"grafton": { // mirror of the component's grafton meta
"leaf": true,
"t": true,
"slots": ["header", "footer", "trigger"],
"renderers": ["renderItem"],
"registry": { "Title": "AlertDialogTitle" }
},
"showcase": [
{
"title": "AlertDialog with Trigger",
"description": "optional case description",
"props": { /* grafton view schema fragment, merged onto the component */ }
}
]
}Props metadata
Both formats are valid and can be mixed inside one array; legacy manifests (plain strings) keep working without changes:
"props": [
"className", // legacy: name only
{
"name": "variant",
"type": "enum", // string | number | boolean | object | array
// | enum | slot | action | schema
"options": ["default", "destructive"],
"default": "default",
"required": false,
"description": "按钮视觉变体"
}
]slot / action / schema are grafton-specific prop types shared with the
Wise View editor's property panel and the (future) controls panel.
Normalization happens on the consumer side (normalizeManifest, exported by
this package): string props become { name }, every case gets a unique
anchor slug.
Case props
A case's props object is both the props passed to the component in the
preview and a grafton view schema fragment. A case-level $type replaces the
component as the root node (useful for wrapping a widget in Form or div).
Binding expressions (@store::test.x, @action::alert, two-way
<>@store::test.y) resolve against the stores passed to showcase().
Validation
The manifest zod schema is exported from this package (manifestSchema and
friends from manifest-schema.js) so library packages can validate their
manifests. See packages/shadcn/scripts/check-manifest.ts for a full checker
that also resolves every case's $type against the real component registry
(run with bun run check:manifest), and
packages/shadcn/test/showcase.smoke.test.ts for a browser smoke test that
visits every component route (bun run test:smoke).
