Skip to content

Commit a63e2eb

Browse files
Copilothuangyiirene
andcommitted
Add interactive demo component with Preview/Code tabs
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
1 parent bde7b7c commit a63e2eb

2 files changed

Lines changed: 121 additions & 62 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+
}

0 commit comments

Comments
 (0)