Skip to content

fix: Use inline themed SVG for loader spinner#2378

Closed
deadlyjack wants to merge 1 commit into
mainfrom
ajit/fix-ui
Closed

fix: Use inline themed SVG for loader spinner#2378
deadlyjack wants to merge 1 commit into
mainfrom
ajit/fix-ui

Conversation

@deadlyjack

Copy link
Copy Markdown
Member

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.

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-apps

greptile-apps Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR replaces the CSS border-based spinner in the loader dialog with an inline SVG (tail-spin.svg) whose colors are driven by currentColor/--primary-color, and removes the old async theme-side path that read and rewrote the SVG on disk for each theme change.

  • Both Rspack and Webpack configs gain a ?raw rule (asset/source) placed before the general asset rule, with the existing rule narrowed by resourceQuery: { not: [/raw/] } — the correct Webpack 5 pattern.
  • src/theme/list.js drops the fsOperation file-read/write block that recolored the SVG per theme, cleaning up three now-unused imports.
  • The SVG viewBox is expanded to -1 -1 40 40 to prevent stroke clipping at the edges, and all hard-coded #fff values are replaced with currentColor.

Confidence Score: 4/5

Safe 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

Filename Overview
src/dialogs/loader.js Inlines the tail-spin SVG via a build-time ?raw import set as innerHTML; DOMPurify is not applied to the SVG but it is a static bundled asset so no XSS risk. Logic is straightforward.
src/res/tail-spin.svg Switches fill/stroke colors to currentColor and expands viewBox to -1 -1 40 40 to avoid clipping; the generic linearGradient id="a" could conflict with same-ID elements from other inline SVGs in the document.
src/dialogs/style.scss Replaces the circular-loader mixin with inline CSS driven by currentColor/--primary-color; the @use "../styles/mixins.scss" import is correctly removed since no other mixin usages remain in the file.
src/theme/list.js Removes the async file-read/write path that recolored the SVG per theme; also cleans up import paths to use module aliases. Clean removal with no remaining references to the deleted logic.
rspack.config.js Adds a ?raw SVG rule (asset/source) before the general asset rule and narrows the existing rule with resourceQuery: { not: [/raw/] }; correct Rspack 5 pattern.
webpack.config.js Same ?raw SVG split as rspack.config.js; indentation also corrected on the m.scss rule. Change is correct and consistent with the Rspack config.
src/cm/themes/noctisLilac.js Drive-by fix: adds alpha transparency to the activeLine color (#e1def3 → #e1def355). Unrelated to the spinner change but harmless.

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
Loading
%%{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
Loading

Reviews (1): Last reviewed commit: "fix: Use inline themed SVG for loader sp..." | Re-trigger Greptile

Comment thread src/res/tail-spin.svg
<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">

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.

P2 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.

@deadlyjack deadlyjack closed this Jun 24, 2026
@github-project-automation github-project-automation Bot moved this from Backlog to Done in The Code Board - Acode Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant