Skip to content

Fix Meteocons gradient ID collisions across icons#12

Merged
cph5236 merged 2 commits into
mainfrom
fix/icon-gradient-id-collision
Jun 15, 2026
Merged

Fix Meteocons gradient ID collisions across icons#12
cph5236 merged 2 commits into
mainfrom
fix/icon-gradient-id-collision

Conversation

@cph5236

@cph5236 cph5236 commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Problem

Meteocons SVGs reuse generic gradient IDs (a, b, c…). Each WeatherIcon inlines its SVG via dangerouslySetInnerHTML, so when several icons render on the same page — the 24-hour strip and 10-day forecast both render many at once — those IDs collide in the document and icons pick up another icon's gradient.

Fix

  • prefixIds() — gives every icon a private id namespace by prefixing each id, url(#…), and xlink:href/href with the icon name, so gradients can't collide across icons.
  • neutralMoon() — recolors the night moon from Meteocons' icy blue (#86c3db/#5eafcf/#72b9d5) to a white/silver so the crescent reads as a moon rather than an ice crystal. Applied only to clear-night / partly-cloudy-night (fog-night intentionally keeps the icy palette).
  • Code 48 (icy/depositing fog) now maps to a dedicated fog-night icon.

Updated the getWeatherIconName test to cover the 45 vs 48 split.

Verification

  • ✅ typecheck, lint, 65/65 tests pass
  • ✅ production vite build succeeds (validates the new fog-night ?raw import)

Notes

This is web-only and independent of the Android widget. These changes were developed locally (via a throwaway icon-gallery preview page that is not included here) and are validated by the build + test suite; I have not separately rendered the gradients in a browser as part of this PR.

Also includes a small chore: a root .gitignore for .playwright-mcp/ output.

🤖 Generated with Claude Code

cph5236 and others added 2 commits June 15, 2026 14:32
Meteocons SVGs reuse generic gradient IDs (a, b, c…). When multiple icons are
inlined on one page (hourly strip, 10-day forecast) the IDs collide and icons
render with another icon's gradient. prefixIds() gives each icon a private id
namespace (id + url(#…) + xlink:href/href).

Also:
- neutralMoon(): recolor the night moon from Meteocons' icy blue to a
  white/silver so the crescent reads as a moon, not an ice crystal (clear-night,
  partly-cloudy-night only — fog-night keeps the icy palette)
- map WMO code 48 (icy/depositing fog) to a dedicated fog-night icon

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@claude

claude Bot commented Jun 15, 2026

Copy link
Copy Markdown

Claude finished @cph5236's task in 2m 17s —— View job


Code Review

  • Gather PR context
  • Read changed files
  • Analyze diff for issues
  • Post review findings

The fix is correct and the approach is solid. A couple of things worth noting:

1. Daytime display of fog-night icon (design trade-off)

SWS_App/src/types/weather.ts:84 — Code 48 always returns 'fog-night' regardless of isDay:

if (code === 48) return 'fog-night'

This means during daytime, users see a night-themed icon for icy/depositing fog. The intent (use the icy palette to convey rime fog) is reasonable, but it breaks the visual convention that night icons only appear after dark, and could look jarring on a daytime forecast strip. A minor nit — the PR explicitly documents the choice — but worth a second look if it ever gets user feedback.

2. Comment verbosity (CLAUDE.md style)

SWS_App/src/components/WeatherIcon.tsx:21–34 — Both prefixIds and neutralMoon have multi-paragraph comment blocks. CLAUDE.md says "Never write multi-paragraph docstrings or multi-line comment blocks — one short line max." The WHY in these comments is genuinely non-obvious (the xlink ordering invariant especially), so the intent is right, but the formatting violates the project standard. They could each be compressed to a single-line comment.

Fix this →

3. Everything else looks correct

  • The prefixIds regex chain is correct: xlink:href is replaced before href, and the negative lookbehind (?<!xlink:) prevents double-prefixing after the first pass.
  • Using the icon name (not an instance counter) as the prefix is the right call — same-icon duplicate IDs are harmless (identical gradients), while cross-icon collisions are the actual bug being fixed.
  • neutralMoon correctly excludes fog-night, and MOON_ICONS correctly excludes day variants and fog.
  • The module-level init loop processes all icons once at startup — correct and efficient.
  • Updated test coverage for the 45 vs 48 split is thorough (includes both isDay=true and false for code 48).

✅ No bugs found. Approve once the comment style is addressed (or accepted as-is).

@github-actions

Copy link
Copy Markdown

Preview deployed

https://cph5236.github.io/SimpleWeatherService/pr-previews/67f39bf47716bbfe6a36f2513c4e4ada4026af90/

Commit: 67f39bf47716bbfe6a36f2513c4e4ada4026af90

It may take a minute or two for the page to go live after the workflow completes.

@cph5236
cph5236 merged commit a30c52d into main Jun 15, 2026
6 checks 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.

1 participant