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.
Files changed (3) hide show
  1. package/README.md +2 -0
  2. package/dist/cli.js +41 -3
  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.1.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 svg = buildSvg(
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 text = format === "svg" ? svg + "\n" : svgToJsx(svg, comp) + "\n";
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.1.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": "^8.5.0",
23
+ "tsup": "^9.0.0",
24
24
  "typescript": "^5.6.0"
25
25
  }
26
26
  }