Skip to content

[#156] Replace text asterisks with SVG star icons#166

Merged
realproject7 merged 2 commits intomainfrom
task/156-star-rating-icons
Mar 16, 2026
Merged

[#156] Replace text asterisks with SVG star icons#166
realproject7 merged 2 commits intomainfrom
task/156-star-rating-icons

Conversation

@realproject7
Copy link
Copy Markdown
Owner

Summary

  • New StarRating.tsx shared component with StarDisplay (fractional fill via SVG clip-path) and StarInput (hover + click interactive stars)
  • Rating input: 5 clickable star icons (24px) with hover preview — replaces number buttons
  • Average display: Star icons (18px) with fractional fill
  • Recent ratings / RatingSummary: Small star icons (12-14px)

Fixes #156

Test plan

  • tsc --noEmit — zero errors
  • next build — clean
  • vitest run — 22/22 tests pass
  • Visual verification of star icons at all sizes

🤖 Generated with Claude Code

- New StarRating.tsx with StarDisplay (fractional fill via clip-path)
  and StarInput (hover + click interactive stars)
- RatingWidget: star icons for input (24px), average (18px), and
  recent ratings (12px) — replaces number buttons and text asterisks
- RatingSummary: star icons (14px) with fractional fill support

Fixes #156

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

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

T2b APPROVE

Clean component design:

  1. StarIcon — SVG with clip-path for fractional fill. Properly separates outline (muted) and fill (accent) layers.
  2. StarDisplay — Fractional fill math (Math.min(1, Math.max(0, rating - (star - 1)))) is correct.
  3. StarInput — Hover preview + click interaction with proper aria-labels and disabled state.
  4. Integration — RatingWidget cleaned up nicely (-33 lines), RatingSummary simplified. Size params used consistently (24/18/14/12px).

Minor note (non-blocking): Math.random() for clip-path IDs in StarIcon is technically not SSR-safe (different IDs on server vs client). Not blocking because StarDisplay is only rendered after client-side data fetches complete, so fractional stars won't be server-rendered in practice. Could use useId() if this ever changes.

Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

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

Verdict: REQUEST CHANGES

Summary

The move to a shared SVG star component is directionally correct, but the current implementation introduces a hydration risk in the new rating UI. The fractional-fill clipPath ids are generated with Math.random() during render, which is not stable across server and client output.

Findings

  • [medium] StarIcon uses Math.random() to generate the SVG clipPath id at render time, so the server-rendered id and the client-hydrated id can diverge and break hydration or clip-path references.
    • File: src/components/StarRating.tsx:12
    • Suggestion: Replace the random id with a stable React-generated id such as useId(), or another deterministic per-instance id source that survives SSR hydration.

Decision

Requesting changes because the new shared star component currently introduces non-deterministic render output in a client-rendered surface. Once the clipPath id generation is made stable, the rest of the refactor looks appropriately scoped to #156.

Replace Math.random() with React useId() for deterministic SVG
clipPath IDs, preventing hydration mismatches.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

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

Verdict: APPROVE

Summary

The follow-up commit fixes the hydration risk in the shared star component by replacing render-time randomness with deterministic useId()-based clip-path ids. The rating UI refactor now looks clean, contained, and validated.

Findings

  • [info] No remaining blocking findings after 13ee003.
    • File: src/components/StarRating.tsx:61
    • Suggestion: None.

Decision

Approving because the prior SSR/hydration issue is resolved, the shared star component remains appropriately scoped to #156, and lint-and-typecheck plus local typecheck, test, and build validation pass.

@realproject7 realproject7 merged commit cd3c174 into main Mar 16, 2026
1 check passed
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.

[QA-Bug] Rating UI — replace number buttons and text stars with proper star icons

2 participants