@stacksjs/stx 0.0.9 → 0.1.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.
Files changed (50) hide show
  1. package/README.md +69 -21
  2. package/dist/a11y.d.ts +40 -0
  3. package/dist/analyzer.d.ts +64 -0
  4. package/dist/animation.d.ts +64 -0
  5. package/dist/assets.d.ts +19 -0
  6. package/dist/auth.d.ts +11 -0
  7. package/dist/bin/cli.js +2821 -154
  8. package/dist/caching.d.ts +18 -6
  9. package/dist/chunk-2ndtnc0t.js +9822 -0
  10. package/dist/{chunk-ywm063e4.js → chunk-e11q5a3p.js} +2 -2
  11. package/dist/chunk-vsbm352h.js +670 -0
  12. package/dist/client.d.ts +19 -35
  13. package/dist/components.d.ts +6 -0
  14. package/dist/conditionals.d.ts +17 -1
  15. package/dist/config.d.ts +6 -2
  16. package/dist/csrf.d.ts +28 -0
  17. package/dist/custom-directives.d.ts +5 -6
  18. package/dist/dev-server.d.ts +21 -0
  19. package/dist/docs.d.ts +39 -3
  20. package/dist/error-handling.d.ts +101 -0
  21. package/dist/expressions.d.ts +43 -4
  22. package/dist/formatter.d.ts +16 -0
  23. package/dist/forms.d.ts +15 -25
  24. package/dist/i18n.d.ts +17 -20
  25. package/dist/includes.d.ts +21 -18
  26. package/dist/index.d.ts +30 -24
  27. package/dist/init.d.ts +9 -0
  28. package/dist/js-ts.d.ts +10 -0
  29. package/dist/loops.d.ts +4 -3
  30. package/dist/markdown.d.ts +8 -0
  31. package/dist/method-spoofing.d.ts +13 -0
  32. package/dist/middleware.d.ts +9 -1
  33. package/dist/performance-utils.d.ts +58 -0
  34. package/dist/plugin.d.ts +2 -0
  35. package/dist/process.d.ts +9 -7
  36. package/dist/release.d.ts +1 -0
  37. package/dist/routes.d.ts +36 -0
  38. package/dist/safe-evaluator.d.ts +16 -0
  39. package/dist/seo.d.ts +33 -0
  40. package/dist/serve.d.ts +35 -0
  41. package/dist/src/index.js +2893 -135
  42. package/dist/streaming.d.ts +30 -14
  43. package/dist/types.d.ts +214 -48
  44. package/dist/utils.d.ts +21 -3
  45. package/dist/view-composers.d.ts +26 -0
  46. package/dist/web-components.d.ts +7 -14
  47. package/package.json +18 -9
  48. package/dist/chunk-04bqmpzb.js +0 -7069
  49. package/dist/chunk-8ehp5m3y.js +0 -4279
  50. package/dist/chunk-9ynf73q9.js +0 -2502
@@ -1,3 +1,4 @@
1
+ // @bun
1
2
  var __create = Object.create;
2
3
  var __getProtoOf = Object.getPrototypeOf;
3
4
  var __defProp = Object.defineProperty;
@@ -14,7 +15,6 @@ var __toESM = (mod, isNodeMode, target) => {
14
15
  });
15
16
  return to;
16
17
  };
17
- var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
18
18
  var __require = import.meta.require;
19
19
 
20
- export { __toESM, __commonJS, __require };
20
+ export { __toESM, __require };
@@ -0,0 +1,670 @@
1
+ // @bun
2
+ import {
3
+ __require
4
+ } from "./chunk-e11q5a3p.js";
5
+
6
+ // ../iconify-generator/src/index.ts
7
+ import { mkdir, writeFile } from "fs/promises";
8
+ import { join } from "path";
9
+ var ICONIFY_API = "https://api.iconify.design";
10
+ async function fetchCollections() {
11
+ const response = await fetch(`${ICONIFY_API}/collections`);
12
+ if (!response.ok) {
13
+ throw new Error(`Failed to fetch collections: ${response.statusText}`);
14
+ }
15
+ return await response.json();
16
+ }
17
+ async function fetchCollectionIcons(prefix, icons) {
18
+ try {
19
+ const iconifyJsonPath = __require.resolve("@iconify/json");
20
+ const basePath = `${iconifyJsonPath.substring(0, iconifyJsonPath.lastIndexOf("/node_modules/@iconify/json/"))}/node_modules/@iconify/json`;
21
+ const jsonPath = `${basePath}/json/${prefix}.json`;
22
+ const file = Bun.file(jsonPath);
23
+ if (await file.exists()) {
24
+ const data = await file.json();
25
+ if (icons && icons.length > 0) {
26
+ const filteredIcons = {};
27
+ for (const iconName of icons) {
28
+ if (data.icons[iconName]) {
29
+ filteredIcons[iconName] = data.icons[iconName];
30
+ }
31
+ }
32
+ return {
33
+ ...data,
34
+ icons: filteredIcons
35
+ };
36
+ }
37
+ return data;
38
+ }
39
+ } catch {}
40
+ const url = icons && icons.length > 0 ? `${ICONIFY_API}/${prefix}.json?icons=${icons.join(",")}` : `${ICONIFY_API}/${prefix}.json`;
41
+ const response = await fetch(url);
42
+ if (!response.ok) {
43
+ throw new Error(`Failed to fetch icons for ${prefix}: ${response.statusText}`);
44
+ }
45
+ return await response.json();
46
+ }
47
+ function convertIconData(data, defaultWidth = 24, defaultHeight = 24) {
48
+ return {
49
+ body: data.body,
50
+ width: data.width || defaultWidth,
51
+ height: data.height || defaultHeight,
52
+ viewBox: `0 0 ${data.width || defaultWidth} ${data.height || defaultHeight}`
53
+ };
54
+ }
55
+ function generateIconData(name, iconData) {
56
+ const camelCaseName = toCamelCase(name);
57
+ return `import type { IconData } from '@stacksjs/iconify-core'
58
+
59
+ export const ${camelCaseName}: IconData = ${JSON.stringify(iconData, null, 2)}
60
+
61
+ export default ${camelCaseName}
62
+ `;
63
+ }
64
+ function generateIconComponent(_name, iconData) {
65
+ return `<script>
66
+ // Get props with defaults (handle undefined)
67
+ const iconWidth = (typeof width !== 'undefined' ? width : null) || (typeof size !== 'undefined' ? size : null) || ${iconData.width || 24}
68
+ const iconHeight = (typeof height !== 'undefined' ? height : null) || (typeof size !== 'undefined' ? size : null) || ${iconData.height || 24}
69
+ const iconColor = typeof color !== 'undefined' ? color : 'currentColor'
70
+ const viewBox = "${iconData.viewBox || `0 0 ${iconData.width || 24} ${iconData.height || 24}`}"
71
+
72
+ // Build transform
73
+ const transforms = []
74
+ if (typeof hFlip !== 'undefined' && hFlip) transforms.push('scaleX(-1)')
75
+ if (typeof vFlip !== 'undefined' && vFlip) transforms.push('scaleY(-1)')
76
+ if (typeof rotate !== 'undefined' && rotate) {
77
+ const rotateNum = typeof rotate === 'string' ? parseInt(rotate, 10) : rotate
78
+ const deg = typeof rotateNum === 'number' && rotateNum < 4 ? rotateNum * 90 : rotateNum
79
+ transforms.push(\`rotate(\${deg}deg)\`)
80
+ }
81
+
82
+ const transform = transforms.length > 0 ? transforms.join(' ') : ''
83
+ const transformStyle = transform ? \`transform: \${transform};\` : ''
84
+
85
+ // Build style
86
+ const styles = []
87
+ if (transformStyle) styles.push(transformStyle)
88
+ if (typeof style !== 'undefined' && style) styles.push(style)
89
+
90
+ const styleAttr = styles.length > 0 ? \` style="\${styles.join(' ')}"\` : ''
91
+ const classAttr = typeof className !== 'undefined' && className ? \` class="\${className}"\` : ''
92
+
93
+ // Icon body
94
+ let body = ${JSON.stringify(iconData.body)}
95
+ if (iconColor && iconColor !== 'currentColor') {
96
+ body = body.replace(/currentColor/g, iconColor)
97
+ }
98
+
99
+ // Generate SVG
100
+ const svg = \`<svg xmlns="http://www.w3.org/2000/svg" width="\${iconWidth}" height="\${iconHeight}" viewBox="\${viewBox}"\${classAttr}\${styleAttr}>\${body}</svg>\`
101
+ </script>
102
+
103
+ {!! svg !!}
104
+ `;
105
+ }
106
+ function generateIndexFile(iconNames) {
107
+ const dataExports = iconNames.map((name) => {
108
+ const camelCaseName = toCamelCase(name);
109
+ return `export { default as ${camelCaseName} } from './${name}.js'`;
110
+ }).join(`
111
+ `);
112
+ return `// Icon data exports
113
+ ${dataExports}
114
+
115
+ export * from './types.js'
116
+ `;
117
+ }
118
+ function generateTypesFile(prefix) {
119
+ return `import type { IconData, IconProps } from '@stacksjs/iconify-core'
120
+
121
+ export type { IconData, IconProps }
122
+
123
+ export type ${toPascalCase(prefix)}Icon = IconData
124
+ `;
125
+ }
126
+ function generatePackageJson(prefix, collectionInfo, _iconCount) {
127
+ const packageJson = {
128
+ name: `@stacksjs/iconify-${prefix}`,
129
+ type: "module",
130
+ version: "0.0.1",
131
+ description: `${collectionInfo.name} icons for stx from Iconify`,
132
+ author: collectionInfo.author?.name || "Iconify",
133
+ license: collectionInfo.license?.spdx || "MIT",
134
+ repository: {
135
+ type: "git",
136
+ url: "https://github.com/stacksjs/stx.git",
137
+ directory: `packages/iconify-${prefix}`
138
+ },
139
+ keywords: [
140
+ "iconify",
141
+ "icons",
142
+ "svg",
143
+ prefix,
144
+ collectionInfo.name,
145
+ "stx"
146
+ ],
147
+ sideEffects: false,
148
+ exports: {
149
+ ".": {
150
+ types: "./dist/index.d.ts",
151
+ import: "./dist/index.js"
152
+ },
153
+ "./*": "./dist/*"
154
+ },
155
+ main: "./dist/index.js",
156
+ module: "./dist/index.js",
157
+ types: "./dist/index.d.ts",
158
+ files: [
159
+ "dist"
160
+ ],
161
+ scripts: {
162
+ build: "bun build.ts"
163
+ },
164
+ dependencies: {
165
+ "@stacksjs/iconify-core": "workspace:*"
166
+ }
167
+ };
168
+ return JSON.stringify(packageJson, null, 2);
169
+ }
170
+ function generateBuildFile(prefix) {
171
+ return `import { join, dirname } from 'node:path'
172
+ import { fileURLToPath } from 'node:url'
173
+ import dts from 'bun-plugin-dtsx'
174
+
175
+ const __dirname = dirname(fileURLToPath(import.meta.url))
176
+
177
+ await Bun.build({
178
+ entrypoints: [join(__dirname, 'src/index.ts')],
179
+ outdir: join(__dirname, 'dist'),
180
+ target: 'bun',
181
+ format: 'esm',
182
+ plugins: [dts()],
183
+ minify: false,
184
+ sourcemap: 'external',
185
+ splitting: true,
186
+ })
187
+
188
+ console.log('\u2713 Built @stacksjs/iconify-${prefix}')
189
+ `;
190
+ }
191
+ function generateReadme(prefix, collectionInfo, iconCount) {
192
+ return `# @stacksjs/iconify-${prefix}
193
+
194
+ ${collectionInfo.name} icons for stx from Iconify.
195
+
196
+ ## Installation
197
+
198
+ \`\`\`bash
199
+ bun add @stacksjs/iconify-${prefix}
200
+ \`\`\`
201
+
202
+ ## Usage
203
+
204
+ ### In stx templates
205
+
206
+ \`\`\`html
207
+ <script>
208
+ import { home } from '@stacksjs/iconify-${prefix}'
209
+ import { renderIcon } from '@stacksjs/iconify-core'
210
+
211
+ export const homeIcon = renderIcon(home, { size: 24, color: 'currentColor' })
212
+ </script>
213
+
214
+ <div class="icon">
215
+ {!! homeIcon !!}
216
+ </div>
217
+ \`\`\`
218
+
219
+ ### In TypeScript/JavaScript
220
+
221
+ \`\`\`typescript
222
+ import { home, account, settings } from '@stacksjs/iconify-${prefix}'
223
+ import { renderIcon } from '@stacksjs/iconify-core'
224
+
225
+ const svg = renderIcon(home, {
226
+ size: 24,
227
+ color: '#000000',
228
+ })
229
+ \`\`\`
230
+
231
+ ## Available Icons
232
+
233
+ This package contains ${iconCount} icons from ${collectionInfo.name}.
234
+
235
+ ## License
236
+
237
+ ${collectionInfo.license?.title || "MIT"}
238
+
239
+ ${collectionInfo.license?.url ? `License: ${collectionInfo.license.url}` : ""}
240
+
241
+ ## Credits
242
+
243
+ - Icons: ${collectionInfo.author?.name || "Iconify"}${collectionInfo.author?.url ? ` (${collectionInfo.author.url})` : ""}
244
+ - Iconify: https://iconify.design/
245
+ `;
246
+ }
247
+ function generateDocumentation(prefix, collectionInfo, iconNames) {
248
+ const iconCount = iconNames.length;
249
+ const exampleIcons = iconNames.slice(0, 5).map(toCamelCase);
250
+ const exampleComponents = exampleIcons.map((name) => `${name.charAt(0).toUpperCase()}${name.slice(1)}Icon`);
251
+ const allIconsList = iconNames.map((name) => {
252
+ const camelName = toCamelCase(name);
253
+ return `- \`${camelName}\``;
254
+ }).join(`
255
+ `);
256
+ return `# ${collectionInfo.name}
257
+
258
+ > ${collectionInfo.name} icons for stx from Iconify
259
+
260
+ ## Overview
261
+
262
+ This package provides access to ${iconCount} icons from the ${collectionInfo.name} collection through the stx iconify integration.
263
+
264
+ **Collection ID:** \`${prefix}\`
265
+ **Total Icons:** ${iconCount}
266
+ ${collectionInfo.author?.name ? `**Author:** ${collectionInfo.author.name}${collectionInfo.author.url ? ` ([Website](${collectionInfo.author.url}))` : ""}` : ""}
267
+ ${collectionInfo.license?.title ? `**License:** ${collectionInfo.license.title}${collectionInfo.license.url ? ` ([Details](${collectionInfo.license.url}))` : ""}` : ""}
268
+ ${collectionInfo.category ? `**Category:** ${collectionInfo.category}` : ""}
269
+ ${collectionInfo.palette !== undefined ? `**Palette:** ${collectionInfo.palette ? "Yes (color icons)" : "No (monotone icons)"}` : ""}
270
+
271
+ ## Installation
272
+
273
+ \`\`\`bash
274
+ bun add @stacksjs/iconify-${prefix}
275
+ \`\`\`
276
+
277
+ ## Quick Start
278
+
279
+ ### Component Usage (Recommended)
280
+
281
+ Icons are available as .stx components that can be used directly in templates:
282
+
283
+ \`\`\`html
284
+ <${exampleComponents[0] || "Icon"} height="1em" />
285
+ <${exampleComponents[0] || "Icon"} width="1em" height="1em" />
286
+ <${exampleComponents[0] || "Icon"} height="24" />
287
+ \`\`\`
288
+
289
+ ### With Properties
290
+
291
+ \`\`\`html
292
+ <!-- Using size property -->
293
+ <${exampleComponents[0] || "Icon"} size="24" />
294
+ <${exampleComponents[0] || "Icon"} size="1em" />
295
+
296
+ <!-- Using width and height -->
297
+ <${exampleComponents[0] || "Icon"} width="24" height="32" />
298
+
299
+ <!-- With color -->
300
+ <${exampleComponents[0] || "Icon"} size="24" color="red" />
301
+ <${exampleComponents[0] || "Icon"} size="24" color="#4a90e2" />
302
+
303
+ <!-- With CSS class -->
304
+ <${exampleComponents[0] || "Icon"} size="24" class="icon-primary" />
305
+
306
+ <!-- With all properties -->
307
+ <${exampleComponents[0] || "Icon"}
308
+ size="32"
309
+ color="#4a90e2"
310
+ class="my-icon"
311
+ style="opacity: 0.8;"
312
+ />
313
+ \`\`\`
314
+
315
+ ### In stx Templates
316
+
317
+ \`\`\`html
318
+ <!DOCTYPE html>
319
+ <html>
320
+ <head>
321
+ <title>Icon Demo</title>
322
+ <style>
323
+ .icon-grid {
324
+ display: flex;
325
+ gap: 1rem;
326
+ align-items: center;
327
+ }
328
+ </style>
329
+ </head>
330
+ <body>
331
+ <div class="icon-grid">
332
+ <${exampleComponents[0] || "Icon"} size="24" />
333
+ <${exampleComponents[1] || "Icon"} size="24" color="#4a90e2" />
334
+ <${exampleComponents[2] || "Icon"} size="32" class="my-icon" />
335
+ </div>
336
+ </body>
337
+ </html>
338
+ \`\`\`
339
+
340
+ ### Data-Only Import
341
+
342
+ You can also import icon data and use the \`renderIcon\` function directly:
343
+
344
+ \`\`\`typescript
345
+ import { ${exampleIcons.slice(0, 3).join(", ")} } from '@stacksjs/iconify-${prefix}'
346
+ import { renderIcon } from '@stacksjs/iconify-core'
347
+
348
+ const svg = renderIcon(${exampleIcons[0] || "icon"}, { size: 24 })
349
+ \`\`\`
350
+
351
+ ## Icon Properties
352
+
353
+ All icon component functions and \`renderIcon\` accept the following properties:
354
+
355
+ | Property | Type | Default | Description |
356
+ |----------|------|---------|-------------|
357
+ | \`size\` | \`string \\| number\` | - | Icon size (sets both width and height) |
358
+ | \`width\` | \`string \\| number\` | - | Icon width (overrides size) |
359
+ | \`height\` | \`string \\| number\` | - | Icon height (overrides size) |
360
+ | \`color\` | \`string\` | \`'currentColor'\` | Icon color (CSS color or hex) |
361
+ | \`hFlip\` | \`boolean\` | \`false\` | Flip horizontally |
362
+ | \`vFlip\` | \`boolean\` | \`false\` | Flip vertically |
363
+ | \`rotate\` | \`0 \\| 90 \\| 180 \\| 270\` | \`0\` | Rotation in degrees |
364
+ | \`class\` | \`string\` | - | Additional CSS classes |
365
+ | \`style\` | \`string\` | - | Inline styles |
366
+
367
+ ## Color
368
+
369
+ ${collectionInfo.palette ? `### Color Icons
370
+
371
+ This collection contains color icons. While you can still set a color property, it may override the original colors.` : "### Monotone Icons\n\nMonotone icons use `currentColor` by default, allowing you to change icon color via the `color` property or CSS:"}
372
+
373
+ \`\`\`html
374
+ <!-- Via color property -->
375
+ <${exampleComponents[0] || "Icon"} size="24" color="red" />
376
+ <${exampleComponents[0] || "Icon"} size="24" color="#4a90e2" />
377
+
378
+ <!-- Via inline style -->
379
+ <${exampleComponents[0] || "Icon"} size="24" style="color: green;" />
380
+
381
+ <!-- Via CSS class -->
382
+ <${exampleComponents[0] || "Icon"} size="24" class="text-primary" />
383
+ \`\`\`
384
+
385
+ ${!collectionInfo.palette ? `\`\`\`css
386
+ /* In your CSS */
387
+ .text-primary {
388
+ color: #4a90e2;
389
+ }
390
+
391
+ .icon:hover {
392
+ color: #357abd;
393
+ }
394
+ \`\`\`` : ""}
395
+
396
+ ## Size
397
+
398
+ Unlike other components, SVG + CSS components do not set icon size by default. This has advantages and disadvantages.
399
+
400
+ **Disadvantages:**
401
+ - You need to set size yourself.
402
+
403
+ **Advantages:**
404
+ - You have full control over icon size.
405
+
406
+ You can change icon size by:
407
+ - Setting \`width\` and \`height\` properties
408
+ - Using CSS
409
+
410
+ ### Properties
411
+
412
+ All icon components support \`width\` and \`height\` properties.
413
+
414
+ Value is a string or number.
415
+
416
+ You do not need to set both properties. If you set one property, the other property will automatically be calculated from the icon's width/height ratio.
417
+
418
+ **Examples:**
419
+
420
+ \`\`\`html
421
+ <${exampleComponents[0] || "DraftsIcon"} height="1em" />
422
+ <${exampleComponents[0] || "DraftsIcon"} width="1em" height="1em" />
423
+ <${exampleComponents[0] || "DraftsIcon"} height="24" />
424
+ \`\`\`
425
+
426
+ You can also use the \`size\` property as a shorthand for setting both width and height:
427
+
428
+ \`\`\`html
429
+ <${exampleComponents[0] || "DraftsIcon"} size="24" />
430
+ <${exampleComponents[0] || "DraftsIcon"} size="1em" />
431
+ \`\`\`
432
+
433
+ ### CSS Sizing
434
+
435
+ You can also control icon size via CSS:
436
+
437
+ \`\`\`css
438
+ .${toCamelCase(prefix)}-icon {
439
+ width: 1em;
440
+ height: 1em;
441
+ }
442
+ \`\`\`
443
+
444
+ \`\`\`html
445
+ <${exampleComponents[0] || "DraftsIcon"} class="${toCamelCase(prefix)}-icon" />
446
+ \`\`\`
447
+
448
+ ## Available Icons
449
+
450
+ This package contains **${iconCount}** icons:
451
+
452
+ ${allIconsList}
453
+
454
+ ## Usage Examples
455
+
456
+ ### Navigation Menu
457
+
458
+ \`\`\`html
459
+ <nav>
460
+ <a href="/"><${exampleComponents[0] || "Icon"} size="20" class="nav-icon" /> Home</a>
461
+ <a href="/about"><${exampleComponents[1] || "Icon"} size="20" class="nav-icon" /> About</a>
462
+ <a href="/contact"><${exampleComponents[2] || "Icon"} size="20" class="nav-icon" /> Contact</a>
463
+ <a href="/settings"><${exampleComponents[3] || "Icon"} size="20" class="nav-icon" /> Settings</a>
464
+ </nav>
465
+
466
+ <style>
467
+ nav {
468
+ display: flex;
469
+ gap: 1rem;
470
+ }
471
+ nav a {
472
+ display: flex;
473
+ align-items: center;
474
+ gap: 0.5rem;
475
+ }
476
+ .nav-icon {
477
+ color: currentColor;
478
+ }
479
+ </style>
480
+ \`\`\`
481
+
482
+ ### Custom Styling
483
+
484
+ \`\`\`html
485
+ <${exampleComponents[0] || "Icon"}
486
+ size="24"
487
+ class="icon icon-primary"
488
+ style="opacity: 0.8; transition: opacity 0.2s;"
489
+ />
490
+
491
+ <style>
492
+ .icon-primary {
493
+ color: #4a90e2;
494
+ }
495
+ .icon-primary:hover {
496
+ opacity: 1;
497
+ }
498
+ </style>
499
+ \`\`\`
500
+
501
+ ### Status Indicators
502
+
503
+ \`\`\`html
504
+ <div class="status-grid">
505
+ <div class="status-item">
506
+ <${exampleComponents[0] || "Icon"} size="16" color="#22c55e" />
507
+ <span>Success</span>
508
+ </div>
509
+ <div class="status-item">
510
+ <${exampleComponents[1] || "Icon"} size="16" color="#f59e0b" />
511
+ <span>Warning</span>
512
+ </div>
513
+ <div class="status-item">
514
+ <${exampleComponents[2] || "Icon"} size="16" color="#ef4444" />
515
+ <span>Error</span>
516
+ </div>
517
+ </div>
518
+ \`\`\`
519
+
520
+ ## Best Practices
521
+
522
+ 1. **Use Components Directly**: Import and use icon components in your templates
523
+ \`\`\`html
524
+ <!-- Recommended -->
525
+ <${exampleComponents[0] || "Icon"} size="24" />
526
+ <${exampleComponents[1] || "Icon"} size="24" color="#4a90e2" />
527
+ \`\`\`
528
+
529
+ 2. **Use CSS for Theming**: Apply consistent styling through CSS classes
530
+ \`\`\`css
531
+ .icon {
532
+ color: currentColor;
533
+ opacity: 0.8;
534
+ transition: opacity 0.2s;
535
+ }
536
+
537
+ .icon:hover {
538
+ opacity: 1;
539
+ }
540
+ \`\`\`
541
+
542
+ \`\`\`html
543
+ <${exampleComponents[0] || "Icon"} size="24" class="icon" />
544
+ \`\`\`
545
+
546
+ 3. **Set Appropriate Sizes**: Use \`1em\` for inline icons, fixed pixel sizes for standalone icons
547
+ \`\`\`html
548
+ <!-- Inline with text -->
549
+ <p>Click the <${exampleComponents[0] || "Icon"} height="1em" /> icon to continue</p>
550
+
551
+ <!-- Standalone -->
552
+ <${exampleComponents[0] || "Icon"} size="24" />
553
+ \`\`\`
554
+
555
+ 4. **Use Data Import for Advanced Use Cases**: When you need more control
556
+ \`\`\`html
557
+ @js
558
+ import { ${exampleIcons[0] || "icon"} } from '@stacksjs/iconify-${prefix}'
559
+ import { renderIcon } from '@stacksjs/iconify-core'
560
+ global.customIcon = renderIcon(${exampleIcons[0] || "icon"}, { size: 24 })
561
+ @endjs
562
+
563
+ {!! customIcon !!}
564
+ \`\`\`
565
+
566
+ ## TypeScript Support
567
+
568
+ This package includes full TypeScript support with type definitions for all icons.
569
+
570
+ \`\`\`typescript
571
+ import type { IconData } from '@stacksjs/iconify-core'
572
+ import { ${exampleIcons[0] || "icon"} } from '@stacksjs/iconify-${prefix}'
573
+
574
+ // Icons are typed as IconData
575
+ const myIcon: IconData = ${exampleIcons[0] || "icon"}
576
+ \`\`\`
577
+
578
+ ## Related Packages
579
+
580
+ - [\`@stacksjs/iconify-core\`](../iconify#installation) - Core rendering functions and utilities
581
+ - [Iconify Integration Guide](../iconify) - Complete guide to using Iconify with stx
582
+ - [stx Documentation](../) - Main stx documentation
583
+
584
+ ## License
585
+
586
+ ${collectionInfo.license?.title || "MIT"}
587
+
588
+ ${collectionInfo.license?.url ? `See [license details](${collectionInfo.license.url}) for more information.` : ""}
589
+
590
+ ## Credits
591
+
592
+ - **Icons**: ${collectionInfo.author?.name || "Iconify"}${collectionInfo.author?.url ? ` ([Website](${collectionInfo.author.url}))` : ""}
593
+ - **Iconify**: [https://iconify.design/](https://iconify.design/)
594
+ - **Icon Set**: [View on Iconify](https://icon-sets.iconify.design/${prefix}/)
595
+
596
+ ## Resources
597
+
598
+ - [Browse all icons in this collection](https://icon-sets.iconify.design/${prefix}/)
599
+ - [Iconify documentation](https://iconify.design/docs/)
600
+ - [stx iconify integration guide](../../docs/iconify.md)
601
+ `;
602
+ }
603
+ async function generatePackage(prefix, outputDir, icons, docsDir) {
604
+ console.log(`
605
+ \uD83D\uDCE6 Generating package for ${prefix}...`);
606
+ const collections = await fetchCollections();
607
+ const collectionInfo = collections[prefix];
608
+ if (!collectionInfo) {
609
+ throw new Error(`Collection ${prefix} not found`);
610
+ }
611
+ console.log(` Collection: ${collectionInfo.name}`);
612
+ console.log(` Total icons: ${collectionInfo.total}`);
613
+ const collectionData = await fetchCollectionIcons(prefix, icons);
614
+ const iconNames = Object.keys(collectionData.icons);
615
+ console.log(` Generating ${iconNames.length} icons...`);
616
+ const packageDir = join(outputDir, `iconify-${prefix}`);
617
+ const srcDir = join(packageDir, "src");
618
+ await mkdir(srcDir, { recursive: true });
619
+ const defaultWidth = collectionData.width || 24;
620
+ const defaultHeight = collectionData.height || 24;
621
+ for (const iconName of iconNames) {
622
+ const iconData = collectionData.icons[iconName];
623
+ const converted = convertIconData(iconData, defaultWidth, defaultHeight);
624
+ const dataFile = generateIconData(iconName, converted);
625
+ await writeFile(join(srcDir, `${iconName}.ts`), dataFile);
626
+ const componentFile = generateIconComponent(iconName, converted);
627
+ await writeFile(join(srcDir, `${iconName}-icon.stx`), componentFile);
628
+ }
629
+ const indexContent = generateIndexFile(iconNames);
630
+ await writeFile(join(srcDir, "index.ts"), indexContent);
631
+ const typesContent = generateTypesFile(prefix);
632
+ await writeFile(join(srcDir, "types.ts"), typesContent);
633
+ const packageJsonContent = generatePackageJson(prefix, collectionInfo, iconNames.length);
634
+ await writeFile(join(packageDir, "package.json"), packageJsonContent);
635
+ const buildContent = generateBuildFile(prefix);
636
+ await writeFile(join(packageDir, "build.ts"), buildContent);
637
+ const readmeContent = generateReadme(prefix, collectionInfo, iconNames.length);
638
+ await writeFile(join(packageDir, "README.md"), readmeContent);
639
+ if (docsDir) {
640
+ const docsPath = join(docsDir, `iconify-${prefix}.md`);
641
+ const docContent = generateDocumentation(prefix, collectionInfo, iconNames);
642
+ await mkdir(docsDir, { recursive: true });
643
+ await writeFile(docsPath, docContent);
644
+ console.log(` \u2713 Generated documentation in ${docsPath}`);
645
+ }
646
+ console.log(` \u2713 Generated ${iconNames.length} icons in ${packageDir}`);
647
+ }
648
+ function toCamelCase(str) {
649
+ return str.replace(/-([a-z0-9])/g, (g) => g[1].toUpperCase());
650
+ }
651
+ function toPascalCase(str) {
652
+ const camel = toCamelCase(str);
653
+ return camel.charAt(0).toUpperCase() + camel.slice(1);
654
+ }
655
+ export {
656
+ toPascalCase,
657
+ toCamelCase,
658
+ generateTypesFile,
659
+ generateReadme,
660
+ generatePackageJson,
661
+ generatePackage,
662
+ generateIndexFile,
663
+ generateIconData,
664
+ generateIconComponent,
665
+ generateDocumentation,
666
+ generateBuildFile,
667
+ fetchCollections,
668
+ fetchCollectionIcons,
669
+ convertIconData
670
+ };