diff --git a/apps/site/app/components/ComponentDemo.tsx b/apps/site/app/components/ComponentDemo.tsx index b5d92a418..70e422d7d 100644 --- a/apps/site/app/components/ComponentDemo.tsx +++ b/apps/site/app/components/ComponentDemo.tsx @@ -4,5 +4,8 @@ export { InteractiveDemo as ComponentDemo, DemoGrid } from './InteractiveDemo'; // Legacy exports for backward compatibility export { InteractiveDemo, InteractiveDemo as CodeDemo } from './InteractiveDemo'; +// Export PluginLoader for use in MDX files +export { PluginLoader } from './PluginLoader'; + // Export types for use in MDX files export type { SchemaNode } from './InteractiveDemo'; diff --git a/apps/site/app/components/InteractiveDemo.tsx b/apps/site/app/components/InteractiveDemo.tsx index 59cfdfe6c..45c07f631 100644 --- a/apps/site/app/components/InteractiveDemo.tsx +++ b/apps/site/app/components/InteractiveDemo.tsx @@ -1,6 +1,6 @@ 'use client'; -import React, { useState, useEffect } from 'react'; +import React from 'react'; import { SchemaRenderer } from '@object-ui/react'; import type { SchemaNode } from '@object-ui/core'; import { Tabs, Tab } from 'fumadocs-ui/components/tabs'; @@ -9,26 +9,6 @@ import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock'; // Re-export SchemaNode type for use in MDX files export type { SchemaNode } from '@object-ui/core'; -// Load plugins promise that we can await -const pluginsLoading = typeof window !== 'undefined' - ? Promise.all([ - import('@object-ui/plugin-aggrid'), - import('@object-ui/plugin-editor'), - import('@object-ui/plugin-charts'), - import('@object-ui/plugin-dashboard'), - import('@object-ui/plugin-kanban'), - import('@object-ui/plugin-markdown'), - import('@object-ui/plugin-timeline'), - import('@object-ui/plugin-calendar'), - import('@object-ui/plugin-gantt'), - import('@object-ui/plugin-map'), - import('@object-ui/plugin-chatbot'), - import('@object-ui/plugin-form'), - import('@object-ui/plugin-grid'), - import('@object-ui/plugin-view'), - ]) - : Promise.resolve([]); - interface InteractiveDemoProps { schema: SchemaNode; title?: string; @@ -49,14 +29,6 @@ export function InteractiveDemo({ description, examples }: InteractiveDemoProps) { - const [pluginsLoaded, setPluginsLoaded] = useState(false); - - useEffect(() => { - // Wait for plugins to load before rendering - pluginsLoading.then(() => { - setPluginsLoaded(true); - }); - }, []); // If examples are provided, show a multi-example view if (examples && examples.length > 0) { @@ -70,27 +42,23 @@ export function InteractiveDemo({ )} - {!pluginsLoaded ? ( -
Loading plugins...
- ) : ( -
- {examples.map((example, index) => ( -
- {example.label && ( -
-

{example.label}

- {example.description && ( -

{example.description}

- )} -
- )} -
- +
+ {examples.map((example, index) => ( +
+ {example.label && ( +
+

{example.label}

+ {example.description && ( +

{example.description}

+ )}
+ )} +
+
- ))} -
- )} +
+ ))} +
@@ -125,11 +93,7 @@ export function InteractiveDemo({
- {!pluginsLoaded ? ( -
Loading plugins...
- ) : ( - - )} +
diff --git a/apps/site/app/components/PluginLoader.tsx b/apps/site/app/components/PluginLoader.tsx new file mode 100644 index 000000000..60571e9c2 --- /dev/null +++ b/apps/site/app/components/PluginLoader.tsx @@ -0,0 +1,115 @@ +'use client'; + +import { useEffect, useState } from 'react'; + +type PluginName = + | 'aggrid' + | 'editor' + | 'charts' + | 'dashboard' + | 'kanban' + | 'markdown' + | 'timeline' + | 'calendar' + | 'gantt' + | 'map' + | 'chatbot' + | 'form' + | 'grid' + | 'view'; + +interface PluginLoaderProps { + plugins: PluginName[]; + children: React.ReactNode; +} + +/** + * PluginLoader component - Loads specific plugins on-demand + * + * Usage in MDX files: + * ```mdx + * import { PluginLoader } from '@/app/components/PluginLoader'; + * + * + * + * + * ``` + */ +export function PluginLoader({ plugins, children }: PluginLoaderProps) { + const [loaded, setLoaded] = useState(false); + + useEffect(() => { + let cancelled = false; + + const loadPlugins = async () => { + // On server side, skip actual imports but mark as loaded to avoid hydration mismatch + if (typeof window === 'undefined') { + if (!cancelled) { + setLoaded(true); + } + return; + } + + try { + // Dynamically import plugins based on the list + const imports = plugins.map(async (plugin) => { + switch (plugin) { + case 'aggrid': + return import('@object-ui/plugin-aggrid'); + case 'editor': + return import('@object-ui/plugin-editor'); + case 'charts': + return import('@object-ui/plugin-charts'); + case 'dashboard': + return import('@object-ui/plugin-dashboard'); + case 'kanban': + return import('@object-ui/plugin-kanban'); + case 'markdown': + return import('@object-ui/plugin-markdown'); + case 'timeline': + return import('@object-ui/plugin-timeline'); + case 'calendar': + return import('@object-ui/plugin-calendar'); + case 'gantt': + return import('@object-ui/plugin-gantt'); + case 'map': + return import('@object-ui/plugin-map'); + case 'chatbot': + return import('@object-ui/plugin-chatbot'); + case 'form': + return import('@object-ui/plugin-form'); + case 'grid': + return import('@object-ui/plugin-grid'); + case 'view': + return import('@object-ui/plugin-view'); + default: + console.warn(`Unknown plugin: ${plugin}`); + return Promise.resolve(); + } + }); + + await Promise.all(imports); + if (!cancelled) { + setLoaded(true); + } + } catch (error) { + console.error('Failed to load plugins:', error); + if (!cancelled) { + setLoaded(true); // Still render children even if plugin loading fails + } + } + }; + + loadPlugins(); + + return () => { + cancelled = true; + }; + }, [plugins]); + + if (!loaded) { + return
Loading plugins...
; + } + + return <>{children}; +} diff --git a/apps/site/package.json b/apps/site/package.json index 7dc8ca30f..0d77f5565 100644 --- a/apps/site/package.json +++ b/apps/site/package.json @@ -17,6 +17,7 @@ "@object-ui/plugin-calendar": "workspace:*", "@object-ui/plugin-charts": "workspace:*", "@object-ui/plugin-chatbot": "workspace:*", + "@object-ui/plugin-dashboard": "workspace:*", "@object-ui/plugin-editor": "workspace:*", "@object-ui/plugin-gantt": "workspace:*", "@object-ui/plugin-kanban": "workspace:*", diff --git a/content/docs/plugins/plugin-aggrid.mdx b/content/docs/plugins/plugin-aggrid.mdx index f7929f786..6e8f1ce1f 100644 --- a/content/docs/plugins/plugin-aggrid.mdx +++ b/content/docs/plugins/plugin-aggrid.mdx @@ -3,6 +3,7 @@ title: "Plugin AgGrid" --- import { InteractiveDemo } from '@/app/components/InteractiveDemo'; +import { PluginLoader } from '@/app/components/PluginLoader'; Data grid component powered by AG Grid Community Edition with lazy loading for optimal performance. @@ -14,6 +15,8 @@ npm install @object-ui/plugin-aggrid ag-grid-community ag-grid-react Note: `ag-grid-community` and `ag-grid-react` are peer dependencies and must be installed separately. + + ## Interactive Examples ### Basic Data Grid @@ -641,3 +644,5 @@ This results in significantly faster initial page loads for applications that do - [AG Grid Community Documentation](https://www.ag-grid.com/documentation/) - [Column Definitions Guide](https://www.ag-grid.com/documentation/javascript/column-definitions/) - [Grid Options Reference](https://www.ag-grid.com/documentation/javascript/grid-options/) + + diff --git a/content/docs/plugins/plugin-calendar.mdx b/content/docs/plugins/plugin-calendar.mdx index 8df232bd2..aec330125 100644 --- a/content/docs/plugins/plugin-calendar.mdx +++ b/content/docs/plugins/plugin-calendar.mdx @@ -3,6 +3,7 @@ title: "Plugin Calendar" --- import { InteractiveDemo } from '@/app/components/InteractiveDemo'; +import { PluginLoader } from '@/app/components/PluginLoader'; Calendar view components for ObjectUI - includes both ObjectQL-integrated and standalone calendar components. @@ -12,6 +13,8 @@ Calendar view components for ObjectUI - includes both ObjectQL-integrated and st npm install @object-ui/plugin-calendar ``` + + ## Overview 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 - [Plugin System Overview](/docs/concepts/plugins) - [Package README](https://github.com/objectstack-ai/objectui/tree/main/packages/plugin-calendar) + + diff --git a/content/docs/plugins/plugin-charts.mdx b/content/docs/plugins/plugin-charts.mdx index c24478420..1c8db1d44 100644 --- a/content/docs/plugins/plugin-charts.mdx +++ b/content/docs/plugins/plugin-charts.mdx @@ -3,6 +3,7 @@ title: "Plugin Charts" --- import { InteractiveDemo } from '@/app/components/InteractiveDemo'; +import { PluginLoader } from '@/app/components/PluginLoader'; Data visualization components powered by Recharts. @@ -12,6 +13,8 @@ Data visualization components powered by Recharts. npm install @object-ui/plugin-charts ``` + + ## Interactive Examples diff --git a/content/docs/plugins/plugin-chatbot.mdx b/content/docs/plugins/plugin-chatbot.mdx index fc6f406f4..5d40ca637 100644 --- a/content/docs/plugins/plugin-chatbot.mdx +++ b/content/docs/plugins/plugin-chatbot.mdx @@ -3,6 +3,7 @@ title: "Plugin Chatbot" --- import { InteractiveDemo } from '@/app/components/InteractiveDemo'; +import { PluginLoader } from '@/app/components/PluginLoader'; Chat interface component with message history, typing indicators, and customizable avatars. @@ -12,6 +13,8 @@ Chat interface component with message history, typing indicators, and customizab npm install @object-ui/plugin-chatbot ``` + + ## Interactive Examples ### Basic Chatbot @@ -464,3 +467,5 @@ const chatbotSchema: ChatbotSchema = { - [Plugin System Overview](/docs/concepts/plugins) - [Package README](https://github.com/objectstack-ai/objectui/tree/main/packages/plugin-chatbot) + + diff --git a/content/docs/plugins/plugin-dashboard.mdx b/content/docs/plugins/plugin-dashboard.mdx index 4fd8900d0..94d4bb9e4 100644 --- a/content/docs/plugins/plugin-dashboard.mdx +++ b/content/docs/plugins/plugin-dashboard.mdx @@ -3,6 +3,7 @@ title: "Plugin Dashboard" --- import { InteractiveDemo } from '@/app/components/InteractiveDemo'; +import { PluginLoader } from '@/app/components/PluginLoader'; Dashboard layouts and metric widgets for creating beautiful dashboards with KPIs, charts, and statistics. @@ -12,6 +13,8 @@ Dashboard layouts and metric widgets for creating beautiful dashboards with KPIs npm install @object-ui/plugin-dashboard ``` + + ## Interactive Examples diff --git a/content/docs/plugins/plugin-editor.mdx b/content/docs/plugins/plugin-editor.mdx index 1c726f373..cd254d960 100644 --- a/content/docs/plugins/plugin-editor.mdx +++ b/content/docs/plugins/plugin-editor.mdx @@ -3,6 +3,7 @@ title: "Plugin Editor" --- import { InteractiveDemo } from '@/app/components/InteractiveDemo'; +import { PluginLoader } from '@/app/components/PluginLoader'; Code editor component powered by Monaco Editor (VS Code's editor). @@ -12,6 +13,8 @@ Code editor component powered by Monaco Editor (VS Code's editor). npm install @object-ui/plugin-editor ``` + + ## Interactive Examples diff --git a/content/docs/plugins/plugin-form.mdx b/content/docs/plugins/plugin-form.mdx index ecdbf5d98..ff16d33e9 100644 --- a/content/docs/plugins/plugin-form.mdx +++ b/content/docs/plugins/plugin-form.mdx @@ -3,6 +3,7 @@ title: "Plugin Form" --- import { InteractiveDemo } from '@/app/components/InteractiveDemo'; +import { PluginLoader } from '@/app/components/PluginLoader'; Advanced form components with validation, multi-step forms, and comprehensive field support. @@ -12,6 +13,8 @@ Advanced form components with validation, multi-step forms, and comprehensive fi npm install @object-ui/plugin-form ``` + + ## Interactive Examples diff --git a/content/docs/plugins/plugin-grid.mdx b/content/docs/plugins/plugin-grid.mdx index c667619c9..22f69f12e 100644 --- a/content/docs/plugins/plugin-grid.mdx +++ b/content/docs/plugins/plugin-grid.mdx @@ -3,6 +3,7 @@ title: "Plugin Grid" --- import { InteractiveDemo } from '@/app/components/InteractiveDemo'; +import { PluginLoader } from '@/app/components/PluginLoader'; Advanced data grid with sorting, filtering, pagination, and row selection capabilities. @@ -12,6 +13,8 @@ Advanced data grid with sorting, filtering, pagination, and row selection capabi npm install @object-ui/plugin-grid ``` + + ## Interactive Examples diff --git a/content/docs/plugins/plugin-kanban.mdx b/content/docs/plugins/plugin-kanban.mdx index 818b05a5b..88fe81928 100644 --- a/content/docs/plugins/plugin-kanban.mdx +++ b/content/docs/plugins/plugin-kanban.mdx @@ -3,6 +3,7 @@ title: "Plugin Kanban" --- import { InteractiveDemo } from '@/app/components/InteractiveDemo'; +import { PluginLoader } from '@/app/components/PluginLoader'; Kanban board component with drag-and-drop powered by @dnd-kit. @@ -12,6 +13,8 @@ Kanban board component with drag-and-drop powered by @dnd-kit. npm install @object-ui/plugin-kanban ``` + + ## Interactive Examples diff --git a/content/docs/plugins/plugin-markdown.mdx b/content/docs/plugins/plugin-markdown.mdx index f6700eb11..fc637d025 100644 --- a/content/docs/plugins/plugin-markdown.mdx +++ b/content/docs/plugins/plugin-markdown.mdx @@ -3,6 +3,7 @@ title: "Plugin Markdown" --- import { InteractiveDemo } from '@/app/components/InteractiveDemo'; +import { PluginLoader } from '@/app/components/PluginLoader'; Markdown renderer with GitHub Flavored Markdown support. @@ -12,6 +13,8 @@ Markdown renderer with GitHub Flavored Markdown support. npm install @object-ui/plugin-markdown ``` + + ## Usage ### Basic Usage @@ -379,3 +382,5 @@ const markdownSchema: MarkdownSchema = { - [Plugin System Overview](/docs/concepts/plugins) - [Lazy-Loaded Plugins Architecture](../concepts/lazy-loading) - [Package README](https://github.com/objectstack-ai/objectui/tree/main/packages/plugin-markdown) + + diff --git a/content/docs/plugins/plugin-timeline.mdx b/content/docs/plugins/plugin-timeline.mdx index 9503faa77..fd520bb25 100644 --- a/content/docs/plugins/plugin-timeline.mdx +++ b/content/docs/plugins/plugin-timeline.mdx @@ -3,6 +3,7 @@ title: "Plugin Timeline" --- import { InteractiveDemo } from '@/app/components/InteractiveDemo'; +import { PluginLoader } from '@/app/components/PluginLoader'; Timeline component with vertical, horizontal, and Gantt-style layouts for displaying events and project timelines. @@ -12,6 +13,8 @@ Timeline component with vertical, horizontal, and Gantt-style layouts for displa npm install @object-ui/plugin-timeline ``` + + ## Interactive Examples ### Vertical Timeline @@ -462,3 +465,5 @@ const timelineSchema: TimelineSchema = { - [Plugin System Overview](/docs/concepts/plugins) - [Package README](https://github.com/objectstack-ai/objectui/tree/main/packages/plugin-timeline) + + diff --git a/content/docs/plugins/plugin-view.mdx b/content/docs/plugins/plugin-view.mdx index e257747d3..e1a34327d 100644 --- a/content/docs/plugins/plugin-view.mdx +++ b/content/docs/plugins/plugin-view.mdx @@ -3,6 +3,7 @@ title: "Plugin View" --- import { InteractiveDemo } from '@/app/components/InteractiveDemo'; +import { PluginLoader } from '@/app/components/PluginLoader'; Unified view component for ObjectQL objects with automatic form and grid generation. @@ -12,6 +13,8 @@ Unified view component for ObjectQL objects with automatic form and grid generat npm install @object-ui/plugin-view ``` + + ## Features - **Automatic Views** - Generate views from ObjectQL schemas @@ -256,3 +259,5 @@ const userView: ObjectViewSchema = { ## License MIT + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f1ff554ce..2713c3441 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -126,6 +126,9 @@ importers: '@object-ui/plugin-chatbot': specifier: workspace:* version: link:../../packages/plugin-chatbot + '@object-ui/plugin-dashboard': + specifier: workspace:* + version: link:../../packages/plugin-dashboard '@object-ui/plugin-editor': specifier: workspace:* version: link:../../packages/plugin-editor