fix: Use inline themed SVG for loader spinner#2378
Conversation
Import tail-spin.svg as raw SVG markup and render it through the loader DOM instead of using the circular border/background spinner. Update the SVG to inherit currentColor, expand its viewBox to avoid edge clipping, and style the dialog spinner with the app primary theme color. Add ?raw SVG handling to both Rspack and Webpack so inline SVG imports do not conflict with normal asset/resource SVG usage. Also removes the old theme-side tail-spin recoloring path now that the spinner color is driven by CSS.
Greptile SummaryThis PR replaces the CSS border-based spinner in the loader dialog with an inline SVG (tail-spin.svg) whose colors are driven by
Confidence Score: 4/5Safe to merge; the spinner change is well-scoped and the old async file-write path is cleanly removed. The implementation is correct and the bundler config changes follow the proper Webpack 5 resourceQuery pattern. The one thing worth watching is the generic linearGradient id="a" in the now-inlined SVG — if any other icon SVG in the document uses the same ID, the gradient stroke reference could silently resolve to the wrong element. It's not a crash or data issue, but it could produce a visually broken spinner in edge cases. src/res/tail-spin.svg — the linearGradient id="a" should use a scoped name to avoid potential collisions with other inline SVG assets in the document. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Builder as Bundler (Rspack/Webpack)
participant Loader as loader.js
participant DOM
participant Theme as theme/list.js
participant CSS as style.scss
Builder->>Loader: import tail-spin.svg?raw → inlined SVG string
Loader->>DOM: "createElement span.loader, innerHTML = tailSpinSvg"
DOM-->>CSS: ".loader { color: var(--primary-color) }"
CSS-->>DOM: currentColor propagates into SVG stroke/fill
Theme->>DOM: apply() sets --primary-color via theme.css
DOM-->>DOM: Spinner color updates automatically
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Builder as Bundler (Rspack/Webpack)
participant Loader as loader.js
participant DOM
participant Theme as theme/list.js
participant CSS as style.scss
Builder->>Loader: import tail-spin.svg?raw → inlined SVG string
Loader->>DOM: "createElement span.loader, innerHTML = tailSpinSvg"
DOM-->>CSS: ".loader { color: var(--primary-color) }"
CSS-->>DOM: currentColor propagates into SVG stroke/fill
Theme->>DOM: apply() sets --primary-color via theme.css
DOM-->>DOM: Spinner color updates automatically
Reviews (1): Last reviewed commit: "fix: Use inline themed SVG for loader sp..." | Re-trigger Greptile |
| <svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg"> | ||
| <svg width="38" height="38" viewBox="-1 -1 40 40" xmlns="http://www.w3.org/2000/svg"> | ||
| <defs> | ||
| <linearGradient x1="8.042%" y1="0%" x2="65.682%" y2="23.865%" id="a"> |
There was a problem hiding this comment.
Generic gradient ID may conflict with other inline SVGs
The linearGradient uses id="a", a very generic identifier. Because the SVG is now inlined into the HTML document (not loaded as <img src="...">), all IDs become part of the global document namespace. If any other icon or SVG asset on the page also defines id="a" — which is common in icon libraries and auto-exported SVGs — the browser will resolve url(#a) to whichever element appears first in DOM order, causing the spinner's gradient stroke to render incorrectly (likely invisible or black). Using a scoped ID like tail-spin-gradient would eliminate this risk.
Import tail-spin.svg as raw SVG markup and render it through the loader DOM instead of using the circular border/background spinner. Update the SVG to inherit currentColor, expand its viewBox to avoid edge clipping, and style the dialog spinner with the app primary theme color.
Add ?raw SVG handling to both Rspack and Webpack so inline SVG imports do not conflict with normal asset/resource SVG usage. Also removes the old theme-side tail-spin recoloring path now that the spinner color is driven by CSS.