11<div align =" center " >
22
3- # @react-zero-ui/icon-sprite
3+ # @react-zero-ui/icon-sprite
44
5- [ ![ MIT] ( https://img.shields.io/badge/License-MIT-green.svg )] ( https://github.com/react-zero-ui/icon-sprite/blob/main/LICENSE ) [ ![ npm] ( https://img.shields.io/npm/v/@react-zero-ui/icon-sprite.svg )] ( https://www.npmjs.com/package/@react-zero-ui/icon-sprite )
5+ [ ![ MIT] ( https://img.shields.io/badge/License-MIT-green.svg )] ( https://github.com/react-zero-ui/icon-sprite/blob/main/LICENSE ) [ ![ npm] ( https://img.shields.io/npm/v/@react-zero-ui/icon-sprite.svg )] ( https://www.npmjs.com/package/@react-zero-ui/icon-sprite )
66
7-
8-
97</div >
108
11- > ![ Note] ( https://img.shields.io/badge/Note-blue )
12- > ** Generates one SVG sprite containing only the icons you used** - Lucide + custom SVGs.
9+ > ![ Note] ( https://img.shields.io/badge/Note-blue ) > ** Generates one SVG sprite containing only the icons you used** - Lucide + custom SVGs.
1310> DX with real ` <Icon/> ` in dev ➡️ zero-runtime ` <use/> ` in prod.
1411
1512> Part of the [ React Zero-UI] ( https://github.com/react-zero-ui ) ecosystem.
16-
1713
1814---
1915
3430 Only icons actually used in your app are included.
3531
3632## 🙏 Custom Icon Support
33+
3734Drop SVGs into ** ` /public/zero-ui-icons/ ` ** , then use ` <CustomIcon /> ` with the filename (no ` .svg ` ).
3835
39- > ![ Tip] ( https://img.shields.io/badge/Tip-green )
40- > ``` txt
41- >📁/public
36+ > ![ Tip] ( https://img.shields.io/badge/Tip-green )
37+ >
38+ > ``` txt
39+ > 📁/public
4240> └──📁/zero-ui-icons/
4341> └──dog.svg
4442> ```
43+ >
4544> ```tsx
46- >import { CustomIcon } from "@react-zero-ui/icon-sprite";
47- >//❗The name MUST match the name of the file name (no .svg extension).
48- ><CustomIcon name="dog" size={24} />
49- >```
50-
45+ > import { CustomIcon } from '@react-zero-ui/icon-sprite';
46+ > //❗The name MUST match the name of the file name (no .svg extension).
47+ > <CustomIcon name='dog' size={24} />;
48+ > ```
5149
52- >
50+ > 
5351> In dev you may see a brief FOUC using custom icons; this is removed in production.
5452
55-
56-
5753---
5854
5955## 📦 Installation
@@ -65,15 +61,18 @@ npm install @react-zero-ui/icon-sprite
6561---
6662
6763## ❗ Build Command
64+
6865> ![ Caution] ( https://img.shields.io/badge/Caution-red )
6966> Run this before your app build so the sprite exists.
70- > ``` bash
71- > npx zero-icons
72- > ` ` `
67+ >
68+ > ``` bash
69+ > npx zero-icons
70+ > ` ` `
7371
7472This command builds the icons sprite for production.
7573
7674Or add this to your ` package.json` scripts:
75+
7776` ` ` json
7877{
7978 " scripts" : {
@@ -82,14 +81,14 @@ Or add this to your `package.json` scripts:
8281 }
8382}
8483```
84+
8585That's it!
8686
8787---
8888
8989## 🔨 Usage
9090
91- > ![ Warning] ( https://img.shields.io/badge/Warning-orange )
92- > ** Pass ` size ` , or both ` width ` and ` height ` , to ensure identical dev/prod rendering.**
91+ > ![ Warning] ( https://img.shields.io/badge/Warning-orange ) > ** Pass ` size ` , or both ` width ` and ` height ` , to ensure identical dev/prod rendering.**
9392> Dev defaults (Lucide 24×24) differ from sprite viewBoxes in production. Missing these props will ** very likely** change the visual size in prod.
9493
9594### For Lucide Icons:
@@ -104,14 +103,13 @@ import { ArrowRight, Mail } from "@react-zero-ui/icon-sprite";
104103### Custom Icons:
105104
106105Drop SVGs into ** ` /public/zero-ui-icons/ ` ** , then use ` <CustomIcon /> ` with the filename (no ` .svg ` ).
106+
107107``` tsx
108- import { CustomIcon } from " @react-zero-ui/icon-sprite" ;
108+ import { CustomIcon } from ' @react-zero-ui/icon-sprite' ;
109109// ❗The name MUST match the name of the file name (without .svg).
110- <CustomIcon name = " dog" size = { 32 } />
110+ <CustomIcon name = ' dog' size = { 32 } />;
111111```
112112
113-
114-
115113---
116114
117115## 🧪 How It Works (Under the Hood)
@@ -121,10 +119,10 @@ import { CustomIcon } from "@react-zero-ui/icon-sprite";
121119In dev, each icon wrapper looks like this:
122120
123121``` tsx
124- import { ArrowRight as DevIcon } from " lucide-react" ;
122+ import { ArrowRight as DevIcon } from ' lucide-react' ;
125123
126- export const ArrowRight = ( props ) =>
127- process .env .NODE_ENV === " development" ? (
124+ export const ArrowRight = props =>
125+ process .env .NODE_ENV === ' development' ? (
128126 <DevIcon { ... props } />
129127 ) : (
130128 <svg { ... props } >
@@ -135,10 +133,10 @@ export const ArrowRight = (props) =>
135133
136134This ensures:
137135
138- * Dev uses Lucide's real React components (` lucide-react ` )
139- * Full props support (e.g. ` strokeWidth ` , ` className ` )
140- * No caching issues from SVG sprites
141- * No FOUC (Flash of Unstyled Content)
136+ - Dev uses Lucide's real React components (` lucide-react ` )
137+ - Full props support (e.g. ` strokeWidth ` , ` className ` )
138+ - No caching issues from SVG sprites
139+ - No FOUC (Flash of Unstyled Content)
142140
143141### ⚙️ Production Mode: Minimal Runtime, Maximum Speed
144142
@@ -150,6 +148,41 @@ At build time:
150148
151149---
152150
151+ ## ⚙️ Configuration
152+
153+ You can customize the scanner behavior by creating a ` zero-ui.config.js ` file in your project root:
154+
155+ ``` js
156+ // zero-ui.config.js
157+ export default {
158+ // Package name to scan for (default: "@react-zero-ui/icon-sprite")
159+ IMPORT_NAME : ' @react-zero-ui/icon-sprite' ,
160+
161+ // Path where the sprite will be served (default: "/icons.svg")
162+ SPRITE_PATH : ' /icons.svg' ,
163+
164+ // Directory to scan for icon usage (default: "src")
165+ ROOT_DIR : ' src' ,
166+
167+ // Directory containing custom SVG files (default: "zero-ui-icons")
168+ CUSTOM_SVG_DIR : ' zero-ui-icons' ,
169+
170+ // Output directory for the sprite (default: "public")
171+ OUTPUT_DIR : ' public' ,
172+
173+ // Icon names to ignore during scanning (default: ["CustomIcon"])
174+ IGNORE_ICONS : [' CustomIcon' ],
175+
176+ // Directories to exclude from scanning (default: ["node_modules", ".git", "dist", "build", ".next", "out"])
177+ EXCLUDE_DIRS : [' node_modules' , ' .git' , ' dist' , ' build' , ' .next' , ' out' ],
178+ };
179+ ```
180+
181+ > ![ Note] ( https://img.shields.io/badge/Note-blue )
182+ > The scanner now defaults to scanning only the ` src ` directory and automatically excludes ` node_modules ` and other common build directories. This prevents build failures from dependencies with unsupported syntax (e.g., TypeScript decorators).
183+
184+ ---
185+
153186## ⚡️ Tooling
154187
155188To generate everything:
@@ -160,22 +193,19 @@ npx zero-icons
160193
161194This runs the full pipeline:
162195
163- | Script | Purpose |
164- | --- | --- |
165- | ` scan-icons.js ` | Parse your codebase for used icons (` Icon ` usage or named imports) |
166- | ` used-icons.js ` | Collects a list of unique icon names |
196+ | Script | Purpose |
197+ | ----------------- | --------------------------------------------------------------------------------------------------------- --- |
198+ | ` scan-icons.js ` | Parse your codebase for used icons (` Icon ` usage or named imports) |
199+ | ` used-icons.js ` | Collects a list of unique icon names |
167200| ` build-sprite.js ` | Uses [ ` svgstore ` ] ( https://github.com/DIYgod/svgstore ) to generate ` icons.svg ` from used Lucide + custom SVGs |
168-
169201
170- ---
202+ ---
171203
172204## ✨ Why This Beats Icon Libraries Everywhere
173205
174- * ** DX-first in dev** : No flicker. No sprite caching. Live updates.
175- * ** Zero-runtime in production** : Sprites are native, fast, lightweight & highly Cached.
176- * ** Only ships the icons you actually use** - smallest possible sprite.
177- * ** Custom icon support** : Drop SVGs into ` /public/zero-ui-icons/ ` and use ` <CustomIcon /> `
178-
206+ - ** DX-first in dev** : No flicker. No sprite caching. Live updates.
207+ - ** Zero-runtime in production** : Sprites are native, fast, lightweight & highly Cached.
208+ - ** Only ships the icons you actually use** - smallest possible sprite.
209+ - ** Custom icon support** : Drop SVGs into ` /public/zero-ui-icons/ ` and use ` <CustomIcon /> `
179210
180211Made with ❤️ for the React community by [ @austin1serb ] ( https://github.com/austin1serb )
181-
0 commit comments