@bookklik/senangstart-icons 1.0.3

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/index.html ADDED
@@ -0,0 +1,479 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="scroll-smooth">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>SenangStart Icons | Curated icons designed for Starters</title>
7
+
8
+ <link rel="apple-touch-icon" sizes="180x180" href="ss.png" />
9
+ <link rel="shortcut icon" href="ss.png" type="image/x-icon" />
10
+
11
+ <!-- Google Fonts: Outfit -->
12
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
13
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
14
+ <link
15
+ href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap"
16
+ rel="stylesheet"
17
+ />
18
+
19
+ <!-- SenangStart Styles/Scripts -->
20
+ <link rel="stylesheet" href="dist/senangstart.min.css" />
21
+ <script src="dist/senangstart-icon.min.js"></script>
22
+
23
+ <!-- Senangwebs Jot -->
24
+ <link
25
+ rel="stylesheet"
26
+ href="https://unpkg.com/senangwebs-jot@latest/dist/swj.css"
27
+ />
28
+ <script src="https://unpkg.com/senangwebs-jot@latest/dist/swj.js"></script>
29
+
30
+ <!-- Senangwebs Modals -->
31
+ <link
32
+ rel="stylesheet"
33
+ href="https://unpkg.com/senangwebs-modals@latest/dist/swm.css"
34
+ />
35
+ <script src="https://unpkg.com/senangwebs-modals@latest/dist/swm.js"></script>
36
+
37
+ <!-- Alpine.js -->
38
+ <script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
39
+
40
+ <!-- Tailwind CSS -->
41
+ <script src="https://cdn.tailwindcss.com"></script>
42
+ <script>
43
+ tailwind.config = {
44
+ theme: {
45
+ extend: {
46
+ fontFamily: {
47
+ sans: ["Outfit", "sans-serif"],
48
+ },
49
+ colors: {
50
+ brand: {
51
+ 600: "#2563EB",
52
+ 700: "#1D4ED8",
53
+ },
54
+ },
55
+ },
56
+ },
57
+ };
58
+ </script>
59
+
60
+ <style type="text/tailwindcss">
61
+ @layer base {
62
+ body {
63
+ @apply antialiased text-slate-900 bg-slate-50;
64
+ }
65
+ }
66
+
67
+ @layer components {
68
+ #search-container input {
69
+ @apply w-full max-w-xl px-5 py-3.5 text-base text-slate-900 bg-white border border-slate-200 rounded-full shadow-sm outline-none transition-all duration-200 placeholder:text-slate-400;
70
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' xmlns='http://www.w3.org/2000/svg'%3E%3Cg%3E%3Cpath d='M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z' /%3E%3C/g%3E%3C/svg%3E");
71
+ background-repeat: no-repeat;
72
+ background-position: right 1rem center;
73
+ background-size: 1.25rem;
74
+ }
75
+
76
+ #search-container input:focus {
77
+ @apply border-brand-600 ring-4 ring-blue-500/10;
78
+ }
79
+
80
+ .swi-pagination-list {
81
+ @apply flex flex-wrap justify-center items-center gap-2 list-none p-0 mt-12;
82
+ }
83
+
84
+ .swi-pagination-btn {
85
+ @apply flex items-center justify-center min-w-[2.5rem] h-10 px-3 text-sm font-medium text-slate-600 bg-white border border-slate-200 rounded-lg transition-all duration-200 hover:border-brand-600 hover:text-brand-600;
86
+ }
87
+
88
+ .swi-pagination-item.swi-active .swi-pagination-btn {
89
+ @apply z-10 bg-brand-600 text-white border-brand-600 shadow-md shadow-blue-500/20 pointer-events-none;
90
+ }
91
+
92
+ .swi-pagination-item.swi-disabled .swi-pagination-btn {
93
+ @apply opacity-50 cursor-not-allowed bg-slate-50 text-slate-400 hover:border-slate-200 hover:text-slate-400;
94
+ }
95
+
96
+ .swj-button {
97
+ @apply bg-brand-600 text-white;
98
+ }
99
+
100
+ .swj-btn .swj-button {
101
+ @apply w-full;
102
+ }
103
+ }
104
+ </style>
105
+ </head>
106
+ <body class="flex flex-col min-h-screen">
107
+ <header class="w-full h-16 lg:h-24 bg-white">
108
+ <nav class="fixed z-50 w-full p-6" x-data="{ isOpen: false }">
109
+ <div
110
+ class="max-w-7xl mx-auto flex w-full flex-col rounded-xl bg-white bg-opacity-80 p-2 backdrop-blur backdrop-filter lg:flex-row border border-slate-200"
111
+ >
112
+ <div class="flex h-12 items-center">
113
+ <a href="https://senangstart.com/" target="_blank"
114
+ ><img src="ss.svg" class="h-8 pl-2"
115
+ /></a>
116
+ <div class="flex-grow lg:hidden"></div>
117
+ <div
118
+ x-on:click="isOpen = !isOpen"
119
+ x-on:click.outside="isOpen = false"
120
+ class="flex w-12 h-12 cursor-pointer flex items-center justify-center lg:hidden text-3xl"
121
+ >
122
+ <i class="ss ss-bars-3" :class="!isOpen ? '' : 'hidden'"></i>
123
+ <i class="ss ss-x-mark" :class="isOpen ? '' : 'hidden'"></i>
124
+ </div>
125
+ </div>
126
+ <div
127
+ :class="isOpen ? '' : 'hidden'"
128
+ class="flex-grow flex-col justify-end pt-4 lg:flex lg:flex-row lg:pt-0"
129
+ >
130
+ <a
131
+ href="#all-icons"
132
+ class="-mx-2 flex h-12 items-center px-6 lg:mx-0"
133
+ >Icons</a
134
+ >
135
+ <a
136
+ href="https://github.com/bookklik-technologies/senangstart-icons"
137
+ target="_blank"
138
+ class="-mx-2 flex h-12 items-center px-6 lg:mx-0"
139
+ >Github
140
+ <i class="ss ss-arrow-top-right-on-square ml-1" thickness="2"></i>
141
+ </a>
142
+ <a
143
+ href="#installation"
144
+ class="mx-4 mb-4 mt-4 flex h-12 items-center justify-center rounded-lg bg-blue-600 px-6 text-white lg:mb-0 lg:ml-4 lg:mr-0 lg:mt-0"
145
+ >Install</a
146
+ >
147
+ </div>
148
+ </div>
149
+ </nav>
150
+ </header>
151
+
152
+ <main class="flex-grow">
153
+ <div class="bg-white border-b border-slate-100 pb-12 pt-16 px-6">
154
+ <div class="max-w-4xl mx-auto text-center">
155
+ <h1
156
+ class="text-4xl md:text-5xl font-semibold text-slate-900 tracking-tight mb-4"
157
+ >
158
+ Icons for
159
+ <span class="text-brand-600"
160
+ >Senang<span class="font-normal">Start</span></span
161
+ >.
162
+ </h1>
163
+ <p class="text-lg text-slate-500 mb-8 max-w-2xl mx-auto">
164
+ Curated icons designed for Starters.
165
+ </p>
166
+
167
+ <div
168
+ class="max-w-4xl mx-auto flex flex-col md:flex-row md:flex-row justify-center items-center gap-8"
169
+ >
170
+ <div
171
+ id="search-container"
172
+ class="flex flex-col md:flex-row justify-center items-center flex-grow max-w-xl"
173
+ >
174
+ <input type="text" placeholder="Search icons..." />
175
+ </div>
176
+ <div class="flex justify-center items-center gap-4">
177
+ <label
178
+ for="thickness-slider"
179
+ class="text-sm font-medium text-slate-700"
180
+ >Thickness</label
181
+ >
182
+
183
+ <input
184
+ id="thickness-slider"
185
+ type="range"
186
+ min="1"
187
+ max="4"
188
+ step="0.1"
189
+ value="2.2"
190
+ class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-blue-600"
191
+ />
192
+ <span
193
+ id="thickness-value"
194
+ class="text-xs font-mono w-16 text-slate-500 bg-slate-100 px-1.5 py-0.5 rounded"
195
+ >2.2</span
196
+ >
197
+ </div>
198
+ </div>
199
+ </div>
200
+ </div>
201
+
202
+ <div id="all-icons" class="max-w-7xl mx-auto px-6 py-12">
203
+ <div class="senangstart-icons">
204
+ <div
205
+ id="icons-container"
206
+ class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-4"
207
+ >
208
+ <!-- Icons injected here -->
209
+ </div>
210
+
211
+ <div id="pagination-container">
212
+ <!-- Pagination injected here -->
213
+ </div>
214
+ </div>
215
+ </div>
216
+
217
+ <section
218
+ id="installation"
219
+ class="bg-white border-t border-slate-200 py-16 lg:py-24"
220
+ >
221
+ <div class="max-w-7xl mx-auto px-6">
222
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-12 lg:gap-20">
223
+ <div>
224
+ <h2 class="text-3xl font-bold text-slate-900 tracking-tight mb-6">
225
+ Quick Installation
226
+ </h2>
227
+ <p class="text-slate-600 mb-8 leading-relaxed">
228
+ Choose how you want to include SenangStart Icons in your
229
+ project. Use NPM for module bundlers or the CDN for quick
230
+ prototyping.
231
+ </p>
232
+
233
+ <div class="mb-8">
234
+ <div class="flex items-center justify-between mb-3">
235
+ <span class="text-sm font-semibold text-slate-900"
236
+ >Install via NPM</span
237
+ >
238
+ </div>
239
+ <div class="relative group">
240
+ <div
241
+ class="absolute inset-y-0 left-0 w-1 bg-brand-600 rounded-l-lg"
242
+ ></div>
243
+ <pre
244
+ class="bg-slate-900 text-slate-50 p-5 rounded-r-lg rounded-l-md overflow-x-auto font-mono text-sm shadow-xl"
245
+ ><code data-swj-id="code-install" data-swj-value>npm install senangstart-icons</code></pre>
246
+ </div>
247
+ <div class="flex justify-end w-full mt-2">
248
+ <button
249
+ type="button"
250
+ class="absolute inset-y-0 top-2 right-2 w-8 h-8 bg-brand-600 rounded flex items-center justify-center"
251
+ data-swj-copy="code-install"
252
+ ></button>
253
+ </div>
254
+ </div>
255
+
256
+ <div>
257
+ <div class="flex items-center justify-between mb-3">
258
+ <span class="text-sm font-semibold text-slate-900"
259
+ >CDN Link</span
260
+ >
261
+ <span
262
+ class="text-xs text-brand-600 bg-blue-50 px-2 py-0.5 rounded border border-blue-100"
263
+ >Recommended for static sites</span
264
+ >
265
+ </div>
266
+ <div class="relative group">
267
+ <div
268
+ class="absolute inset-y-0 left-0 w-1 bg-slate-600 rounded-l-lg"
269
+ ></div>
270
+ <pre
271
+ class="bg-slate-900 text-slate-50 p-5 rounded-r-lg rounded-l-md overflow-x-auto font-mono text-sm shadow-xl"
272
+ ><code>&lt;link rel="stylesheet" href="https://cdn.example.com/senangstart.min.css" /&gt;
273
+ &lt;script src="https://cdn.example.com/senangstart-icon.min.js"&gt;&lt;/script&gt;</code></pre>
274
+ </div>
275
+ </div>
276
+ </div>
277
+
278
+ <div
279
+ class="bg-slate-50 rounded-2xl border border-slate-200 p-8 lg:p-10 flex flex-col justify-center"
280
+ >
281
+ <h2 class="text-2xl font-bold text-slate-900 mb-6">How to use</h2>
282
+ <p class="text-slate-600 mb-8">
283
+ Simply use the
284
+ <code
285
+ class="text-brand-700 bg-blue-100 px-1.5 py-0.5 rounded font-mono text-sm"
286
+ >ss-icon</code
287
+ >
288
+ custom element and pass the icon name to the
289
+ <code
290
+ class="text-brand-700 bg-blue-100 px-1.5 py-0.5 rounded font-mono text-sm"
291
+ >icon</code
292
+ >
293
+ attribute.
294
+ </p>
295
+
296
+ <div
297
+ class="bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden mb-6"
298
+ >
299
+ <div
300
+ class="bg-slate-100 px-4 py-2 border-b border-slate-200 flex items-center gap-2"
301
+ >
302
+ <div class="w-3 h-3 rounded-full bg-red-400"></div>
303
+ <div class="w-3 h-3 rounded-full bg-amber-400"></div>
304
+ <div class="w-3 h-3 rounded-full bg-green-400"></div>
305
+ </div>
306
+ <div class="p-8 flex items-center justify-evenly gap-6">
307
+ <div class="flex flex-col items-center gap-3 mt-auto">
308
+ <i class="ss ss-save text-blue-600 text-4xl"></i>
309
+ <span class="text-xs text-slate-400 font-mono"
310
+ >Icon: Save</span
311
+ >
312
+ </div>
313
+ <div class="flex flex-col items-center gap-3 mt-auto">
314
+ <ss-icon icon="home"></ss-icon>
315
+ <span class="text-xs text-slate-400 font-mono"
316
+ >Size: Default</span
317
+ >
318
+ </div>
319
+ <div class="flex flex-col items-center gap-3">
320
+ <ss-icon
321
+ icon="heart"
322
+ thickness="4"
323
+ class="text-brand-600 w-12 h-12"
324
+ ></ss-icon>
325
+ <span class="text-xs text-slate-400 font-mono"
326
+ >Size: 48px</span
327
+ >
328
+ </div>
329
+ </div>
330
+ </div>
331
+
332
+ <div class="relative">
333
+ <pre
334
+ class="bg-slate-900 text-slate-50 p-4 rounded-lg overflow-x-auto font-mono text-sm leading-relaxed"
335
+ ><code><span class="text-slate-500">&lt;!-- Basic Usage --&gt;</span>
336
+ &lt;i class="ss ss-save text-blue-600 text-4xl"&gt;&lt;/i&gt;
337
+ &lt;ss-icon icon="home"&gt;&lt;/ss-icon&gt;
338
+
339
+ <span class="text-slate-500">&lt;!-- With Tailwind Classes --&gt;</span>
340
+ &lt;ss-icon icon="heart" thickness="4" class="text-brand-600 w-12 h-12"&gt;&lt;/ss-icon&gt;</code></pre>
341
+ </div>
342
+ </div>
343
+ </div>
344
+ </div>
345
+ </section>
346
+ </main>
347
+
348
+ <!-- Footer -->
349
+ <footer class="bg-white border-t border-slate-200 py-8 mt-auto">
350
+ <div
351
+ class="max-w-7xl mx-auto px-6 flex flex-col md:flex-row justify-between items-center gap-4"
352
+ >
353
+ <p class="text-sm text-slate-500">
354
+ Created with by
355
+ <a href="https://bookklik.com/" target="_blank" class="text-brand-600"
356
+ >Bookklik Technologies<i
357
+ class="ss ss-arrow-top-right-on-square ml-1"
358
+ thickness="2"
359
+ ></i
360
+ ></a>
361
+ </p>
362
+ <div class="flex gap-6">
363
+ <a
364
+ href="https://senangstart.com/license"
365
+ class="text-sm text-slate-400 hover:text-slate-900"
366
+ >License</a
367
+ >
368
+ <a
369
+ href="https://senangstart.com/privacy_policy"
370
+ class="text-sm text-slate-400 hover:text-slate-900"
371
+ >Privacy</a
372
+ >
373
+ </div>
374
+ </div>
375
+ </footer>
376
+
377
+ <script src="https://unpkg.com/senangwebs-index@latest/dist/swi.js"></script>
378
+ <script>
379
+ let currentThickness = 2.2;
380
+ document.addEventListener("DOMContentLoaded", () => {
381
+ const icons = "./src/icons.json";
382
+
383
+ const swi = new SenangWebsIndex({
384
+ container: "#icons-container",
385
+ data: icons,
386
+ itemTemplate: (item) => {
387
+ // Polished Card Template
388
+ return `
389
+ <div class="group relative flex flex-col items-center justify-between p-4 bg-white border border-slate-200 rounded-xl cursor-pointer transition-all duration-300 hover:border-brand-600 hover:shadow-lg hover:shadow-blue-500/10 aspect-square" onclick="iconDetails('${item.name}', '${item.slug}', '${item.tags}')">
390
+ <div class="flex-grow flex items-center justify-center mb-2 text-slate-700 transition-colors duration-300 group-hover:text-brand-600">
391
+ <ss-icon icon="${item.slug}" thickness="${currentThickness}" class="w-12 h-12"></ss-icon>
392
+ </div>
393
+
394
+ <div class="w-full text-center">
395
+ <div class=" max-w-full">
396
+ <code class="block text-[12px] leading-tight text-slate-400 bg-slate-50 border border-slate-100 rounded px-1.5 py-0.5 font-mono truncate transition-colors group-hover:text-brand-600 group-hover:bg-blue-50 group-hover:border-blue-100">
397
+ ${item.slug}
398
+ </code>
399
+ </div>
400
+ </div>
401
+
402
+ </div>
403
+ `;
404
+ },
405
+ search: {
406
+ enabled: true,
407
+ selector: "#search-container",
408
+ searchKey: "tags",
409
+ },
410
+ pagination: {
411
+ enabled: true,
412
+ selector: "#pagination-container",
413
+ itemsPerPage: 48,
414
+ },
415
+ });
416
+
417
+ const thicknessSlider = document.getElementById("thickness-slider");
418
+ const thicknessValue = document.getElementById("thickness-value");
419
+
420
+ thicknessSlider.addEventListener("input", (e) => {
421
+ currentThickness = e.target.value;
422
+ thicknessValue.textContent = currentThickness;
423
+
424
+ // Update all currently visible icons
425
+ const icons = document.querySelectorAll("#icons-container ss-icon");
426
+ icons.forEach((icon) => {
427
+ icon.setAttribute("thickness", currentThickness);
428
+ });
429
+ });
430
+ });
431
+
432
+ const targetDiv = document.getElementById("icons-container");
433
+ const config = { childList: true, subtree: true, characterData: true };
434
+ const callback = function (mutationsList, observer) {
435
+ for (const mutation of mutationsList) {
436
+ if (
437
+ mutation.type === "childList" ||
438
+ mutation.type === "characterData"
439
+ ) {
440
+ SWJ.refresh();
441
+ }
442
+ }
443
+ };
444
+ const observer = new MutationObserver(callback);
445
+ observer.observe(targetDiv, config);
446
+
447
+ function iconDetails(name, slug, tags) {
448
+ let thickness = currentThickness;
449
+ SWM.createModal({
450
+ title: `${name}`,
451
+ content: `<div class="flex flex-col justify-center items-center lg:flex-row gap-4 w-full py-2">
452
+ <div class="bg-slate-50 border border-slate-200 p-4 rounded-lg text-7xl aspect-square w-48 flex items-center justify-center">
453
+ <ss-icon icon="${slug}" thickness="${thickness}"></ss-icon>
454
+ </div>
455
+ <div class="flex flex-col gap-2 justify-between flex-grow lg:h-48">
456
+ <div class="relative group">
457
+ <div class="absolute inset-y-0 left-0 w-1 bg-brand-600 rounded-l-lg"></div>
458
+ <pre class="bg-slate-900 text-slate-50 p-5 rounded-r-lg rounded-l-md overflow-x-auto font-mono text-sm shadow-xl max-w-[calc(100vw-4rem)]"><code>&#x3C;ss-icon icon=&#x22;${slug}&#x22; thickness=&#x22;${thickness}&#x22;&#x3E;&#x3C;/ss-icon&#x3E;
459
+ &#x3C;i class=&#x22;ss ss-${slug}&#x22;&#x3E;&#x3C;/i&#x3E;</code></pre>
460
+ </div>
461
+ <div class="text-xs text-slate-400 mb-auto">tags: ${tags}</div>
462
+ <textarea id="copy-code-${slug}" class="w-0 h-0" data-swj-id="copy-code-${slug}" data-swj-value><ss-icon icon="${slug}" thickness="${thickness}"></ss-icon></textarea>
463
+ <div class="flex items-center justify-center lg:justify-end">
464
+ <button
465
+ type="button"
466
+ class="bg-brand-600 rounded flex items-center justify-center text-white px-2 py-1"
467
+ data-swj-copy="copy-code-${slug}"
468
+ >Copy</button>
469
+ </div>
470
+ </div>
471
+ </div>`,
472
+ position: "top",
473
+ zIndex: "50",
474
+ });
475
+ SWJ.refresh();
476
+ }
477
+ </script>
478
+ </body>
479
+ </html>
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@bookklik/senangstart-icons",
3
+ "version": "1.0.3",
4
+ "description": "Curated Starter icons designed for web projects.",
5
+ "main": "dist/senangstart-icon.min.js",
6
+ "scripts": {
7
+ "build:svg": "node scripts/build-svgs.js",
8
+ "build": "npm run build:svg && webpack --mode production",
9
+ "build:watch": "npm run build:svg && webpack --mode production --watch",
10
+ "dev": "npm run build:svg && webpack --mode development --watch",
11
+ "test": "echo \"Error: no test specified\" && exit 1"
12
+ },
13
+ "keywords": [
14
+ "icons",
15
+ "svg",
16
+ "web-components"
17
+ ],
18
+ "author": "a-hakim",
19
+ "license": "MIT",
20
+ "devDependencies": {
21
+ "@babel/core": "^7.23.0",
22
+ "@babel/preset-env": "^7.23.0",
23
+ "babel-loader": "^9.1.3",
24
+ "css-loader": "^6.8.1",
25
+ "css-minimizer-webpack-plugin": "^5.0.1",
26
+ "mini-css-extract-plugin": "^2.7.6",
27
+ "terser-webpack-plugin": "^5.3.9",
28
+ "webpack": "^5.89.0",
29
+ "webpack-cli": "^5.1.4"
30
+ }
31
+ }
@@ -0,0 +1,51 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const iconsPath = path.resolve(__dirname, "../src/icons.json");
5
+ const svgDir = path.resolve(__dirname, "../src/svg");
6
+
7
+ // Read icons.json
8
+ const icons = JSON.parse(fs.readFileSync(iconsPath, "utf8"));
9
+
10
+ // Ensure svg directory exists
11
+ if (!fs.existsSync(svgDir)) {
12
+ fs.mkdirSync(svgDir, { recursive: true });
13
+ }
14
+
15
+ const iconExports = [];
16
+
17
+ icons.forEach((icon) => {
18
+ const { slug, src, viewBox, fill, stroke, strokeWidth } = icon;
19
+
20
+ // Default values
21
+ const vBox = viewBox || "0 0 24 24";
22
+ const fl = fill || "none";
23
+ const strk = stroke || "currentColor";
24
+ const strkWidth = strokeWidth || "2";
25
+
26
+ // Create SVG content
27
+ const svgContent = `<svg viewBox="${vBox}" fill="${fl}" stroke="${strk}" stroke-width="${strkWidth}" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg">
28
+ <g><path d="${src}" /></g>
29
+ </svg>`;
30
+
31
+ // Write SVG file
32
+ const svgFilePath = path.join(svgDir, `${slug}.svg`);
33
+ fs.writeFileSync(svgFilePath, svgContent);
34
+ console.log(`Generated ${slug}.svg`);
35
+
36
+ // Add to exports
37
+ // Convert slug to camelCase or valid identifier if needed, but for now using slug as key in object
38
+ // Since we want to export an object mapping slugs to svg content (via webpack asset/source)
39
+ iconExports.push(`"${slug}": require("./${slug}.svg")`);
40
+ });
41
+
42
+ // Generate index.js
43
+ const indexContent = `const icons = {
44
+ ${iconExports.join(",\n ")}
45
+ };
46
+
47
+ export default icons;
48
+ `;
49
+
50
+ fs.writeFileSync(path.join(svgDir, "index.js"), indexContent);
51
+ console.log("Generated src/svg/index.js");