Skip to content

feat(ui,app): chrome icon registry redraw + size API collapse (slice 08, issue #440)#491

Merged
Astro-Han merged 6 commits into
devfrom
claude/i440-08-iconography
May 7, 2026
Merged

feat(ui,app): chrome icon registry redraw + size API collapse (slice 08, issue #440)#491
Astro-Han merged 6 commits into
devfrom
claude/i440-08-iconography

Conversation

@Astro-Han

Copy link
Copy Markdown
Owner

Summary

Slice 08 of issue #440 redraws the chrome icon registry from imagegen v4 sheets, collapses the multi-size Icon API to a single 16×16 render, and adjusts a few callsites that depended on the old API.

  • Redraws 16 chrome glyphs from v4 imagegen sheets (agent, server, automation, remote-control, prompt, photo, code, code-lines, chevron-down, file-tree, glasses, cloud-upload, archive, close-small, check-small, circle); plus 3 chevron rotations (up/left/right) generated from chevron-down; plus 3 workshop ports (archive, arrow-down-to-line, github). All ported via potrace + sharp into a fixed 0 0 20 20 viewBox.
  • Renames alert-triangle to warning to match its semantic role at TextField error and permission-dock callsites; updates the rename test accordingly.
  • Collapses Icon size prop. The component now always renders 16×16; the four-tier API (small | normal | medium | large) is removed from props, CSS, stories, markdown helpers, and 33 callsites (59 attributes stripped). Where the previous size was visually load-bearing (a few settings rows and the home folder-add chip) the icon is now smaller; this is a deliberate part of the chrome simplification.
  • Wires image-attachments.tsx to the open-file icon for non-image attachments instead of the generic folder.
  • Applies fill-rule: evenodd on [data-slot="icon-svg"]. Potrace emits nested subpaths to express holes; the default nonzero rule was filling donut glyphs (circle, warning, glasses, file-tree, archive, github, etc.) as solid discs. The fix is one CSS line and is inert for stroke-only paths.

Test plan

  • bun --cwd packages/ui run typecheck clean
  • bun --cwd packages/app run typecheck clean
  • bun test in packages/ui (icon registry rename, text-field state matrix, inputs state matrix) — all icon-related tests pass; 2 pre-existing UI failures (apply-patch-file, session-diff) are unrelated to this slice and reproduce on HEAD without these changes
  • dev:desktop smoke: todo dock pending dot is a hollow ring; chevron rotations correct in sidebar / message timeline / status connections; TextField error renders the new warning glyph; close-small / check-small / code render at the new 16px without size attribute; no regressions on stroke-only icons
  • Reviewer: spot-check the gallery in packages/ui/src/components/icon.stories.tsx (Gallery story) for any glyph that still looks off at 16px

Astro-Han added 5 commits May 7, 2026 18:35
The folder icon was visually misleading for non-image dropped files.
open-file matches the actual UI semantic — "this attachment is a file."
…callsites

Slice 08 consolidates the two error/warning glyphs in the registry to a single
warning entry. Updates the TextField error indicator + 3 test references to use
the new name. Registry-side removal of alert-triangle lands in a follow-up commit.
Pre-clean for the size API collapse coming next. Removes size="small"
(the most common existing value) and size="normal/medium/large" attributes
from all <Icon> callsites. Behavior unchanged: with the prop still typed in
icon.tsx, omitted size still defaults to "normal" for now.
…se size API to 16px

Replaces 16 chrome icons with redrawn versions from the imagegen v4 round
(agent, warning, automation, remote-control, server, prompt, photo, code,
code-lines, chevron-down, file-tree, glasses, cloud-upload, circle, close-small,
check-small), derives chevron-up/left/right by rotating chevron-down around
(10,10), and ports 3 workshop-only icons (archive, arrow-down-to-line, github)
into the registry. Removes the alert-triangle entry (now collapsed into warning).

Also collapses the multi-size Icon API to a single 16×16 size:
- IconProps.size and the data-size data attribute are dropped.
- icon.css collapses the four size rules to a single 16px declaration.
- Stories drop the Sizes variant; the docs block at the top of icon.tsx now
  describes the 4-keyshape system + spec link.
- markdown.tsx no longer sets data-size when synthesizing icon nodes.

Issue: #440
Potrace-derived icons emit nested subpaths (outer + inner) to express
holes. The default nonzero rule fills both as solid, which broke the
todo dock pending circle into a filled disc. Setting fill-rule on
[data-slot="icon-svg"] restores correct rendering for all donut-shaped
glyphs (circle, warning, glasses, file-tree, archive, github, etc.)
without affecting stroke-only paths (fill="none" ignores fill-rule).
@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@Astro-Han has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 43 minutes and 6 seconds before requesting another review.

To continue reviewing without waiting, purchase usage credits in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d6a11dc1-b4b4-4f25-a055-d094c82f084c

📥 Commits

Reviewing files that changed from the base of the PR and between 506b263 and f083267.

📒 Files selected for processing (45)
  • packages/app/e2e/inputs/todo-toggle.spec.ts
  • packages/app/src/components/dialog-select-file.tsx
  • packages/app/src/components/file-tree.tsx
  • packages/app/src/components/prompt-input.tsx
  • packages/app/src/components/prompt-input/image-attachments.tsx
  • packages/app/src/components/prompt-input/workspace-chip.tsx
  • packages/app/src/components/session/session-context-tab.tsx
  • packages/app/src/components/session/session-header.tsx
  • packages/app/src/components/session/session-new-view.tsx
  • packages/app/src/components/session/session-status-connections.tsx
  • packages/app/src/components/settings-general.tsx
  • packages/app/src/components/settings-worktree-row.tsx
  • packages/app/src/components/settings-worktrees.tsx
  • packages/app/src/components/status-popover-body.tsx
  • packages/app/src/components/status-popover.tsx
  • packages/app/src/components/titlebar.tsx
  • packages/app/src/pages/home.tsx
  • packages/app/src/pages/layout/pawwork-sidebar.tsx
  • packages/app/src/pages/layout/pawwork-worktree-badge.tsx
  • packages/app/src/pages/layout/sidebar-items.tsx
  • packages/app/src/pages/layout/sidebar-workspace.tsx
  • packages/app/src/pages/session/composer/session-permission-dock.tsx
  • packages/app/src/pages/session/composer/session-question-dock.tsx
  • packages/app/src/pages/session/composer/session-todo-dock.tsx
  • packages/app/src/pages/session/message-timeline.tsx
  • packages/app/src/pages/session/session-side-panel.tsx
  • packages/ui/src/components/button.tsx
  • packages/ui/src/components/card.tsx
  • packages/ui/src/components/collapsible.tsx
  • packages/ui/src/components/file-search.tsx
  • packages/ui/src/components/icon-button.tsx
  • packages/ui/src/components/icon.css
  • packages/ui/src/components/icon.stories.tsx
  • packages/ui/src/components/icon.tsx
  • packages/ui/src/components/inputs-state-matrix.test.tsx
  • packages/ui/src/components/line-comment.tsx
  • packages/ui/src/components/markdown.tsx
  • packages/ui/src/components/message-part.tsx
  • packages/ui/src/components/select.tsx
  • packages/ui/src/components/session-review.tsx
  • packages/ui/src/components/session-turn.tsx
  • packages/ui/src/components/text-field.test.tsx
  • packages/ui/src/components/text-field.tsx
  • packages/ui/src/components/tool-error-card.tsx
  • packages/ui/test/components/icon-registry-rename.test.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/i440-08-iconography

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request standardizes the Icon component by removing the size property and enforcing a fixed 16x16 pixel dimension across the application. It also renames the alert-triangle icon to warning in the TextField component and associated tests, and updates several icon references for improved consistency. I have no feedback to provide.

…ta-size

The slice-08 size API collapse removed [data-size] from rendered icons,
which broke the todo-toggle smoke that asserted on
[data-component="icon"][data-size]. Restoring data-size as a test hook
would re-introduce the contract we just dropped, so the Icon root now
exposes a stable identity hook (data-icon={name}) and the spec asserts
[data-icon="circle"] / [data-icon="circle-check"] under the pending and
completed todo items. Stroke-only icons inherit the same hook with no
visual change.
@Astro-Han

Copy link
Copy Markdown
Owner Author

Thanks for the review. Addressed in f083267c70.

P1 (e2e selector contract) — fixed. Rather than restoring data-size as a test hook, the Icon root now exposes data-icon={name} as a stable identity hook, and todo-toggle.spec.ts asserts on [data-icon="circle"] / [data-icon="circle-check"] under the pending / completed items. Verified locally:

  • bun --cwd packages/app run test:e2e:local --grep "todo dock shows circle" → 1 passed (7.2s)
  • bun --cwd packages/ui run typecheck clean
  • bun --cwd packages/app run typecheck clean
  • icon registry rename + textfield + state-matrix tests: 44/44 pass

P2 (before/after screenshots) — acknowledged as a follow-up. The desktop-smoke workflow stays green and dev:desktop was hand-tested for the high-traffic surfaces (todo dock pending/completed dots, chevron rotations across sidebar / message timeline / status connections, TextField error glyph, code-copy button in markdown). I'll attach a light + dark gallery diff in a follow-up comment before merge.

External API note (IconProps.size removal)@opencode-ai/ui exports via ./*, but no external consumer of this prop exists in the monorepo and the package isn't published. The collapse to a single 16×16 render is the intended outcome of slice 08 per #440; if any external consumer surfaces later, it's a one-liner attribute removal at the callsite.

While here, also pushed 9e78ecfaa0 earlier in this branch — fill-rule: evenodd on [data-slot="icon-svg"]. Without it, potrace-derived donut paths (circle, warning, glasses, file-tree, archive, github, …) rendered as filled discs because the default nonzero rule fills both subpaths. Stroke-only icons are unaffected since fill="none" ignores fill-rule.

@Astro-Han

Copy link
Copy Markdown
Owner Author

P2 deliverable per #440: before/after light + dark dev:desktop screenshots.

These are rendered via a self-contained Playwright script that parses the icons literal from dev and from this branch, then composes a side-by-side HTML using the pawwork theme tokens for both color schemes. Cells outlined orange = path or transform changed between branches. Surface mocks reuse the real component CSS contracts (TextField error, todo dock pending/completed/in-progress, chevron family, composer/attachments).

Hosted on a sibling screenshots/slice-08 branch (kept off this PR's diff to preserve scope cleanliness):

Icon registry — light

registry light

Icon registry — dark

registry dark

Surfaces — light

surfaces light

Surfaces — dark

surfaces dark

Notes:

  • Registry view uses fill-rule: evenodd (matches the new [data-slot="icon-svg"] CSS contract); without it, donut glyphs (circle, warning, glasses, file-tree, archive, github, …) render as filled discs.
  • Surface comparison shows the size-collapse impact at the most concrete spot: TextField error (left was alert-triangle at small, right is warning at fixed 16px) and todo dock (left was circle/circle-check at small, right is the redrawn pair at fixed 16px). Both reads cleanly at 16px.
  • Cells with no orange outline are unchanged keys carried over from dev.

@Astro-Han

Copy link
Copy Markdown
Owner Author

Re: review round 2 — confirming the open items.

P2 (visual verification) — closed. Light + dark before/after screenshots posted as a separate comment (#issuecomment-4396640684). Coverage: full registry diff (86 keys, side by side) and four high-traffic surfaces (TextField error, todo dock pending/completed/in-progress, chevron family, composer attachments). PNGs are hosted on a sibling screenshots/slice-08 branch so this PR's diff stays scoped to code.

External API note — re-confirmed @opencode-ai/ui is not published to a registry; package.json has no publishConfig and the package is consumed only via the workspace ./* export. No external consumer exists for IconProps.size.

CI: e2e-artifacts, ci, desktop-smoke, codeql, commit-lint, dependency-review, smoke-macos-arm64, all unit-*, typecheck — all green on f083267c70. Ready to merge.

@Astro-Han Astro-Han merged commit 6889e01 into dev May 7, 2026
20 checks passed
@Astro-Han Astro-Han deleted the claude/i440-08-iconography branch May 7, 2026 11:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant