Skip to content

Commit ace3702

Browse files
authored
Merge pull request #71 from objectstack-ai/copilot/improve-metadata-specifications
2 parents dba6eab + 464b101 commit ace3702

File tree

28 files changed

+5666
-7
lines changed

28 files changed

+5666
-7
lines changed

docs/BEST_PRACTICES.md

Lines changed: 636 additions & 0 deletions
Large diffs are not rendered by default.

docs/integration/api.md

Lines changed: 484 additions & 0 deletions
Large diffs are not rendered by default.

docs/protocol/crud.md

Lines changed: 499 additions & 0 deletions
Large diffs are not rendered by default.

examples/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ These examples demonstrate the new JSON project specification - pure JSON schema
1414
| [**dashboard**](./dashboard) | Analytics dashboard | ⭐⭐ Intermediate | Metrics, activity feeds, grids |
1515
| [**data-display**](./data-display) | Data visualization patterns | ⭐⭐ Intermediate | Lists, profiles, badges, progress |
1616
| [**landing-page**](./landing-page) | Marketing landing page | ⭐⭐⭐ Advanced | Hero sections, CTAs, full layouts |
17+
| [**user-management**](./user-management) | Complete CRUD interface | ⭐⭐⭐ Advanced | Full CRUD, filters, pagination, batch actions |
18+
| [**api-integration**](./api-integration) | API integration patterns | ⭐⭐⭐ Advanced | Data fetching, events, dynamic data |
1719
| [**cli-demo**](./cli-demo) | CLI demonstration | ⭐ Beginner | Bilingual form, gradient backgrounds |
1820

1921
### 🔧 Integration Examples

examples/api-integration/app.json

Lines changed: 366 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
1+
{
2+
"$schema": "https://objectui.org/schema/v1",
3+
"type": "page",
4+
"title": "API Integration Demo",
5+
"description": "Demonstrating dynamic data fetching, API calls, and event handling",
6+
"body": [
7+
{
8+
"type": "card",
9+
"title": "🔄 Real-time Data Fetching",
10+
"description": "Components that automatically fetch and display data from APIs",
11+
"className": "mb-6",
12+
"body": {
13+
"type": "div",
14+
"className": "p-6 space-y-4",
15+
"dataSource": {
16+
"api": "https://api.github.com/repos/objectstack-ai/objectui",
17+
"fetchOnMount": true,
18+
"pollInterval": 30000,
19+
"transform": "data => ({ stars: data.stargazers_count, forks: data.forks_count, issues: data.open_issues_count })"
20+
},
21+
"body": [
22+
{
23+
"type": "div",
24+
"className": "grid grid-cols-3 gap-4",
25+
"body": [
26+
{
27+
"type": "card",
28+
"className": "text-center",
29+
"body": [
30+
{
31+
"type": "text",
32+
"content": "${data.stars}",
33+
"className": "text-3xl font-bold text-yellow-600"
34+
},
35+
{
36+
"type": "text",
37+
"content": "⭐ Stars",
38+
"className": "text-sm text-muted-foreground"
39+
}
40+
]
41+
},
42+
{
43+
"type": "card",
44+
"className": "text-center",
45+
"body": [
46+
{
47+
"type": "text",
48+
"content": "${data.forks}",
49+
"className": "text-3xl font-bold text-blue-600"
50+
},
51+
{
52+
"type": "text",
53+
"content": "🔱 Forks",
54+
"className": "text-sm text-muted-foreground"
55+
}
56+
]
57+
},
58+
{
59+
"type": "card",
60+
"className": "text-center",
61+
"body": [
62+
{
63+
"type": "text",
64+
"content": "${data.issues}",
65+
"className": "text-3xl font-bold text-red-600"
66+
},
67+
{
68+
"type": "text",
69+
"content": "🐛 Issues",
70+
"className": "text-sm text-muted-foreground"
71+
}
72+
]
73+
}
74+
]
75+
},
76+
{
77+
"type": "text",
78+
"content": "Data updates every 30 seconds automatically",
79+
"className": "text-xs text-muted-foreground text-center"
80+
}
81+
]
82+
}
83+
},
84+
{
85+
"type": "card",
86+
"title": "🎯 Interactive Actions",
87+
"description": "Buttons with API calls and event handlers",
88+
"className": "mb-6",
89+
"body": {
90+
"type": "div",
91+
"className": "p-6 space-y-4",
92+
"body": [
93+
{
94+
"type": "div",
95+
"className": "flex gap-3",
96+
"body": [
97+
{
98+
"type": "button",
99+
"label": "API Call",
100+
"icon": "zap",
101+
"onClick": {
102+
"type": "api",
103+
"api": {
104+
"request": {
105+
"url": "/api/test",
106+
"method": "POST",
107+
"data": {
108+
"message": "Hello from Object UI!"
109+
}
110+
},
111+
"successMessage": "API call successful!",
112+
"errorMessage": "API call failed",
113+
"showLoading": true
114+
}
115+
}
116+
},
117+
{
118+
"type": "button",
119+
"label": "Show Dialog",
120+
"icon": "message-square",
121+
"variant": "outline",
122+
"onClick": {
123+
"type": "dialog",
124+
"dialog": {
125+
"type": "alert",
126+
"title": "Hello!",
127+
"content": "This dialog was triggered by a button click event"
128+
}
129+
}
130+
},
131+
{
132+
"type": "button",
133+
"label": "Show Toast",
134+
"icon": "bell",
135+
"variant": "outline",
136+
"onClick": {
137+
"type": "toast",
138+
"toast": {
139+
"type": "success",
140+
"message": "Toast notification triggered!",
141+
"duration": 3000
142+
}
143+
}
144+
},
145+
{
146+
"type": "button",
147+
"label": "Navigate",
148+
"icon": "external-link",
149+
"variant": "outline",
150+
"onClick": {
151+
"type": "navigation",
152+
"navigate": {
153+
"to": "/users",
154+
"type": "push"
155+
}
156+
}
157+
}
158+
]
159+
}
160+
]
161+
}
162+
},
163+
{
164+
"type": "card",
165+
"title": "📝 Form with API Submission",
166+
"description": "Forms that submit data to APIs with validation",
167+
"className": "mb-6",
168+
"body": {
169+
"type": "div",
170+
"className": "p-6",
171+
"body": {
172+
"type": "form",
173+
"fields": [
174+
{
175+
"name": "name",
176+
"label": "Your Name",
177+
"type": "input",
178+
"placeholder": "Enter your name",
179+
"required": true
180+
},
181+
{
182+
"name": "email",
183+
"label": "Email Address",
184+
"type": "input",
185+
"inputType": "email",
186+
"placeholder": "your@email.com",
187+
"required": true
188+
},
189+
{
190+
"name": "message",
191+
"label": "Message",
192+
"type": "textarea",
193+
"placeholder": "What would you like to tell us?",
194+
"rows": 4,
195+
"required": true
196+
}
197+
],
198+
"submitLabel": "Send Message",
199+
"onSubmit": {
200+
"type": "api",
201+
"api": {
202+
"request": {
203+
"url": "/api/contact",
204+
"method": "POST"
205+
},
206+
"successMessage": "Message sent successfully!",
207+
"errorMessage": "Failed to send message",
208+
"showLoading": true,
209+
"reload": false,
210+
"close": false
211+
}
212+
}
213+
}
214+
}
215+
},
216+
{
217+
"type": "card",
218+
"title": "🔀 Conditional Rendering",
219+
"description": "Components that show/hide based on data conditions",
220+
"className": "mb-6",
221+
"body": {
222+
"type": "div",
223+
"className": "p-6 space-y-4",
224+
"body": [
225+
{
226+
"type": "select",
227+
"name": "userType",
228+
"label": "User Type",
229+
"options": [
230+
{ "label": "Select a type", "value": "" },
231+
{ "label": "Admin", "value": "admin" },
232+
{ "label": "User", "value": "user" },
233+
{ "label": "Guest", "value": "guest" }
234+
]
235+
},
236+
{
237+
"type": "alert",
238+
"variant": "default",
239+
"title": "Admin Access",
240+
"description": "You have full administrative privileges",
241+
"visibleOn": "${form.userType === 'admin'}"
242+
},
243+
{
244+
"type": "alert",
245+
"variant": "default",
246+
"title": "Standard User",
247+
"description": "You have standard user access",
248+
"visibleOn": "${form.userType === 'user'}"
249+
},
250+
{
251+
"type": "alert",
252+
"variant": "destructive",
253+
"title": "Guest Access",
254+
"description": "You have limited guest access",
255+
"visibleOn": "${form.userType === 'guest'}"
256+
},
257+
{
258+
"type": "button",
259+
"label": "Delete Account",
260+
"variant": "destructive",
261+
"visibleOn": "${form.userType === 'admin'}",
262+
"onClick": {
263+
"type": "dialog",
264+
"dialog": {
265+
"type": "confirm",
266+
"title": "Confirm Deletion",
267+
"content": "Are you sure you want to delete this account?",
268+
"actions": [
269+
{
270+
"label": "Cancel"
271+
},
272+
{
273+
"label": "Delete",
274+
"handler": {
275+
"type": "api",
276+
"api": {
277+
"request": {
278+
"url": "/api/account",
279+
"method": "DELETE"
280+
},
281+
"successMessage": "Account deleted",
282+
"close": true
283+
}
284+
}
285+
}
286+
]
287+
}
288+
}
289+
}
290+
]
291+
}
292+
},
293+
{
294+
"type": "card",
295+
"title": "⚡ Event Chaining",
296+
"description": "Multiple actions triggered in sequence",
297+
"className": "mb-6",
298+
"body": {
299+
"type": "div",
300+
"className": "p-6",
301+
"body": {
302+
"type": "button",
303+
"label": "Run Multi-Step Process",
304+
"icon": "play",
305+
"events": [
306+
{
307+
"event": "click",
308+
"type": "toast",
309+
"toast": {
310+
"type": "info",
311+
"message": "Step 1: Starting process..."
312+
}
313+
},
314+
{
315+
"event": "click",
316+
"type": "api",
317+
"api": {
318+
"request": {
319+
"url": "/api/step1",
320+
"method": "POST"
321+
},
322+
"showLoading": true
323+
},
324+
"debounce": 1000
325+
},
326+
{
327+
"event": "click",
328+
"type": "toast",
329+
"toast": {
330+
"type": "success",
331+
"message": "Process completed successfully!"
332+
},
333+
"debounce": 2000
334+
}
335+
]
336+
}
337+
}
338+
},
339+
{
340+
"type": "card",
341+
"title": "💡 Expression System",
342+
"description": "Dynamic values using expressions",
343+
"body": {
344+
"type": "div",
345+
"className": "p-6 space-y-3",
346+
"body": [
347+
{
348+
"type": "text",
349+
"content": "Current time: ${new Date().toLocaleString()}",
350+
"className": "text-sm"
351+
},
352+
{
353+
"type": "text",
354+
"content": "User Agent: ${navigator.userAgent}",
355+
"className": "text-xs text-muted-foreground"
356+
},
357+
{
358+
"type": "text",
359+
"content": "Window Size: ${window.innerWidth}x${window.innerHeight}",
360+
"className": "text-xs text-muted-foreground"
361+
}
362+
]
363+
}
364+
}
365+
]
366+
}

0 commit comments

Comments
 (0)