Conversation
- Created 10 beautiful pre-built widgets using basic components: 1. User Profile Card - profile with avatar, stats, and actions 2. Task List Item - task with priority badge and progress 3. Notification Card - activity notifications with timestamps 4. Weather Widget - current weather with forecast details 5. Stats Dashboard Card - metrics with trend indicators 6. Product Card - e-commerce product with image and details 7. Music Player - compact player with album art and controls 8. Social Media Post - post card with engagement metrics 9. Calendar Event - meeting/event card with participants 10. Email Preview - email card with sender info and actions - Implemented gallery page with: - Grid layout displaying all widgets - Interactive preview of each widget - Dialog showing widget's JSX template with syntax highlighting - "Use This Widget" button to create and edit widget in editor - Navigation integration with sidebar menu Co-authored-by: foreleven <4785594+foreleven@users.noreply.github.com>
- Extract selectedWidgetData to reduce duplication in dialog rendering - Use computed variable instead of repeated null checks and array access - Improve code readability and maintainability Co-authored-by: foreleven <4785594+foreleven@users.noreply.github.com>
| schema={undefined} | ||
| components={components} | ||
| data={item.widget.states?.[0]?.data ?? {}} | ||
| template={item.widget.template} |
There was a problem hiding this comment.
@copilot The WidgetRenderer is not support template not. You can add this support, parse the schema from template when the schema prop not provided
There was a problem hiding this comment.
Added template prop support to WidgetRenderer in commit ab14c6e. When schema is not provided but template is, the renderer now automatically parses the template using parseJSXTemplate and renders the widget.
Changes:
- Added
template?: stringtoWidgetRendererProps - Parse template to schema when schema is undefined
- Gallery widgets now render correctly using the template prop
- Parse template string to schema when schema is not provided - Allows rendering widgets directly from JSX template strings - Enables gallery to use template prop instead of pre-parsing schemas Co-authored-by: foreleven <4785594+foreleven@users.noreply.github.com>
There was a problem hiding this comment.
Pull Request Overview
This PR adds a widget gallery feature that displays pre-built widget templates and allows users to preview and use them in their projects. The implementation includes template parsing support in the WidgetRenderer component and ten example widget templates.
Key changes:
- Enhanced WidgetRenderer to support direct template parsing via a new
templateprop - Added a new gallery page with preview and detailed view functionality
- Created ten pre-built widget templates (weather, profile card, task list, etc.)
Reviewed Changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/widget-renderer/src/WidgetRenderer.tsx | Added template parsing support via new template prop and parseJSXTemplate function |
| apps/widget-builder/src/pages/layout/AppSidebar.tsx | Added gallery navigation link with Sparkles icon |
| apps/widget-builder/src/pages/gallery/WidgetGallery.tsx | Implemented gallery UI with grid layout, preview cards, and detail dialog |
| apps/widget-builder/src/pages/gallery/widgets/*.ts | Ten widget template definitions with JSX templates and sample data |
| apps/widget-builder/src/pages/gallery/widgets/index.ts | Aggregates and exports all gallery widgets |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <div | ||
| key={index} | ||
| className="group relative cursor-pointer rounded-lg border bg-card p-6 hover:border-primary hover:shadow-lg transition-all" | ||
| onClick={() => handleWidgetClick(index)} | ||
| > |
There was a problem hiding this comment.
The clickable gallery item div lacks keyboard accessibility. Add role=\"button\", tabIndex={0}, and an onKeyDown handler to support keyboard navigation (Enter/Space keys) for users who cannot use a mouse.
| <WidgetRenderer | ||
| schema={undefined} | ||
| components={components} | ||
| data={item.widget.states?.[0]?.data ?? {}} | ||
| template={item.widget.template} | ||
| /> |
There was a problem hiding this comment.
The WidgetRenderer parses the template on every render. Consider memoizing the parsed schema with useMemo to avoid redundant parsing operations, especially since the template is static for each gallery item.
| <WidgetRenderer | ||
| schema={undefined} | ||
| components={components} | ||
| data={selectedWidgetData.widget.states?.[0]?.data ?? {}} | ||
| template={selectedWidgetData.widget.template} | ||
| /> |
There was a problem hiding this comment.
The WidgetRenderer parses the template on every render in the dialog. Consider memoizing the parsed schema with useMemo to avoid redundant parsing operations when the dialog is opened.
| let effectiveSchema = schema; | ||
| if (!effectiveSchema && template) { | ||
| const parseResult = parseJSXTemplate(template); | ||
| if (parseResult.success && parseResult.schema) { | ||
| effectiveSchema = parseResult.schema; | ||
| } else { | ||
| console.warn("Failed to parse template:", parseResult.errors); | ||
| return null; | ||
| } | ||
| } |
There was a problem hiding this comment.
The template is parsed on every render of the component. Consider using useMemo to cache the parsed schema based on the template string to avoid redundant parsing operations.
- Cache parsed schema in useRef to avoid re-parsing on every render - Only parse template when it changes using useEffect - Track last template value to detect changes - Improves performance by preventing unnecessary parsing operations Co-authored-by: foreleven <4785594+foreleven@users.noreply.github.com>
|
@copilot Change the avatar or image url to |
- Replace pravatar.cc URLs with picsum.photos/150/150?random=X
- Replace unsplash URLs with picsum.photos/{width}/{height}?random=X
- All avatar images now use 150x150 format
- Album art and product images use appropriate dimensions
- Social media post image uses 600x400 aspect ratio
Co-authored-by: foreleven <4785594+foreleven@users.noreply.github.com>
Updated all image URLs to use picsum.photos in commit b370f1d. Changes:
All widgets now use consistent placeholder images from picsum.photos. |
- Add role="button" to clickable gallery items
- Add tabIndex={0} for keyboard navigation
- Add onKeyDown handler for Enter and Space keys
- Add aria-label for screen reader support
- Add focus ring styling with focus:ring-2 focus:ring-primary
- Improves accessibility for users who rely on keyboard navigation
Co-authored-by: foreleven <4785594+foreleven@users.noreply.github.com>


Gallery Page Implementation
This PR implements a complete gallery page for the widget builder with ten pre-built beautiful widgets.
Screenshots:
Completed:
src/pages/gallery/widgets/)templateprop support to WidgetRendererFeatures:
templateprop: automatically parses JSX template to schema when schema is not providedOriginal prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.