svg-dynamic-icon 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -19
- package/dist/index.js +5 -51
- package/dist/index.js.map +2 -2
- package/dist/src/DynamicIcon.d.ts +1 -2
- package/dist/src/DynamicIcon.js +3 -27
- package/package.json +1 -1
- package/src/DynamicIcon.tsx +6 -23
package/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# svg-dynamic-icon
|
2
2
|
|
3
3
|
- A lightweight React component for rendering **custom-made SVG icons** with **TailwindCSS** support.
|
4
|
-
-
|
4
|
+
- Ideal for projects with a custom icon set, where you want a clean API without manually importing every icon.
|
5
5
|
|
6
6
|
#
|
7
7
|
|
@@ -13,17 +13,96 @@ npm install svg-dynamic-icon
|
|
13
13
|
|
14
14
|
#
|
15
15
|
|
16
|
-
##
|
16
|
+
## 📁 Place Your Icons
|
17
|
+
|
18
|
+
- Put all your custom SVGs inside:
|
19
|
+
|
20
|
+
```bash
|
21
|
+
src/assets/icons/
|
22
|
+
```
|
23
|
+
|
24
|
+
## 🧠 Setup the Icon Map
|
25
|
+
|
26
|
+
- ⚡ Vite (for React, Svelte, etc.)
|
17
27
|
|
18
28
|
```bash
|
29
|
+
// src/lib/iconMap.ts
|
30
|
+
|
31
|
+
export const iconMap = import.meta.glob("../assets/icons/*.svg", {
|
32
|
+
eager: true,
|
33
|
+
import: "default",
|
34
|
+
});
|
35
|
+
```
|
36
|
+
|
37
|
+
- ⚡ Next.js
|
38
|
+
|
39
|
+
```bash
|
40
|
+
// next.config.js
|
41
|
+
|
42
|
+
const nextConfig = {
|
43
|
+
webpack(config) {
|
44
|
+
config.module.rules.push({
|
45
|
+
test: /\.svg$/,
|
46
|
+
issuer: /\.[jt]sx?$/,
|
47
|
+
use: ["@svgr/webpack"],
|
48
|
+
});
|
49
|
+
return config;
|
50
|
+
},
|
51
|
+
};
|
52
|
+
module.exports = nextConfig;
|
53
|
+
```
|
54
|
+
|
55
|
+
- ⚡ Webpack (Create React App)
|
56
|
+
|
57
|
+
```bash
|
58
|
+
// src/lib/iconMap.ts
|
59
|
+
|
60
|
+
const importAll = (r: __WebpackModuleApi.RequireContext) =>
|
61
|
+
Object.fromEntries(
|
62
|
+
r.keys().map((key) => [
|
63
|
+
key.replace("./", "").replace(".svg", ""),
|
64
|
+
r(key).default ?? r(key),
|
65
|
+
])
|
66
|
+
);
|
67
|
+
|
68
|
+
export const iconMap = importAll(
|
69
|
+
require.context("../assets/icons", false, /\.svg$/)
|
70
|
+
);
|
71
|
+
```
|
72
|
+
|
73
|
+
#
|
74
|
+
|
75
|
+
## 💡 Create a Wrapper Component
|
76
|
+
|
77
|
+
- This allows you to use iconName instead of manually importing SVG paths.
|
78
|
+
|
79
|
+
```bash
|
80
|
+
// src/components/Icon.tsx
|
81
|
+
|
19
82
|
import { DynamicIcon } from "svg-dynamic-icon";
|
83
|
+
import { iconMap } from "../lib/iconMap";
|
84
|
+
|
85
|
+
const Icon = ({ iconName, ...props }) => {
|
86
|
+
const iconSrc = iconMap[iconName];
|
87
|
+
return iconSrc ? <DynamicIcon iconSrc={iconSrc} {...props} /> : null;
|
88
|
+
};
|
89
|
+
|
90
|
+
export default Icon;
|
91
|
+
```
|
92
|
+
|
93
|
+
#
|
94
|
+
|
95
|
+
## 🚀 Use It Anywhere
|
96
|
+
|
97
|
+
```bash
|
98
|
+
import Icon from "./components/Icon";
|
20
99
|
|
21
100
|
function Example() {
|
22
101
|
return (
|
23
|
-
<
|
24
|
-
iconName="Checkmark"
|
25
|
-
size={32}
|
26
|
-
color="text-blue-500"
|
102
|
+
<Icon
|
103
|
+
iconName="Checkmark" // matches Checkmark.svg in /assets/icons
|
104
|
+
size={32} // renders 32px x 32px
|
105
|
+
color="text-blue-500" // tailwind class
|
27
106
|
/>
|
28
107
|
);
|
29
108
|
}
|
@@ -31,21 +110,13 @@ function Example() {
|
|
31
110
|
|
32
111
|
#
|
33
112
|
|
34
|
-
## 📁 Icon Setup
|
35
|
-
|
36
|
-
- Place your SVG icons in the /assets/icons/ folder.
|
37
|
-
- File names must match the iconName prop exactly (MyIcon.svg → iconName="MyIcon").
|
38
|
-
- Upload square-shaped icons for best rendering (e.g., 24x24 or 64x64).
|
39
|
-
|
40
|
-
#
|
41
|
-
|
42
113
|
## ⚙️ Props
|
43
114
|
|
44
|
-
| **Prop** | **Type** | **Required** | **Description**
|
45
|
-
| :------- | :------- | :----------- |
|
46
|
-
|
|
47
|
-
| size | number | no | Icon size in pixels (width & height). Default: 25
|
48
|
-
| color | string | no | TailwindCSS text color class (e.g., text-white, text-gray-500)
|
115
|
+
| **Prop** | **Type** | **Required** | **Description** |
|
116
|
+
| :------- | :------- | :----------- | :------------------------------------------------------------- |
|
117
|
+
| iconSrc | string | yes | Full path to the SVG file (auto-handled by wrapper) |
|
118
|
+
| size | number | no | Icon size in pixels (width & height). Default: 25 |
|
119
|
+
| color | string | no | TailwindCSS text color class (e.g., text-white, text-gray-500) |
|
49
120
|
|
50
121
|
#
|
51
122
|
|
package/dist/index.js
CHANGED
@@ -1,18 +1,8 @@
|
|
1
1
|
"use strict";
|
2
|
-
var __create = Object.create;
|
3
2
|
var __defProp = Object.defineProperty;
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
8
|
-
var __glob = (map) => (path) => {
|
9
|
-
var fn = map[path];
|
10
|
-
if (fn) return fn();
|
11
|
-
throw new Error("Module not found in bundle: " + path);
|
12
|
-
};
|
13
|
-
var __commonJS = (cb, mod) => function __require() {
|
14
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
15
|
-
};
|
16
6
|
var __export = (target, all) => {
|
17
7
|
for (var name in all)
|
18
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
@@ -25,23 +15,8 @@ var __copyProps = (to, from, except, desc) => {
|
|
25
15
|
}
|
26
16
|
return to;
|
27
17
|
};
|
28
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
29
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
30
|
-
// file that has been converted to a CommonJS file using a Babel-
|
31
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
32
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
33
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
34
|
-
mod
|
35
|
-
));
|
36
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
37
19
|
|
38
|
-
// assets/icons/Fallback.svg
|
39
|
-
var require_Fallback = __commonJS({
|
40
|
-
"assets/icons/Fallback.svg"(exports2, module2) {
|
41
|
-
module2.exports = "./assets/Fallback-R62GNTAJ.svg";
|
42
|
-
}
|
43
|
-
});
|
44
|
-
|
45
20
|
// index.ts
|
46
21
|
var index_exports = {};
|
47
22
|
__export(index_exports, {
|
@@ -50,41 +25,20 @@ __export(index_exports, {
|
|
50
25
|
module.exports = __toCommonJS(index_exports);
|
51
26
|
|
52
27
|
// src/DynamicIcon.tsx
|
53
|
-
var import_react = require("react");
|
54
28
|
var import_react_svg = require("react-svg");
|
55
29
|
var import_jsx_runtime = require("react/jsx-runtime");
|
56
|
-
|
57
|
-
// import("../assets/icons/**/*.svg") in src/DynamicIcon.tsx
|
58
|
-
var globImport_assets_icons_svg = __glob({
|
59
|
-
"../assets/icons/Fallback.svg": () => Promise.resolve().then(() => __toESM(require_Fallback()))
|
60
|
-
});
|
61
|
-
|
62
|
-
// src/DynamicIcon.tsx
|
63
30
|
var DynamicIcon = ({
|
64
|
-
|
65
|
-
size =
|
66
|
-
color
|
31
|
+
iconSrc,
|
32
|
+
size = 24,
|
33
|
+
color
|
67
34
|
}) => {
|
68
|
-
const [iconUrl, setIconUrl] = (0, import_react.useState)(null);
|
69
|
-
(0, import_react.useEffect)(() => {
|
70
|
-
const importIcon = async () => {
|
71
|
-
try {
|
72
|
-
const icon = await globImport_assets_icons_svg(`../assets/icons/${iconName}.svg`);
|
73
|
-
setIconUrl(icon.default);
|
74
|
-
} catch (error) {
|
75
|
-
console.error(`Icon ${iconName} not found`);
|
76
|
-
setIconUrl(null);
|
77
|
-
}
|
78
|
-
};
|
79
|
-
importIcon();
|
80
|
-
}, [iconName]);
|
81
35
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
82
36
|
import_react_svg.ReactSVG,
|
83
37
|
{
|
84
|
-
src:
|
38
|
+
src: iconSrc,
|
85
39
|
className: color,
|
86
40
|
beforeInjection: (svg) => {
|
87
|
-
svg.setAttribute("style", `width: ${size}px; height: ${size}px
|
41
|
+
svg.setAttribute("style", `width: ${size}px; height: ${size}px`);
|
88
42
|
svg.setAttribute("fill", "currentColor");
|
89
43
|
svg.querySelectorAll("path").forEach((path) => {
|
90
44
|
path.setAttribute("fill", "currentColor");
|
package/dist/index.js.map
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"version": 3,
|
3
3
|
"sources": ["../index.ts", "../src/DynamicIcon.tsx"],
|
4
|
-
"sourcesContent": ["export { default as DynamicIcon } from \"./src/DynamicIcon\";\r\n", "import
|
5
|
-
"mappings": "
|
4
|
+
"sourcesContent": ["export { default as DynamicIcon } from \"./src/DynamicIcon\";\r\n", "import { ReactSVG } from \"react-svg\";\r\n\r\ninterface DynamicIconProps {\r\n iconSrc: string;\r\n size?: number;\r\n color?: string;\r\n}\r\n\r\nconst DynamicIcon: React.FC<DynamicIconProps> = ({\r\n iconSrc,\r\n size = 24,\r\n color,\r\n}) => {\r\n return (\r\n <ReactSVG\r\n src={iconSrc}\r\n className={color}\r\n beforeInjection={(svg) => {\r\n svg.setAttribute(\"style\", `width: ${size}px; height: ${size}px`);\r\n svg.setAttribute(\"fill\", \"currentColor\");\r\n svg.querySelectorAll(\"path\").forEach((path) => {\r\n path.setAttribute(\"fill\", \"currentColor\");\r\n });\r\n }}\r\n />\r\n );\r\n};\r\n\r\nexport default DynamicIcon;\r\n"],
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,uBAAyB;AAcrB;AANJ,IAAM,cAA0C,CAAC;AAAA,EAC/C;AAAA,EACA,OAAO;AAAA,EACP;AACF,MAAM;AACJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAW;AAAA,MACX,iBAAiB,CAAC,QAAQ;AACxB,YAAI,aAAa,SAAS,UAAU,IAAI,eAAe,IAAI,IAAI;AAC/D,YAAI,aAAa,QAAQ,cAAc;AACvC,YAAI,iBAAiB,MAAM,EAAE,QAAQ,CAAC,SAAS;AAC7C,eAAK,aAAa,QAAQ,cAAc;AAAA,QAC1C,CAAC;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,sBAAQ;",
|
6
6
|
"names": []
|
7
7
|
}
|
package/dist/src/DynamicIcon.js
CHANGED
@@ -1,32 +1,8 @@
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8
|
-
});
|
9
|
-
};
|
10
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
11
|
-
import { useEffect, useState } from "react";
|
12
2
|
import { ReactSVG } from "react-svg";
|
13
|
-
const DynamicIcon = ({
|
14
|
-
|
15
|
-
|
16
|
-
const importIcon = () => __awaiter(void 0, void 0, void 0, function* () {
|
17
|
-
try {
|
18
|
-
const icon = yield import(`../assets/icons/${iconName}.svg`);
|
19
|
-
setIconUrl(icon.default);
|
20
|
-
}
|
21
|
-
catch (error) {
|
22
|
-
console.error(`Icon ${iconName} not found`);
|
23
|
-
setIconUrl(null);
|
24
|
-
}
|
25
|
-
});
|
26
|
-
importIcon();
|
27
|
-
}, [iconName]);
|
28
|
-
return (_jsx(ReactSVG, { src: iconUrl || "", className: color, beforeInjection: (svg) => {
|
29
|
-
svg.setAttribute("style", `width: ${size}px; height: ${size}px;`);
|
3
|
+
const DynamicIcon = ({ iconSrc, size = 24, color, }) => {
|
4
|
+
return (_jsx(ReactSVG, { src: iconSrc, className: color, beforeInjection: (svg) => {
|
5
|
+
svg.setAttribute("style", `width: ${size}px; height: ${size}px`);
|
30
6
|
svg.setAttribute("fill", "currentColor");
|
31
7
|
svg.querySelectorAll("path").forEach((path) => {
|
32
8
|
path.setAttribute("fill", "currentColor");
|
package/package.json
CHANGED
package/src/DynamicIcon.tsx
CHANGED
@@ -1,39 +1,22 @@
|
|
1
|
-
import React, { useEffect, useState } from "react";
|
2
1
|
import { ReactSVG } from "react-svg";
|
3
2
|
|
4
3
|
interface DynamicIconProps {
|
5
|
-
|
4
|
+
iconSrc: string;
|
6
5
|
size?: number;
|
7
6
|
color?: string;
|
8
7
|
}
|
9
8
|
|
10
9
|
const DynamicIcon: React.FC<DynamicIconProps> = ({
|
11
|
-
|
12
|
-
size =
|
13
|
-
color
|
10
|
+
iconSrc,
|
11
|
+
size = 24,
|
12
|
+
color,
|
14
13
|
}) => {
|
15
|
-
const [iconUrl, setIconUrl] = useState<string | null>(null);
|
16
|
-
|
17
|
-
useEffect(() => {
|
18
|
-
const importIcon = async () => {
|
19
|
-
try {
|
20
|
-
const icon = await import(`../assets/icons/${iconName}.svg`);
|
21
|
-
setIconUrl(icon.default);
|
22
|
-
} catch (error) {
|
23
|
-
console.error(`Icon ${iconName} not found`);
|
24
|
-
setIconUrl(null);
|
25
|
-
}
|
26
|
-
};
|
27
|
-
|
28
|
-
importIcon();
|
29
|
-
}, [iconName]);
|
30
|
-
|
31
14
|
return (
|
32
15
|
<ReactSVG
|
33
|
-
src={
|
16
|
+
src={iconSrc}
|
34
17
|
className={color}
|
35
18
|
beforeInjection={(svg) => {
|
36
|
-
svg.setAttribute("style", `width: ${size}px; height: ${size}px
|
19
|
+
svg.setAttribute("style", `width: ${size}px; height: ${size}px`);
|
37
20
|
svg.setAttribute("fill", "currentColor");
|
38
21
|
svg.querySelectorAll("path").forEach((path) => {
|
39
22
|
path.setAttribute("fill", "currentColor");
|