Skip to content

Commit 37d8d05

Browse files
committed
feat(sdui-page-starter): add SDUI page starter example with schema-driven UI integration
1 parent 86215f6 commit 37d8d05

File tree

19 files changed

+660
-1
lines changed

19 files changed

+660
-1
lines changed
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
---
2+
name: objectui-sdui-page-builder
3+
description: Build and integrate Schema-Driven UI pages in third-party projects using Object UI. Use this skill whenever the user asks to create app pages from JSON schemas, wire SchemaRenderer into an existing React app, implement CRUD/dashboard/form/list/detail pages with Object UI, or migrate handwritten React pages to schema-driven rendering. Use it even if the user does not explicitly mention "skill" or "SchemaRenderer" but describes metadata-driven page development, console-like page composition, or JSON-to-UI workflows.
4+
---
5+
6+
# ObjectUI SDUI Page Builder
7+
8+
Use this skill to guide app developers (not framework maintainers) to build production pages with Object UI's Schema-Driven UI Engine.
9+
10+
## What this skill should optimize for
11+
12+
- Deliver working page features quickly with JSON-first design.
13+
- Keep architecture aligned with Object UI conventions.
14+
- Keep third-party projects backend-agnostic through DataSource interfaces.
15+
- Produce outputs that are immediately usable in app codebases.
16+
17+
## When to use this skill
18+
19+
Use this skill when requests include:
20+
21+
- "Build a page with Object UI / SchemaRenderer"
22+
- "Create a CRUD/dashboard/form/detail page from JSON"
23+
- "Integrate Object UI in an existing React/Vite/Next app"
24+
- "Design a metadata-driven page similar to console"
25+
- "Move an existing React page to schema-driven rendering"
26+
27+
Do not use this skill for:
28+
29+
- Modifying Shadcn upstream primitives under `packages/components/src/ui/**`.
30+
- Core engine internals that belong to `@object-ui/core` maintenance.
31+
- Non-UI backend implementation unrelated to schema rendering.
32+
33+
## Required mindset
34+
35+
1. JSON first, React second.
36+
2. Protocol compatibility before convenience shortcuts.
37+
3. Reusable schema blocks before one-off page code.
38+
4. DataSource abstraction over hardcoded transport logic.
39+
40+
## Standard workflow
41+
42+
### 1. Frame the page contract first
43+
44+
Before writing implementation code, define:
45+
46+
- Page purpose (dashboard, list, detail, form, wizard, board).
47+
- Required data inputs and output actions.
48+
- User roles and visibility rules.
49+
- Interaction model (navigation, submit, bulk actions, modals).
50+
51+
Then produce a first schema draft.
52+
53+
### 2. Select the right package boundaries
54+
55+
Use these boundaries in guidance and generated code:
56+
57+
- `@object-ui/types`: schema and typed interfaces.
58+
- `@object-ui/core`: expression/action/registry logic.
59+
- `@object-ui/components`: base visual components and wrappers.
60+
- `@object-ui/fields`: form input renderers.
61+
- `@object-ui/layout`: shell and page composition.
62+
- `@object-ui/plugin-*`: heavy feature widgets (grid, charts, kanban, map).
63+
- `@object-ui/react`: `SchemaRenderer`, provider wiring, runtime bridge.
64+
65+
When helping third-party apps, consume these packages; avoid duplicating core runtime logic in the app layer.
66+
67+
### 3. Compose schema using proven node shape
68+
69+
Use a strict component schema shape similar to:
70+
71+
```json
72+
{
73+
"type": "card",
74+
"id": "customer_summary",
75+
"className": "col-span-12 lg:col-span-4",
76+
"props": {
77+
"title": "Customer Summary"
78+
},
79+
"hidden": "${data.userRole !== 'admin'}",
80+
"children": [
81+
{
82+
"type": "text",
83+
"props": {
84+
"content": "Active users: ${data.metrics.activeUsers}"
85+
}
86+
}
87+
]
88+
}
89+
```
90+
91+
Prefer expression-based behavior (`hidden`, `disabled`, computed props) over imperative branching in component code.
92+
93+
### 4. Wire renderer and registry cleanly
94+
95+
Typical integration sequence:
96+
97+
1. Register default renderers/components.
98+
2. Register plugin components needed by the page type.
99+
3. Provide `dataSource` and contextual data through renderer provider.
100+
4. Render schema via `SchemaRenderer`.
101+
102+
Keep custom component registrations namespaced to avoid collisions.
103+
104+
### 5. Use action data, not inline callback spaghetti
105+
106+
Represent interactions as data where possible:
107+
108+
```json
109+
{
110+
"events": {
111+
"onClick": [
112+
{ "action": "validate", "target": "customer_form" },
113+
{ "action": "submit", "target": "customer_form" },
114+
{ "action": "navigate", "params": { "url": "/customers" } }
115+
]
116+
}
117+
}
118+
```
119+
120+
If custom app-side handlers are needed, isolate them in action handlers instead of embedding business logic into presentation components.
121+
122+
### 6. Validate responsiveness and accessibility
123+
124+
For every generated page, ensure:
125+
126+
- Responsive layout behavior (mobile/tablet/desktop).
127+
- Semantic labels and ARIA fields where relevant.
128+
- Keyboard-safe interactions for forms and actions.
129+
- Error and loading states are present in schema or wrappers.
130+
131+
### 7. Ship with verification artifacts
132+
133+
Always include:
134+
135+
- Final page schema JSON.
136+
- Integration code snippet (provider + renderer + registry wiring).
137+
- Test checklist (rendering, expressions, actions, data loading).
138+
- Optional migration notes if replacing legacy React page code.
139+
140+
## Output format
141+
142+
Always structure results in this order:
143+
144+
1. `Page Goal` - one paragraph.
145+
2. `Schema JSON` - complete runnable draft.
146+
3. `Integration Steps` - app wiring steps.
147+
4. `Code Snippets` - minimal required TS/TSX examples.
148+
5. `Validation Checklist` - what to test before merge.
149+
6. `Extension Options` - how to add fields/plugins/actions next.
150+
151+
## Console-inspired patterns to reuse
152+
153+
When users ask for a "console-like" experience, prefer:
154+
155+
- App-shell layout with persistent navigation.
156+
- Metadata-driven detail pages composed from widgets.
157+
- Registry-based component resolution over switch/case rendering.
158+
- PageSchema factories for page variants of the same domain entity.
159+
160+
## Common mistakes to avoid
161+
162+
- Writing large bespoke React JSX trees before schema definition.
163+
- Hardcoding API calls directly inside visual renderers.
164+
- Introducing package coupling (for example, UI package depending on business logic package).
165+
- Registering components without namespace in plugin-heavy projects.
166+
- Skipping docs updates for newly introduced schema patterns.
167+
168+
## Fast triage playbook for ambiguous requests
169+
170+
If the request is underspecified:
171+
172+
1. Infer likely page category (list/detail/form/dashboard).
173+
2. Produce a minimal viable schema first.
174+
3. Mark assumptions clearly.
175+
4. Provide one conservative and one advanced variant.
176+
177+
This keeps momentum while inviting focused user feedback.
178+
179+
## Example prompts this skill should handle well
180+
181+
- "In our CRM app, create a customer detail page with tabs, related orders, and action buttons using SchemaRenderer."
182+
- "Migrate this existing React order list to Object UI schema, keep filters and bulk actions."
183+
- "Set up a dashboard page in a Vite app with Object UI cards + chart plugin and role-based visibility."
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"skill_name": "objectui-sdui-page-builder",
3+
"evals": [
4+
{
5+
"id": 1,
6+
"prompt": "We have a React + Vite internal app for inventory. Please create a schema-driven list page for products with search, status filter, row actions, and a create-product action. Use Object UI patterns and include integration snippets.",
7+
"expected_output": "Produces a complete page schema JSON for list/grid behavior, includes integration wiring steps for SchemaRenderer and component registration, and provides a validation checklist.",
8+
"files": []
9+
},
10+
{
11+
"id": 2,
12+
"prompt": "请帮我把现有的客户详情页改成 Schema-Driven UI:需要基本信息、联系人列表、最近订单三个分区,并且只有 admin 可以看到“编辑客户”按钮。项目技术栈是 React + TypeScript。",
13+
"expected_output": "Provides a structured detail-page schema with expression-based visibility for admin-only actions, keeps sections modular, and explains how to integrate into an app project.",
14+
"files": []
15+
},
16+
{
17+
"id": 3,
18+
"prompt": "Build a console-like analytics dashboard page in an existing Object UI project: KPI cards on top, trend chart in the middle, and recent activity list at the bottom. Also include action definitions for refresh and navigate-to-report.",
19+
"expected_output": "Generates dashboard schema with layout composition, plugin-oriented chart usage, action definitions as data, and testing guidance for responsiveness and interaction.",
20+
"files": []
21+
}
22+
]
23+
}

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ coverage
2727

2828
# IDEs
2929
.idea
30-
.vscode
3130
*.swp
3231
*.swo
3332

.vscode/mcp.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"servers": {
3+
"io.github.ChromeDevTools/chrome-devtools-mcp": {
4+
"command": "npx",
5+
"args": [
6+
"-y",
7+
"chrome-devtools-mcp"
8+
],
9+
"env": {},
10+
"type": "stdio"
11+
}
12+
},
13+
"inputs": []
14+
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ ObjectStack examples that demonstrate different features and use cases:
8484
- **[examples/todo](examples/todo)** - Simple task management app demonstrating basic ObjectStack configuration and field types.
8585
- **[examples/kitchen-sink](examples/kitchen-sink)** - Comprehensive component catalog showing all available field types, dashboard widgets, and view types.
8686
- **[examples/msw-todo](examples/msw-todo)** - Frontend-first development example using MSW (Mock Service Worker) to run ObjectStack in the browser.
87+
- **[examples/sdui-page-starter](examples/sdui-page-starter)** - Third-party project starter for building schema-driven pages with `SchemaRenderer` and expression-based UI behavior.
8788

8889
### Running Examples as API Servers
8990

examples/crm/.vscode/tasks.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "server: crm",
6+
"type": "shell",
7+
"command": "pnpm",
8+
"args": [
9+
"run",
10+
"dev"
11+
],
12+
"isBackground": true,
13+
"problemMatcher": [
14+
"$tsc-watch"
15+
],
16+
"group": "test"
17+
}
18+
]
19+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# SDUI Page Starter Example
2+
3+
A practical starter example for third-party application teams that want to build pages with Object UI Schema-Driven UI Engine.
4+
5+
## What this example demonstrates
6+
7+
1. JSON-first page composition using `schema.json`
8+
2. Data-driven expressions such as `${data.metrics.activeCustomers}`
9+
3. Role-based visibility with expression rules (`hidden`)
10+
4. Minimal React integration using `SchemaRendererProvider` + `SchemaRenderer`
11+
12+
## Files
13+
14+
```
15+
examples/sdui-page-starter/
16+
├── index.html # Vite HTML entry
17+
├── vite.config.ts # Vite dev server config
18+
├── tailwind.config.js # Tailwind CSS config
19+
├── postcss.config.js # PostCSS plugins
20+
├── tsconfig.json # TypeScript config
21+
├── package.json
22+
├── README.md
23+
└── src/
24+
├── main.tsx # React entry point
25+
├── App.tsx # Renderer wiring with provider data source
26+
└── schema.json # Complete page schema
27+
```
28+
29+
## How to run
30+
31+
```bash
32+
# From the monorepo root
33+
pnpm install
34+
pnpm build
35+
36+
# Start this example
37+
pnpm --filter @object-ui/example-sdui-page-starter dev
38+
# Opens http://localhost:3001
39+
```
40+
41+
## Use this in your own project
42+
43+
1. Copy `src/schema.json` into your app.
44+
2. Provide runtime data from your own API adapter or state layer.
45+
3. Render with:
46+
47+
```tsx
48+
import '@object-ui/components';
49+
import { SchemaRendererProvider, SchemaRenderer } from '@object-ui/react';
50+
import schema from './schema.json';
51+
52+
export function CustomerOpsPage() {
53+
const dataSource = {
54+
user: { role: 'admin' },
55+
metrics: { activeCustomers: 1284, monthlyRevenue: '$96,430', conversionRate: '4.2%' },
56+
recentOrders: []
57+
};
58+
59+
return (
60+
<SchemaRendererProvider dataSource={dataSource}>
61+
<SchemaRenderer schema={schema} />
62+
</SchemaRendererProvider>
63+
);
64+
}
65+
```
66+
67+
## Next steps
68+
69+
- Replace `data-table` section with `plugin-grid` when you need sorting, pagination, and bulk actions.
70+
- Move action behavior to ActionEngine for reusable event logic.
71+
- Split large pages into schema fragments and compose them in page factories.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>SDUI Page Starter — Object UI</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.tsx"></script>
12+
</body>
13+
</html>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "@object-ui/example-sdui-page-starter",
3+
"version": "3.1.0",
4+
"private": true,
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "tsc && vite build",
9+
"preview": "vite preview"
10+
},
11+
"dependencies": {
12+
"@object-ui/components": "workspace:*",
13+
"@object-ui/core": "workspace:*",
14+
"@object-ui/react": "workspace:*",
15+
"react": "19.2.4",
16+
"react-dom": "19.2.4"
17+
},
18+
"devDependencies": {
19+
"@tailwindcss/postcss": "^4.2.2",
20+
"@types/react": "19.2.14",
21+
"@types/react-dom": "19.2.3",
22+
"@vitejs/plugin-react": "^6.0.1",
23+
"autoprefixer": "^10.4.27",
24+
"postcss": "^8.5.8",
25+
"tailwindcss": "^4.2.2",
26+
"typescript": "^6.0.2",
27+
"vite": "^8.0.5"
28+
}
29+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default {
2+
plugins: {
3+
'@tailwindcss/postcss': {},
4+
autoprefixer: {},
5+
},
6+
}

0 commit comments

Comments
 (0)