-
Notifications
You must be signed in to change notification settings - Fork 0
Add Storybook stories for all 14 plugin packages #252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
@copilot Unable to preload CSS for https://objectui-components-git-copilot-add-stories-751319-object-stack.vercel.app/assets/preview-BblJuEE8.css |
…rcular dependencies Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Fixed in commit 8dda86b. Root cause: Plugin packages weren't imported in Storybook, causing component registration and CSS loading failures. Solution: Added Vite aliases in Verification: Storybook now builds successfully and all plugin components render correctly. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
- Changed titles in calendar, card, carousel, charts, chatbot, code editor, collapsible, controls, dashboard, data table, data display extras, date picker, dialog, feedback extras, feedback others, form advanced, form extras, form inputs, grid, icon, input, kanban, layout extended, layout flex, markdown, menus, navigation menu, object form, object gantt, object grid, object map, object view, overlay extras, overlay others, page, resizable, select, separator, sidebar, statistic, tabs, timeline, typography, and button stories to reflect the new schema structure.
📦 Bundle Size Report
Size Limits
|
Added @storybook/test-runner and playwright to devDependencies in package.json and introduced a new 'test:storybook' script. This enables automated testing for Storybook components.
|
✅ All checks passed!
|
📦 Bundle Size Report
Size Limits
|
|
✅ All checks passed!
|
📦 Bundle Size Report
Size Limits
|
📦 Bundle Size Report
Size Limits
|
|
✅ All checks passed!
|
1 similar comment
|
✅ All checks passed!
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request adds comprehensive Storybook integration for the ObjectUI monorepo, including stories for all 14 plugin packages and reorganizing the existing component stories.
Changes:
- Moved Storybook configuration from package-level (
packages/components/.storybook/) to repository root (.storybook/) - Created 14 new story files for plugin components (aggrid, calendar, charts, chatbot, code-editor, dashboard, kanban, markdown, object-form, object-gantt, object-grid, object-map, object-view, timeline)
- Reorganized existing stories into a new category structure (Schema/Actions, Schema/Inputs, Schema/Layout, Schema/Data Display, Schema/Navigation, Schema/Feedback, Schema/Plugins)
- Fixed plugin component infinite loop issues in ObjectMap, ObjectGrid, and ObjectGantt by adding useMemo for dataConfig
- Refactored toggle-group component to use
selectionTypeinstead ofgroupType - Added CI workflow for Storybook testing via Playwright
- Configured Vercel deployment for Storybook static build
Reviewed changes
Copilot reviewed 70 out of 73 changed files in this pull request and generated 21 comments.
Show a summary per file
| File | Description |
|---|---|
.storybook/main.ts |
New root-level Storybook configuration with Vite aliases for plugin packages |
.storybook/preview.ts |
New preview configuration importing all plugin packages and setting up story sorting |
packages/components/.storybook/* |
Removed old package-level Storybook configs (moved to root) |
packages/components/src/stories-json/*.stories.tsx |
14 new plugin stories + reorganized 35+ existing stories into new categories |
packages/plugin-*/src/*.tsx |
Added useMemo pattern to prevent infinite loops in data fetching |
packages/components/src/renderers/disclosure/toggle-group.tsx |
Renamed groupType to selectionType and extracted type prop |
packages/components/src/renderers/form/toggle.tsx |
Fixed enum property naming issue (changed index to enum) |
packages/components/src/index.css |
Updated @source path for Tailwind scanning |
package.json |
Added Storybook scripts and dependencies at root level |
.github/workflows/storybook-tests.yml |
New CI workflow for automated Storybook testing |
vercel.json |
Configuration for Storybook deployment |
postcss.config.mjs |
Added PostCSS configuration for Tailwind |
|
|
||
| /* Scan sources for Tailwind classes */ | ||
| @source './src/**/*.{ts,tsx}'; | ||
| @source '../src/**/*.{ts,tsx}'; |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The @source path '../src/**/*.{ts,tsx}' appears incorrect. This file is located at packages/components/src/index.css, so '../src' would resolve to 'packages/components/src/src' which doesn't exist.
The original path './src/**/*.{ts,tsx}' would resolve to 'packages/components/src/src' from the CSS file's location, which also seems wrong unless there's a nested src folder.
Most likely, the @source directive should use a pattern relative to where this CSS file is processed (usually the project root or package root). Consider using './**/*.{ts,tsx}' to scan the current directory and subdirectories, or verify the intended Tailwind v4 @source pattern for this monorepo setup.
| @source '../src/**/*.{ts,tsx}'; | |
| @source './**/*.{ts,tsx}'; |
| title: 'Schema/Plugins/Personal Information', | ||
| fields: [ | ||
| { name: 'firstName', label: 'First Name', type: 'text', required: true }, | ||
| { name: 'lastName', label: 'Last Name', type: 'text', required: true }, | ||
| { name: 'dateOfBirth', label: 'Date of Birth', type: 'date' } | ||
| ] | ||
| }, | ||
| { | ||
| title: 'Schema/Plugins/Contact Details', | ||
| fields: [ | ||
| { name: 'email', label: 'Email', type: 'email', required: true }, | ||
| { name: 'phone', label: 'Phone', type: 'tel' }, | ||
| { name: 'address', label: 'Address', type: 'textarea' } | ||
| ] | ||
| } | ||
| ], |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Story data contains "Schema/Plugins/" prefix in section titles which appears to be incorrectly copy-pasted from the Storybook category path. Section titles like 'Schema/Plugins/Personal Information', 'Schema/Plugins/Contact Details' should just be 'Personal Information', 'Contact Details'.
The meta.title defines the Storybook category ('Schema/Plugins/Object Form'), but the actual data items within stories should have plain titles without the category prefix.
| args: { | ||
| type: 'dialog', | ||
| title: 'Edit profile', | ||
| title: 'Schema/Feedback/Edit profile', |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Story data contains "Schema/Feedback/" prefix in the title which appears to be incorrectly copy-pasted from the Storybook category path. The title should just be 'Edit profile', not 'Schema/Feedback/Edit profile'.
The meta.title defines the Storybook category ('Schema/Feedback/Dialog'), but the actual data items within stories should have plain titles without the category prefix.
| import type { StorybookConfig } from "@storybook/react-vite"; | ||
| import { mergeConfig } from 'vite'; | ||
| import path from 'path'; | ||
|
|
||
| const config: StorybookConfig = { | ||
| stories: ["../packages/**/src/**/*.mdx", "../packages/**/src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], | ||
| addons: [ | ||
| "@storybook/addon-links", | ||
| "@storybook/addon-essentials", | ||
| "@storybook/addon-interactions", | ||
| ], | ||
| framework: { | ||
| name: "@storybook/react-vite", | ||
| options: {}, | ||
| }, | ||
| docs: { | ||
| autodocs: "tag", | ||
| }, | ||
| async viteFinal(config) { | ||
| return mergeConfig(config, { | ||
| resolve: { | ||
| alias: { | ||
| // Alias components package to source to avoid circular dependency during build | ||
| '@object-ui/core': path.resolve(__dirname, '../packages/core/src/index.ts'), | ||
| '@object-ui/react': path.resolve(__dirname, '../packages/react/src/index.ts'), | ||
| '@object-ui/components': path.resolve(__dirname, '../packages/components/src/index.ts'), | ||
| '@object-ui/fields': path.resolve(__dirname, '../packages/fields/src/index.tsx'), | ||
| '@object-ui/layout': path.resolve(__dirname, '../packages/layout/src/index.ts'), | ||
| // Alias plugin packages for Storybook to resolve them from workspace | ||
| '@object-ui/plugin-aggrid': path.resolve(__dirname, '../packages/plugin-aggrid/src/index.tsx'), | ||
| '@object-ui/plugin-calendar': path.resolve(__dirname, '../packages/plugin-calendar/src/index.tsx'), | ||
| '@object-ui/plugin-charts': path.resolve(__dirname, '../packages/plugin-charts/src/index.tsx'), | ||
| '@object-ui/plugin-chatbot': path.resolve(__dirname, '../packages/plugin-chatbot/src/index.tsx'), | ||
| '@object-ui/plugin-dashboard': path.resolve(__dirname, '../packages/plugin-dashboard/src/index.tsx'), | ||
| '@object-ui/plugin-editor': path.resolve(__dirname, '../packages/plugin-editor/src/index.tsx'), | ||
| '@object-ui/plugin-form': path.resolve(__dirname, '../packages/plugin-form/src/index.tsx'), | ||
| '@object-ui/plugin-gantt': path.resolve(__dirname, '../packages/plugin-gantt/src/index.tsx'), | ||
| '@object-ui/plugin-grid': path.resolve(__dirname, '../packages/plugin-grid/src/index.tsx'), | ||
| '@object-ui/plugin-kanban': path.resolve(__dirname, '../packages/plugin-kanban/src/index.tsx'), | ||
| '@object-ui/plugin-map': path.resolve(__dirname, '../packages/plugin-map/src/index.tsx'), | ||
| '@object-ui/plugin-markdown': path.resolve(__dirname, '../packages/plugin-markdown/src/index.tsx'), | ||
| '@object-ui/plugin-timeline': path.resolve(__dirname, '../packages/plugin-timeline/src/index.tsx'), | ||
| '@object-ui/plugin-view': path.resolve(__dirname, '../packages/plugin-view/src/index.tsx'), | ||
| }, | ||
| }, | ||
| }); | ||
| }, | ||
| }; | ||
| export default config; |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to Guideline #2 (Documentation Driven Development), any feature implemented or refactored must include corresponding documentation updates. This PR adds:
- New Storybook configuration at the repository root
- 14 new plugin story files
- Moves Storybook from package-level to monorepo-level
However, there are no documentation updates in content/docs/guide/ to explain:
- How to run Storybook (the new pnpm storybook command)
- The new Storybook structure and organization
- How to add new stories for future components
Consider adding documentation in content/docs/guide/ or updating the relevant package README files to reflect the new Storybook setup and usage patterns.
| const rawDataConfig = getDataConfig(schema); | ||
| // Memoize dataConfig using deep comparison to prevent infinite loops | ||
| const dataConfig = useMemo(() => { | ||
| return rawDataConfig; | ||
| }, [JSON.stringify(rawDataConfig)]); |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using JSON.stringify in the dependency array of useMemo defeats its purpose and creates a performance anti-pattern. On every render, JSON.stringify creates a new string, causing the useMemo to recompute every time even if the actual data hasn't changed.
Instead, consider one of these approaches:
- Use a deep comparison library like react-fast-compare or use-deep-compare-effect
- List specific primitive dependencies from rawDataConfig (e.g., rawDataConfig?.provider, rawDataConfig?.object)
- Use useRef to store the previous value and do a manual deep comparison if truly necessary
The current implementation provides no memoization benefit while adding the computational cost of JSON.stringify on every render.
| className: "w-[350px]", | ||
| // Using high-level props supported by CardRenderer | ||
| title: "Create Project", | ||
| title: 'Schema/Layout/Create Project', |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Story data contains "Schema/Layout/" prefix in the title which appears to be incorrectly copy-pasted from the Storybook category path. The title should just be 'Create Project', not 'Schema/Layout/Create Project'.
The meta.title defines the Storybook category ('Schema/Layout/Card'), but the actual data items within stories should have plain titles without the category prefix.
| title: 'Schema/Layout/Create Project', | |
| title: 'Create Project', |
| setData(prev => { | ||
| const newItems = dataConfig.items as any[]; | ||
| if (JSON.stringify(prev) !== JSON.stringify(newItems)) { | ||
| return newItems; | ||
| } | ||
| return prev; | ||
| }); |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using JSON.stringify for deep comparison in setState is inefficient and creates unnecessary computational overhead on every effect run. This pattern performs serialization twice (once for prev, once for newItems) on every render when hasInlineData is true.
Consider using a dedicated deep comparison library like fast-deep-equal, or better yet, rely on React's built-in object identity checks if the data source properly memoizes the items array.
| { name: 'variant', type: 'enum', index: ['default', 'outline'], defaultValue: 'default', label: 'Variant' }, | ||
| { name: 'size', type: 'enum', index: ['default', 'sm', 'lg'], defaultValue: 'default', label: 'Size' }, |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The property name should be 'enum' not 'index'. This is inconsistent with the rest of the codebase where 'enum' is used to specify the allowed values for enum type inputs (see button-group.tsx, separator.tsx, carousel.tsx, etc.).
Change 'index' to 'enum' to maintain consistency with the established pattern.
| { name: 'variant', type: 'enum', index: ['default', 'outline'], defaultValue: 'default', label: 'Variant' }, | |
| { name: 'size', type: 'enum', index: ['default', 'sm', 'lg'], defaultValue: 'default', label: 'Size' }, | |
| { name: 'variant', type: 'enum', enum: ['default', 'outline'], defaultValue: 'default', label: 'Variant' }, | |
| { name: 'size', type: 'enum', enum: ['default', 'sm', 'lg'], defaultValue: 'default', label: 'Size' }, |
| title: 'Schema/Data Display/Project Started', | ||
| description: 'Kickoff meeting and initial planning', | ||
| variant: 'success', | ||
| icon: '🚀', | ||
| }, | ||
| { | ||
| time: '2024-02-01', | ||
| title: 'Schema/Data Display/First Milestone', | ||
| description: 'Completed initial design phase', | ||
| variant: 'info', | ||
| icon: '🎨', | ||
| }, | ||
| { | ||
| time: '2024-03-15', | ||
| title: 'Schema/Data Display/Beta Release', | ||
| description: 'Released beta version to testers', | ||
| variant: 'warning', | ||
| icon: '⚡', | ||
| }, | ||
| { | ||
| time: '2024-04-01', | ||
| title: 'Schema/Data Display/Launch', | ||
| description: 'Official product launch', | ||
| variant: 'success', | ||
| icon: '🎉', | ||
| }, | ||
| ] | ||
| } as any, | ||
| }; | ||
|
|
||
| export const Horizontal: Story = { | ||
| render: renderStory, | ||
| args: { | ||
| type: 'timeline', | ||
| variant: 'horizontal', | ||
| dateFormat: 'short', | ||
| items: [ | ||
| { | ||
| time: '2024-01-01', | ||
| title: 'Schema/Data Display/Q1', | ||
| description: 'First quarter goals', | ||
| variant: 'default', | ||
| }, | ||
| { | ||
| time: '2024-04-01', | ||
| title: 'Schema/Data Display/Q2', | ||
| description: 'Second quarter goals', | ||
| variant: 'info', | ||
| }, | ||
| { | ||
| time: '2024-07-01', | ||
| title: 'Schema/Data Display/Q3', | ||
| description: 'Third quarter goals', | ||
| variant: 'warning', | ||
| }, | ||
| { | ||
| time: '2024-10-01', | ||
| title: 'Schema/Data Display/Q4', | ||
| description: 'Fourth quarter goals', | ||
| variant: 'success', | ||
| }, | ||
| ] |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Story data contains "Schema/Data Display/" prefix in titles which appears to be incorrectly copy-pasted from the Storybook category path. Titles like 'Schema/Data Display/Project Started', 'Schema/Data Display/Q1', etc. should just be 'Project Started', 'Q1', etc.
The meta.title defines the Storybook category ('Schema/Data Display/Timeline'), but the actual data items within stories should have plain titles without the category prefix.
| { type: 'button', props: { variant: 'outline' }, children: [{type: 'text', content: 'Open Sheet'}] } | ||
| ], | ||
| title: 'Edit profile', | ||
| title: 'Schema/Navigation/Edit profile', |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Story data contains "Schema/Navigation/" prefix in the title which appears to be incorrectly copy-pasted from the Storybook category path. The title should just be 'Edit profile', not 'Schema/Navigation/Edit profile'.
The meta.title defines the Storybook category ('Schema/Navigation/Menus'), but the actual data items within stories should have plain titles without the category prefix.

📚 Add Storybook Stories for All Plugin Components
🎯 Task Complete ✅
Successfully evaluated the current Storybook setup and added comprehensive stories for all 14 missing plugin components as requested in the issue (评估目前的storybook,为所有缺少的组件插件添加story).
📊 Summary
Created 14 new story files with 41 individual story examples covering all plugin components in the ObjectUI ecosystem.
✅ All Plugin Components Now Have Stories
Standalone Plugins (9 packages)
aggrid)calendar-view)bar-chart,chart)chatbot)dashboard,metric)code-editor)kanban)markdown)timeline)ObjectStack-Integrated Plugins (5 packages)
object-form)object-gantt)object-grid)object-map)object-view)🔧 Implementation Details
packages/components/src/stories-json/SchemaRenderercomponent🐛 Fixed Build Issue
@object-ui/components.storybook/main.tsto resolve plugin packages from source during Storybook build✨ Quality Assurance
📝 Files Modified/Added
🎓 Story Coverage
Each plugin now includes stories demonstrating:
🔍 Before & After
Before: 35 story files, 0 plugin stories, build failures
After: 49 story files, 14 plugin stories covering all 14 plugin packages, successful builds
🚀 Usage
All stories are now accessible in Storybook under the "Plugins" category:
📚 Documentation Value
These stories serve as:
🔒 Security Summary
Issue Resolved: 评估目前的storybook,为所有缺少的组件插件添加story ✅
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.