Skip to content

chore(react-icons): improve font/svg generator performance and add svg-sprites opt-in generators#1013

Merged
Hotell merged 21 commits intomicrosoft:mainfrom
Hotell:react-icons/svg-sprites-inc/1
Mar 24, 2026
Merged

chore(react-icons): improve font/svg generator performance and add svg-sprites opt-in generators#1013
Hotell merged 21 commits intomicrosoft:mainfrom
Hotell:react-icons/svg-sprites-inc/1

Conversation

@Hotell
Copy link
Copy Markdown
Collaborator

@Hotell Hotell commented Mar 20, 2026

Summary

This PR introduces:

  • existing svg/font generators refactoring for better perf and simpler code
  • SVG sprite generation support for @fluentui/react-icons as a preview feature, gated behind an opt-in --sprites CLI flag.

NOTE: Sprites are not included in stable releases.

Generators Refactoring & Fixes

  • convert.jsprocessPerIcon() now accepts optional spriteDest parameter; sprite metadata is only computed when sprites are enabled.
  • convert.utils.jsgeneratePerIconFiles() refactored to handle both per-icon atoms and sprite generation in a single pass.
  • per-icon.writer.js — Refactored grouping logic; shared between SVG atoms and sprite writer.
  • convert-font.js / convert-font.utils.js — Refactored generatePerIconFiles signature to accept { resizable, sized } object instead of flat array.
  • convert-font.utils.test.js — Fixed test calls to match the refactored generatePerIconFiles signature (was passing flat array, now passes { resizable: [], sized: entries }).
  • merge-metadata.js — Added log start/end blocks.

SVG Sprites

SVG Sprite Generation Pipeline (new)

  • sprite.writer.js — New module that generates SVG sprite pairs (.svg + .tsx) from the same icon data used for per-icon atoms. Each sprite file contains <symbol> elements for
    all icon variants, and a companion TSX module that uses createFluentIcon with a sprite URL reference.
  • src/utils/createFluentIcon.svg-sprite.tsx — New createFluentIcon factory for sprite-based icons that renders <use href="..."> references instead of inline SVG paths.
  • src/assets.d.ts — merged TypeScript declaration for .svg and font static asset imports.

Opt-in --sprites Flag

  • convert.js — Added --sprites boolean CLI flag to parseArgs(). When absent (default), --spriteDest is ignored and all sprite generation, directory creation, and metadata
    writing are skipped. When --sprites is passed, --spriteDest is required and sprites are generated as before.
  • build.js — Sprite SVG asset copying (src/atoms/svg-sprite/*.svglib/ and lib-cjs/) is guarded behind an existsSync() check. When sprites are present,
    addSpriteExportMap() dynamically injects the ./svg-sprite/* export map entry into package.json.
  • package.json — Removed static ./svg-sprite/* export map entry. It is now generated at build time only when sprites are enabled.

Documentation

  • docs/preview-features.md — Documentation for the SVG sprite preview feature.
  • README.md — Added reference to preview features docs.

How to Enable Sprites

Add --sprites to the convert:svg script and restore the ./svg-sprite/* export map in package.json:

# In convert:svg script, add --sprites flag:
node convert.js --source=./intermediate --dest=./src --perIconDest=./src/atoms/svg --spriteDest=./src/atoms/svg-sprite --sprites --rtl=./intermediate/rtl.json 
--metadata=./tmp/metadata-svg.json

When sprites are stabilized, the --sprites flag can be added permanently and the export map will be auto-generated during build.

@Hotell Hotell changed the title React icons/svg sprites inc/1 chore(react-icons): improve font/svg generator performance and add svg-sprites opt-in generators Mar 20, 2026
"lint": "eslint src",
"test": "vitest --exclude build-verify.test.js"
"test": "vitest --exclude build-verify.test.js",
"type-check:infra": "../../node_modules/.bin/tsc -p tsconfig.utils.json"
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

this is necessary as our infra uses latest node / TS 5+ which is hoisted to workspace root

@Hotell Hotell force-pushed the react-icons/svg-sprites-inc/1 branch from e3f03b2 to 50417b4 Compare March 23, 2026 10:37
@Hotell Hotell marked this pull request as ready for review March 23, 2026 13:00
@Hotell Hotell requested review from a team and spencer-nelson as code owners March 23, 2026 13:00
@Hotell Hotell requested a review from ValentinaKozlova March 23, 2026 15:18
const addCirclePath = path.join(atomDir, 'add-circle.js');
expect(fs.existsSync(addCirclePath)).toBe(true);
const addCircleContent = await readFile(addCirclePath, 'utf-8');
expect(addCircleContent).toContain('{ color: true }');
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.

If color variants will be deprecated, do we need tests for them?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

we do,

deprecated != removed.

to maintain API contract we can remove it only with major bump -> 3.0.0

@Hotell Hotell merged commit 5861b27 into microsoft:main Mar 24, 2026
7 checks passed
@Hotell Hotell deleted the react-icons/svg-sprites-inc/1 branch March 24, 2026 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants