Skip to content

Commit 7844818

Browse files
committed
feat(atomic-loader): add svg-sprite variant support
1 parent e3f2841 commit 7844818

5 files changed

Lines changed: 44 additions & 11 deletions

File tree

packages/react-icons-atomic-webpack-loader/README.md

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ module.exports = {
6363

6464
## Options
6565

66-
| Option | Type | Default | Description |
67-
| ------------- | -------------------- | ------- | ----------------------------------------------------- |
68-
| `iconVariant` | `'svg'` \| `'fonts'` | `'svg'` | Whether icons resolve to SVG or font-based components |
66+
| Option | Type | Default | Description |
67+
| ------------- | -------------------------------------- | ------- | ------------------------------------------------------------------ |
68+
| `iconVariant` | `'svg'` \| `'fonts'` \| `'svg-sprite'` | `'svg'` | Whether icons resolve to SVG, font-based, or SVG sprite components |
6969

7070
### Using font icons
7171

@@ -86,15 +86,34 @@ module.exports = {
8686

8787
This changes icon resolution from `@fluentui/react-icons/svg/*` to `@fluentui/react-icons/fonts/*`. Non-icon exports (`utils`, `providers`) are unaffected.
8888

89+
### Using SVG sprite icons
90+
91+
```js
92+
{
93+
test: /\.[mc]?[jt]sx?$/,
94+
enforce: 'pre',
95+
use: [
96+
{
97+
loader: '@fluentui/react-icons-atomic-webpack-loader',
98+
options: {
99+
iconVariant: 'svg-sprite',
100+
},
101+
},
102+
],
103+
}
104+
```
105+
106+
This changes icon resolution from `@fluentui/react-icons/svg/*` to `@fluentui/react-icons/svg-sprite/*`. Non-icon exports (`utils`, `providers`) are unaffected.
107+
89108
## How it works
90109

91110
The loader uses a Babel transform to rewrite import and re-export declarations that reference `@fluentui/react-icons`. Each named specifier is routed to an atomic subpath based on its name:
92111

93-
| Export type | Example | Resolved path |
94-
| -------------- | ------------------------------------------------ | ------------------------------------------------- |
95-
| Icon component | `AddFilled`, `ArrowLeftRegular` | `@fluentui/react-icons/svg/add` (or `/fonts/add`) |
96-
| Context / hook | `useIconContext`, `IconDirectionContextProvider` | `@fluentui/react-icons/providers` |
97-
| Utility | `bundleIcon`, `createFluentIcon` | `@fluentui/react-icons/utils` |
112+
| Export type | Example | Resolved path |
113+
| -------------- | ------------------------------------------------ | -------------------------------------------------------------------- |
114+
| Icon component | `AddFilled`, `ArrowLeftRegular` | `@fluentui/react-icons/svg/add` (or `/fonts/add`, `/svg-sprite/add`) |
115+
| Context / hook | `useIconContext`, `IconDirectionContextProvider` | `@fluentui/react-icons/providers` |
116+
| Utility | `bundleIcon`, `createFluentIcon` | `@fluentui/react-icons/utils` |
98117

99118
Files that don't reference `@fluentui/react-icons` are passed through untouched (fast regex pre-check).
100119

packages/react-icons-atomic-webpack-loader/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { LoaderContext } from 'webpack';
44
const REACT_ICONS_IMPORT_REGEX = /['"]@fluentui\/react-icons['";\s]/;
55

66
export interface FluentIconsAtomicImportLoaderOptions {
7-
iconVariant?: 'svg' | 'fonts';
7+
iconVariant?: 'svg' | 'fonts' | 'svg-sprite';
88
}
99

1010
export default function fluentIconsAtomicImportLoader(

packages/react-icons-atomic-webpack-loader/src/transform.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ const MODULE_NAME = '@fluentui/react-icons';
99
const ICON_SUFFIX_REGEX = /(\d*)?(Regular|Filled|Light|Color)$/;
1010

1111
interface TransformOptions {
12-
iconVariant: 'svg' | 'fonts';
12+
iconVariant: 'svg' | 'fonts' | 'svg-sprite';
1313
isTypescript: boolean;
1414
isTsx: boolean;
1515
}
1616

17-
function getAtomicImportPath(importName: string, iconVariant: 'svg' | 'fonts'): string {
17+
function getAtomicImportPath(importName: string, iconVariant: 'svg' | 'fonts' | 'svg-sprite'): string {
1818
if (importName === 'useIconContext' || importName === 'IconDirectionContextProvider') {
1919
return '@fluentui/react-icons/providers';
2020
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { AddFilled } from '@fluentui/react-icons';
2+
import { ArrowLeftRegular, bundleIcon } from '@fluentui/react-icons';
3+
4+
console.log(AddFilled, ArrowLeftRegular, bundleIcon);

packages/react-icons-atomic-webpack-loader/test/webpack.config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ const entries = {
3939
],
4040
mustExclude: ['"@fluentui/react-icons"', '@fluentui/react-icons/svg/'],
4141
},
42+
'svg-sprite-imports': {
43+
src: './src/svg-sprite-imports.js',
44+
loaderOptions: { iconVariant: 'svg-sprite' },
45+
mustInclude: [
46+
'@fluentui/react-icons/svg-sprite/add',
47+
'@fluentui/react-icons/svg-sprite/arrow-left',
48+
'@fluentui/react-icons/utils',
49+
],
50+
mustExclude: ['"@fluentui/react-icons"', '@fluentui/react-icons/svg/', '@fluentui/react-icons/fonts/'],
51+
},
4252
};
4353

4454
/**

0 commit comments

Comments
 (0)