Skip to content

Commit 1ce68bb

Browse files
authored
Merge pull request #233 from objectstack-ai/copilot/update-demo-docs-with-plugin-code
2 parents 6eac8fe + 71bd4c7 commit 1ce68bb

17 files changed

+199
-53
lines changed

apps/site/app/components/ComponentDemo.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ export { InteractiveDemo as ComponentDemo, DemoGrid } from './InteractiveDemo';
44
// Legacy exports for backward compatibility
55
export { InteractiveDemo, InteractiveDemo as CodeDemo } from './InteractiveDemo';
66

7+
// Export PluginLoader for use in MDX files
8+
export { PluginLoader } from './PluginLoader';
9+
710
// Export types for use in MDX files
811
export type { SchemaNode } from './InteractiveDemo';

apps/site/app/components/InteractiveDemo.tsx

Lines changed: 17 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import React, { useState, useEffect } from 'react';
3+
import React from 'react';
44
import { SchemaRenderer } from '@object-ui/react';
55
import type { SchemaNode } from '@object-ui/core';
66
import { Tabs, Tab } from 'fumadocs-ui/components/tabs';
@@ -9,26 +9,6 @@ import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock';
99
// Re-export SchemaNode type for use in MDX files
1010
export type { SchemaNode } from '@object-ui/core';
1111

12-
// Load plugins promise that we can await
13-
const pluginsLoading = typeof window !== 'undefined'
14-
? Promise.all([
15-
import('@object-ui/plugin-aggrid'),
16-
import('@object-ui/plugin-editor'),
17-
import('@object-ui/plugin-charts'),
18-
import('@object-ui/plugin-dashboard'),
19-
import('@object-ui/plugin-kanban'),
20-
import('@object-ui/plugin-markdown'),
21-
import('@object-ui/plugin-timeline'),
22-
import('@object-ui/plugin-calendar'),
23-
import('@object-ui/plugin-gantt'),
24-
import('@object-ui/plugin-map'),
25-
import('@object-ui/plugin-chatbot'),
26-
import('@object-ui/plugin-form'),
27-
import('@object-ui/plugin-grid'),
28-
import('@object-ui/plugin-view'),
29-
])
30-
: Promise.resolve([]);
31-
3212
interface InteractiveDemoProps {
3313
schema: SchemaNode;
3414
title?: string;
@@ -49,14 +29,6 @@ export function InteractiveDemo({
4929
description,
5030
examples
5131
}: InteractiveDemoProps) {
52-
const [pluginsLoaded, setPluginsLoaded] = useState(false);
53-
54-
useEffect(() => {
55-
// Wait for plugins to load before rendering
56-
pluginsLoading.then(() => {
57-
setPluginsLoaded(true);
58-
});
59-
}, []);
6032

6133
// If examples are provided, show a multi-example view
6234
if (examples && examples.length > 0) {
@@ -70,27 +42,23 @@ export function InteractiveDemo({
7042
)}
7143
<Tabs items={['Preview', 'Code']} defaultIndex={0}>
7244
<Tab value="Preview">
73-
{!pluginsLoaded ? (
74-
<div className="p-6 text-center text-muted-foreground">Loading plugins...</div>
75-
) : (
76-
<div className="space-y-6">
77-
{examples.map((example, index) => (
78-
<div key={index} className="border rounded-lg overflow-hidden">
79-
{example.label && (
80-
<div className="border-b bg-muted px-4 py-2">
81-
<p className="text-sm font-medium">{example.label}</p>
82-
{example.description && (
83-
<p className="text-xs text-muted-foreground mt-0.5">{example.description}</p>
84-
)}
85-
</div>
86-
)}
87-
<div className="p-6 bg-background">
88-
<SchemaRenderer schema={example.schema} />
45+
<div className="space-y-6">
46+
{examples.map((example, index) => (
47+
<div key={index} className="border rounded-lg overflow-hidden">
48+
{example.label && (
49+
<div className="border-b bg-muted px-4 py-2">
50+
<p className="text-sm font-medium">{example.label}</p>
51+
{example.description && (
52+
<p className="text-xs text-muted-foreground mt-0.5">{example.description}</p>
53+
)}
8954
</div>
55+
)}
56+
<div className="p-6 bg-background">
57+
<SchemaRenderer schema={example.schema} />
9058
</div>
91-
))}
92-
</div>
93-
)}
59+
</div>
60+
))}
61+
</div>
9462
</Tab>
9563
<Tab value="Code">
9664
<div className="space-y-4">
@@ -125,11 +93,7 @@ export function InteractiveDemo({
12593
<Tabs items={['Preview', 'Code']} defaultIndex={0}>
12694
<Tab value="Preview">
12795
<div className="border rounded-lg p-6 bg-background">
128-
{!pluginsLoaded ? (
129-
<div className="text-center text-muted-foreground">Loading plugins...</div>
130-
) : (
131-
<SchemaRenderer schema={schema} />
132-
)}
96+
<SchemaRenderer schema={schema} />
13397
</div>
13498
</Tab>
13599
<Tab value="Code">
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
'use client';
2+
3+
import { useEffect, useState } from 'react';
4+
5+
type PluginName =
6+
| 'aggrid'
7+
| 'editor'
8+
| 'charts'
9+
| 'dashboard'
10+
| 'kanban'
11+
| 'markdown'
12+
| 'timeline'
13+
| 'calendar'
14+
| 'gantt'
15+
| 'map'
16+
| 'chatbot'
17+
| 'form'
18+
| 'grid'
19+
| 'view';
20+
21+
interface PluginLoaderProps {
22+
plugins: PluginName[];
23+
children: React.ReactNode;
24+
}
25+
26+
/**
27+
* PluginLoader component - Loads specific plugins on-demand
28+
*
29+
* Usage in MDX files:
30+
* ```mdx
31+
* import { PluginLoader } from '@/app/components/PluginLoader';
32+
*
33+
* <PluginLoader plugins={['aggrid']}>
34+
* <InteractiveDemo schema={{...}} />
35+
* </PluginLoader>
36+
* ```
37+
*/
38+
export function PluginLoader({ plugins, children }: PluginLoaderProps) {
39+
const [loaded, setLoaded] = useState(false);
40+
41+
useEffect(() => {
42+
let cancelled = false;
43+
44+
const loadPlugins = async () => {
45+
// On server side, skip actual imports but mark as loaded to avoid hydration mismatch
46+
if (typeof window === 'undefined') {
47+
if (!cancelled) {
48+
setLoaded(true);
49+
}
50+
return;
51+
}
52+
53+
try {
54+
// Dynamically import plugins based on the list
55+
const imports = plugins.map(async (plugin) => {
56+
switch (plugin) {
57+
case 'aggrid':
58+
return import('@object-ui/plugin-aggrid');
59+
case 'editor':
60+
return import('@object-ui/plugin-editor');
61+
case 'charts':
62+
return import('@object-ui/plugin-charts');
63+
case 'dashboard':
64+
return import('@object-ui/plugin-dashboard');
65+
case 'kanban':
66+
return import('@object-ui/plugin-kanban');
67+
case 'markdown':
68+
return import('@object-ui/plugin-markdown');
69+
case 'timeline':
70+
return import('@object-ui/plugin-timeline');
71+
case 'calendar':
72+
return import('@object-ui/plugin-calendar');
73+
case 'gantt':
74+
return import('@object-ui/plugin-gantt');
75+
case 'map':
76+
return import('@object-ui/plugin-map');
77+
case 'chatbot':
78+
return import('@object-ui/plugin-chatbot');
79+
case 'form':
80+
return import('@object-ui/plugin-form');
81+
case 'grid':
82+
return import('@object-ui/plugin-grid');
83+
case 'view':
84+
return import('@object-ui/plugin-view');
85+
default:
86+
console.warn(`Unknown plugin: ${plugin}`);
87+
return Promise.resolve();
88+
}
89+
});
90+
91+
await Promise.all(imports);
92+
if (!cancelled) {
93+
setLoaded(true);
94+
}
95+
} catch (error) {
96+
console.error('Failed to load plugins:', error);
97+
if (!cancelled) {
98+
setLoaded(true); // Still render children even if plugin loading fails
99+
}
100+
}
101+
};
102+
103+
loadPlugins();
104+
105+
return () => {
106+
cancelled = true;
107+
};
108+
}, [plugins]);
109+
110+
if (!loaded) {
111+
return <div className="p-6 text-center text-muted-foreground">Loading plugins...</div>;
112+
}
113+
114+
return <>{children}</>;
115+
}

apps/site/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"@object-ui/plugin-calendar": "workspace:*",
1818
"@object-ui/plugin-charts": "workspace:*",
1919
"@object-ui/plugin-chatbot": "workspace:*",
20+
"@object-ui/plugin-dashboard": "workspace:*",
2021
"@object-ui/plugin-editor": "workspace:*",
2122
"@object-ui/plugin-gantt": "workspace:*",
2223
"@object-ui/plugin-kanban": "workspace:*",

content/docs/plugins/plugin-aggrid.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: "Plugin AgGrid"
33
---
44

55
import { InteractiveDemo } from '@/app/components/InteractiveDemo';
6+
import { PluginLoader } from '@/app/components/PluginLoader';
67

78
Data grid component powered by AG Grid Community Edition with lazy loading for optimal performance.
89

@@ -14,6 +15,8 @@ npm install @object-ui/plugin-aggrid ag-grid-community ag-grid-react
1415

1516
Note: `ag-grid-community` and `ag-grid-react` are peer dependencies and must be installed separately.
1617

18+
<PluginLoader plugins={['aggrid']}>
19+
1720
## Interactive Examples
1821

1922
### Basic Data Grid
@@ -641,3 +644,5 @@ This results in significantly faster initial page loads for applications that do
641644
- [AG Grid Community Documentation](https://www.ag-grid.com/documentation/)
642645
- [Column Definitions Guide](https://www.ag-grid.com/documentation/javascript/column-definitions/)
643646
- [Grid Options Reference](https://www.ag-grid.com/documentation/javascript/grid-options/)
647+
648+
</PluginLoader>

content/docs/plugins/plugin-calendar.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: "Plugin Calendar"
33
---
44

55
import { InteractiveDemo } from '@/app/components/InteractiveDemo';
6+
import { PluginLoader } from '@/app/components/PluginLoader';
67

78
Calendar view components for ObjectUI - includes both ObjectQL-integrated and standalone calendar components.
89

@@ -12,6 +13,8 @@ Calendar view components for ObjectUI - includes both ObjectQL-integrated and st
1213
npm install @object-ui/plugin-calendar
1314
```
1415

16+
<PluginLoader plugins={['calendar']}>
17+
1518
## Overview
1619

1720
The `@object-ui/plugin-calendar` plugin provides two calendar components:
@@ -511,3 +514,5 @@ All functionality remains the same - just update your imports and package depend
511514

512515
- [Plugin System Overview](/docs/concepts/plugins)
513516
- [Package README](https://github.com/objectstack-ai/objectui/tree/main/packages/plugin-calendar)
517+
518+
</PluginLoader>

content/docs/plugins/plugin-charts.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: "Plugin Charts"
33
---
44

55
import { InteractiveDemo } from '@/app/components/InteractiveDemo';
6+
import { PluginLoader } from '@/app/components/PluginLoader';
67

78
Data visualization components powered by Recharts.
89

@@ -12,6 +13,8 @@ Data visualization components powered by Recharts.
1213
npm install @object-ui/plugin-charts
1314
```
1415

16+
<PluginLoader plugins={['charts']}>
17+
1518
## Interactive Examples
1619

1720
<InteractiveDemo
@@ -341,3 +344,5 @@ const chartSchema: BarChartSchema = {
341344
- [Plugin System Overview](/docs/concepts/plugins)
342345
- [Lazy-Loaded Plugins Architecture](../concepts/lazy-loading)
343346
- [Package README](https://github.com/objectstack-ai/objectui/tree/main/packages/plugin-charts)
347+
348+
</PluginLoader>

content/docs/plugins/plugin-chatbot.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: "Plugin Chatbot"
33
---
44

55
import { InteractiveDemo } from '@/app/components/InteractiveDemo';
6+
import { PluginLoader } from '@/app/components/PluginLoader';
67

78
Chat interface component with message history, typing indicators, and customizable avatars.
89

@@ -12,6 +13,8 @@ Chat interface component with message history, typing indicators, and customizab
1213
npm install @object-ui/plugin-chatbot
1314
```
1415

16+
<PluginLoader plugins={['chatbot']}>
17+
1518
## Interactive Examples
1619

1720
### Basic Chatbot
@@ -464,3 +467,5 @@ const chatbotSchema: ChatbotSchema = {
464467

465468
- [Plugin System Overview](/docs/concepts/plugins)
466469
- [Package README](https://github.com/objectstack-ai/objectui/tree/main/packages/plugin-chatbot)
470+
471+
</PluginLoader>

content/docs/plugins/plugin-dashboard.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: "Plugin Dashboard"
33
---
44

55
import { InteractiveDemo } from '@/app/components/InteractiveDemo';
6+
import { PluginLoader } from '@/app/components/PluginLoader';
67

78
Dashboard layouts and metric widgets for creating beautiful dashboards with KPIs, charts, and statistics.
89

@@ -12,6 +13,8 @@ Dashboard layouts and metric widgets for creating beautiful dashboards with KPIs
1213
npm install @object-ui/plugin-dashboard
1314
```
1415

16+
<PluginLoader plugins={['dashboard']}>
17+
1518
## Interactive Examples
1619

1720
<InteractiveDemo
@@ -193,3 +196,5 @@ const dashboard: DashboardSchema = {
193196
## License
194197

195198
MIT
199+
200+
</PluginLoader>

content/docs/plugins/plugin-editor.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: "Plugin Editor"
33
---
44

55
import { InteractiveDemo } from '@/app/components/InteractiveDemo';
6+
import { PluginLoader } from '@/app/components/PluginLoader';
67

78
Code editor component powered by Monaco Editor (VS Code's editor).
89

@@ -12,6 +13,8 @@ Code editor component powered by Monaco Editor (VS Code's editor).
1213
npm install @object-ui/plugin-editor
1314
```
1415

16+
<PluginLoader plugins={['editor']}>
17+
1518
## Interactive Examples
1619

1720
<InteractiveDemo
@@ -181,3 +184,5 @@ const editorSchema: CodeEditorSchema = {
181184
- [Plugin System Overview](/docs/concepts/plugins)
182185
- [Lazy-Loaded Plugins Architecture](../concepts/lazy-loading)
183186
- [Package README](https://github.com/objectstack-ai/objectui/tree/main/packages/plugin-editor)
187+
188+
</PluginLoader>

0 commit comments

Comments
 (0)