feat(a2ui-playground): unify icon set and button system#2776
Conversation
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds lucide-react and a centralized Icon module, implements a forwardRef Button component with CSS, and replaces inline buttons, SVGs, and glyphs across the a2ui-playground with the new Button and Icon primitives. ChangesButton Component System and Icon Consolidation
🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
Polishes the a2ui-playground UI by consolidating icon usage and replacing multiple bespoke button styles with a single reusable <Button> primitive, improving consistency across pages/components.
Changes:
- Added a centralized Lucide icon barrel (
Icon.tsx) plus anICON_SIZEscale. - Introduced a unified button component (
Button.tsx+Button.css) with variant/size axes and icon slots. - Swept the playground UI to replace emoji/inline SVG icons and per-page button styles with the new primitives.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds lockfile entries for the new lucide-react dependency. |
| packages/genui/a2ui-playground/package.json | Adds lucide-react dependency to the playground package. |
| packages/genui/a2ui-playground/src/styles.css | Removes legacy theme/preview button styling and aligns selectors with the new .btn primitive. |
| packages/genui/a2ui-playground/src/pages/OpenUIDemosPage.tsx | Replaces toolbar render button with <Button> + Lucide icon. |
| packages/genui/a2ui-playground/src/pages/DemosPage.tsx | Replaces playback/toolbar/back controls with <Button> + Lucide icons. |
| packages/genui/a2ui-playground/src/pages/DemosPage.css | Removes legacy button styles in favor of the shared button primitive. |
| packages/genui/a2ui-playground/src/pages/AIChatPage.tsx | Replaces chat send button + status icons and updates empty-state icon to JSX. |
| packages/genui/a2ui-playground/src/pages/AIChatPage.css | Removes legacy chat/conversation button styles and updates icon-related styling. |
| packages/genui/a2ui-playground/src/components/PreviewPanel.tsx | Replaces inline SVG and text glyph buttons with icon-only <Button> usage. |
| packages/genui/a2ui-playground/src/components/MobileTabBar.tsx | Replaces inline SVG tab icons with Lucide icons and shared sizing. |
| packages/genui/a2ui-playground/src/components/InstantExamplesStrip.tsx | Replaces emoji/arrow glyphs with Lucide icons and shared sizing. |
| packages/genui/a2ui-playground/src/components/Icon.tsx | New Lucide icon barrel + shared icon size scale. |
| packages/genui/a2ui-playground/src/components/ConversationListPanel.tsx | Replaces “New Chat” and row action buttons with <Button> + Lucide icons. |
| packages/genui/a2ui-playground/src/components/Button.tsx | New button primitive component (variants/sizes, icon slots, fullWidth/iconOnly). |
| packages/genui/a2ui-playground/src/components/Button.css | New shared styling for the button system (variants/sizes/focus/disabled). |
| packages/genui/a2ui-playground/src/App.tsx | Replaces theme toggle glyph button with icon-only <Button>. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <Button | ||
| variant='secondary' | ||
| size='lg' | ||
| fullWidth | ||
| iconBefore={MessageSquarePlus} | ||
| disabled={disabled} | ||
| onClick={onCreate} | ||
| > | ||
| <span className='conversationNewButtonIcon'>💬</span> | ||
| <span className='conversationNewButtonLabel'>+ New Chat</span> | ||
| </button> | ||
| New Chat | ||
| </Button> |
| <Button | ||
| variant='primary' | ||
| size='lg' | ||
| iconBefore={Send} | ||
| disabled={isGenerating || inputValue.trim().length === 0} | ||
| onClick={handleSend} | ||
| > | ||
| <span className='chatSendIcon' aria-hidden='true'>↖</span> | ||
| {isGenerating ? 'Generating' : 'Send'} | ||
| </button> | ||
| </Button> |
| <Button | ||
| variant='secondary' | ||
| size='md' | ||
| iconBefore={ChevronLeft} | ||
| onClick={handleBackToExamples} | ||
| aria-label='Back to Examples' | ||
| > | ||
| <span className='detailBackIcon'>←</span> | ||
| <span className='detailBackLabel'>Back to Examples</span> | ||
| </button> | ||
| Back to Examples | ||
| </Button> |
| <Button | ||
| variant='ghost' | ||
| size='sm' | ||
| iconBefore={RotateCcw} | ||
| onClick={handleFillExample} | ||
| title='Reset' | ||
| title='Reset to example' | ||
| > | ||
| ↻ Reset | ||
| </button> | ||
| <button | ||
| type='button' | ||
| className='toolbarBtn' | ||
| Reset | ||
| </Button> | ||
| <Button | ||
| variant='ghost' | ||
| size='sm' | ||
| iconBefore={X} | ||
| onClick={handleClear} | ||
| title='Clear' | ||
| title='Clear editor' | ||
| > | ||
| ✕ Clear | ||
| </button> | ||
| <button | ||
| type='button' | ||
| className='toolbarBtn primary' | ||
| Clear | ||
| </Button> | ||
| <Button | ||
| variant='primary' | ||
| size='sm' | ||
| iconBefore={Play} | ||
| onClick={handleRender} | ||
| disabled={isPublishingPayload} | ||
| > | ||
| {isPublishingPayload ? 'Publishing...' : '▶ Render'} | ||
| </button> | ||
| {isPublishingPayload ? 'Publishing...' : 'Render'} | ||
| </Button> |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
packages/genui/a2ui-playground/src/components/Button.tsx (3)
56-66: ⚡ Quick winIcon-only buttons need an accessible name.
In
iconOnlymode the label is dropped, so without anaria-labelthe button has no accessible name for screen readers. It's currently only available via...rest, so nothing prevents a consumer from omitting it. Consider documenting/enforcingaria-labelfor icon-only usage.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/genui/a2ui-playground/src/components/Button.tsx` around lines 56 - 66, When iconOnly is true the visible label (children) is removed so the button needs an accessible name; update the Button component to require an accessible name when iconOnly is set by checking props spread (rest) for aria-label or aria-labelledby and failing fast in development: in the Button render (where iconOnly, IconBefore, IconAfter, children are used) detect if iconOnly && !('aria-label' in props || 'aria-labelledby' in props) and emit a clear developer error/warning (or throw in dev) and/or add a TypeScript/PropTypes requirement so consumers must provide aria-label/aria-labelledby for icon-only buttons. Ensure the check references iconOnly and the incoming props (rest) so it prevents silent omission.
45-46: 💤 Low valueSimplify redundant
iconSizelookup.
sizeis already constrained to'sm' | 'md' | 'lg', so the nested ternary is equivalent to indexing directly.♻️ Proposed change
- const iconSize = - ICON_SIZE[size === 'lg' ? 'lg' : (size === 'sm' ? 'sm' : 'md')]; + const iconSize = ICON_SIZE[size];🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/genui/a2ui-playground/src/components/Button.tsx` around lines 45 - 46, The iconSize lookup in Button.tsx is overly verbose — replace the nested ternary expression with a direct index into ICON_SIZE using the existing size variable (i.e. use ICON_SIZE[size]) to simplify the code; update the expression that assigns iconSize (referencing ICON_SIZE and the size prop/variable) and, if necessary for TS, ensure size is typed as 'sm' | 'md' | 'lg' or cast to the correct key type so the index is type-safe.
17-18: ⚡ Quick winButton.tsx: React namespace types are already used in-package; ComponentType import is optional
Other TSX files under
packages/genui/a2ui-playgroundalready referenceReact.*types without importingReact(e.g.,AIChatPage.tsx,Chip.tsx), and the packagetsconfig.jsonhasstrict: truewithtypes: ["react", "react-dom"], soReact.*type namespaces are expected to work. SwitchingReact.ComponentTypeto an importedComponentTypeis still a reasonable consistency/clarity cleanup.♻️ Proposed change
-import type { ButtonHTMLAttributes, ReactNode } from 'react'; +import type { ButtonHTMLAttributes, ComponentType, ReactNode } from 'react';- iconBefore?: React.ComponentType<{ size?: number; strokeWidth?: number }>; - iconAfter?: React.ComponentType<{ size?: number; strokeWidth?: number }>; + iconBefore?: ComponentType<{ size?: number; strokeWidth?: number }>; + iconAfter?: ComponentType<{ size?: number; strokeWidth?: number }>;
- Double-check icon-only rendering has an accessible name (e.g.,
aria-label/aria-labelledby).- Confirm any icon sizing logic/conditional styling is simplified/consistent with the
sizeunion.- Ensure inline
strokeWidthand CSSstroke-widthdon’t conflict for the same SVG.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/genui/a2ui-playground/src/components/Button.tsx` around lines 17 - 18, The Button.tsx props currently declare iconBefore and iconAfter as ComponentType imports; change them to use the React namespace (React.ComponentType<{ size?: number; strokeWidth?: number }>) or import ComponentType consistently across the package to match other files, then ensure when rendering icon-only buttons the element always has an accessible name (add aria-label or aria-labelledby when no children), validate the size prop union usage in the render to simplify/normalize sizing logic against the declared size union, and ensure you do not apply conflicting strokeWidth via both inline prop and CSS (harmonize to a single source of truth for SVG stroke width).packages/genui/a2ui-playground/src/components/Icon.tsx (1)
9-52: ⚡ Quick winCollapse the duplicated import/export into a single re-export.
The icon names are listed twice, so adding/removing an icon requires editing both blocks and risks divergence. A direct re-export keeps tree-shaking and a single source of truth.
♻️ Proposed refactor
-import { - ArrowRight, - ArrowUpRight, - ChevronLeft, - Copy, - Maximize2, - MessageSquarePlus, - Minimize2, - Moon, - Pause, - Pencil, - Play, - RotateCcw, - Send, - Smartphone, - Sparkles, - Sun, - Trash2, - X, - Zap, -} from 'lucide-react'; -import type { LucideProps } from 'lucide-react'; - -export { - ArrowRight, - ArrowUpRight, - ChevronLeft, - Copy, - Maximize2, - MessageSquarePlus, - Minimize2, - Moon, - Pause, - Pencil, - Play, - RotateCcw, - Send, - Smartphone, - Sparkles, - Sun, - Trash2, - X, - Zap, -}; +export { + ArrowRight, + ArrowUpRight, + ChevronLeft, + Copy, + Maximize2, + MessageSquarePlus, + Minimize2, + Moon, + Pause, + Pencil, + Play, + RotateCcw, + Send, + Smartphone, + Sparkles, + Sun, + Trash2, + X, + Zap, +} from 'lucide-react'; +import type { LucideProps } from 'lucide-react';🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/genui/a2ui-playground/src/components/Icon.tsx` around lines 9 - 52, Remove the duplicated import+export block by replacing the two-step pattern with a single re-export: export the listed icon symbols (ArrowRight, ArrowUpRight, ChevronLeft, Copy, Maximize2, MessageSquarePlus, Minimize2, Moon, Pause, Pencil, Play, RotateCcw, Send, Smartphone, Sparkles, Sun, Trash2, X, Zap) directly from 'lucide-react' and re-export the LucideProps type (export type { LucideProps } from 'lucide-react'); this keeps a single source of truth and preserves tree-shaking while eliminating the need to edit icons in two places.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/genui/a2ui-playground/src/components/Button.css`:
- Around line 199-206: The comment and rules are inconsistent: the base rule
.btn svg sets stroke-width: 2 and .btn-lg svg sets 1.9 but the comment claims
"down to 1.8 on the larger sizes" and is placed on the base rule; update the
comment to reflect the actual values and move it to the .btn-lg svg block (or
change the numeric values to match the comment if 1.8 was intended).
Specifically, either change the explanatory text to mention nudging from 2 to
1.9 and attach it to .btn-lg svg, or adjust .btn svg / .btn-lg svg stroke-widths
so the comment accurately describes them.
---
Nitpick comments:
In `@packages/genui/a2ui-playground/src/components/Button.tsx`:
- Around line 56-66: When iconOnly is true the visible label (children) is
removed so the button needs an accessible name; update the Button component to
require an accessible name when iconOnly is set by checking props spread (rest)
for aria-label or aria-labelledby and failing fast in development: in the Button
render (where iconOnly, IconBefore, IconAfter, children are used) detect if
iconOnly && !('aria-label' in props || 'aria-labelledby' in props) and emit a
clear developer error/warning (or throw in dev) and/or add a
TypeScript/PropTypes requirement so consumers must provide
aria-label/aria-labelledby for icon-only buttons. Ensure the check references
iconOnly and the incoming props (rest) so it prevents silent omission.
- Around line 45-46: The iconSize lookup in Button.tsx is overly verbose —
replace the nested ternary expression with a direct index into ICON_SIZE using
the existing size variable (i.e. use ICON_SIZE[size]) to simplify the code;
update the expression that assigns iconSize (referencing ICON_SIZE and the size
prop/variable) and, if necessary for TS, ensure size is typed as 'sm' | 'md' |
'lg' or cast to the correct key type so the index is type-safe.
- Around line 17-18: The Button.tsx props currently declare iconBefore and
iconAfter as ComponentType imports; change them to use the React namespace
(React.ComponentType<{ size?: number; strokeWidth?: number }>) or import
ComponentType consistently across the package to match other files, then ensure
when rendering icon-only buttons the element always has an accessible name (add
aria-label or aria-labelledby when no children), validate the size prop union
usage in the render to simplify/normalize sizing logic against the declared size
union, and ensure you do not apply conflicting strokeWidth via both inline prop
and CSS (harmonize to a single source of truth for SVG stroke width).
In `@packages/genui/a2ui-playground/src/components/Icon.tsx`:
- Around line 9-52: Remove the duplicated import+export block by replacing the
two-step pattern with a single re-export: export the listed icon symbols
(ArrowRight, ArrowUpRight, ChevronLeft, Copy, Maximize2, MessageSquarePlus,
Minimize2, Moon, Pause, Pencil, Play, RotateCcw, Send, Smartphone, Sparkles,
Sun, Trash2, X, Zap) directly from 'lucide-react' and re-export the LucideProps
type (export type { LucideProps } from 'lucide-react'); this keeps a single
source of truth and preserves tree-shaking while eliminating the need to edit
icons in two places.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 3adfc6d6-b0be-4fd9-9940-f9be16791549
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (15)
packages/genui/a2ui-playground/package.jsonpackages/genui/a2ui-playground/src/App.tsxpackages/genui/a2ui-playground/src/components/Button.csspackages/genui/a2ui-playground/src/components/Button.tsxpackages/genui/a2ui-playground/src/components/ConversationListPanel.tsxpackages/genui/a2ui-playground/src/components/Icon.tsxpackages/genui/a2ui-playground/src/components/InstantExamplesStrip.tsxpackages/genui/a2ui-playground/src/components/MobileTabBar.tsxpackages/genui/a2ui-playground/src/components/PreviewPanel.tsxpackages/genui/a2ui-playground/src/pages/AIChatPage.csspackages/genui/a2ui-playground/src/pages/AIChatPage.tsxpackages/genui/a2ui-playground/src/pages/DemosPage.csspackages/genui/a2ui-playground/src/pages/DemosPage.tsxpackages/genui/a2ui-playground/src/pages/OpenUIDemosPage.tsxpackages/genui/a2ui-playground/src/styles.css
| /* Lucide strokes look heaviest at their baseline weight; nudging stroke | ||
| down to 1.8 on the larger sizes keeps icons from outweighing the label. */ | ||
| stroke-width: 2; | ||
| } | ||
|
|
||
| .btn-lg svg { | ||
| stroke-width: 1.9; | ||
| } |
There was a problem hiding this comment.
Comment doesn't match the code.
The comment states the stroke is nudged "down to 1.8 on the larger sizes," but .btn svg is set to 2 and the large-size override (.btn-lg svg) is 1.9. Also, the explanatory comment lives on the base .btn svg rule rather than the .btn-lg svg rule it describes. Align the comment with the actual values/location.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/genui/a2ui-playground/src/components/Button.css` around lines 199 -
206, The comment and rules are inconsistent: the base rule .btn svg sets
stroke-width: 2 and .btn-lg svg sets 1.9 but the comment claims "down to 1.8 on
the larger sizes" and is placed on the base rule; update the comment to reflect
the actual values and move it to the .btn-lg svg block (or change the numeric
values to match the comment if 1.8 was intended). Specifically, either change
the explanatory text to mention nudging from 2 to 1.9 and attach it to .btn-lg
svg, or adjust .btn svg / .btn-lg svg stroke-widths so the comment accurately
describes them.
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/genui/a2ui-playground/src/pages/DemosPage.css (1)
1098-1105:⚠️ Potential issue | 🟠 Major | ⚡ Quick winMobile toolbar compaction rules currently target removed
.toolbarBtnclasses.At Line 1098 and Line 1103, these selectors no longer match the migrated shared
<Button>controls, so the ≤720px compaction can silently stop applying and the toolbar may wrap/crowd again on phones.Suggested selector update
- .codePanelToolbar .toolbarBtn { + .codePanelToolbar .btn { height: 26px; padding: 0 8px; font-size: 11px; } - .codePanelToolbar .toolbarBtn.primary { + .codePanelToolbar .btn.btn-primary { padding: 0 10px; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/genui/a2ui-playground/src/pages/DemosPage.css` around lines 1098 - 1105, The media-query compaction rules currently target the removed selectors ".codePanelToolbar .toolbarBtn" and ".codePanelToolbar .toolbarBtn.primary", so update those selectors to match the migrated shared Button component (and native button elements) used in the toolbar; for example replace occurrences of ".codePanelToolbar .toolbarBtn" with selectors that target the shared Button class and elements such as ".codePanelToolbar .Button" and ".codePanelToolbar button", and update the primary variant selector proportionally (e.g. ".codePanelToolbar .Button.primary" or ".codePanelToolbar button.primary") so the ≤720px compaction still applies to the toolbar controls.
🧹 Nitpick comments (1)
packages/genui/a2ui-playground/src/pages/DemosPage.css (1)
1049-1056: ⚡ Quick winLegacy back-button selectors are now dead CSS after Button migration.
Line 1049 and Line 1052 target
.detailBackLabel/.detailBackButton, but the sidebar back control now renders through shared<Button>(withresponsiveIconOnly), so these hooks are stale and misleading.Cleanup option
- .detailBackLabel { - display: none; - } - .detailBackButton { - min-height: 32px; - padding: 6px 10px; - box-shadow: none; - }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/genui/a2ui-playground/src/pages/DemosPage.css` around lines 1049 - 1056, Remove the dead CSS selectors .detailBackLabel and .detailBackButton from DemosPage.css since the sidebar back control now uses the shared Button component with the responsiveIconOnly prop; search for .detailBackLabel and .detailBackButton in the file and delete those rule blocks (or consolidate any remaining needed styling onto the shared Button styles/variants instead) to avoid stale, misleading hooks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@packages/genui/a2ui-playground/src/pages/DemosPage.css`:
- Around line 1098-1105: The media-query compaction rules currently target the
removed selectors ".codePanelToolbar .toolbarBtn" and ".codePanelToolbar
.toolbarBtn.primary", so update those selectors to match the migrated shared
Button component (and native button elements) used in the toolbar; for example
replace occurrences of ".codePanelToolbar .toolbarBtn" with selectors that
target the shared Button class and elements such as ".codePanelToolbar .Button"
and ".codePanelToolbar button", and update the primary variant selector
proportionally (e.g. ".codePanelToolbar .Button.primary" or ".codePanelToolbar
button.primary") so the ≤720px compaction still applies to the toolbar controls.
---
Nitpick comments:
In `@packages/genui/a2ui-playground/src/pages/DemosPage.css`:
- Around line 1049-1056: Remove the dead CSS selectors .detailBackLabel and
.detailBackButton from DemosPage.css since the sidebar back control now uses the
shared Button component with the responsiveIconOnly prop; search for
.detailBackLabel and .detailBackButton in the file and delete those rule blocks
(or consolidate any remaining needed styling onto the shared Button
styles/variants instead) to avoid stale, misleading hooks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 3dcbe706-c0df-4e61-b03b-ef7e02fffee4
📒 Files selected for processing (5)
packages/genui/a2ui-playground/src/components/Button.csspackages/genui/a2ui-playground/src/components/Button.tsxpackages/genui/a2ui-playground/src/components/ConversationListPanel.tsxpackages/genui/a2ui-playground/src/pages/DemosPage.csspackages/genui/a2ui-playground/src/pages/DemosPage.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
- packages/genui/a2ui-playground/src/components/ConversationListPanel.tsx
- packages/genui/a2ui-playground/src/components/Button.tsx
- packages/genui/a2ui-playground/src/pages/DemosPage.tsx
- packages/genui/a2ui-playground/src/components/Button.css
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/genui/a2ui-playground/src/pages/AIChatPage.css`:
- Around line 1466-1469: The horizontal gutter for .promptSuggestionsRail was
reduced to 14px but the element that controls snapping still uses
scroll-padding-left: 24px, causing snap alignment issues on mobile; update the
scroll-padding-left value (wherever it is set for the suggestions rail/scroll
container) to 14px to match .promptSuggestionsRail so snap positions align, or
set an explicit scroll-padding-inline/start property on .promptSuggestionsRail
to 14px to ensure consistent snapping.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 0b410842-66fc-4d3a-8efc-44e48ee7fc3e
📒 Files selected for processing (1)
packages/genui/a2ui-playground/src/pages/AIChatPage.css
| .promptSuggestionsRail { | ||
| padding: 2px 14px 4px; | ||
| margin: 0 -14px; | ||
| } |
There was a problem hiding this comment.
Fix snap offset mismatch in the mobile suggestions rail.
You reduced .promptSuggestionsRail horizontal gutter to 14px, but scroll-padding-left still inherits 24px, so snap alignment is off on mobile.
Suggested fix
.promptSuggestionsRail {
padding: 2px 14px 4px;
margin: 0 -14px;
+ scroll-padding-left: 14px;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .promptSuggestionsRail { | |
| padding: 2px 14px 4px; | |
| margin: 0 -14px; | |
| } | |
| .promptSuggestionsRail { | |
| padding: 2px 14px 4px; | |
| margin: 0 -14px; | |
| scroll-padding-left: 14px; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/genui/a2ui-playground/src/pages/AIChatPage.css` around lines 1466 -
1469, The horizontal gutter for .promptSuggestionsRail was reduced to 14px but
the element that controls snapping still uses scroll-padding-left: 24px, causing
snap alignment issues on mobile; update the scroll-padding-left value (wherever
it is set for the suggestions rail/scroll container) to 14px to match
.promptSuggestionsRail so snap positions align, or set an explicit
scroll-padding-inline/start property on .promptSuggestionsRail to 14px to ensure
consistent snapping.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/genui/a2ui-playground/src/pages/DemosPage.css (1)
1069-1076:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winMobile toolbar compaction selector is stale after Button migration.
Line 1069 still targets
.toolbarBtn, but toolbar controls now use.btnclasses from the shared Button primitive, so these mobile compact rules never apply.Suggested fix
- .codePanelToolbar .toolbarBtn { + .codePanelToolbar .btn.btn-sm { height: 26px; padding: 0 8px; font-size: 11px; } - .codePanelToolbar .toolbarBtn.primary { + .codePanelToolbar .btn.btn-primary.btn-sm { padding: 0 10px; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/genui/a2ui-playground/src/pages/DemosPage.css` around lines 1069 - 1076, Styles targeting the deprecated .toolbarBtn selector in .codePanelToolbar no longer apply after the Button migration; update the selectors to target the new Button class (e.g., change occurrences of .codePanelToolbar .toolbarBtn and .codePanelToolbar .toolbarBtn.primary to .codePanelToolbar .btn and .codePanelToolbar .btn.primary) and preserve the intended mobile compaction values (height, padding, font-size) so the toolbar uses the compact layout for mobile. Ensure any specific overrides for the "primary" variant (previously .toolbarBtn.primary) are applied to .btn.primary as well and keep specificity consistent with the shared Button primitive.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@packages/genui/a2ui-playground/src/pages/DemosPage.css`:
- Around line 1069-1076: Styles targeting the deprecated .toolbarBtn selector in
.codePanelToolbar no longer apply after the Button migration; update the
selectors to target the new Button class (e.g., change occurrences of
.codePanelToolbar .toolbarBtn and .codePanelToolbar .toolbarBtn.primary to
.codePanelToolbar .btn and .codePanelToolbar .btn.primary) and preserve the
intended mobile compaction values (height, padding, font-size) so the toolbar
uses the compact layout for mobile. Ensure any specific overrides for the
"primary" variant (previously .toolbarBtn.primary) are applied to .btn.primary
as well and keep specificity consistent with the shared Button primitive.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 170398d0-ce4d-42b8-ac95-46c3c4cff63a
📒 Files selected for processing (3)
packages/genui/a2ui-playground/src/pages/DemosPage.csspackages/genui/a2ui-playground/src/pages/DemosPage.tsxpackages/genui/a2ui-playground/src/styles.css
Adds Lucide-based icon barrel (`src/components/Icon.tsx`) and a unified `<Button>` primitive (`src/components/Button.tsx`) with variant (primary/secondary/ghost/danger) and size (sm/md/lg) axes, then sweeps the existing UI to use them. Replaces ad-hoc glyphs (↖ Send, ← Back, ↻ Reset, ⏸/▶ Play, ✕ Clear, ⤢/✕ Expand, ☀/☾ theme, 💬/⚡/✨ status) and inline SVGs (MobileTabBar Pencil + Smartphone, PreviewPanel Phone) with consistent Lucide icons. Collapses six previous button styles — toolbarBtn, chatSendBtn, detailBackButton, conversationNewButton, conversationIconButton, themeToggle, previewInfoBtn, previewExpandBtn — into one pill-shaped Geist-aligned system. Net -275 LOC.
…polish Playback header
- Add `responsiveIconOnly` to <Button>: hides the label and squares the
hit-target at ≤720px (compound selectors override fullWidth). Apply to
New Chat (ConversationListPanel) and Back to Examples (DemosPage) so
the leftmost button stops eating horizontal space on phones.
- Replace the chunky "LLM stream" badge with a refined inline meta
("Playback · LLM STREAM") that reads as one visual unit with the title.
- Swap the unicode ▶ in the idle hint for a Lucide Play icon; trim copy
to "Replay payload chunk by chunk" (Play button right next to it makes
"Press · to" redundant). Hide the hint below 720px.
The instant-example cards and chat composer were eating the entire mobile viewport, leaving no scrollable area for chat bubbles after the first exchange. Inside the existing ≤720px media query: - Instant tiles: 244→180px wide, preview height 220→150px - Suggestion chips: 28→26px tall, slimmer padding - Composer: drop min-height 132→0, textarea min-height 66→38px - Send button shrinks to size-sm in mobile composer - Tighter padding/gap across `.chatInputArea` and `.promptSuggestionsRail` Result: ~180px of vertical space recovered between the AI welcome bubble and the suggestion strip — the conversation now actually has room to land.
… JSON) Both "LLM stream" and "JSON" labels now use a single `.sectionBadge` utility — bordered chip, visible at every viewport. Drops the prior `display: none` that was hiding the JSON chip on mobile, so the type indicator stays informative at every width. The pulsing "playing" state dot for the LLM stream remains untouched.
…k header The playback button morphed between primary (Play, Resume) and ghost (Pause), so the toolbar's visual weight shifted whenever state changed. Pause is the main action while playing — same emphasis as Resume while paused — so it should share the primary variant.
36132dc to
c9b174e
Compare
Summary
Polishes the playground UI by collapsing fragmented icons and button styles into one cohesive system.
New primitives
src/components/Icon.tsx— Lucide-react barrel (same set Shadcn uses). Centralizes the icon vocabulary with consistent stroke weight and a pairedICON_SIZEscale.src/components/Button.tsx+Button.css— pill-shaped Geist-aligned button withvariant(primary/secondary/ghost/danger) ×size(sm/md/lg) axes, plusiconBefore/iconAfter/iconOnlyslots.Icon sweep
↖→Send, Back←→ChevronLeft, Reset/Restart↻→RotateCcw, Play▶→Play, Pause⏸→Pause, Clear✕→X, Expand⤢/✕→Maximize2/Minimize2, theme☀/☾→Sun/Moon, New Chat💬→MessageSquarePlus, status✨/⚡→Sparkles/Zap, See all→→ArrowRight.PencilandSmartphone.Button consolidation
toolbarBtn,chatSendBtn,detailBackButton,conversationNewButton,conversationIconButton,themeToggle,previewInfoBtn,previewExpandBtn→ all use<Button>.Verified visually in light + dark, desktop + mobile, on the Create page, the Examples detail page, and the MobileTabBar.
Test plan
pnpm buildpassespnpm testpasses (mountQueue tests)toolbarBtn/chatSendBtn/ etc. selectors remain that I missedSummary by CodeRabbit
New Features
Style
Chores