Skip to content

Commit 1158164

Browse files
authored
Merge pull request #142 from objectstack-ai/copilot/add-demo-blocks-for-components
2 parents 26bea99 + ac2b1de commit 1158164

10 files changed

Lines changed: 675 additions & 64 deletions

File tree

Lines changed: 4 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,5 @@
1-
'use client';
1+
// Re-export the new InteractiveDemo as the main demo component
2+
export { InteractiveDemo as ComponentDemo, DemoGrid } from './InteractiveDemo';
23

3-
import React from 'react';
4-
import { SchemaRenderer } from '@object-ui/react';
5-
import type { SchemaNode } from '@object-ui/core';
6-
7-
interface ComponentDemoProps {
8-
schema: SchemaNode;
9-
title?: string;
10-
description?: string;
11-
}
12-
13-
export function ComponentDemo({ schema, title, description }: ComponentDemoProps) {
14-
return (
15-
<div className="not-prose my-6">
16-
{(title || description) && (
17-
<div className="mb-3">
18-
{title && <h4 className="text-sm font-semibold mb-1">{title}</h4>}
19-
{description && <p className="text-sm text-muted-foreground">{description}</p>}
20-
</div>
21-
)}
22-
<div className="border rounded-lg p-6 bg-background">
23-
<SchemaRenderer schema={schema} />
24-
</div>
25-
</div>
26-
);
27-
}
28-
29-
interface DemoGridProps {
30-
children: React.ReactNode;
31-
}
32-
33-
export function DemoGrid({ children }: DemoGridProps) {
34-
return (
35-
<div className="not-prose grid gap-4 md:grid-cols-2 my-6">
36-
{children}
37-
</div>
38-
);
39-
}
40-
41-
interface CodeDemoProps {
42-
schema: SchemaNode;
43-
code: string;
44-
title?: string;
45-
}
46-
47-
export function CodeDemo({ schema, code, title }: CodeDemoProps) {
48-
return (
49-
<div className="not-prose my-6">
50-
{title && <h4 className="text-sm font-semibold mb-3">{title}</h4>}
51-
<div className="grid gap-4 lg:grid-cols-2">
52-
<div className="border rounded-lg p-6 bg-background">
53-
<SchemaRenderer schema={schema} />
54-
</div>
55-
<div className="border rounded-lg overflow-hidden">
56-
<pre className="p-4 text-xs overflow-auto max-h-96 bg-muted">
57-
<code>{code}</code>
58-
</pre>
59-
</div>
60-
</div>
61-
</div>
62-
);
63-
}
4+
// Legacy exports for backward compatibility
5+
export { InteractiveDemo, InteractiveDemo as CodeDemo } from './InteractiveDemo';
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
'use client';
2+
3+
import React from 'react';
4+
import { SchemaRenderer } from '@object-ui/react';
5+
import type { SchemaNode } from '@object-ui/core';
6+
import { Tabs, Tab } from 'fumadocs-ui/components/tabs';
7+
import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock';
8+
9+
interface InteractiveDemoProps {
10+
schema: SchemaNode;
11+
title?: string;
12+
description?: string;
13+
/**
14+
* Show multiple examples with their own schemas
15+
*/
16+
examples?: Array<{
17+
schema: SchemaNode;
18+
label: string;
19+
description?: string;
20+
}>;
21+
}
22+
23+
export function InteractiveDemo({
24+
schema,
25+
title,
26+
description,
27+
examples
28+
}: InteractiveDemoProps) {
29+
// If examples are provided, show a multi-example view
30+
if (examples && examples.length > 0) {
31+
return (
32+
<div className="not-prose my-6">
33+
{(title || description) && (
34+
<div className="mb-3">
35+
{title && <h4 className="text-sm font-semibold mb-1">{title}</h4>}
36+
{description && <p className="text-sm text-muted-foreground">{description}</p>}
37+
</div>
38+
)}
39+
<Tabs items={['Preview', 'Code']} defaultIndex={0}>
40+
<Tab value="Preview">
41+
<div className="space-y-6">
42+
{examples.map((example, index) => (
43+
<div key={index} className="border rounded-lg overflow-hidden">
44+
{example.label && (
45+
<div className="border-b bg-muted px-4 py-2">
46+
<p className="text-sm font-medium">{example.label}</p>
47+
{example.description && (
48+
<p className="text-xs text-muted-foreground mt-0.5">{example.description}</p>
49+
)}
50+
</div>
51+
)}
52+
<div className="p-6 bg-background">
53+
<SchemaRenderer schema={example.schema} />
54+
</div>
55+
</div>
56+
))}
57+
</div>
58+
</Tab>
59+
<Tab value="Code">
60+
<div className="space-y-4">
61+
{examples.map((example, index) => (
62+
<div key={index}>
63+
{example.label && (
64+
<p className="text-sm font-medium mb-2">{example.label}</p>
65+
)}
66+
<CodeBlock>
67+
<Pre>
68+
<code>{JSON.stringify(example.schema, null, 2)}</code>
69+
</Pre>
70+
</CodeBlock>
71+
</div>
72+
))}
73+
</div>
74+
</Tab>
75+
</Tabs>
76+
</div>
77+
);
78+
}
79+
80+
// Single example view with Preview/Code tabs
81+
return (
82+
<div className="not-prose my-6">
83+
{(title || description) && (
84+
<div className="mb-3">
85+
{title && <h4 className="text-sm font-semibold mb-1">{title}</h4>}
86+
{description && <p className="text-sm text-muted-foreground">{description}</p>}
87+
</div>
88+
)}
89+
<Tabs items={['Preview', 'Code']} defaultIndex={0}>
90+
<Tab value="Preview">
91+
<div className="border rounded-lg p-6 bg-background">
92+
<SchemaRenderer schema={schema} />
93+
</div>
94+
</Tab>
95+
<Tab value="Code">
96+
<CodeBlock>
97+
<Pre>
98+
<code>{JSON.stringify(schema, null, 2)}</code>
99+
</Pre>
100+
</CodeBlock>
101+
</Tab>
102+
</Tabs>
103+
</div>
104+
);
105+
}
106+
107+
interface DemoGridProps {
108+
children: React.ReactNode;
109+
}
110+
111+
export function DemoGrid({ children }: DemoGridProps) {
112+
return (
113+
<div className="not-prose grid gap-4 md:grid-cols-2 my-6">
114+
{children}
115+
</div>
116+
);
117+
}

apps/site/app/page.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,6 @@ export default function HomePage() {
248248
{ icon: "📝", title: "Forms", desc: "Complex multi-step forms" },
249249
{ icon: "📄", title: "CMS", desc: "Content management systems" },
250250
{ icon: "🔧", title: "Internal Tools", desc: "Business applications" },
251-
{ icon: "🎨", title: "Prototypes", desc: "Rapid UI prototyping" }
252251
].map((useCase) => (
253252
<div key={useCase.title} className="rounded-xl border border-fd-border bg-fd-card p-6">
254253
<div className="text-4xl mb-3">{useCase.icon}</div>
@@ -260,6 +259,18 @@ export default function HomePage() {
260259
</p>
261260
</div>
262261
))}
262+
<Link
263+
href="/docs/guide/interactive-demos"
264+
className="rounded-xl border border-fd-border bg-fd-card p-6 transition-all hover:shadow-lg hover:border-fd-primary/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fd-primary focus-visible:ring-offset-2"
265+
>
266+
<div className="text-4xl mb-3"></div>
267+
<h3 className="text-lg font-semibold text-fd-foreground mb-1">
268+
Interactive Examples
269+
</h3>
270+
<p className="text-fd-muted-foreground text-sm">
271+
Explore 30+ components with live demos
272+
</p>
273+
</Link>
263274
</div>
264275
</div>
265276
</section>
Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
title: "Plugin Charts"
33
---
44

5+
import { InteractiveDemo } from '@/app/components/InteractiveDemo';
6+
57
Data visualization components powered by Recharts.
68

79
## Installation
@@ -10,6 +12,66 @@ Data visualization components powered by Recharts.
1012
npm install @object-ui/plugin-charts
1113
```
1214

15+
## Interactive Examples
16+
17+
<InteractiveDemo
18+
schema={{
19+
type: "bar-chart",
20+
data: [
21+
{ name: "Jan", value: 400 },
22+
{ name: "Feb", value: 300 },
23+
{ name: "Mar", value: 600 },
24+
{ name: "Apr", value: 800 },
25+
{ name: "May", value: 500 },
26+
{ name: "Jun", value: 700 }
27+
],
28+
dataKey: "value",
29+
xAxisKey: "name",
30+
height: 300,
31+
color: "#8884d8"
32+
}}
33+
title="Bar Chart"
34+
description="Display data as vertical bars"
35+
/>
36+
37+
<InteractiveDemo
38+
schema={{
39+
type: "line-chart",
40+
data: [
41+
{ month: "Jan", revenue: 4000, expenses: 2400 },
42+
{ month: "Feb", revenue: 3000, expenses: 1398 },
43+
{ month: "Mar", revenue: 6000, expenses: 3800 },
44+
{ month: "Apr", revenue: 8000, expenses: 3908 },
45+
{ month: "May", revenue: 5000, expenses: 4800 },
46+
{ month: "Jun", revenue: 7000, expenses: 3800 }
47+
],
48+
lines: [
49+
{ dataKey: "revenue", stroke: "#8884d8", name: "Revenue" },
50+
{ dataKey: "expenses", stroke: "#82ca9d", name: "Expenses" }
51+
],
52+
xAxisKey: "month",
53+
height: 300
54+
}}
55+
title="Multi-Line Chart"
56+
description="Compare multiple metrics over time"
57+
/>
58+
59+
<InteractiveDemo
60+
schema={{
61+
type: "pie-chart",
62+
data: [
63+
{ name: "Desktop", value: 45, fill: "#8884d8" },
64+
{ name: "Mobile", value: 35, fill: "#82ca9d" },
65+
{ name: "Tablet", value: 20, fill: "#ffc658" }
66+
],
67+
dataKey: "value",
68+
nameKey: "name",
69+
height: 300
70+
}}
71+
title="Pie Chart"
72+
description="Show proportional data distribution"
73+
/>
74+
1375
## Usage
1476

1577
### Basic Usage
@@ -57,7 +119,7 @@ const schema = {
57119

58120
| Property | Type | Default | Description |
59121
|----------|------|---------|-------------|
60-
| `data` | Array<Record<string, any>> | `[]` | Array of data objects to visualize |
122+
| `data` | Array of objects | `[]` | Array of data objects to visualize |
61123
| `dataKey` | string | `'value'` | Key in data objects for Y-axis values |
62124
| `xAxisKey` | string | `'name'` | Key in data objects for X-axis labels |
63125
| `height` | number | `400` | Chart height in pixels |
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
title: "Plugin Editor"
33
---
44

5+
import { InteractiveDemo } from '@/app/components/InteractiveDemo';
6+
57
Code editor component powered by Monaco Editor (VS Code's editor).
68

79
## Installation
@@ -10,6 +12,45 @@ Code editor component powered by Monaco Editor (VS Code's editor).
1012
npm install @object-ui/plugin-editor
1113
```
1214

15+
## Interactive Examples
16+
17+
<InteractiveDemo
18+
schema={{
19+
type: "code-editor",
20+
value: "function greet(name) {\n console.log(`Hello, ${name}!`);\n return `Welcome, ${name}`;\n}\n\ngreet('Developer');",
21+
language: "javascript",
22+
theme: "vs-dark",
23+
height: "300px"
24+
}}
25+
title="JavaScript Editor"
26+
description="Full-featured Monaco editor with syntax highlighting"
27+
/>
28+
29+
<InteractiveDemo
30+
schema={{
31+
type: "code-editor",
32+
value: "def calculate_fibonacci(n):\n if n <= 1:\n return n\n return calculate_fibonacci(n-1) + calculate_fibonacci(n-2)\n\n# Calculate first 10 Fibonacci numbers\nfor i in range(10):\n print(f'F({i}) = {calculate_fibonacci(i)}')",
33+
language: "python",
34+
theme: "vs-dark",
35+
height: "300px"
36+
}}
37+
title="Python Editor"
38+
description="Support for 100+ programming languages"
39+
/>
40+
41+
<InteractiveDemo
42+
schema={{
43+
type: "code-editor",
44+
value: '{\n "name": "objectui-demo",\n "version": "1.0.0",\n "description": "Interactive demo",\n "main": "index.js",\n "dependencies": {\n "@object-ui/core": "latest",\n "@object-ui/react": "latest"\n }\n}',
45+
language: "json",
46+
theme: "vs-dark",
47+
height: "300px",
48+
readOnly: true
49+
}}
50+
title="Read-only JSON Viewer"
51+
description="Perfect for displaying code snippets"
52+
/>
53+
1354
## Usage
1455

1556
### Basic Usage

0 commit comments

Comments
 (0)