-
Notifications
You must be signed in to change notification settings - Fork 0
Refactor views to Shadcn UI primitives and extract visualization plugins #215
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>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
📦 Bundle Size Report
Size Limits
|
|
✅ 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 PR refactors view components in the ObjectUI library to adopt Shadcn UI primitives and extracts three visualization components (ObjectCalendar, ObjectGantt, ObjectMap) into separate plugin packages for better modularity and reduced bundle size.
Changes:
- Replaced raw HTML elements in field renderers with Shadcn UI components (Badge with icons for Boolean, Avatar for User, Button with asChild for links)
- Refactored ObjectGrid action buttons to use DropdownMenu with icons, improving UI consistency and saving space
- Extracted ObjectCalendar, ObjectGantt, and ObjectMap from @object-ui/views to dedicated plugin packages with proper component registration
Reviewed changes
Copilot reviewed 21 out of 25 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/views/src/field-renderers.tsx | Refactored to use Shadcn primitives: Badge with Check/X icons for Boolean, Avatar/AvatarFallback for User, Button variant="link" asChild for Email/URL, consistent size-* utilities for images |
| packages/views/src/ObjectGrid.tsx | Replaced inline action buttons with DropdownMenu containing Edit/Delete menu items with proper icons and destructive variant |
| packages/views/src/index.tsx | Removed exports and registrations for extracted visualization components (ObjectKanban, ObjectCalendar, ObjectGantt, ObjectMap) |
| packages/views/src/tests/field-renderers.test.tsx | Updated test assertions to match new Badge text ("True"/"False") and Avatar data-slot selector |
| packages/views/src/tests/Object*.test.tsx | Removed test files for extracted components |
| packages/plugin-calendar/* | New plugin package with ObjectCalendar component, proper package.json, vite config, and component registration |
| packages/plugin-gantt/* | New plugin package with ObjectGantt component, proper package.json, vite config, and component registration |
| packages/plugin-map/* | New plugin package with ObjectMap component, proper package.json, vite config, and component registration |
| pnpm-lock.yaml | Added dependency entries for three new plugin packages |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
| export type { ObjectCalendarProps }; | ||
|
|
||
| // Register component | ||
| const ObjectCalendarRenderer: React.FC<{ schema: any }> = ({ schema }) => { |
Copilot
AI
Jan 26, 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 plugin renderers (ObjectCalendarRenderer, ObjectGanttRenderer, ObjectMapRenderer) pass dataSource={null as any} to their components without checking if the schema has inline data first. This differs from the pattern used in the views package where ObjectGridRenderer, ObjectFormRenderer, and ObjectViewRenderer check for inline data before rendering.
If these components are rendered without inline data (i.e., when schema.data.provider is not 'value'), they will throw an error "DataSource required for object/api providers" which will be displayed as an error state. While this is handled gracefully, it would be more consistent to add the same inline data guards that exist in the views package renderers.
Consider adding the same pattern used in packages/views/src/index.tsx lines 68-84 to provide a clearer error message upfront.
| const ObjectCalendarRenderer: React.FC<{ schema: any }> = ({ schema }) => { | |
| const ObjectCalendarRenderer: React.FC<{ schema: any }> = ({ schema }) => { | |
| const provider = schema?.data?.provider; | |
| if (provider && provider !== 'value') { | |
| return ( | |
| <div className="text-sm text-destructive"> | |
| object-calendar plugin renderer requires inline data (schema.data.provider = 'value') when no dataSource is provided. | |
| </div> | |
| ); | |
| } |
| export type { ObjectGanttProps }; | ||
|
|
||
| // Register component | ||
| const ObjectGanttRenderer: React.FC<{ schema: any }> = ({ schema }) => { |
Copilot
AI
Jan 26, 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 plugin renderers (ObjectCalendarRenderer, ObjectGanttRenderer, ObjectMapRenderer) pass dataSource={null as any} to their components without checking if the schema has inline data first. This differs from the pattern used in the views package where ObjectGridRenderer, ObjectFormRenderer, and ObjectViewRenderer check for inline data before rendering.
If these components are rendered without inline data (i.e., when schema.data.provider is not 'value'), they will throw an error "DataSource required for object/api providers" which will be displayed as an error state. While this is handled gracefully, it would be more consistent to add the same inline data guards that exist in the views package renderers.
Consider adding the same pattern used in packages/views/src/index.tsx lines 68-84 to provide a clearer error message upfront.
| const ObjectGanttRenderer: React.FC<{ schema: any }> = ({ schema }) => { | |
| const ObjectGanttRenderer: React.FC<{ schema: any }> = ({ schema }) => { | |
| const provider = schema?.data?.provider; | |
| // When used as a standalone plugin renderer, we only support inline data (provider: 'value') | |
| // because no external DataSource is injected here. This mirrors the guard logic used in | |
| // the views package to fail fast with a clearer error message. | |
| if (provider && provider !== 'value') { | |
| return ( | |
| <div className="text-sm text-destructive"> | |
| ObjectGantt plugin requires inline data (schema.data.provider === "value") when no | |
| DataSource is provided. Use a views renderer or supply inline data for this plugin. | |
| </div> | |
| ); | |
| } |
|
|
||
| // Register component | ||
| const ObjectMapRenderer: React.FC<{ schema: any }> = ({ schema }) => { | ||
| return <ObjectMap schema={schema} dataSource={null as any} />; |
Copilot
AI
Jan 26, 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 plugin renderers (ObjectCalendarRenderer, ObjectGanttRenderer, ObjectMapRenderer) pass dataSource={null as any} to their components without checking if the schema has inline data first. This differs from the pattern used in the views package where ObjectGridRenderer, ObjectFormRenderer, and ObjectViewRenderer check for inline data before rendering.
If these components are rendered without inline data (i.e., when schema.data.provider is not 'value'), they will throw an error "DataSource required for object/api providers" which will be displayed as an error state. While this is handled gracefully, it would be more consistent to add the same inline data guards that exist in the views package renderers.
Consider adding the same pattern used in packages/views/src/index.tsx lines 68-84 to provide a clearer error message upfront.
| return <ObjectMap schema={schema} dataSource={null as any} />; | |
| const provider = schema?.data?.provider; | |
| const hasInlineData = provider === 'value'; | |
| const inlineData = hasInlineData ? schema?.data?.value : undefined; | |
| if (!hasInlineData) { | |
| return ( | |
| <div className="text-sm text-red-500"> | |
| Object Map plugin requires inline data. Set <code>schema.data.provider = "value"</code> and provide | |
| inline data to use this renderer. | |
| </div> | |
| ); | |
| } | |
| return <ObjectMap schema={schema} dataSource={inlineData} />; |
Replaces raw HTML/Tailwind in field renderers with Shadcn UI components and extracts complex visualization components to separate plugin packages for better modularity.
Field Renderer Changes
Badgewith LucideCheck/Xicons instead of hardcoded symbolsBadge variant="outline"with color mappingAvatar/AvatarFallbackprimitivesButton variant="link" asChildwrapping<a>tagssize-*utilitiesObjectGrid Actions
Replaced inline action buttons with
DropdownMenu:Plugin Extraction
Created standalone packages for visualization components:
@object-ui/plugin-calendar(ObjectCalendar)@object-ui/plugin-gantt(ObjectGantt)@object-ui/plugin-map(ObjectMap)Each plugin includes component registration and proper externals configuration. Removed from core
@object-ui/viewspackage to reduce bundle size.Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.