Skip to content

fix(ui): refit read-file icon into 0-20 viewBox#964

Merged
Astro-Han merged 3 commits into
devfrom
claude/icon-read-file-fit
May 28, 2026
Merged

fix(ui): refit read-file icon into 0-20 viewBox#964
Astro-Han merged 3 commits into
devfrom
claude/icon-read-file-fit

Conversation

@Astro-Han

@Astro-Han Astro-Han commented May 28, 2026

Copy link
Copy Markdown
Owner

Summary

Refit the read-file chrome icon so its rendered geometry stays inside the 0 0 20 20 viewBox. Add an end-to-end regression test that locks every entry in the icon registry to the same bound.

Why

In every "read N files" tool-row summary, the read-file document glyph's bottom edge was clipped on screen. The svg element's UA overflow: hidden was doing the clipping because the glyph's <g transform> rescaled the traced path slightly too tall — its rendered bbox extended to y≈22.10, past the 20-unit viewBox edge.

read-file was the only one of the 91 entries in the chrome icon registry to cross the 0..20 bounds. Its v4-batch siblings skill and thinking, drawn with the same negative-Y-scale trace pipeline, were rescaled correctly. Only the "Claude rescales to 20×20" step documented in docs/design/pawwork-chrome-icon-imagegen-v4-slice08/README.md was off for this one glyph.

The artwork itself is the user's intended new drawing; only the fit transform was wrong.

Related Issue

No issue — surfaced by direct user report of bottom-truncated read-file icons in chat tool rows.

Human Review Status

Approved by @Astro-Han

Review Focus

  • The new transform in packages/ui/src/components/icon.tsx:72: derived by measuring the raw path's untransformed bbox in chromium, then computing translate/scale so the rendered bbox lands at x:[2.76, 17.24] y:[0.88, 19.12] — centered, with ~1-unit margin and the same height as skill / thinking.
  • The regression test design (packages/app/e2e/icon-viewbox-fit.spec.ts): uses chromium's native getBBox rather than a pixel snap, so the assertion is geometric, deterministic, and prints exactly which side and by how much an offending glyph overflows.

Risk Notes

Visible UI: read-file's on-screen size and position shift slightly — it now sits centered with ~1-unit margin instead of overhanging the bottom edge by ~10% of the icon height. No other icon is touched. No platform/packaging/copy/data/permissions surface.

How To Verify

Regression test (before fix): 1 failed — "read-file: bottom 22.10 (bbox x:[3.26,18.54] y:[2.85,22.10])"
Regression test (after fix):  1 passed
  PLAYWRIGHT_SKIP_WEB_SERVER=1 bunx playwright test e2e/icon-viewbox-fit.spec.ts --project=chromium
typecheck packages/ui:  ok (tsgo --noEmit)
typecheck packages/app: ok (tsgo -b)
lint packages/ui/src/components/icon.tsx: ok
Scope blast: only icons sharing the negative-Y trace transform are read-file / skill / thinking; the new test covers all 91 registry entries going forward.

Screenshots or Recordings

icon-viewbox

Checklist

How to use this checklist:

  • Tick a box by replacing [ ] with [x]. Do not edit, add, or remove items.
  • The bot-applied label items can only be honestly ticked AFTER the PR is opened and the labeler / priority-triage bots have run — return to the PR description and tick them then.
  • Most items are required. The few that are conditional are explicitly marked (conditional); for those, leave unticked if they truly do not apply and explain why in Risk Notes. All other items must be ticked before requesting human review.
  • Type label — this PR carries exactly one of bug, enhancement, task, documentation. Type labels are author-added; the labeler bot does NOT assign them. Add the label in the GitHub UI, then tick this.
  • Routing labels — this PR carries at least one of app, ui, platform, harness, ci. The labeler bot assigns these on PR open based on changed paths. Confirm the bot's choice (or override if wrong), then tick this.
  • Priority label — this PR carries exactly one of P0, P1, P2, P3. The priority-triage bot suggests one on PR open. Confirm or override, then tick this.
  • Human Review Status above is set to Pending, Approved by @<reviewer>, or Not required: <reason> (default is Pending; "not required" is restricted to bot-authored low-risk PRs).
  • I linked the related issue, or stated in Summary why there is no issue.
  • I described the review focus and any meaningful risks.
  • I replaced the example block in How To Verify with the real verification steps and the key result for each.
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope.
  • (conditional) I manually checked visible UI or copy changes when needed, with screenshots or recordings. Leave unticked only if no visible UI or copy changed.
  • (conditional) I considered macOS and Windows impact for platform, packaging, updater, signing, paths, shell, or permissions changes. Leave unticked only if no platform/packaging surface was touched.
  • (conditional) I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant. Leave unticked only if none of those surfaces was touched.
  • I reviewed the final diff for unrelated changes and suspicious dependency changes.
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English.

The read-file glyph's port-side rescale into the chrome icon registry
overshot the canvas: its rendered bbox extended to y=22.10, past the
viewBox's lower edge, so the svg's UA overflow:hidden clipped the
document's bottom edge in every tool-row summary that shows 'read N
files'. Among the 91 icons in the registry, read-file was the only one
crossing the 0-20 bounds.

The artwork is correct (newly drawn in the v4 slice08 batch alongside
skill and thinking — those two fit fine); only the translate/scale
'rescale to 20x20' step documented in
docs/design/pawwork-chrome-icon-imagegen-v4-slice08/README.md was off
for this one glyph. Recompute the transform so the bbox lands at
x:[2.76,17.24] y:[0.88,19.12] — centered with 1-unit margin and
matching the family height of its v4 batchmates.

Add packages/app/e2e/icon-viewbox-fit.spec.ts: a browser-rendered
getBBox compliance check that scans every entry of the icons registry
and asserts the rendered geometry stays within 0..20. Catches any
future port that overshoots a side before it ships.
@Astro-Han Astro-Han added the bug Something isn't working label May 28, 2026
@github-actions github-actions Bot added app Application behavior and product flows ui Design system and user interface labels May 28, 2026
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR adds a smoke test that validates all icon glyphs fit within a 0 0 20 20 SVG viewBox, and updates the read-file icon's transform to meet that constraint. The test dynamically measures every icon glyph by rendering it in the browser and calling getBBox(), then asserts none overflow the bounds.

Changes

Icon ViewBox Fit Validation

Layer / File(s) Summary
Icon glyph transform update
packages/ui/src/components/icon.tsx
The read-file icon's SVG transform parameters are adjusted to position and scale the glyph within the viewBox.
ViewBox fit smoke test
packages/app/e2e/icon-viewbox-fit.spec.ts
New Playwright test that reads the icon registry source file, renders each icon in a browser page with viewBox="0 0 20 20", measures rendered bounding boxes via getBBox(), and fails with a detailed overflow report if any glyph exceeds the 0–20 range.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • Astro-Han/pawwork#359: Adds or modifies icon definitions in the registry that the new test will validate for viewBox fit.
  • Astro-Han/pawwork#191: Updates icon SVG transforms and integrates icons into app components, directly related to the glyph geometry changes.

Suggested labels

ui

Poem

🐰 Glyphs must fit, within their box,
Twenty by twenty, never locked.
A test now watches, ensures the fit,
No glyph shall clip, not even a bit!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(ui): refit read-file icon into 0-20 viewBox' accurately and concisely summarizes the main change—refitting the read-file icon to fit within the SVG viewBox bounds.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed PR description is comprehensive and complete, with all required template sections filled out, including Summary, Why, Related Issue, Human Review Status, Review Focus, Risk Notes, verification steps, and a screenshot.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/icon-read-file-fit

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.

@github-actions github-actions Bot added the P2 Medium priority label May 28, 2026

@github-actions github-actions 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.

Suggested priority: P2 (includes non-doc, non-test paths outside the low-risk bucket).

P1/P0 are reserved for maintainer confirmation. Please relabel manually if this is a release blocker, security issue, data-loss risk, or updater/runtime failure.

@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 introduces a new Playwright smoke test (icon-viewbox-fit.spec.ts) to ensure that all SVG icons in the registry fit within the standard 0 0 20 20 viewBox. It also adjusts the scale and translation properties of the read-file icon in icon.tsx to resolve a clipping issue. The reviewer pointed out that the parsing logic in loadIcons is fragile and could easily break with minor formatting changes, and provided a robust regular expression-based suggestion to make the test more resilient.

Comment thread packages/app/e2e/icon-viewbox-fit.spec.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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/app/e2e/icon-viewbox-fit.spec.ts`:
- Line 22: Replace the top-level import so the E2E spec uses the repo fixtures:
change the import of { test, expect } to come from "../fixtures" rather than
"`@playwright/test`" (leave the imported symbols { test, expect } unchanged) so
the spec file icon-viewbox-fit.spec.ts adheres to the packages/app/e2e fixture
contract.
🪄 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 Plus

Run ID: a3e04fa8-ff36-42e2-943e-69711a326f29

📥 Commits

Reviewing files that changed from the base of the PR and between ae6b778 and 83be0af.

📒 Files selected for processing (2)
  • packages/app/e2e/icon-viewbox-fit.spec.ts
  • packages/ui/src/components/icon.tsx

Comment thread packages/app/e2e/icon-viewbox-fit.spec.ts Outdated
@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown

Perf delta summary

Comparator: pass

Profile / Scenario interaction median interaction worst long task max tbt frame gap p95 frame gap max jank count cls status
default / homepage-cold 48 -> 24 (-24) 80 -> 24 (-56) 82 -> 68 (-14) 32 -> 18 (-14) 33.4 -> 33.4 (0) 166.7 -> 116.6 (-50.1) 5 -> 3 (-2) 0 -> 0 (0) pass
default / long-session-input-lag 48 -> 48 (0) 48 -> 48 (0) 0 -> 0 (0) 0 -> 0 (0) 16.7 -> 16.7 (0) 16.8 -> 16.7 (-0.1) 0 -> 0 (0) 0 -> 0 (0) pass
default / session-streaming-long 32 -> 32 (0) 64 -> 56 (-8) 0 -> 0 (0) 0 -> 0 (0) 16.7 -> 16.7 (0) 16.8 -> 16.7 (-0.1) 0 -> 0 (0) 0 -> 0 (0) pass
default / tool-call-expand 24 -> 24 (0) 40 -> 56 (+16) 0 -> 0 (0) 0 -> 0 (0) 16.8 -> 16.7 (-0.1) 16.8 -> 16.7 (-0.1) 0 -> 0 (0) 0 -> 0 (0) pass
default / terminal-side-panel-open 48 -> 48 (0) 56 -> 48 (-8) 0 -> 0 (0) 0 -> 0 (0) 33.2 -> 33.4 (+0.2) 33.4 -> 33.4 (0) 0 -> 0 (0) 0 -> 0 (0) pass
default / session-scroll-reading 16 -> 16 (0) 16 -> 32 (+16) 0 -> 0 (0) 0 -> 0 (0) 16.8 -> 16.8 (0) 16.8 -> 16.8 (0) 0 -> 0 (0) 0 -> 0 (0) pass

Astro-Han added 2 commits May 28, 2026 10:56
A picture next to the regression test: read-file rendered with both the
pre-fix and post-fix transform, plus skill and thinking as v4-batch
references, each with a red dashed viewBox edge marker. Regenerate with
`bun run snap icon-viewbox` — the grid lands at
docs/design/preview/screenshots/icon-viewbox.png (gitignored).
Two review findings from CodeRabbit and Gemini:

- packages/app/e2e/AGENTS.md mandates importing `test` / `expect` from
  `../fixtures`, not `@playwright/test` directly. Both the
  icon-viewbox-fit spec and the icon-viewbox snap target violated that;
  switch them to the fixture imports. Fixtures are lazy, so the suites
  that only use `page` don't pull in the opencode backend.
- Regex-parsing icon.tsx to read the glyph table was fragile (any
  formatting drift could silently skip glyphs). Replace with a direct
  `import { icons } from "@opencode-ai/ui/icon"` so the suite reads
  the same exported value the app ships.
@Astro-Han Astro-Han merged commit 51726fa into dev May 28, 2026
29 checks passed
@Astro-Han Astro-Han deleted the claude/icon-read-file-fit branch May 28, 2026 03:43
Astro-Han added a commit that referenced this pull request May 28, 2026
Bump PawWork desktop release version to 2026.5.29.

Changes since v2026.5.28:
- feat(settings): move Connections to Integrations + global toast monitor (#975)
- feat(ui): display cache hit rate with one decimal place (#967)
- fix: stabilize session opening state (#969)
- fix(session): repair stale paginated question blockers (#962)
- fix(ui): refit read-file icon into 0-20 viewBox (#964)
- fix: allow running tools to expand
- fix: add run lifecycle diagnostics
- fix: harden Electron repair fallback
- refactor: remove legacy theme choices
- ci: stabilize e2e Playwright install and PR triage paths

Verification: diff scope matches prior release bump (#958) — only the version string in packages/desktop-electron/package.json and the workspace entry in bun.lock. All CI checks green (e2e-artifacts required a rerun due to Playwright browser install flake unrelated to this change).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app Application behavior and product flows bug Something isn't working P2 Medium priority ui Design system and user interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant