rdicons 0.1.0 → 0.3.0
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 +2 -0
- package/dist/cli.js +41 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -30,6 +30,8 @@ rdicons sets list the 19 libraries with their licenses
|
|
|
30
30
|
| `--stroke` | the icon's own | stroke width (outline icons) |
|
|
31
31
|
| `--padding` | `0` | extra space around the icon |
|
|
32
32
|
| `--background` | none | solid background |
|
|
33
|
+
| `--animated [mode]` | off | add the icon's animation (rd icons): `hover` (default), `parent`, `play` or `loop`. The CSS is inside the file. Other libraries have no animation and get the still icon |
|
|
34
|
+
| `--speed <n>` | `1` | animation speed, `2` is twice as fast (needs `--animated`) |
|
|
33
35
|
|
|
34
36
|
Icons come from https://rdicons.vimalbhatt.com (set `RDICONS_URL` to use another address). Needs Node 18+.
|
|
35
37
|
|
package/dist/cli.js
CHANGED
|
@@ -65,6 +65,7 @@ function propsString(o = {}) {
|
|
|
65
65
|
if (o.color) p.push(`color="${o.color}"`);
|
|
66
66
|
if (o.strokeWidth != null) p.push(`strokeWidth={${o.strokeWidth}}`);
|
|
67
67
|
if (o.animate) p.push(o.animate === "hover" ? "animate" : `animate="${o.animate}"`);
|
|
68
|
+
if (o.animate && o.speed && o.speed !== 1) p.push(`speed={${o.speed}}`);
|
|
68
69
|
return p.length ? " " + p.join(" ") : "";
|
|
69
70
|
}
|
|
70
71
|
function componentName(icon) {
|
|
@@ -124,7 +125,7 @@ export function Example() {
|
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
// src/cli.ts
|
|
127
|
-
var VERSION = "0.
|
|
128
|
+
var VERSION = "0.3.0";
|
|
128
129
|
var BASE = (process.env.RDICONS_URL || "https://rdicons.vimalbhatt.com").replace(/\/$/, "");
|
|
129
130
|
var HELP = `rdicons ${VERSION}: add open-source icons to your project
|
|
130
131
|
|
|
@@ -142,14 +143,41 @@ Options for "add"
|
|
|
142
143
|
--stroke <number> stroke width for outline icons
|
|
143
144
|
--padding <number> extra space around the icon (viewBox units)
|
|
144
145
|
--background <color> solid background behind the icon
|
|
146
|
+
--animated [mode] add the icon's animation (rd icons): hover (default), parent, play or loop
|
|
147
|
+
--speed <number> animation speed, 2 is twice as fast (default 1; needs --animated)
|
|
145
148
|
|
|
146
149
|
Examples
|
|
147
150
|
npx rdicons add lucide:house
|
|
148
151
|
npx rdicons add tabler:bell ph:heart --format tsx --out src/icons --color "#4f46e5"
|
|
152
|
+
npx rdicons add rd:bell --animated loop --speed 1.5 --format tsx
|
|
149
153
|
npx rdicons search "arrow right" --set lucide
|
|
150
154
|
|
|
151
155
|
Icons keep their original license, shown by "rdicons sets". Site: ${BASE}
|
|
152
156
|
`;
|
|
157
|
+
var MODES = ["hover", "parent", "play", "loop"];
|
|
158
|
+
var animCache = /* @__PURE__ */ new Map();
|
|
159
|
+
async function fetchAnimation(set, name) {
|
|
160
|
+
if (!animCache.has(set)) animCache.set(set, await getJson(`/api/animations?set=${encodeURIComponent(set)}`));
|
|
161
|
+
return animCache.get(set)?.[name] ?? null;
|
|
162
|
+
}
|
|
163
|
+
function animatedSvg(name, a, o) {
|
|
164
|
+
const css = [o.color ? `color:${o.color}` : "", o.speed !== 1 ? `--rd-speed:${+(1 / o.speed).toFixed(2)}` : ""].filter(Boolean).join(";");
|
|
165
|
+
const body = o.stroke == null ? a.b : a.b.replace(/stroke-width="[^"]*"/g, `stroke-width="${o.stroke}"`);
|
|
166
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="${o.size}" height="${o.size}" class="rd-a-${name}" data-rd-animate="${o.mode}"${css ? ` style="${css}"` : ""}>
|
|
167
|
+
<style>${a.c}</style>
|
|
168
|
+
${body}
|
|
169
|
+
</svg>`;
|
|
170
|
+
}
|
|
171
|
+
function jsxifyAnimated(jsx, ts) {
|
|
172
|
+
const cast = ts ? " as React.CSSProperties" : "";
|
|
173
|
+
return jsx.replace(/<style>([\s\S]*?)<\/style>/, (_, css) => "<style>{`" + css.replace(/[`\\]|\$\{/g, (m) => "\\" + m) + "`}</style>").replace(/ style="([^"]*)"/, (_, decl) => {
|
|
174
|
+
const props = decl.split(";").filter(Boolean).map((d) => {
|
|
175
|
+
const [k, ...v] = d.split(":");
|
|
176
|
+
return `'${k.trim()}': '${v.join(":").trim()}'`;
|
|
177
|
+
});
|
|
178
|
+
return ` style={{ ${props.join(", ")} }${cast}}`;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
153
181
|
var CliError = class extends Error {
|
|
154
182
|
};
|
|
155
183
|
function fail(msg) {
|
|
@@ -173,6 +201,7 @@ function parseArgs(argv) {
|
|
|
173
201
|
if (a.startsWith("--")) {
|
|
174
202
|
const [k, inline] = a.slice(2).split("=");
|
|
175
203
|
if (inline !== void 0) flags[k] = inline;
|
|
204
|
+
else if (k === "animated") flags[k] = MODES.includes(argv[i + 1]) ? argv[++i] : "true";
|
|
176
205
|
else if (argv[i + 1] !== void 0 && !argv[i + 1].startsWith("--")) flags[k] = argv[++i];
|
|
177
206
|
else flags[k] = "true";
|
|
178
207
|
} else positional.push(a);
|
|
@@ -234,10 +263,18 @@ async function cmdAdd(positional, flags) {
|
|
|
234
263
|
const format = flags.format ?? "svg";
|
|
235
264
|
if (!["svg", "jsx", "tsx"].includes(format)) fail("--format must be svg, jsx or tsx");
|
|
236
265
|
const out = resolve(flags.out ?? "icons");
|
|
266
|
+
const mode = flags.animated === void 0 ? null : flags.animated === "true" ? "hover" : flags.animated;
|
|
267
|
+
if (mode && !MODES.includes(mode)) fail(`--animated must be one of ${MODES.join(", ")} (or just --animated for hover)`);
|
|
268
|
+
const speed = flags.speed === void 0 ? 1 : Number(flags.speed);
|
|
269
|
+
if (!(speed > 0 && speed <= 10)) fail("--speed must be a number between 0 and 10, for example --speed 1.5");
|
|
270
|
+
if (flags.speed !== void 0 && !mode) fail("--speed only works together with --animated");
|
|
271
|
+
if (mode && (flags.padding !== void 0 || flags.background !== void 0)) fail("--animated cannot be combined with --padding or --background");
|
|
237
272
|
await mkdir(out, { recursive: true });
|
|
238
273
|
for (const ref of positional) {
|
|
239
274
|
const it = await fetchIcon(ref);
|
|
240
|
-
const
|
|
275
|
+
const anim = mode ? await fetchAnimation(it.s, it.n) : null;
|
|
276
|
+
if (mode && !anim) console.log(` note: ${it.s}:${it.n} has no animation (only rd icons move), so the still icon is written.`);
|
|
277
|
+
const svg = anim ? animatedSvg(it.n, anim, { size: flags.size ? Number(flags.size) : 24, color: flags.color, stroke: flags.stroke ? Number(flags.stroke) : null, mode, speed }) : buildSvg(
|
|
241
278
|
{ body: it.b, width: it.w ?? 24, height: it.h ?? 24 },
|
|
242
279
|
{
|
|
243
280
|
color: flags.color,
|
|
@@ -250,7 +287,8 @@ async function cmdAdd(positional, flags) {
|
|
|
250
287
|
);
|
|
251
288
|
const comp = it.c ?? toPascalCase(it.n);
|
|
252
289
|
const file = format === "svg" ? `${it.s}-${it.n}.svg` : `${comp}.${format}`;
|
|
253
|
-
const
|
|
290
|
+
const jsx = format === "svg" ? "" : svgToJsx(svg, comp);
|
|
291
|
+
const text = format === "svg" ? svg + "\n" : (anim ? jsxifyAnimated(jsx, format === "tsx") : jsx) + "\n";
|
|
254
292
|
await writeFile(join(out, file), text, "utf8");
|
|
255
293
|
console.log(`\u2713 ${it.s}:${it.n} -> ${join(flags.out ?? "icons", file)}`);
|
|
256
294
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rdicons",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "rdicons command line: search 78,000+ open-source icons and add them to your project as SVG, JSX or TSX. Try: npx rdicons add lucide:house",
|
|
5
5
|
"keywords": ["icons", "cli", "svg", "react", "tsx", "icon-generator", "lucide", "tabler", "rdicons"],
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@rdicons/core": "*",
|
|
23
|
-
"tsup": "^
|
|
23
|
+
"tsup": "^9.0.0",
|
|
24
24
|
"typescript": "^5.6.0"
|
|
25
25
|
}
|
|
26
26
|
}
|