@stacksjs/iconify-generator 0.2.300 ā 0.2.302
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/dist/cli.js +21 -21
- package/dist/cli.js.map +3 -3
- package/dist/index.d.ts +7 -0
- package/dist/index.js +71 -71
- package/dist/index.js.map +3 -3
- package/package.json +2 -2
- package/src/index.ts +29 -0
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
var
|
|
3
|
+
var O=import.meta.require;import{mkdir as S,writeFile as K}from"fs/promises";import{join as T}from"path";var Z="https://api.iconify.design";async function q(){let y=await fetch(`${Z}/collections`);if(!y.ok)throw Error(`Failed to fetch collections: ${y.statusText}`);return await y.json()}async function _(y,g){try{let G=O.resolve("/home/runner/work/stx/stx/node_modules/@iconify/json/dist/index.cjs"),k=`${`${G.substring(0,G.lastIndexOf("/node_modules/@iconify/json/"))}/node_modules/@iconify/json`}/json/${y}.json`,U=Bun.file(k);if(await U.exists()){let E=await U.json();if(g&&g.length>0){let v={};for(let Q of g)if(E.icons[Q])v[Q]=E.icons[Q];return{...E,icons:v}}return E}}catch{}let u=g&&g.length>0?`${Z}/${y}.json?icons=${g.join(",")}`:`${Z}/${y}.json`,$=await fetch(u);if(!$.ok)throw Error(`Failed to fetch icons for ${y}: ${$.statusText}`);return await $.json()}function j(y,g=24,u=24){return{body:y.body,width:y.width||g,height:y.height||u,viewBox:`0 0 ${y.width||g} ${y.height||u}`}}function F(y,g){let u=L(y);return`import type { IconData } from '@stacksjs/iconify-core'
|
|
4
4
|
|
|
5
5
|
export const ${u}: IconData = ${JSON.stringify(g,null,2)}
|
|
6
6
|
|
|
@@ -45,7 +45,7 @@ const svg = \`<svg xmlns="http://www.w3.org/2000/svg" width="\${iconWidth}" heig
|
|
|
45
45
|
|
|
46
46
|
{!! svg !!}
|
|
47
47
|
`}function N(y){let g=new Set;return`// Icon data exports
|
|
48
|
-
${y.map(($)=>{let b=
|
|
48
|
+
${y.map(($)=>{let b=L($);if(g.has(b)){let k=$.replace(/[^a-zA-Z0-9]/g,"_");if(/^[0-9]/.test(k))k=`_${k}`;b=k;let U=2;while(g.has(b))b=`${k}_${U}`,U++}return g.add(b),`export { default as ${b} } from './${$}.js'`}).join(`
|
|
49
49
|
`)}
|
|
50
50
|
|
|
51
51
|
export * from './types.js'
|
|
@@ -53,7 +53,7 @@ export * from './types.js'
|
|
|
53
53
|
|
|
54
54
|
export type { IconData, IconProps }
|
|
55
55
|
|
|
56
|
-
export type ${
|
|
56
|
+
export type ${f(y)}Icon = IconData
|
|
57
57
|
`}function D(y,g,u){let $={name:`@stacksjs/iconify-${y}`,type:"module",version:"0.0.1",description:`${g.name} icons for stx from Iconify`,author:g.author?.name||"Iconify",license:g.license?.spdx||"MIT",repository:{type:"git",url:"https://github.com/stacksjs/stx.git",directory:`packages/iconify-${y}`},keywords:["iconify","icons","svg",y,g.name,"stx"],sideEffects:!1,exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./*":"./dist/*"},main:"./dist/index.js",module:"./dist/index.js",types:"./dist/index.d.ts",files:["dist"],scripts:{build:"bun build.ts",prepublishOnly:"bun build.ts"},dependencies:{"@stacksjs/iconify-core":"workspace:*"}};return JSON.stringify($,null,2)}function r(y){return`import { existsSync, readdirSync, statSync } from 'node:fs'
|
|
58
58
|
import { dirname, join } from 'node:path'
|
|
59
59
|
import { fileURLToPath } from 'node:url'
|
|
@@ -156,7 +156,7 @@ ${g.license?.url?`License: ${g.license.url}`:""}
|
|
|
156
156
|
|
|
157
157
|
- Icons: ${g.author?.name||"Iconify"}${g.author?.url?` (${g.author.url})`:""}
|
|
158
158
|
- Iconify: https://iconify.design/
|
|
159
|
-
`}function x(y,g,u){let $=u.length,
|
|
159
|
+
`}function x(y,g,u){let $=u.length,G=u.slice(0,5).map(L),b=G.map((U)=>`${U.charAt(0).toUpperCase()}${U.slice(1)}Icon`),k=u.map((U)=>{return`- \`${L(U)}\``}).join(`
|
|
160
160
|
`);return`# ${g.name}
|
|
161
161
|
|
|
162
162
|
> ${g.name} icons for stx from Iconify
|
|
@@ -246,10 +246,10 @@ Icons are available as .stx components that can be used directly in templates:
|
|
|
246
246
|
You can also import icon data and use the \`renderIcon\` function directly:
|
|
247
247
|
|
|
248
248
|
\`\`\`typescript
|
|
249
|
-
import { ${
|
|
249
|
+
import { ${G.slice(0,3).join(", ")} } from '@stacksjs/iconify-${y}'
|
|
250
250
|
import { renderIcon } from '@stacksjs/iconify-core'
|
|
251
251
|
|
|
252
|
-
const svg = renderIcon(${
|
|
252
|
+
const svg = renderIcon(${G[0]||"icon"}, { size: 24 })
|
|
253
253
|
\`\`\`
|
|
254
254
|
|
|
255
255
|
## Icon Properties
|
|
@@ -339,21 +339,21 @@ You can also use the \`size\` property as a shorthand for setting both width and
|
|
|
339
339
|
You can also control icon size via CSS:
|
|
340
340
|
|
|
341
341
|
\`\`\`css
|
|
342
|
-
.${
|
|
342
|
+
.${L(y)}-icon {
|
|
343
343
|
width: 1em;
|
|
344
344
|
height: 1em;
|
|
345
345
|
}
|
|
346
346
|
\`\`\`
|
|
347
347
|
|
|
348
348
|
\`\`\`html
|
|
349
|
-
<${b[0]||"DraftsIcon"} class="${
|
|
349
|
+
<${b[0]||"DraftsIcon"} class="${L(y)}-icon" />
|
|
350
350
|
\`\`\`
|
|
351
351
|
|
|
352
352
|
## Available Icons
|
|
353
353
|
|
|
354
354
|
This package contains **${$}** icons:
|
|
355
355
|
|
|
356
|
-
${
|
|
356
|
+
${k}
|
|
357
357
|
|
|
358
358
|
## Usage Examples
|
|
359
359
|
|
|
@@ -459,9 +459,9 @@ ${h}
|
|
|
459
459
|
4. **Use Data Import for Advanced Use Cases**: When you need more control
|
|
460
460
|
\`\`\`html
|
|
461
461
|
@js
|
|
462
|
-
import { ${
|
|
462
|
+
import { ${G[0]||"icon"} } from '@stacksjs/iconify-${y}'
|
|
463
463
|
import { renderIcon } from '@stacksjs/iconify-core'
|
|
464
|
-
global.customIcon = renderIcon(${
|
|
464
|
+
global.customIcon = renderIcon(${G[0]||"icon"}, { size: 24 })
|
|
465
465
|
@endjs
|
|
466
466
|
|
|
467
467
|
{!! customIcon !!}
|
|
@@ -473,10 +473,10 @@ This package includes full TypeScript support with type definitions for all icon
|
|
|
473
473
|
|
|
474
474
|
\`\`\`typescript
|
|
475
475
|
import type { IconData } from '@stacksjs/iconify-core'
|
|
476
|
-
import { ${
|
|
476
|
+
import { ${G[0]||"icon"} } from '@stacksjs/iconify-${y}'
|
|
477
477
|
|
|
478
478
|
// Icons are typed as IconData
|
|
479
|
-
const myIcon: IconData = ${
|
|
479
|
+
const myIcon: IconData = ${G[0]||"icon"}
|
|
480
480
|
\`\`\`
|
|
481
481
|
|
|
482
482
|
## Related Packages
|
|
@@ -502,8 +502,8 @@ ${g.license?.url?`See [license details](${g.license.url}) for more information.`
|
|
|
502
502
|
- [Browse all icons in this collection](https://icon-sets.iconify.design/${y}/)
|
|
503
503
|
- [Iconify documentation](https://iconify.design/docs/)
|
|
504
504
|
- [stx iconify integration guide](../../docs/iconify.md)
|
|
505
|
-
`}async function
|
|
506
|
-
\uD83D\uDCE6 Generating package for ${y}...`);let b=(await
|
|
505
|
+
`}async function V(y,g,u,$){console.log(`
|
|
506
|
+
\uD83D\uDCE6 Generating package for ${y}...`);let b=(await q())[y];if(!b)throw Error(`Collection ${y} not found`);console.log(` Collection: ${b.name}`),console.log(` Total icons: ${b.total}`);let k=await _(y,u),U=Object.keys(k.icons);console.log(` Generating ${U.length} icons...`);let E=T(g,`iconify-${y}`),v=T(E,"src");await S(v,{recursive:!0});let Q=k.width||24,A=k.height||24;for(let z of U){let X=k.icons[z],B=j(X,Q,A),J=F(z,B);await K(T(v,`${z}.ts`),J);let P=s(z,B);await K(T(v,`${z}-icon.stx`),P)}let R=N(U);await K(T(v,"index.ts"),R);let Y=d(y);await K(T(v,"types.ts"),Y);let w=D(y,b,U.length);await K(T(E,"package.json"),w);let W=r(y);await K(T(E,"build.ts"),W);let H=C(y,b,U.length);if(await K(T(E,"README.md"),H),$){let z=T($,`iconify-${y}.md`),X=x(y,b,U);await S($,{recursive:!0}),await K(z,X),console.log(` \u2713 Generated documentation in ${z}`)}console.log(` \u2713 Generated ${U.length} icons in ${E}`)}var I=new Set(["break","case","catch","class","const","continue","debugger","default","delete","do","else","enum","export","extends","false","finally","for","function","if","import","in","instanceof","new","null","return","super","switch","this","throw","true","try","typeof","var","void","while","with","let","static","yield","implements","interface","package","private","protected","public","await","eval","arguments"]);function L(y){let g=y.replace(/-([a-z0-9])/g,(u)=>u[1].toUpperCase());if(g=g.replace(/[^a-zA-Z0-9_$]/g,"_"),/^[0-9]/.test(g))g=`_${g}`;if(I.has(g))g=`${g}_`;return g}function f(y){let g=L(y);return g.charAt(0).toUpperCase()+g.slice(1)}import{join as m}from"path";import M from"process";var h=M.argv.slice(2);async function p(){if(h.length===0||h.includes("--help")||h.includes("-h"))console.log(`
|
|
507
507
|
stx-iconify - Generate Iconify icon packages for stx
|
|
508
508
|
|
|
509
509
|
Usage:
|
|
@@ -526,12 +526,12 @@ Examples:
|
|
|
526
526
|
stx-iconify generate tabler --output ./packages
|
|
527
527
|
stx-iconify generate lucide --docs ./docs/collections
|
|
528
528
|
stx-iconify generate mdi --output ./packages --docs ./docs/collections
|
|
529
|
-
`),
|
|
529
|
+
`),M.exit(0);let y=h[0];if(y==="list"){console.log(`
|
|
530
530
|
\uD83D\uDCDA Fetching available icon collections...
|
|
531
|
-
`);let g=await
|
|
532
|
-
`);for(let[$,
|
|
533
|
-
Total: ${u.length} collections`)}else if(y==="generate"){let g=
|
|
531
|
+
`);let g=await q(),u=Object.entries(g).sort(($,G)=>G[1].total-$[1].total);console.log(`Available collections:
|
|
532
|
+
`);for(let[$,G]of u)console.log(` ${$.padEnd(30)} ${G.name} (${G.total} icons)`);console.log(`
|
|
533
|
+
Total: ${u.length} collections`)}else if(y==="generate"){let g=h[1];if(!g)console.error("Error: Please specify a collection prefix"),console.error("Usage: stx-iconify generate <prefix> [icons...]"),M.exit(1);let u=m(M.cwd(),"packages"),$,G=[];for(let b=2;b<h.length;b++)if(h[b]==="--output"||h[b]==="-o")u=h[b+1],b++;else if(h[b]==="--docs"||h[b]==="-d")$=h[b+1],b++;else if(!h[b].startsWith("--")&&!h[b].startsWith("-"))G.push(h[b]);await V(g,u,G.length>0?G:void 0,$),console.log(`
|
|
534
534
|
\u2713 Package generated successfully!`),console.log(`
|
|
535
|
-
To use the package:`),console.log(` 1. cd packages/iconify-${g}`),console.log(" 2. bun install"),console.log(" 3. bun run build")}else console.error(`Unknown command: ${y}`),console.error('Run "stx-iconify --help" for usage information'),
|
|
535
|
+
To use the package:`),console.log(` 1. cd packages/iconify-${g}`),console.log(" 2. bun install"),console.log(" 3. bun run build")}else console.error(`Unknown command: ${y}`),console.error('Run "stx-iconify --help" for usage information'),M.exit(1)}p().catch((y)=>{console.error("Error:",y.message),M.exit(1)});
|
|
536
536
|
|
|
537
|
-
//# debugId=
|
|
537
|
+
//# debugId=9F4361B94767790964756E2164756E21
|
package/dist/cli.js.map
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/cli.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/* eslint-disable no-console, style/max-statements-per-line, indent */\nimport type { IconData } from '@stacksjs/iconify-core'\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport interface IconifyCollection {\n prefix: string\n name: string\n total: number\n author?: {\n name: string\n url?: string\n }\n license?: {\n title: string\n spdx: string\n url?: string\n }\n height?: number\n category?: string\n palette?: boolean\n}\n\nexport interface IconifyIconData {\n body: string\n width?: number\n height?: number\n left?: number\n top?: number\n rotate?: number\n hFlip?: boolean\n vFlip?: boolean\n}\n\nexport interface IconifyCollectionData {\n prefix: string\n lastModified: number\n icons: Record<string, IconifyIconData>\n aliases?: Record<string, {\n parent: string\n hFlip?: boolean\n vFlip?: boolean\n rotate?: number\n }>\n width?: number\n height?: number\n}\n\nconst ICONIFY_API = 'https://api.iconify.design'\n\n/**\n * Fetch available icon collections from Iconify\n */\nexport async function fetchCollections(): Promise<Record<string, IconifyCollection>> {\n const response = await fetch(`${ICONIFY_API}/collections`)\n if (!response.ok) {\n throw new Error(`Failed to fetch collections: ${response.statusText}`)\n }\n return await response.json()\n}\n\n/**\n * Fetch icons from a specific collection\n */\nexport async function fetchCollectionIcons(\n prefix: string,\n icons?: string[],\n): Promise<IconifyCollectionData> {\n // Try to load from @iconify/json package first\n try {\n const iconifyJsonPath = require.resolve('@iconify/json')\n // The resolve gives us the main module path, get the package directory\n const basePath = `${iconifyJsonPath.substring(0, iconifyJsonPath.lastIndexOf('/node_modules/@iconify/json/'))}/node_modules/@iconify/json`\n const jsonPath = `${basePath}/json/${prefix}.json`\n\n const file = Bun.file(jsonPath)\n if (await file.exists()) {\n const data: IconifyCollectionData = await file.json()\n\n // If specific icons are requested, filter them\n if (icons && icons.length > 0) {\n const filteredIcons: Record<string, IconifyIconData> = {}\n for (const iconName of icons) {\n if (data.icons[iconName]) {\n filteredIcons[iconName] = data.icons[iconName]\n }\n }\n return {\n ...data,\n icons: filteredIcons,\n }\n }\n\n return data\n }\n }\n catch {\n // Fall through to API if local file not found\n }\n\n // Fallback to API (only works for specific icons, not full collections)\n const url = icons && icons.length > 0\n ? `${ICONIFY_API}/${prefix}.json?icons=${icons.join(',')}`\n : `${ICONIFY_API}/${prefix}.json`\n\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`Failed to fetch icons for ${prefix}: ${response.statusText}`)\n }\n return await response.json()\n}\n\n/**\n * Convert Iconify icon data to our IconData format\n */\nexport function convertIconData(data: IconifyIconData, defaultWidth = 24, defaultHeight = 24): IconData {\n return {\n body: data.body,\n width: data.width || defaultWidth,\n height: data.height || defaultHeight,\n viewBox: `0 0 ${data.width || defaultWidth} ${data.height || defaultHeight}`,\n }\n}\n\n/**\n * Generate TypeScript icon data file\n */\nexport function generateIconData(\n name: string,\n iconData: IconData,\n): string {\n const camelCaseName = toCamelCase(name)\n\n return `import type { IconData } from '@stacksjs/iconify-core'\n\nexport const ${camelCaseName}: IconData = ${JSON.stringify(iconData, null, 2)}\n\nexport default ${camelCaseName}\n`\n}\n\n/**\n * Generate stx icon component file\n */\nexport function generateIconComponent(\n _name: string,\n iconData: IconData,\n): string {\n return `<script>\n// Get props with defaults (handle undefined)\nconst iconWidth = (typeof width !== 'undefined' ? width : null) || (typeof size !== 'undefined' ? size : null) || ${iconData.width || 24}\nconst iconHeight = (typeof height !== 'undefined' ? height : null) || (typeof size !== 'undefined' ? size : null) || ${iconData.height || 24}\nconst iconColor = typeof color !== 'undefined' ? color : 'currentColor'\nconst viewBox = \"${iconData.viewBox || `0 0 ${iconData.width || 24} ${iconData.height || 24}`}\"\n\n// Build transform\nconst transforms = []\nif (typeof hFlip !== 'undefined' && hFlip) transforms.push('scaleX(-1)')\nif (typeof vFlip !== 'undefined' && vFlip) transforms.push('scaleY(-1)')\nif (typeof rotate !== 'undefined' && rotate) {\n const rotateNum = typeof rotate === 'string' ? parseInt(rotate, 10) : rotate\n const deg = typeof rotateNum === 'number' && rotateNum < 4 ? rotateNum * 90 : rotateNum\n transforms.push(\\`rotate(\\${deg}deg)\\`)\n}\n\nconst transform = transforms.length > 0 ? transforms.join(' ') : ''\nconst transformStyle = transform ? \\`transform: \\${transform};\\` : ''\n\n// Build style\nconst styles = []\nif (transformStyle) styles.push(transformStyle)\nif (typeof style !== 'undefined' && style) styles.push(style)\n\nconst styleAttr = styles.length > 0 ? \\` style=\"\\${styles.join(' ')}\"\\` : ''\nconst classAttr = typeof className !== 'undefined' && className ? \\` class=\"\\${className}\"\\` : ''\n\n// Icon body\nlet body = ${JSON.stringify(iconData.body)}\nif (iconColor && iconColor !== 'currentColor') {\n body = body.replace(/currentColor/g, iconColor)\n}\n\n// Generate SVG\nconst svg = \\`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"\\${iconWidth}\" height=\"\\${iconHeight}\" viewBox=\"\\${viewBox}\"\\${classAttr}\\${styleAttr}>\\${body}</svg>\\`\n</script>\n\n{!! svg !!}\n`\n}\n\n/**\n * Generate index file for a collection\n */\nexport function generateIndexFile(iconNames: string[]): string {\n // toCamelCase can produce collisions across distinct kebab names\n // (e.g. \"mp-401\" and \"mp-4-01\" both ā \"mp401\"). Track used identifiers\n // and disambiguate later occurrences with a fully-sanitized form of the\n // original kebab name, then a numeric suffix as a final fallback.\n const used = new Set<string>()\n const dataExports = iconNames.map((name) => {\n const primary = toCamelCase(name)\n let id = primary\n if (used.has(id)) {\n let candidate = name.replace(/[^a-zA-Z0-9]/g, '_')\n if (/^[0-9]/.test(candidate))\n candidate = `_${candidate}`\n id = candidate\n let n = 2\n while (used.has(id)) {\n id = `${candidate}_${n}`\n n++\n }\n }\n used.add(id)\n return `export { default as ${id} } from './${name}.js'`\n }).join('\\n')\n\n return `// Icon data exports\n${dataExports}\n\nexport * from './types.js'\n`\n}\n\n/**\n * Generate types file\n */\nexport function generateTypesFile(prefix: string): string {\n return `import type { IconData, IconProps } from '@stacksjs/iconify-core'\n\nexport type { IconData, IconProps }\n\nexport type ${toPascalCase(prefix)}Icon = IconData\n`\n}\n\n/**\n * Generate package.json for a collection\n */\nexport function generatePackageJson(\n prefix: string,\n collectionInfo: IconifyCollection,\n _iconCount: number,\n): string {\n const packageJson = {\n name: `@stacksjs/iconify-${prefix}`,\n type: 'module',\n version: '0.0.1',\n description: `${collectionInfo.name} icons for stx from Iconify`,\n author: collectionInfo.author?.name || 'Iconify',\n license: collectionInfo.license?.spdx || 'MIT',\n repository: {\n type: 'git',\n url: 'https://github.com/stacksjs/stx.git',\n directory: `packages/iconify-${prefix}`,\n },\n keywords: [\n 'iconify',\n 'icons',\n 'svg',\n prefix,\n collectionInfo.name,\n 'stx',\n ],\n sideEffects: false,\n exports: {\n '.': {\n types: './dist/index.d.ts',\n import: './dist/index.js',\n },\n './*': './dist/*',\n },\n main: './dist/index.js',\n module: './dist/index.js',\n types: './dist/index.d.ts',\n files: [\n 'dist',\n ],\n scripts: {\n build: 'bun build.ts',\n prepublishOnly: 'bun build.ts',\n },\n dependencies: {\n '@stacksjs/iconify-core': 'workspace:*',\n },\n }\n\n return JSON.stringify(packageJson, null, 2)\n}\n\n/**\n * Generate build.ts file for a collection\n */\nexport function generateBuildFile(prefix: string): string {\n return `import { existsSync, readdirSync, statSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport dts from 'bun-plugin-dtsx'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst srcDir = join(__dirname, 'src')\nconst distDir = join(__dirname, 'dist')\nconst distEntry = join(distDir, 'index.js')\n\n// Skip rebuild when dist is already up to date. Makes prepublishOnly a\n// no-op when CI pre-built the package in parallel earlier in the\n// pipeline ā and a no-op for local re-runs that didn't touch src/.\n//\n// Walks src/ recursively so changes inside subdirectories (if we ever\n// add them) properly invalidate the cached dist.\nfunction isDistFresh() {\n if (!existsSync(distEntry)) return false\n const distMtime = statSync(distEntry).mtimeMs\n function newer(dir) {\n for (const name of readdirSync(dir)) {\n const p = join(dir, name)\n const s = statSync(p)\n if (s.isDirectory()) {\n if (newer(p)) return true\n } else if (s.mtimeMs > distMtime) {\n return true\n }\n }\n return false\n }\n return !newer(srcDir)\n}\n\nif (isDistFresh()) {\n console.log('ā @stacksjs/iconify-${prefix} dist is fresh, skipping rebuild')\n} else {\n await Bun.build({\n entrypoints: [join(srcDir, 'index.ts')],\n outdir: distDir,\n target: 'bun',\n format: 'esm',\n plugins: [dts()],\n minify: true,\n sourcemap: 'external',\n splitting: true,\n })\n console.log('ā Built @stacksjs/iconify-${prefix}')\n}\n`\n}\n\n/**\n * Generate README for a collection\n */\nexport function generateReadme(\n prefix: string,\n collectionInfo: IconifyCollection,\n iconCount: number,\n): string {\n return `# @stacksjs/iconify-${prefix}\n\n${collectionInfo.name} icons for stx from Iconify.\n\n## Installation\n\n\\`\\`\\`bash\nbun add @stacksjs/iconify-${prefix}\n\\`\\`\\`\n\n## Usage\n\n### In stx templates\n\n\\`\\`\\`html\n<script>\n import { home } from '@stacksjs/iconify-${prefix}'\n import { renderIcon } from '@stacksjs/iconify-core'\n\n export const homeIcon = renderIcon(home, { size: 24, color: 'currentColor' })\n</script>\n\n<div class=\"icon\">\n {!! homeIcon !!}\n</div>\n\\`\\`\\`\n\n### In TypeScript/JavaScript\n\n\\`\\`\\`typescript\nimport { home, account, settings } from '@stacksjs/iconify-${prefix}'\nimport { renderIcon } from '@stacksjs/iconify-core'\n\nconst svg = renderIcon(home, {\n size: 24,\n color: '#000000',\n})\n\\`\\`\\`\n\n## Available Icons\n\nThis package contains ${iconCount} icons from ${collectionInfo.name}.\n\n## License\n\n${collectionInfo.license?.title || 'MIT'}\n\n${collectionInfo.license?.url ? `License: ${collectionInfo.license.url}` : ''}\n\n## Credits\n\n- Icons: ${collectionInfo.author?.name || 'Iconify'}${collectionInfo.author?.url ? ` (${collectionInfo.author.url})` : ''}\n- Iconify: https://iconify.design/\n`\n}\n\n/**\n * Generate documentation file for a collection\n */\nexport function generateDocumentation(\n prefix: string,\n collectionInfo: IconifyCollection,\n iconNames: string[],\n): string {\n const iconCount = iconNames.length\n const exampleIcons = iconNames.slice(0, 5).map(toCamelCase)\n const exampleComponents = exampleIcons.map(name => `${name.charAt(0).toUpperCase()}${name.slice(1)}Icon`)\n\n // Generate full icon list\n const allIconsList = iconNames.map((name) => {\n const camelName = toCamelCase(name)\n return `- \\`${camelName}\\``\n }).join('\\n')\n\n return `# ${collectionInfo.name}\n\n> ${collectionInfo.name} icons for stx from Iconify\n\n## Overview\n\nThis package provides access to ${iconCount} icons from the ${collectionInfo.name} collection through the stx iconify integration.\n\n**Collection ID:** \\`${prefix}\\`\n**Total Icons:** ${iconCount}\n${collectionInfo.author?.name ? `**Author:** ${collectionInfo.author.name}${collectionInfo.author.url ? ` ([Website](${collectionInfo.author.url}))` : ''}` : ''}\n${collectionInfo.license?.title ? `**License:** ${collectionInfo.license.title}${collectionInfo.license.url ? ` ([Details](${collectionInfo.license.url}))` : ''}` : ''}\n${collectionInfo.category ? `**Category:** ${collectionInfo.category}` : ''}\n${collectionInfo.palette !== undefined ? `**Palette:** ${collectionInfo.palette ? 'Yes (color icons)' : 'No (monotone icons)'}` : ''}\n\n## Installation\n\n\\`\\`\\`bash\nbun add @stacksjs/iconify-${prefix}\n\\`\\`\\`\n\n## Quick Start\n\n### Component Usage (Recommended)\n\nIcons are available as .stx components that can be used directly in templates:\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'Icon'} height=\"1em\" />\n<${exampleComponents[0] || 'Icon'} width=\"1em\" height=\"1em\" />\n<${exampleComponents[0] || 'Icon'} height=\"24\" />\n\\`\\`\\`\n\n### With Properties\n\n\\`\\`\\`html\n<!-- Using size property -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" />\n<${exampleComponents[0] || 'Icon'} size=\"1em\" />\n\n<!-- Using width and height -->\n<${exampleComponents[0] || 'Icon'} width=\"24\" height=\"32\" />\n\n<!-- With color -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"red\" />\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n\n<!-- With CSS class -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" class=\"icon-primary\" />\n\n<!-- With all properties -->\n<${exampleComponents[0] || 'Icon'}\n size=\"32\"\n color=\"#4a90e2\"\n class=\"my-icon\"\n style=\"opacity: 0.8;\"\n/>\n\\`\\`\\`\n\n### In stx Templates\n\n\\`\\`\\`html\n<!DOCTYPE html>\n<html>\n<head>\n <title>Icon Demo</title>\n <style>\n .icon-grid {\n display: flex;\n gap: 1rem;\n align-items: center;\n }\n </style>\n</head>\n<body>\n <div class=\"icon-grid\">\n <${exampleComponents[0] || 'Icon'} size=\"24\" />\n <${exampleComponents[1] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n <${exampleComponents[2] || 'Icon'} size=\"32\" class=\"my-icon\" />\n </div>\n</body>\n</html>\n\\`\\`\\`\n\n### Data-Only Import\n\nYou can also import icon data and use the \\`renderIcon\\` function directly:\n\n\\`\\`\\`typescript\nimport { ${exampleIcons.slice(0, 3).join(', ')} } from '@stacksjs/iconify-${prefix}'\nimport { renderIcon } from '@stacksjs/iconify-core'\n\nconst svg = renderIcon(${exampleIcons[0] || 'icon'}, { size: 24 })\n\\`\\`\\`\n\n## Icon Properties\n\nAll icon component functions and \\`renderIcon\\` accept the following properties:\n\n| Property | Type | Default | Description |\n|----------|------|---------|-------------|\n| \\`size\\` | \\`string \\\\| number\\` | - | Icon size (sets both width and height) |\n| \\`width\\` | \\`string \\\\| number\\` | - | Icon width (overrides size) |\n| \\`height\\` | \\`string \\\\| number\\` | - | Icon height (overrides size) |\n| \\`color\\` | \\`string\\` | \\`'currentColor'\\` | Icon color (CSS color or hex) |\n| \\`hFlip\\` | \\`boolean\\` | \\`false\\` | Flip horizontally |\n| \\`vFlip\\` | \\`boolean\\` | \\`false\\` | Flip vertically |\n| \\`rotate\\` | \\`0 \\\\| 90 \\\\| 180 \\\\| 270\\` | \\`0\\` | Rotation in degrees |\n| \\`class\\` | \\`string\\` | - | Additional CSS classes |\n| \\`style\\` | \\`string\\` | - | Inline styles |\n\n## Color\n\n${collectionInfo.palette ? '### Color Icons\\n\\nThis 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:'}\n\n\\`\\`\\`html\n<!-- Via color property -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"red\" />\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n\n<!-- Via inline style -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" style=\"color: green;\" />\n\n<!-- Via CSS class -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" class=\"text-primary\" />\n\\`\\`\\`\n\n${!collectionInfo.palette\n ? `\\`\\`\\`css\n/* In your CSS */\n.text-primary {\n color: #4a90e2;\n}\n\n.icon:hover {\n color: #357abd;\n}\n\\`\\`\\``\n : ''}\n\n## Size\n\nUnlike other components, SVG + CSS components do not set icon size by default. This has advantages and disadvantages.\n\n**Disadvantages:**\n- You need to set size yourself.\n\n**Advantages:**\n- You have full control over icon size.\n\nYou can change icon size by:\n- Setting \\`width\\` and \\`height\\` properties\n- Using CSS\n\n### Properties\n\nAll icon components support \\`width\\` and \\`height\\` properties.\n\nValue is a string or number.\n\nYou 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.\n\n**Examples:**\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'DraftsIcon'} height=\"1em\" />\n<${exampleComponents[0] || 'DraftsIcon'} width=\"1em\" height=\"1em\" />\n<${exampleComponents[0] || 'DraftsIcon'} height=\"24\" />\n\\`\\`\\`\n\nYou can also use the \\`size\\` property as a shorthand for setting both width and height:\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'DraftsIcon'} size=\"24\" />\n<${exampleComponents[0] || 'DraftsIcon'} size=\"1em\" />\n\\`\\`\\`\n\n### CSS Sizing\n\nYou can also control icon size via CSS:\n\n\\`\\`\\`css\n.${toCamelCase(prefix)}-icon {\n width: 1em;\n height: 1em;\n}\n\\`\\`\\`\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'DraftsIcon'} class=\"${toCamelCase(prefix)}-icon\" />\n\\`\\`\\`\n\n## Available Icons\n\nThis package contains **${iconCount}** icons:\n\n${allIconsList}\n\n## Usage Examples\n\n### Navigation Menu\n\n\\`\\`\\`html\n<nav>\n <a href=\"/\"><${exampleComponents[0] || 'Icon'} size=\"20\" class=\"nav-icon\" /> Home</a>\n <a href=\"/about\"><${exampleComponents[1] || 'Icon'} size=\"20\" class=\"nav-icon\" /> About</a>\n <a href=\"/contact\"><${exampleComponents[2] || 'Icon'} size=\"20\" class=\"nav-icon\" /> Contact</a>\n <a href=\"/settings\"><${exampleComponents[3] || 'Icon'} size=\"20\" class=\"nav-icon\" /> Settings</a>\n</nav>\n\n<style>\n nav {\n display: flex;\n gap: 1rem;\n }\n nav a {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n .nav-icon {\n color: currentColor;\n }\n</style>\n\\`\\`\\`\n\n### Custom Styling\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'Icon'}\n size=\"24\"\n class=\"icon icon-primary\"\n style=\"opacity: 0.8; transition: opacity 0.2s;\"\n/>\n\n<style>\n .icon-primary {\n color: #4a90e2;\n }\n .icon-primary:hover {\n opacity: 1;\n }\n</style>\n\\`\\`\\`\n\n### Status Indicators\n\n\\`\\`\\`html\n<div class=\"status-grid\">\n <div class=\"status-item\">\n <${exampleComponents[0] || 'Icon'} size=\"16\" color=\"#22c55e\" />\n <span>Success</span>\n </div>\n <div class=\"status-item\">\n <${exampleComponents[1] || 'Icon'} size=\"16\" color=\"#f59e0b\" />\n <span>Warning</span>\n </div>\n <div class=\"status-item\">\n <${exampleComponents[2] || 'Icon'} size=\"16\" color=\"#ef4444\" />\n <span>Error</span>\n </div>\n</div>\n\\`\\`\\`\n\n## Best Practices\n\n1. **Use Components Directly**: Import and use icon components in your templates\n \\`\\`\\`html\n <!-- Recommended -->\n <${exampleComponents[0] || 'Icon'} size=\"24\" />\n <${exampleComponents[1] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n \\`\\`\\`\n\n2. **Use CSS for Theming**: Apply consistent styling through CSS classes\n \\`\\`\\`css\n .icon {\n color: currentColor;\n opacity: 0.8;\n transition: opacity 0.2s;\n }\n\n .icon:hover {\n opacity: 1;\n }\n \\`\\`\\`\n\n \\`\\`\\`html\n <${exampleComponents[0] || 'Icon'} size=\"24\" class=\"icon\" />\n \\`\\`\\`\n\n3. **Set Appropriate Sizes**: Use \\`1em\\` for inline icons, fixed pixel sizes for standalone icons\n \\`\\`\\`html\n <!-- Inline with text -->\n <p>Click the <${exampleComponents[0] || 'Icon'} height=\"1em\" /> icon to continue</p>\n\n <!-- Standalone -->\n <${exampleComponents[0] || 'Icon'} size=\"24\" />\n \\`\\`\\`\n\n4. **Use Data Import for Advanced Use Cases**: When you need more control\n \\`\\`\\`html\n @js\n import { ${exampleIcons[0] || 'icon'} } from '@stacksjs/iconify-${prefix}'\n import { renderIcon } from '@stacksjs/iconify-core'\n global.customIcon = renderIcon(${exampleIcons[0] || 'icon'}, { size: 24 })\n @endjs\n\n {!! customIcon !!}\n \\`\\`\\`\n\n## TypeScript Support\n\nThis package includes full TypeScript support with type definitions for all icons.\n\n\\`\\`\\`typescript\nimport type { IconData } from '@stacksjs/iconify-core'\nimport { ${exampleIcons[0] || 'icon'} } from '@stacksjs/iconify-${prefix}'\n\n// Icons are typed as IconData\nconst myIcon: IconData = ${exampleIcons[0] || 'icon'}\n\\`\\`\\`\n\n## Related Packages\n\n- [\\`@stacksjs/iconify-core\\`](../iconify#installation) - Core rendering functions and utilities\n- [Iconify Integration Guide](../iconify) - Complete guide to using Iconify with stx\n- [stx Documentation](../) - Main stx documentation\n\n## License\n\n${collectionInfo.license?.title || 'MIT'}\n\n${collectionInfo.license?.url ? `See [license details](${collectionInfo.license.url}) for more information.` : ''}\n\n## Credits\n\n- **Icons**: ${collectionInfo.author?.name || 'Iconify'}${collectionInfo.author?.url ? ` ([Website](${collectionInfo.author.url}))` : ''}\n- **Iconify**: [https://iconify.design/](https://iconify.design/)\n- **Icon Set**: [View on Iconify](https://icon-sets.iconify.design/${prefix}/)\n\n## Resources\n\n- [Browse all icons in this collection](https://icon-sets.iconify.design/${prefix}/)\n- [Iconify documentation](https://iconify.design/docs/)\n- [stx iconify integration guide](../../docs/iconify.md)\n`\n}\n\n/**\n * Generate a complete icon package\n */\nexport async function generatePackage(\n prefix: string,\n outputDir: string,\n icons?: string[],\n docsDir?: string,\n): Promise<void> {\n console.log(`\\nš¦ Generating package for ${prefix}...`)\n\n // Fetch collection info\n const collections = await fetchCollections()\n const collectionInfo = collections[prefix]\n\n if (!collectionInfo) {\n throw new Error(`Collection ${prefix} not found`)\n }\n\n console.log(` Collection: ${collectionInfo.name}`)\n console.log(` Total icons: ${collectionInfo.total}`)\n\n // Fetch icons\n const collectionData = await fetchCollectionIcons(prefix, icons)\n const iconNames = Object.keys(collectionData.icons)\n\n console.log(` Generating ${iconNames.length} icons...`)\n\n // Create package directory structure\n const packageDir = join(outputDir, `iconify-${prefix}`)\n const srcDir = join(packageDir, 'src')\n\n await mkdir(srcDir, { recursive: true })\n\n // Generate icon files\n const defaultWidth = collectionData.width || 24\n const defaultHeight = collectionData.height || 24\n\n for (const iconName of iconNames) {\n const iconData = collectionData.icons[iconName]\n const converted = convertIconData(iconData, defaultWidth, defaultHeight)\n\n // Generate data file (.ts)\n const dataFile = generateIconData(iconName, converted)\n await writeFile(join(srcDir, `${iconName}.ts`), dataFile)\n\n // Generate component file (.stx) with -icon suffix for PascalCase component names\n const componentFile = generateIconComponent(iconName, converted)\n await writeFile(join(srcDir, `${iconName}-icon.stx`), componentFile)\n }\n\n // Generate index file\n const indexContent = generateIndexFile(iconNames)\n await writeFile(join(srcDir, 'index.ts'), indexContent)\n\n // Generate types file\n const typesContent = generateTypesFile(prefix)\n await writeFile(join(srcDir, 'types.ts'), typesContent)\n\n // Generate package.json\n const packageJsonContent = generatePackageJson(prefix, collectionInfo, iconNames.length)\n await writeFile(join(packageDir, 'package.json'), packageJsonContent)\n\n // Generate build file\n const buildContent = generateBuildFile(prefix)\n await writeFile(join(packageDir, 'build.ts'), buildContent)\n\n // Generate README\n const readmeContent = generateReadme(prefix, collectionInfo, iconNames.length)\n await writeFile(join(packageDir, 'README.md'), readmeContent)\n\n // Generate documentation if docsDir is provided\n if (docsDir) {\n const docsPath = join(docsDir, `iconify-${prefix}.md`)\n const docContent = generateDocumentation(prefix, collectionInfo, iconNames)\n await mkdir(docsDir, { recursive: true })\n await writeFile(docsPath, docContent)\n console.log(` ā Generated documentation in ${docsPath}`)\n }\n\n console.log(` ā Generated ${iconNames.length} icons in ${packageDir}`)\n}\n\n/**\n * Convert kebab-case to a valid JS identifier in camelCase form.\n * Iconify allows names that start with digits (e.g. \"2\", \"3d-move\") and\n * names containing dots/slashes ā none of which are legal JS identifiers.\n * Prefix with `_` when the first char isn't [A-Za-z_$], and replace any\n * remaining illegal chars with `_` so downstream `export { default as X }`\n * always parses.\n */\nexport function toCamelCase(str: string): string {\n let camel = str.replace(/-([a-z0-9])/g, g => g[1].toUpperCase())\n camel = camel.replace(/[^a-zA-Z0-9_$]/g, '_')\n if (/^[0-9]/.test(camel))\n camel = `_${camel}`\n return camel\n}\n\n/**\n * Convert kebab-case to PascalCase\n */\nexport function toPascalCase(str: string): string {\n const camel = toCamelCase(str)\n return camel.charAt(0).toUpperCase() + camel.slice(1)\n}\n",
|
|
5
|
+
"/* eslint-disable no-console, style/max-statements-per-line, indent */\nimport type { IconData } from '@stacksjs/iconify-core'\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport interface IconifyCollection {\n prefix: string\n name: string\n total: number\n author?: {\n name: string\n url?: string\n }\n license?: {\n title: string\n spdx: string\n url?: string\n }\n height?: number\n category?: string\n palette?: boolean\n}\n\nexport interface IconifyIconData {\n body: string\n width?: number\n height?: number\n left?: number\n top?: number\n rotate?: number\n hFlip?: boolean\n vFlip?: boolean\n}\n\nexport interface IconifyCollectionData {\n prefix: string\n lastModified: number\n icons: Record<string, IconifyIconData>\n aliases?: Record<string, {\n parent: string\n hFlip?: boolean\n vFlip?: boolean\n rotate?: number\n }>\n width?: number\n height?: number\n}\n\nconst ICONIFY_API = 'https://api.iconify.design'\n\n/**\n * Fetch available icon collections from Iconify\n */\nexport async function fetchCollections(): Promise<Record<string, IconifyCollection>> {\n const response = await fetch(`${ICONIFY_API}/collections`)\n if (!response.ok) {\n throw new Error(`Failed to fetch collections: ${response.statusText}`)\n }\n return await response.json()\n}\n\n/**\n * Fetch icons from a specific collection\n */\nexport async function fetchCollectionIcons(\n prefix: string,\n icons?: string[],\n): Promise<IconifyCollectionData> {\n // Try to load from @iconify/json package first\n try {\n const iconifyJsonPath = require.resolve('@iconify/json')\n // The resolve gives us the main module path, get the package directory\n const basePath = `${iconifyJsonPath.substring(0, iconifyJsonPath.lastIndexOf('/node_modules/@iconify/json/'))}/node_modules/@iconify/json`\n const jsonPath = `${basePath}/json/${prefix}.json`\n\n const file = Bun.file(jsonPath)\n if (await file.exists()) {\n const data: IconifyCollectionData = await file.json()\n\n // If specific icons are requested, filter them\n if (icons && icons.length > 0) {\n const filteredIcons: Record<string, IconifyIconData> = {}\n for (const iconName of icons) {\n if (data.icons[iconName]) {\n filteredIcons[iconName] = data.icons[iconName]\n }\n }\n return {\n ...data,\n icons: filteredIcons,\n }\n }\n\n return data\n }\n }\n catch {\n // Fall through to API if local file not found\n }\n\n // Fallback to API (only works for specific icons, not full collections)\n const url = icons && icons.length > 0\n ? `${ICONIFY_API}/${prefix}.json?icons=${icons.join(',')}`\n : `${ICONIFY_API}/${prefix}.json`\n\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`Failed to fetch icons for ${prefix}: ${response.statusText}`)\n }\n return await response.json()\n}\n\n/**\n * Convert Iconify icon data to our IconData format\n */\nexport function convertIconData(data: IconifyIconData, defaultWidth = 24, defaultHeight = 24): IconData {\n return {\n body: data.body,\n width: data.width || defaultWidth,\n height: data.height || defaultHeight,\n viewBox: `0 0 ${data.width || defaultWidth} ${data.height || defaultHeight}`,\n }\n}\n\n/**\n * Generate TypeScript icon data file\n */\nexport function generateIconData(\n name: string,\n iconData: IconData,\n): string {\n const camelCaseName = toCamelCase(name)\n\n return `import type { IconData } from '@stacksjs/iconify-core'\n\nexport const ${camelCaseName}: IconData = ${JSON.stringify(iconData, null, 2)}\n\nexport default ${camelCaseName}\n`\n}\n\n/**\n * Generate stx icon component file\n */\nexport function generateIconComponent(\n _name: string,\n iconData: IconData,\n): string {\n return `<script>\n// Get props with defaults (handle undefined)\nconst iconWidth = (typeof width !== 'undefined' ? width : null) || (typeof size !== 'undefined' ? size : null) || ${iconData.width || 24}\nconst iconHeight = (typeof height !== 'undefined' ? height : null) || (typeof size !== 'undefined' ? size : null) || ${iconData.height || 24}\nconst iconColor = typeof color !== 'undefined' ? color : 'currentColor'\nconst viewBox = \"${iconData.viewBox || `0 0 ${iconData.width || 24} ${iconData.height || 24}`}\"\n\n// Build transform\nconst transforms = []\nif (typeof hFlip !== 'undefined' && hFlip) transforms.push('scaleX(-1)')\nif (typeof vFlip !== 'undefined' && vFlip) transforms.push('scaleY(-1)')\nif (typeof rotate !== 'undefined' && rotate) {\n const rotateNum = typeof rotate === 'string' ? parseInt(rotate, 10) : rotate\n const deg = typeof rotateNum === 'number' && rotateNum < 4 ? rotateNum * 90 : rotateNum\n transforms.push(\\`rotate(\\${deg}deg)\\`)\n}\n\nconst transform = transforms.length > 0 ? transforms.join(' ') : ''\nconst transformStyle = transform ? \\`transform: \\${transform};\\` : ''\n\n// Build style\nconst styles = []\nif (transformStyle) styles.push(transformStyle)\nif (typeof style !== 'undefined' && style) styles.push(style)\n\nconst styleAttr = styles.length > 0 ? \\` style=\"\\${styles.join(' ')}\"\\` : ''\nconst classAttr = typeof className !== 'undefined' && className ? \\` class=\"\\${className}\"\\` : ''\n\n// Icon body\nlet body = ${JSON.stringify(iconData.body)}\nif (iconColor && iconColor !== 'currentColor') {\n body = body.replace(/currentColor/g, iconColor)\n}\n\n// Generate SVG\nconst svg = \\`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"\\${iconWidth}\" height=\"\\${iconHeight}\" viewBox=\"\\${viewBox}\"\\${classAttr}\\${styleAttr}>\\${body}</svg>\\`\n</script>\n\n{!! svg !!}\n`\n}\n\n/**\n * Generate index file for a collection\n */\nexport function generateIndexFile(iconNames: string[]): string {\n // toCamelCase can produce collisions across distinct kebab names\n // (e.g. \"mp-401\" and \"mp-4-01\" both ā \"mp401\"). Track used identifiers\n // and disambiguate later occurrences with a fully-sanitized form of the\n // original kebab name, then a numeric suffix as a final fallback.\n const used = new Set<string>()\n const dataExports = iconNames.map((name) => {\n const primary = toCamelCase(name)\n let id = primary\n if (used.has(id)) {\n let candidate = name.replace(/[^a-zA-Z0-9]/g, '_')\n if (/^[0-9]/.test(candidate))\n candidate = `_${candidate}`\n id = candidate\n let n = 2\n while (used.has(id)) {\n id = `${candidate}_${n}`\n n++\n }\n }\n used.add(id)\n return `export { default as ${id} } from './${name}.js'`\n }).join('\\n')\n\n return `// Icon data exports\n${dataExports}\n\nexport * from './types.js'\n`\n}\n\n/**\n * Generate types file\n */\nexport function generateTypesFile(prefix: string): string {\n return `import type { IconData, IconProps } from '@stacksjs/iconify-core'\n\nexport type { IconData, IconProps }\n\nexport type ${toPascalCase(prefix)}Icon = IconData\n`\n}\n\n/**\n * Generate package.json for a collection\n */\nexport function generatePackageJson(\n prefix: string,\n collectionInfo: IconifyCollection,\n _iconCount: number,\n): string {\n const packageJson = {\n name: `@stacksjs/iconify-${prefix}`,\n type: 'module',\n version: '0.0.1',\n description: `${collectionInfo.name} icons for stx from Iconify`,\n author: collectionInfo.author?.name || 'Iconify',\n license: collectionInfo.license?.spdx || 'MIT',\n repository: {\n type: 'git',\n url: 'https://github.com/stacksjs/stx.git',\n directory: `packages/iconify-${prefix}`,\n },\n keywords: [\n 'iconify',\n 'icons',\n 'svg',\n prefix,\n collectionInfo.name,\n 'stx',\n ],\n sideEffects: false,\n exports: {\n '.': {\n types: './dist/index.d.ts',\n import: './dist/index.js',\n },\n './*': './dist/*',\n },\n main: './dist/index.js',\n module: './dist/index.js',\n types: './dist/index.d.ts',\n files: [\n 'dist',\n ],\n scripts: {\n build: 'bun build.ts',\n prepublishOnly: 'bun build.ts',\n },\n dependencies: {\n '@stacksjs/iconify-core': 'workspace:*',\n },\n }\n\n return JSON.stringify(packageJson, null, 2)\n}\n\n/**\n * Generate build.ts file for a collection\n */\nexport function generateBuildFile(prefix: string): string {\n return `import { existsSync, readdirSync, statSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport dts from 'bun-plugin-dtsx'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst srcDir = join(__dirname, 'src')\nconst distDir = join(__dirname, 'dist')\nconst distEntry = join(distDir, 'index.js')\n\n// Skip rebuild when dist is already up to date. Makes prepublishOnly a\n// no-op when CI pre-built the package in parallel earlier in the\n// pipeline ā and a no-op for local re-runs that didn't touch src/.\n//\n// Walks src/ recursively so changes inside subdirectories (if we ever\n// add them) properly invalidate the cached dist.\nfunction isDistFresh() {\n if (!existsSync(distEntry)) return false\n const distMtime = statSync(distEntry).mtimeMs\n function newer(dir) {\n for (const name of readdirSync(dir)) {\n const p = join(dir, name)\n const s = statSync(p)\n if (s.isDirectory()) {\n if (newer(p)) return true\n } else if (s.mtimeMs > distMtime) {\n return true\n }\n }\n return false\n }\n return !newer(srcDir)\n}\n\nif (isDistFresh()) {\n console.log('ā @stacksjs/iconify-${prefix} dist is fresh, skipping rebuild')\n} else {\n await Bun.build({\n entrypoints: [join(srcDir, 'index.ts')],\n outdir: distDir,\n target: 'bun',\n format: 'esm',\n plugins: [dts()],\n minify: true,\n sourcemap: 'external',\n splitting: true,\n })\n console.log('ā Built @stacksjs/iconify-${prefix}')\n}\n`\n}\n\n/**\n * Generate README for a collection\n */\nexport function generateReadme(\n prefix: string,\n collectionInfo: IconifyCollection,\n iconCount: number,\n): string {\n return `# @stacksjs/iconify-${prefix}\n\n${collectionInfo.name} icons for stx from Iconify.\n\n## Installation\n\n\\`\\`\\`bash\nbun add @stacksjs/iconify-${prefix}\n\\`\\`\\`\n\n## Usage\n\n### In stx templates\n\n\\`\\`\\`html\n<script>\n import { home } from '@stacksjs/iconify-${prefix}'\n import { renderIcon } from '@stacksjs/iconify-core'\n\n export const homeIcon = renderIcon(home, { size: 24, color: 'currentColor' })\n</script>\n\n<div class=\"icon\">\n {!! homeIcon !!}\n</div>\n\\`\\`\\`\n\n### In TypeScript/JavaScript\n\n\\`\\`\\`typescript\nimport { home, account, settings } from '@stacksjs/iconify-${prefix}'\nimport { renderIcon } from '@stacksjs/iconify-core'\n\nconst svg = renderIcon(home, {\n size: 24,\n color: '#000000',\n})\n\\`\\`\\`\n\n## Available Icons\n\nThis package contains ${iconCount} icons from ${collectionInfo.name}.\n\n## License\n\n${collectionInfo.license?.title || 'MIT'}\n\n${collectionInfo.license?.url ? `License: ${collectionInfo.license.url}` : ''}\n\n## Credits\n\n- Icons: ${collectionInfo.author?.name || 'Iconify'}${collectionInfo.author?.url ? ` (${collectionInfo.author.url})` : ''}\n- Iconify: https://iconify.design/\n`\n}\n\n/**\n * Generate documentation file for a collection\n */\nexport function generateDocumentation(\n prefix: string,\n collectionInfo: IconifyCollection,\n iconNames: string[],\n): string {\n const iconCount = iconNames.length\n const exampleIcons = iconNames.slice(0, 5).map(toCamelCase)\n const exampleComponents = exampleIcons.map(name => `${name.charAt(0).toUpperCase()}${name.slice(1)}Icon`)\n\n // Generate full icon list\n const allIconsList = iconNames.map((name) => {\n const camelName = toCamelCase(name)\n return `- \\`${camelName}\\``\n }).join('\\n')\n\n return `# ${collectionInfo.name}\n\n> ${collectionInfo.name} icons for stx from Iconify\n\n## Overview\n\nThis package provides access to ${iconCount} icons from the ${collectionInfo.name} collection through the stx iconify integration.\n\n**Collection ID:** \\`${prefix}\\`\n**Total Icons:** ${iconCount}\n${collectionInfo.author?.name ? `**Author:** ${collectionInfo.author.name}${collectionInfo.author.url ? ` ([Website](${collectionInfo.author.url}))` : ''}` : ''}\n${collectionInfo.license?.title ? `**License:** ${collectionInfo.license.title}${collectionInfo.license.url ? ` ([Details](${collectionInfo.license.url}))` : ''}` : ''}\n${collectionInfo.category ? `**Category:** ${collectionInfo.category}` : ''}\n${collectionInfo.palette !== undefined ? `**Palette:** ${collectionInfo.palette ? 'Yes (color icons)' : 'No (monotone icons)'}` : ''}\n\n## Installation\n\n\\`\\`\\`bash\nbun add @stacksjs/iconify-${prefix}\n\\`\\`\\`\n\n## Quick Start\n\n### Component Usage (Recommended)\n\nIcons are available as .stx components that can be used directly in templates:\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'Icon'} height=\"1em\" />\n<${exampleComponents[0] || 'Icon'} width=\"1em\" height=\"1em\" />\n<${exampleComponents[0] || 'Icon'} height=\"24\" />\n\\`\\`\\`\n\n### With Properties\n\n\\`\\`\\`html\n<!-- Using size property -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" />\n<${exampleComponents[0] || 'Icon'} size=\"1em\" />\n\n<!-- Using width and height -->\n<${exampleComponents[0] || 'Icon'} width=\"24\" height=\"32\" />\n\n<!-- With color -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"red\" />\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n\n<!-- With CSS class -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" class=\"icon-primary\" />\n\n<!-- With all properties -->\n<${exampleComponents[0] || 'Icon'}\n size=\"32\"\n color=\"#4a90e2\"\n class=\"my-icon\"\n style=\"opacity: 0.8;\"\n/>\n\\`\\`\\`\n\n### In stx Templates\n\n\\`\\`\\`html\n<!DOCTYPE html>\n<html>\n<head>\n <title>Icon Demo</title>\n <style>\n .icon-grid {\n display: flex;\n gap: 1rem;\n align-items: center;\n }\n </style>\n</head>\n<body>\n <div class=\"icon-grid\">\n <${exampleComponents[0] || 'Icon'} size=\"24\" />\n <${exampleComponents[1] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n <${exampleComponents[2] || 'Icon'} size=\"32\" class=\"my-icon\" />\n </div>\n</body>\n</html>\n\\`\\`\\`\n\n### Data-Only Import\n\nYou can also import icon data and use the \\`renderIcon\\` function directly:\n\n\\`\\`\\`typescript\nimport { ${exampleIcons.slice(0, 3).join(', ')} } from '@stacksjs/iconify-${prefix}'\nimport { renderIcon } from '@stacksjs/iconify-core'\n\nconst svg = renderIcon(${exampleIcons[0] || 'icon'}, { size: 24 })\n\\`\\`\\`\n\n## Icon Properties\n\nAll icon component functions and \\`renderIcon\\` accept the following properties:\n\n| Property | Type | Default | Description |\n|----------|------|---------|-------------|\n| \\`size\\` | \\`string \\\\| number\\` | - | Icon size (sets both width and height) |\n| \\`width\\` | \\`string \\\\| number\\` | - | Icon width (overrides size) |\n| \\`height\\` | \\`string \\\\| number\\` | - | Icon height (overrides size) |\n| \\`color\\` | \\`string\\` | \\`'currentColor'\\` | Icon color (CSS color or hex) |\n| \\`hFlip\\` | \\`boolean\\` | \\`false\\` | Flip horizontally |\n| \\`vFlip\\` | \\`boolean\\` | \\`false\\` | Flip vertically |\n| \\`rotate\\` | \\`0 \\\\| 90 \\\\| 180 \\\\| 270\\` | \\`0\\` | Rotation in degrees |\n| \\`class\\` | \\`string\\` | - | Additional CSS classes |\n| \\`style\\` | \\`string\\` | - | Inline styles |\n\n## Color\n\n${collectionInfo.palette ? '### Color Icons\\n\\nThis 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:'}\n\n\\`\\`\\`html\n<!-- Via color property -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"red\" />\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n\n<!-- Via inline style -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" style=\"color: green;\" />\n\n<!-- Via CSS class -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" class=\"text-primary\" />\n\\`\\`\\`\n\n${!collectionInfo.palette\n ? `\\`\\`\\`css\n/* In your CSS */\n.text-primary {\n color: #4a90e2;\n}\n\n.icon:hover {\n color: #357abd;\n}\n\\`\\`\\``\n : ''}\n\n## Size\n\nUnlike other components, SVG + CSS components do not set icon size by default. This has advantages and disadvantages.\n\n**Disadvantages:**\n- You need to set size yourself.\n\n**Advantages:**\n- You have full control over icon size.\n\nYou can change icon size by:\n- Setting \\`width\\` and \\`height\\` properties\n- Using CSS\n\n### Properties\n\nAll icon components support \\`width\\` and \\`height\\` properties.\n\nValue is a string or number.\n\nYou 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.\n\n**Examples:**\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'DraftsIcon'} height=\"1em\" />\n<${exampleComponents[0] || 'DraftsIcon'} width=\"1em\" height=\"1em\" />\n<${exampleComponents[0] || 'DraftsIcon'} height=\"24\" />\n\\`\\`\\`\n\nYou can also use the \\`size\\` property as a shorthand for setting both width and height:\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'DraftsIcon'} size=\"24\" />\n<${exampleComponents[0] || 'DraftsIcon'} size=\"1em\" />\n\\`\\`\\`\n\n### CSS Sizing\n\nYou can also control icon size via CSS:\n\n\\`\\`\\`css\n.${toCamelCase(prefix)}-icon {\n width: 1em;\n height: 1em;\n}\n\\`\\`\\`\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'DraftsIcon'} class=\"${toCamelCase(prefix)}-icon\" />\n\\`\\`\\`\n\n## Available Icons\n\nThis package contains **${iconCount}** icons:\n\n${allIconsList}\n\n## Usage Examples\n\n### Navigation Menu\n\n\\`\\`\\`html\n<nav>\n <a href=\"/\"><${exampleComponents[0] || 'Icon'} size=\"20\" class=\"nav-icon\" /> Home</a>\n <a href=\"/about\"><${exampleComponents[1] || 'Icon'} size=\"20\" class=\"nav-icon\" /> About</a>\n <a href=\"/contact\"><${exampleComponents[2] || 'Icon'} size=\"20\" class=\"nav-icon\" /> Contact</a>\n <a href=\"/settings\"><${exampleComponents[3] || 'Icon'} size=\"20\" class=\"nav-icon\" /> Settings</a>\n</nav>\n\n<style>\n nav {\n display: flex;\n gap: 1rem;\n }\n nav a {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n .nav-icon {\n color: currentColor;\n }\n</style>\n\\`\\`\\`\n\n### Custom Styling\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'Icon'}\n size=\"24\"\n class=\"icon icon-primary\"\n style=\"opacity: 0.8; transition: opacity 0.2s;\"\n/>\n\n<style>\n .icon-primary {\n color: #4a90e2;\n }\n .icon-primary:hover {\n opacity: 1;\n }\n</style>\n\\`\\`\\`\n\n### Status Indicators\n\n\\`\\`\\`html\n<div class=\"status-grid\">\n <div class=\"status-item\">\n <${exampleComponents[0] || 'Icon'} size=\"16\" color=\"#22c55e\" />\n <span>Success</span>\n </div>\n <div class=\"status-item\">\n <${exampleComponents[1] || 'Icon'} size=\"16\" color=\"#f59e0b\" />\n <span>Warning</span>\n </div>\n <div class=\"status-item\">\n <${exampleComponents[2] || 'Icon'} size=\"16\" color=\"#ef4444\" />\n <span>Error</span>\n </div>\n</div>\n\\`\\`\\`\n\n## Best Practices\n\n1. **Use Components Directly**: Import and use icon components in your templates\n \\`\\`\\`html\n <!-- Recommended -->\n <${exampleComponents[0] || 'Icon'} size=\"24\" />\n <${exampleComponents[1] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n \\`\\`\\`\n\n2. **Use CSS for Theming**: Apply consistent styling through CSS classes\n \\`\\`\\`css\n .icon {\n color: currentColor;\n opacity: 0.8;\n transition: opacity 0.2s;\n }\n\n .icon:hover {\n opacity: 1;\n }\n \\`\\`\\`\n\n \\`\\`\\`html\n <${exampleComponents[0] || 'Icon'} size=\"24\" class=\"icon\" />\n \\`\\`\\`\n\n3. **Set Appropriate Sizes**: Use \\`1em\\` for inline icons, fixed pixel sizes for standalone icons\n \\`\\`\\`html\n <!-- Inline with text -->\n <p>Click the <${exampleComponents[0] || 'Icon'} height=\"1em\" /> icon to continue</p>\n\n <!-- Standalone -->\n <${exampleComponents[0] || 'Icon'} size=\"24\" />\n \\`\\`\\`\n\n4. **Use Data Import for Advanced Use Cases**: When you need more control\n \\`\\`\\`html\n @js\n import { ${exampleIcons[0] || 'icon'} } from '@stacksjs/iconify-${prefix}'\n import { renderIcon } from '@stacksjs/iconify-core'\n global.customIcon = renderIcon(${exampleIcons[0] || 'icon'}, { size: 24 })\n @endjs\n\n {!! customIcon !!}\n \\`\\`\\`\n\n## TypeScript Support\n\nThis package includes full TypeScript support with type definitions for all icons.\n\n\\`\\`\\`typescript\nimport type { IconData } from '@stacksjs/iconify-core'\nimport { ${exampleIcons[0] || 'icon'} } from '@stacksjs/iconify-${prefix}'\n\n// Icons are typed as IconData\nconst myIcon: IconData = ${exampleIcons[0] || 'icon'}\n\\`\\`\\`\n\n## Related Packages\n\n- [\\`@stacksjs/iconify-core\\`](../iconify#installation) - Core rendering functions and utilities\n- [Iconify Integration Guide](../iconify) - Complete guide to using Iconify with stx\n- [stx Documentation](../) - Main stx documentation\n\n## License\n\n${collectionInfo.license?.title || 'MIT'}\n\n${collectionInfo.license?.url ? `See [license details](${collectionInfo.license.url}) for more information.` : ''}\n\n## Credits\n\n- **Icons**: ${collectionInfo.author?.name || 'Iconify'}${collectionInfo.author?.url ? ` ([Website](${collectionInfo.author.url}))` : ''}\n- **Iconify**: [https://iconify.design/](https://iconify.design/)\n- **Icon Set**: [View on Iconify](https://icon-sets.iconify.design/${prefix}/)\n\n## Resources\n\n- [Browse all icons in this collection](https://icon-sets.iconify.design/${prefix}/)\n- [Iconify documentation](https://iconify.design/docs/)\n- [stx iconify integration guide](../../docs/iconify.md)\n`\n}\n\n/**\n * Generate a complete icon package\n */\nexport async function generatePackage(\n prefix: string,\n outputDir: string,\n icons?: string[],\n docsDir?: string,\n): Promise<void> {\n console.log(`\\nš¦ Generating package for ${prefix}...`)\n\n // Fetch collection info\n const collections = await fetchCollections()\n const collectionInfo = collections[prefix]\n\n if (!collectionInfo) {\n throw new Error(`Collection ${prefix} not found`)\n }\n\n console.log(` Collection: ${collectionInfo.name}`)\n console.log(` Total icons: ${collectionInfo.total}`)\n\n // Fetch icons\n const collectionData = await fetchCollectionIcons(prefix, icons)\n const iconNames = Object.keys(collectionData.icons)\n\n console.log(` Generating ${iconNames.length} icons...`)\n\n // Create package directory structure\n const packageDir = join(outputDir, `iconify-${prefix}`)\n const srcDir = join(packageDir, 'src')\n\n await mkdir(srcDir, { recursive: true })\n\n // Generate icon files\n const defaultWidth = collectionData.width || 24\n const defaultHeight = collectionData.height || 24\n\n for (const iconName of iconNames) {\n const iconData = collectionData.icons[iconName]\n const converted = convertIconData(iconData, defaultWidth, defaultHeight)\n\n // Generate data file (.ts)\n const dataFile = generateIconData(iconName, converted)\n await writeFile(join(srcDir, `${iconName}.ts`), dataFile)\n\n // Generate component file (.stx) with -icon suffix for PascalCase component names\n const componentFile = generateIconComponent(iconName, converted)\n await writeFile(join(srcDir, `${iconName}-icon.stx`), componentFile)\n }\n\n // Generate index file\n const indexContent = generateIndexFile(iconNames)\n await writeFile(join(srcDir, 'index.ts'), indexContent)\n\n // Generate types file\n const typesContent = generateTypesFile(prefix)\n await writeFile(join(srcDir, 'types.ts'), typesContent)\n\n // Generate package.json\n const packageJsonContent = generatePackageJson(prefix, collectionInfo, iconNames.length)\n await writeFile(join(packageDir, 'package.json'), packageJsonContent)\n\n // Generate build file\n const buildContent = generateBuildFile(prefix)\n await writeFile(join(packageDir, 'build.ts'), buildContent)\n\n // Generate README\n const readmeContent = generateReadme(prefix, collectionInfo, iconNames.length)\n await writeFile(join(packageDir, 'README.md'), readmeContent)\n\n // Generate documentation if docsDir is provided\n if (docsDir) {\n const docsPath = join(docsDir, `iconify-${prefix}.md`)\n const docContent = generateDocumentation(prefix, collectionInfo, iconNames)\n await mkdir(docsDir, { recursive: true })\n await writeFile(docsPath, docContent)\n console.log(` ā Generated documentation in ${docsPath}`)\n }\n\n console.log(` ā Generated ${iconNames.length} icons in ${packageDir}`)\n}\n\n/**\n * Words that cannot be a binding name, so an icon named after one cannot be\n * exported under that name.\n *\n * Every reserved word, plus the ones reserved only in strict mode, because a\n * module is always strict. `eval` and `arguments` are in here for the same\n * reason: they are not reserved words, but binding either of them in strict\n * mode is a syntax error just the same.\n */\nconst RESERVED_WORDS = new Set([\n 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default',\n 'delete', 'do', 'else', 'enum', 'export', 'extends', 'false', 'finally',\n 'for', 'function', 'if', 'import', 'in', 'instanceof', 'new', 'null',\n 'return', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'var',\n 'void', 'while', 'with',\n 'let', 'static', 'yield', 'implements', 'interface', 'package', 'private',\n 'protected', 'public', 'await',\n 'eval', 'arguments',\n])\n\n/**\n * Convert kebab-case to a valid JS identifier in camelCase form.\n * Iconify allows names that start with digits (e.g. \"2\", \"3d-move\") and\n * names containing dots/slashes ā none of which are legal JS identifiers.\n * Prefix with `_` when the first char isn't [A-Za-z_$], and replace any\n * remaining illegal chars with `_` so downstream `export { default as X }`\n * always parses.\n *\n * A name that survives all of that and still lands on a reserved word gets a\n * trailing `_`. Iconify collections really do contain icons called `switch`,\n * `export`, `class` and `delete`, and each one generated\n * `export const switch: IconData` followed by `export default switch`, which\n * does not parse. The package's own prepublish build then failed, so the\n * collection never published: 95 of 218 were stuck this way, mdi among them.\n */\nexport function toCamelCase(str: string): string {\n let camel = str.replace(/-([a-z0-9])/g, g => g[1].toUpperCase())\n camel = camel.replace(/[^a-zA-Z0-9_$]/g, '_')\n if (/^[0-9]/.test(camel))\n camel = `_${camel}`\n if (RESERVED_WORDS.has(camel))\n camel = `${camel}_`\n return camel\n}\n\n/**\n * Convert kebab-case to PascalCase\n */\nexport function toPascalCase(str: string): string {\n const camel = toCamelCase(str)\n return camel.charAt(0).toUpperCase() + camel.slice(1)\n}\n",
|
|
6
6
|
"#!/usr/bin/env bun\n/* eslint-disable no-console */\nimport { join } from 'node:path'\nimport process from 'node:process'\nimport { fetchCollections, generatePackage } from './index'\n\nconst args = process.argv.slice(2)\n\nasync function main() {\n if (args.length === 0 || args.includes('--help') || args.includes('-h')) {\n console.log(`\nstx-iconify - Generate Iconify icon packages for stx\n\nUsage:\n stx-iconify <command> [options]\n\nCommands:\n list List all available icon collections\n generate <prefix> Generate an icon package for a collection\n generate <prefix> <icons...> Generate specific icons from a collection\n\nOptions:\n --output, -o <dir> Output directory for packages (default: ./packages)\n --docs, -d <dir> Generate documentation in specified directory\n --help, -h Show this help message\n\nExamples:\n stx-iconify list\n stx-iconify generate mdi\n stx-iconify generate lucide home settings user\n stx-iconify generate tabler --output ./packages\n stx-iconify generate lucide --docs ./docs/collections\n stx-iconify generate mdi --output ./packages --docs ./docs/collections\n `)\n process.exit(0)\n }\n\n const command = args[0]\n\n if (command === 'list') {\n console.log('\\nš Fetching available icon collections...\\n')\n const collections = await fetchCollections()\n\n const sortedCollections = Object.entries(collections)\n .sort((a, b) => b[1].total - a[1].total)\n\n console.log('Available collections:\\n')\n for (const [prefix, info] of sortedCollections) {\n console.log(` ${prefix.padEnd(30)} ${info.name} (${info.total} icons)`)\n }\n console.log(`\\nTotal: ${sortedCollections.length} collections`)\n }\n else if (command === 'generate') {\n const prefix = args[1]\n if (!prefix) {\n console.error('Error: Please specify a collection prefix')\n console.error('Usage: stx-iconify generate <prefix> [icons...]')\n process.exit(1)\n }\n\n let outputDir = join(process.cwd(), 'packages')\n let docsDir: string | undefined\n const icons: string[] = []\n\n // Parse remaining args\n for (let i = 2; i < args.length; i++) {\n if (args[i] === '--output' || args[i] === '-o') {\n outputDir = args[i + 1]\n i++\n }\n else if (args[i] === '--docs' || args[i] === '-d') {\n docsDir = args[i + 1]\n i++\n }\n else if (!args[i].startsWith('--') && !args[i].startsWith('-')) {\n icons.push(args[i])\n }\n }\n\n await generatePackage(prefix, outputDir, icons.length > 0 ? icons : undefined, docsDir)\n console.log('\\nā Package generated successfully!')\n console.log(`\\nTo use the package:`)\n console.log(` 1. cd packages/iconify-${prefix}`)\n console.log(` 2. bun install`)\n console.log(` 3. bun run build`)\n }\n else {\n console.error(`Unknown command: ${command}`)\n console.error('Run \"stx-iconify --help\" for usage information')\n process.exit(1)\n }\n}\n\nmain().catch((error) => {\n console.error('Error:', error.message)\n process.exit(1)\n})\n"
|
|
7
7
|
],
|
|
8
|
-
"mappings": "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
|
|
9
|
-
"debugId": "
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "9F4361B94767790964756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -54,6 +54,13 @@ export declare function generatePackage(prefix: string, outputDir: string, icons
|
|
|
54
54
|
* Prefix with `_` when the first char isn't [A-Za-z_$], and replace any
|
|
55
55
|
* remaining illegal chars with `_` so downstream `export { default as X }`
|
|
56
56
|
* always parses.
|
|
57
|
+
*
|
|
58
|
+
* A name that survives all of that and still lands on a reserved word gets a
|
|
59
|
+
* trailing `_`. Iconify collections really do contain icons called `switch`,
|
|
60
|
+
* `export`, `class` and `delete`, and each one generated
|
|
61
|
+
* `export const switch: IconData` followed by `export default switch`, which
|
|
62
|
+
* does not parse. The package's own prepublish build then failed, so the
|
|
63
|
+
* collection never published: 95 of 218 were stuck this way, mdi among them.
|
|
57
64
|
*/
|
|
58
65
|
export declare function toCamelCase(str: string): string;
|
|
59
66
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var
|
|
2
|
+
var b=import.meta.require;import{mkdir as O,writeFile as T}from"fs/promises";import{join as q}from"path";var E="https://api.iconify.design";async function k(){let G=await fetch(`${E}/collections`);if(!G.ok)throw Error(`Failed to fetch collections: ${G.statusText}`);return await G.json()}async function P(G,z){try{let Z=b.resolve("/home/runner/work/stx/stx/node_modules/@iconify/json/dist/index.cjs"),X=`${`${Z.substring(0,Z.lastIndexOf("/node_modules/@iconify/json/"))}/node_modules/@iconify/json`}/json/${G}.json`,Q=Bun.file(X);if(await Q.exists()){let $=await Q.json();if(z&&z.length>0){let B={};for(let S of z)if($.icons[S])B[S]=$.icons[S];return{...$,icons:B}}return $}}catch{}let M=z&&z.length>0?`${E}/${G}.json?icons=${z.join(",")}`:`${E}/${G}.json`,U=await fetch(M);if(!U.ok)throw Error(`Failed to fetch icons for ${G}: ${U.statusText}`);return await U.json()}function j(G,z=24,M=24){return{body:G.body,width:G.width||z,height:G.height||M,viewBox:`0 0 ${G.width||z} ${G.height||M}`}}function F(G,z){let M=V(G);return`import type { IconData } from '@stacksjs/iconify-core'
|
|
3
3
|
|
|
4
|
-
export const ${
|
|
4
|
+
export const ${M}: IconData = ${JSON.stringify(z,null,2)}
|
|
5
5
|
|
|
6
|
-
export default ${
|
|
7
|
-
`}function h(
|
|
6
|
+
export default ${M}
|
|
7
|
+
`}function h(G,z){return`<script>
|
|
8
8
|
// Get props with defaults (handle undefined)
|
|
9
9
|
const iconWidth = (typeof width !== 'undefined' ? width : null) || (typeof size !== 'undefined' ? size : null) || ${z.width||24}
|
|
10
10
|
const iconHeight = (typeof height !== 'undefined' ? height : null) || (typeof size !== 'undefined' ? size : null) || ${z.height||24}
|
|
@@ -43,17 +43,17 @@ const svg = \`<svg xmlns="http://www.w3.org/2000/svg" width="\${iconWidth}" heig
|
|
|
43
43
|
</script>
|
|
44
44
|
|
|
45
45
|
{!! svg !!}
|
|
46
|
-
`}function g(
|
|
47
|
-
${
|
|
46
|
+
`}function g(G){let z=new Set;return`// Icon data exports
|
|
47
|
+
${G.map((U)=>{let K=V(U);if(z.has(K)){let X=U.replace(/[^a-zA-Z0-9]/g,"_");if(/^[0-9]/.test(X))X=`_${X}`;K=X;let Q=2;while(z.has(K))K=`${X}_${Q}`,Q++}return z.add(K),`export { default as ${K} } from './${U}.js'`}).join(`
|
|
48
48
|
`)}
|
|
49
49
|
|
|
50
50
|
export * from './types.js'
|
|
51
|
-
`}function u(
|
|
51
|
+
`}function u(G){return`import type { IconData, IconProps } from '@stacksjs/iconify-core'
|
|
52
52
|
|
|
53
53
|
export type { IconData, IconProps }
|
|
54
54
|
|
|
55
|
-
export type ${
|
|
56
|
-
`}function N(
|
|
55
|
+
export type ${x(G)}Icon = IconData
|
|
56
|
+
`}function N(G,z,M){let U={name:`@stacksjs/iconify-${G}`,type:"module",version:"0.0.1",description:`${z.name} icons for stx from Iconify`,author:z.author?.name||"Iconify",license:z.license?.spdx||"MIT",repository:{type:"git",url:"https://github.com/stacksjs/stx.git",directory:`packages/iconify-${G}`},keywords:["iconify","icons","svg",G,z.name,"stx"],sideEffects:!1,exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./*":"./dist/*"},main:"./dist/index.js",module:"./dist/index.js",types:"./dist/index.d.ts",files:["dist"],scripts:{build:"bun build.ts",prepublishOnly:"bun build.ts"},dependencies:{"@stacksjs/iconify-core":"workspace:*"}};return JSON.stringify(U,null,2)}function D(G){return`import { existsSync, readdirSync, statSync } from 'node:fs'
|
|
57
57
|
import { dirname, join } from 'node:path'
|
|
58
58
|
import { fileURLToPath } from 'node:url'
|
|
59
59
|
import dts from 'bun-plugin-dtsx'
|
|
@@ -88,7 +88,7 @@ function isDistFresh() {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
if (isDistFresh()) {
|
|
91
|
-
console.log('\u2713 @stacksjs/iconify-${
|
|
91
|
+
console.log('\u2713 @stacksjs/iconify-${G} dist is fresh, skipping rebuild')
|
|
92
92
|
} else {
|
|
93
93
|
await Bun.build({
|
|
94
94
|
entrypoints: [join(srcDir, 'index.ts')],
|
|
@@ -100,16 +100,16 @@ if (isDistFresh()) {
|
|
|
100
100
|
sourcemap: 'external',
|
|
101
101
|
splitting: true,
|
|
102
102
|
})
|
|
103
|
-
console.log('\u2713 Built @stacksjs/iconify-${
|
|
103
|
+
console.log('\u2713 Built @stacksjs/iconify-${G}')
|
|
104
104
|
}
|
|
105
|
-
`}function d(
|
|
105
|
+
`}function d(G,z,M){return`# @stacksjs/iconify-${G}
|
|
106
106
|
|
|
107
107
|
${z.name} icons for stx from Iconify.
|
|
108
108
|
|
|
109
109
|
## Installation
|
|
110
110
|
|
|
111
111
|
\`\`\`bash
|
|
112
|
-
bun add @stacksjs/iconify-${
|
|
112
|
+
bun add @stacksjs/iconify-${G}
|
|
113
113
|
\`\`\`
|
|
114
114
|
|
|
115
115
|
## Usage
|
|
@@ -118,7 +118,7 @@ bun add @stacksjs/iconify-${E}
|
|
|
118
118
|
|
|
119
119
|
\`\`\`html
|
|
120
120
|
<script>
|
|
121
|
-
import { home } from '@stacksjs/iconify-${
|
|
121
|
+
import { home } from '@stacksjs/iconify-${G}'
|
|
122
122
|
import { renderIcon } from '@stacksjs/iconify-core'
|
|
123
123
|
|
|
124
124
|
export const homeIcon = renderIcon(home, { size: 24, color: 'currentColor' })
|
|
@@ -132,7 +132,7 @@ bun add @stacksjs/iconify-${E}
|
|
|
132
132
|
### In TypeScript/JavaScript
|
|
133
133
|
|
|
134
134
|
\`\`\`typescript
|
|
135
|
-
import { home, account, settings } from '@stacksjs/iconify-${
|
|
135
|
+
import { home, account, settings } from '@stacksjs/iconify-${G}'
|
|
136
136
|
import { renderIcon } from '@stacksjs/iconify-core'
|
|
137
137
|
|
|
138
138
|
const svg = renderIcon(home, {
|
|
@@ -143,7 +143,7 @@ const svg = renderIcon(home, {
|
|
|
143
143
|
|
|
144
144
|
## Available Icons
|
|
145
145
|
|
|
146
|
-
This package contains ${
|
|
146
|
+
This package contains ${M} icons from ${z.name}.
|
|
147
147
|
|
|
148
148
|
## License
|
|
149
149
|
|
|
@@ -155,17 +155,17 @@ ${z.license?.url?`License: ${z.license.url}`:""}
|
|
|
155
155
|
|
|
156
156
|
- Icons: ${z.author?.name||"Iconify"}${z.author?.url?` (${z.author.url})`:""}
|
|
157
157
|
- Iconify: https://iconify.design/
|
|
158
|
-
`}function C(
|
|
158
|
+
`}function C(G,z,M){let U=M.length,Z=M.slice(0,5).map(V),K=Z.map((Q)=>`${Q.charAt(0).toUpperCase()}${Q.slice(1)}Icon`),X=M.map((Q)=>{return`- \`${V(Q)}\``}).join(`
|
|
159
159
|
`);return`# ${z.name}
|
|
160
160
|
|
|
161
161
|
> ${z.name} icons for stx from Iconify
|
|
162
162
|
|
|
163
163
|
## Overview
|
|
164
164
|
|
|
165
|
-
This package provides access to ${
|
|
165
|
+
This package provides access to ${U} icons from the ${z.name} collection through the stx iconify integration.
|
|
166
166
|
|
|
167
|
-
**Collection ID:** \`${
|
|
168
|
-
**Total Icons:** ${
|
|
167
|
+
**Collection ID:** \`${G}\`
|
|
168
|
+
**Total Icons:** ${U}
|
|
169
169
|
${z.author?.name?`**Author:** ${z.author.name}${z.author.url?` ([Website](${z.author.url}))`:""}`:""}
|
|
170
170
|
${z.license?.title?`**License:** ${z.license.title}${z.license.url?` ([Details](${z.license.url}))`:""}`:""}
|
|
171
171
|
${z.category?`**Category:** ${z.category}`:""}
|
|
@@ -174,7 +174,7 @@ ${z.palette!==void 0?`**Palette:** ${z.palette?"Yes (color icons)":"No (monotone
|
|
|
174
174
|
## Installation
|
|
175
175
|
|
|
176
176
|
\`\`\`bash
|
|
177
|
-
bun add @stacksjs/iconify-${
|
|
177
|
+
bun add @stacksjs/iconify-${G}
|
|
178
178
|
\`\`\`
|
|
179
179
|
|
|
180
180
|
## Quick Start
|
|
@@ -184,30 +184,30 @@ bun add @stacksjs/iconify-${E}
|
|
|
184
184
|
Icons are available as .stx components that can be used directly in templates:
|
|
185
185
|
|
|
186
186
|
\`\`\`html
|
|
187
|
-
<${
|
|
188
|
-
<${
|
|
189
|
-
<${
|
|
187
|
+
<${K[0]||"Icon"} height="1em" />
|
|
188
|
+
<${K[0]||"Icon"} width="1em" height="1em" />
|
|
189
|
+
<${K[0]||"Icon"} height="24" />
|
|
190
190
|
\`\`\`
|
|
191
191
|
|
|
192
192
|
### With Properties
|
|
193
193
|
|
|
194
194
|
\`\`\`html
|
|
195
195
|
<!-- Using size property -->
|
|
196
|
-
<${
|
|
197
|
-
<${
|
|
196
|
+
<${K[0]||"Icon"} size="24" />
|
|
197
|
+
<${K[0]||"Icon"} size="1em" />
|
|
198
198
|
|
|
199
199
|
<!-- Using width and height -->
|
|
200
|
-
<${
|
|
200
|
+
<${K[0]||"Icon"} width="24" height="32" />
|
|
201
201
|
|
|
202
202
|
<!-- With color -->
|
|
203
|
-
<${
|
|
204
|
-
<${
|
|
203
|
+
<${K[0]||"Icon"} size="24" color="red" />
|
|
204
|
+
<${K[0]||"Icon"} size="24" color="#4a90e2" />
|
|
205
205
|
|
|
206
206
|
<!-- With CSS class -->
|
|
207
|
-
<${
|
|
207
|
+
<${K[0]||"Icon"} size="24" class="icon-primary" />
|
|
208
208
|
|
|
209
209
|
<!-- With all properties -->
|
|
210
|
-
<${
|
|
210
|
+
<${K[0]||"Icon"}
|
|
211
211
|
size="32"
|
|
212
212
|
color="#4a90e2"
|
|
213
213
|
class="my-icon"
|
|
@@ -232,9 +232,9 @@ Icons are available as .stx components that can be used directly in templates:
|
|
|
232
232
|
</head>
|
|
233
233
|
<body>
|
|
234
234
|
<div class="icon-grid">
|
|
235
|
-
<${
|
|
236
|
-
<${
|
|
237
|
-
<${
|
|
235
|
+
<${K[0]||"Icon"} size="24" />
|
|
236
|
+
<${K[1]||"Icon"} size="24" color="#4a90e2" />
|
|
237
|
+
<${K[2]||"Icon"} size="32" class="my-icon" />
|
|
238
238
|
</div>
|
|
239
239
|
</body>
|
|
240
240
|
</html>
|
|
@@ -245,10 +245,10 @@ Icons are available as .stx components that can be used directly in templates:
|
|
|
245
245
|
You can also import icon data and use the \`renderIcon\` function directly:
|
|
246
246
|
|
|
247
247
|
\`\`\`typescript
|
|
248
|
-
import { ${
|
|
248
|
+
import { ${Z.slice(0,3).join(", ")} } from '@stacksjs/iconify-${G}'
|
|
249
249
|
import { renderIcon } from '@stacksjs/iconify-core'
|
|
250
250
|
|
|
251
|
-
const svg = renderIcon(${
|
|
251
|
+
const svg = renderIcon(${Z[0]||"icon"}, { size: 24 })
|
|
252
252
|
\`\`\`
|
|
253
253
|
|
|
254
254
|
## Icon Properties
|
|
@@ -275,14 +275,14 @@ This collection contains color icons. While you can still set a color property,
|
|
|
275
275
|
|
|
276
276
|
\`\`\`html
|
|
277
277
|
<!-- Via color property -->
|
|
278
|
-
<${
|
|
279
|
-
<${
|
|
278
|
+
<${K[0]||"Icon"} size="24" color="red" />
|
|
279
|
+
<${K[0]||"Icon"} size="24" color="#4a90e2" />
|
|
280
280
|
|
|
281
281
|
<!-- Via inline style -->
|
|
282
|
-
<${
|
|
282
|
+
<${K[0]||"Icon"} size="24" style="color: green;" />
|
|
283
283
|
|
|
284
284
|
<!-- Via CSS class -->
|
|
285
|
-
<${
|
|
285
|
+
<${K[0]||"Icon"} size="24" class="text-primary" />
|
|
286
286
|
\`\`\`
|
|
287
287
|
|
|
288
288
|
${!z.palette?`\`\`\`css
|
|
@@ -321,16 +321,16 @@ You do not need to set both properties. If you set one property, the other prope
|
|
|
321
321
|
**Examples:**
|
|
322
322
|
|
|
323
323
|
\`\`\`html
|
|
324
|
-
<${
|
|
325
|
-
<${
|
|
326
|
-
<${
|
|
324
|
+
<${K[0]||"DraftsIcon"} height="1em" />
|
|
325
|
+
<${K[0]||"DraftsIcon"} width="1em" height="1em" />
|
|
326
|
+
<${K[0]||"DraftsIcon"} height="24" />
|
|
327
327
|
\`\`\`
|
|
328
328
|
|
|
329
329
|
You can also use the \`size\` property as a shorthand for setting both width and height:
|
|
330
330
|
|
|
331
331
|
\`\`\`html
|
|
332
|
-
<${
|
|
333
|
-
<${
|
|
332
|
+
<${K[0]||"DraftsIcon"} size="24" />
|
|
333
|
+
<${K[0]||"DraftsIcon"} size="1em" />
|
|
334
334
|
\`\`\`
|
|
335
335
|
|
|
336
336
|
### CSS Sizing
|
|
@@ -338,21 +338,21 @@ You can also use the \`size\` property as a shorthand for setting both width and
|
|
|
338
338
|
You can also control icon size via CSS:
|
|
339
339
|
|
|
340
340
|
\`\`\`css
|
|
341
|
-
.${
|
|
341
|
+
.${V(G)}-icon {
|
|
342
342
|
width: 1em;
|
|
343
343
|
height: 1em;
|
|
344
344
|
}
|
|
345
345
|
\`\`\`
|
|
346
346
|
|
|
347
347
|
\`\`\`html
|
|
348
|
-
<${
|
|
348
|
+
<${K[0]||"DraftsIcon"} class="${V(G)}-icon" />
|
|
349
349
|
\`\`\`
|
|
350
350
|
|
|
351
351
|
## Available Icons
|
|
352
352
|
|
|
353
|
-
This package contains **${
|
|
353
|
+
This package contains **${U}** icons:
|
|
354
354
|
|
|
355
|
-
${
|
|
355
|
+
${X}
|
|
356
356
|
|
|
357
357
|
## Usage Examples
|
|
358
358
|
|
|
@@ -360,10 +360,10 @@ ${S}
|
|
|
360
360
|
|
|
361
361
|
\`\`\`html
|
|
362
362
|
<nav>
|
|
363
|
-
<a href="/"><${
|
|
364
|
-
<a href="/about"><${
|
|
365
|
-
<a href="/contact"><${
|
|
366
|
-
<a href="/settings"><${
|
|
363
|
+
<a href="/"><${K[0]||"Icon"} size="20" class="nav-icon" /> Home</a>
|
|
364
|
+
<a href="/about"><${K[1]||"Icon"} size="20" class="nav-icon" /> About</a>
|
|
365
|
+
<a href="/contact"><${K[2]||"Icon"} size="20" class="nav-icon" /> Contact</a>
|
|
366
|
+
<a href="/settings"><${K[3]||"Icon"} size="20" class="nav-icon" /> Settings</a>
|
|
367
367
|
</nav>
|
|
368
368
|
|
|
369
369
|
<style>
|
|
@@ -385,7 +385,7 @@ ${S}
|
|
|
385
385
|
### Custom Styling
|
|
386
386
|
|
|
387
387
|
\`\`\`html
|
|
388
|
-
<${
|
|
388
|
+
<${K[0]||"Icon"}
|
|
389
389
|
size="24"
|
|
390
390
|
class="icon icon-primary"
|
|
391
391
|
style="opacity: 0.8; transition: opacity 0.2s;"
|
|
@@ -406,15 +406,15 @@ ${S}
|
|
|
406
406
|
\`\`\`html
|
|
407
407
|
<div class="status-grid">
|
|
408
408
|
<div class="status-item">
|
|
409
|
-
<${
|
|
409
|
+
<${K[0]||"Icon"} size="16" color="#22c55e" />
|
|
410
410
|
<span>Success</span>
|
|
411
411
|
</div>
|
|
412
412
|
<div class="status-item">
|
|
413
|
-
<${
|
|
413
|
+
<${K[1]||"Icon"} size="16" color="#f59e0b" />
|
|
414
414
|
<span>Warning</span>
|
|
415
415
|
</div>
|
|
416
416
|
<div class="status-item">
|
|
417
|
-
<${
|
|
417
|
+
<${K[2]||"Icon"} size="16" color="#ef4444" />
|
|
418
418
|
<span>Error</span>
|
|
419
419
|
</div>
|
|
420
420
|
</div>
|
|
@@ -425,8 +425,8 @@ ${S}
|
|
|
425
425
|
1. **Use Components Directly**: Import and use icon components in your templates
|
|
426
426
|
\`\`\`html
|
|
427
427
|
<!-- Recommended -->
|
|
428
|
-
<${
|
|
429
|
-
<${
|
|
428
|
+
<${K[0]||"Icon"} size="24" />
|
|
429
|
+
<${K[1]||"Icon"} size="24" color="#4a90e2" />
|
|
430
430
|
\`\`\`
|
|
431
431
|
|
|
432
432
|
2. **Use CSS for Theming**: Apply consistent styling through CSS classes
|
|
@@ -443,24 +443,24 @@ ${S}
|
|
|
443
443
|
\`\`\`
|
|
444
444
|
|
|
445
445
|
\`\`\`html
|
|
446
|
-
<${
|
|
446
|
+
<${K[0]||"Icon"} size="24" class="icon" />
|
|
447
447
|
\`\`\`
|
|
448
448
|
|
|
449
449
|
3. **Set Appropriate Sizes**: Use \`1em\` for inline icons, fixed pixel sizes for standalone icons
|
|
450
450
|
\`\`\`html
|
|
451
451
|
<!-- Inline with text -->
|
|
452
|
-
<p>Click the <${
|
|
452
|
+
<p>Click the <${K[0]||"Icon"} height="1em" /> icon to continue</p>
|
|
453
453
|
|
|
454
454
|
<!-- Standalone -->
|
|
455
|
-
<${
|
|
455
|
+
<${K[0]||"Icon"} size="24" />
|
|
456
456
|
\`\`\`
|
|
457
457
|
|
|
458
458
|
4. **Use Data Import for Advanced Use Cases**: When you need more control
|
|
459
459
|
\`\`\`html
|
|
460
460
|
@js
|
|
461
|
-
import { ${
|
|
461
|
+
import { ${Z[0]||"icon"} } from '@stacksjs/iconify-${G}'
|
|
462
462
|
import { renderIcon } from '@stacksjs/iconify-core'
|
|
463
|
-
global.customIcon = renderIcon(${
|
|
463
|
+
global.customIcon = renderIcon(${Z[0]||"icon"}, { size: 24 })
|
|
464
464
|
@endjs
|
|
465
465
|
|
|
466
466
|
{!! customIcon !!}
|
|
@@ -472,10 +472,10 @@ This package includes full TypeScript support with type definitions for all icon
|
|
|
472
472
|
|
|
473
473
|
\`\`\`typescript
|
|
474
474
|
import type { IconData } from '@stacksjs/iconify-core'
|
|
475
|
-
import { ${
|
|
475
|
+
import { ${Z[0]||"icon"} } from '@stacksjs/iconify-${G}'
|
|
476
476
|
|
|
477
477
|
// Icons are typed as IconData
|
|
478
|
-
const myIcon: IconData = ${
|
|
478
|
+
const myIcon: IconData = ${Z[0]||"icon"}
|
|
479
479
|
\`\`\`
|
|
480
480
|
|
|
481
481
|
## Related Packages
|
|
@@ -494,14 +494,14 @@ ${z.license?.url?`See [license details](${z.license.url}) for more information.`
|
|
|
494
494
|
|
|
495
495
|
- **Icons**: ${z.author?.name||"Iconify"}${z.author?.url?` ([Website](${z.author.url}))`:""}
|
|
496
496
|
- **Iconify**: [https://iconify.design/](https://iconify.design/)
|
|
497
|
-
- **Icon Set**: [View on Iconify](https://icon-sets.iconify.design/${
|
|
497
|
+
- **Icon Set**: [View on Iconify](https://icon-sets.iconify.design/${G}/)
|
|
498
498
|
|
|
499
499
|
## Resources
|
|
500
500
|
|
|
501
|
-
- [Browse all icons in this collection](https://icon-sets.iconify.design/${
|
|
501
|
+
- [Browse all icons in this collection](https://icon-sets.iconify.design/${G}/)
|
|
502
502
|
- [Iconify documentation](https://iconify.design/docs/)
|
|
503
503
|
- [stx iconify integration guide](../../docs/iconify.md)
|
|
504
|
-
`}async function
|
|
505
|
-
\uD83D\uDCE6 Generating package for ${
|
|
504
|
+
`}async function f(G,z,M,U){console.log(`
|
|
505
|
+
\uD83D\uDCE6 Generating package for ${G}...`);let K=(await k())[G];if(!K)throw Error(`Collection ${G} not found`);console.log(` Collection: ${K.name}`),console.log(` Total icons: ${K.total}`);let X=await P(G,M),Q=Object.keys(X.icons);console.log(` Generating ${Q.length} icons...`);let $=q(z,`iconify-${G}`),B=q($,"src");await O(B,{recursive:!0});let S=X.width||24,R=X.height||24;for(let L of Q){let A=X.icons[L],Y=j(A,S,R),_=F(L,Y);await T(q(B,`${L}.ts`),_);let w=h(L,Y);await T(q(B,`${L}-icon.stx`),w)}let v=g(Q);await T(q(B,"index.ts"),v);let y=u(G);await T(q(B,"types.ts"),y);let H=N(G,K,Q.length);await T(q($,"package.json"),H);let J=D(G);await T(q($,"build.ts"),J);let W=d(G,K,Q.length);if(await T(q($,"README.md"),W),U){let L=q(U,`iconify-${G}.md`),A=C(G,K,Q);await O(U,{recursive:!0}),await T(L,A),console.log(` \u2713 Generated documentation in ${L}`)}console.log(` \u2713 Generated ${Q.length} icons in ${$}`)}var I=new Set(["break","case","catch","class","const","continue","debugger","default","delete","do","else","enum","export","extends","false","finally","for","function","if","import","in","instanceof","new","null","return","super","switch","this","throw","true","try","typeof","var","void","while","with","let","static","yield","implements","interface","package","private","protected","public","await","eval","arguments"]);function V(G){let z=G.replace(/-([a-z0-9])/g,(M)=>M[1].toUpperCase());if(z=z.replace(/[^a-zA-Z0-9_$]/g,"_"),/^[0-9]/.test(z))z=`_${z}`;if(I.has(z))z=`${z}_`;return z}function x(G){let z=V(G);return z.charAt(0).toUpperCase()+z.slice(1)}export{x as toPascalCase,V as toCamelCase,u as generateTypesFile,d as generateReadme,N as generatePackageJson,f as generatePackage,g as generateIndexFile,F as generateIconData,h as generateIconComponent,C as generateDocumentation,D as generateBuildFile,k as fetchCollections,P as fetchCollectionIcons,j as convertIconData};
|
|
506
506
|
|
|
507
|
-
//# debugId=
|
|
507
|
+
//# debugId=C37D9DAFB4524F1764756E2164756E21
|
package/dist/index.js.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/* eslint-disable no-console, style/max-statements-per-line, indent */\nimport type { IconData } from '@stacksjs/iconify-core'\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport interface IconifyCollection {\n prefix: string\n name: string\n total: number\n author?: {\n name: string\n url?: string\n }\n license?: {\n title: string\n spdx: string\n url?: string\n }\n height?: number\n category?: string\n palette?: boolean\n}\n\nexport interface IconifyIconData {\n body: string\n width?: number\n height?: number\n left?: number\n top?: number\n rotate?: number\n hFlip?: boolean\n vFlip?: boolean\n}\n\nexport interface IconifyCollectionData {\n prefix: string\n lastModified: number\n icons: Record<string, IconifyIconData>\n aliases?: Record<string, {\n parent: string\n hFlip?: boolean\n vFlip?: boolean\n rotate?: number\n }>\n width?: number\n height?: number\n}\n\nconst ICONIFY_API = 'https://api.iconify.design'\n\n/**\n * Fetch available icon collections from Iconify\n */\nexport async function fetchCollections(): Promise<Record<string, IconifyCollection>> {\n const response = await fetch(`${ICONIFY_API}/collections`)\n if (!response.ok) {\n throw new Error(`Failed to fetch collections: ${response.statusText}`)\n }\n return await response.json()\n}\n\n/**\n * Fetch icons from a specific collection\n */\nexport async function fetchCollectionIcons(\n prefix: string,\n icons?: string[],\n): Promise<IconifyCollectionData> {\n // Try to load from @iconify/json package first\n try {\n const iconifyJsonPath = require.resolve('@iconify/json')\n // The resolve gives us the main module path, get the package directory\n const basePath = `${iconifyJsonPath.substring(0, iconifyJsonPath.lastIndexOf('/node_modules/@iconify/json/'))}/node_modules/@iconify/json`\n const jsonPath = `${basePath}/json/${prefix}.json`\n\n const file = Bun.file(jsonPath)\n if (await file.exists()) {\n const data: IconifyCollectionData = await file.json()\n\n // If specific icons are requested, filter them\n if (icons && icons.length > 0) {\n const filteredIcons: Record<string, IconifyIconData> = {}\n for (const iconName of icons) {\n if (data.icons[iconName]) {\n filteredIcons[iconName] = data.icons[iconName]\n }\n }\n return {\n ...data,\n icons: filteredIcons,\n }\n }\n\n return data\n }\n }\n catch {\n // Fall through to API if local file not found\n }\n\n // Fallback to API (only works for specific icons, not full collections)\n const url = icons && icons.length > 0\n ? `${ICONIFY_API}/${prefix}.json?icons=${icons.join(',')}`\n : `${ICONIFY_API}/${prefix}.json`\n\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`Failed to fetch icons for ${prefix}: ${response.statusText}`)\n }\n return await response.json()\n}\n\n/**\n * Convert Iconify icon data to our IconData format\n */\nexport function convertIconData(data: IconifyIconData, defaultWidth = 24, defaultHeight = 24): IconData {\n return {\n body: data.body,\n width: data.width || defaultWidth,\n height: data.height || defaultHeight,\n viewBox: `0 0 ${data.width || defaultWidth} ${data.height || defaultHeight}`,\n }\n}\n\n/**\n * Generate TypeScript icon data file\n */\nexport function generateIconData(\n name: string,\n iconData: IconData,\n): string {\n const camelCaseName = toCamelCase(name)\n\n return `import type { IconData } from '@stacksjs/iconify-core'\n\nexport const ${camelCaseName}: IconData = ${JSON.stringify(iconData, null, 2)}\n\nexport default ${camelCaseName}\n`\n}\n\n/**\n * Generate stx icon component file\n */\nexport function generateIconComponent(\n _name: string,\n iconData: IconData,\n): string {\n return `<script>\n// Get props with defaults (handle undefined)\nconst iconWidth = (typeof width !== 'undefined' ? width : null) || (typeof size !== 'undefined' ? size : null) || ${iconData.width || 24}\nconst iconHeight = (typeof height !== 'undefined' ? height : null) || (typeof size !== 'undefined' ? size : null) || ${iconData.height || 24}\nconst iconColor = typeof color !== 'undefined' ? color : 'currentColor'\nconst viewBox = \"${iconData.viewBox || `0 0 ${iconData.width || 24} ${iconData.height || 24}`}\"\n\n// Build transform\nconst transforms = []\nif (typeof hFlip !== 'undefined' && hFlip) transforms.push('scaleX(-1)')\nif (typeof vFlip !== 'undefined' && vFlip) transforms.push('scaleY(-1)')\nif (typeof rotate !== 'undefined' && rotate) {\n const rotateNum = typeof rotate === 'string' ? parseInt(rotate, 10) : rotate\n const deg = typeof rotateNum === 'number' && rotateNum < 4 ? rotateNum * 90 : rotateNum\n transforms.push(\\`rotate(\\${deg}deg)\\`)\n}\n\nconst transform = transforms.length > 0 ? transforms.join(' ') : ''\nconst transformStyle = transform ? \\`transform: \\${transform};\\` : ''\n\n// Build style\nconst styles = []\nif (transformStyle) styles.push(transformStyle)\nif (typeof style !== 'undefined' && style) styles.push(style)\n\nconst styleAttr = styles.length > 0 ? \\` style=\"\\${styles.join(' ')}\"\\` : ''\nconst classAttr = typeof className !== 'undefined' && className ? \\` class=\"\\${className}\"\\` : ''\n\n// Icon body\nlet body = ${JSON.stringify(iconData.body)}\nif (iconColor && iconColor !== 'currentColor') {\n body = body.replace(/currentColor/g, iconColor)\n}\n\n// Generate SVG\nconst svg = \\`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"\\${iconWidth}\" height=\"\\${iconHeight}\" viewBox=\"\\${viewBox}\"\\${classAttr}\\${styleAttr}>\\${body}</svg>\\`\n</script>\n\n{!! svg !!}\n`\n}\n\n/**\n * Generate index file for a collection\n */\nexport function generateIndexFile(iconNames: string[]): string {\n // toCamelCase can produce collisions across distinct kebab names\n // (e.g. \"mp-401\" and \"mp-4-01\" both ā \"mp401\"). Track used identifiers\n // and disambiguate later occurrences with a fully-sanitized form of the\n // original kebab name, then a numeric suffix as a final fallback.\n const used = new Set<string>()\n const dataExports = iconNames.map((name) => {\n const primary = toCamelCase(name)\n let id = primary\n if (used.has(id)) {\n let candidate = name.replace(/[^a-zA-Z0-9]/g, '_')\n if (/^[0-9]/.test(candidate))\n candidate = `_${candidate}`\n id = candidate\n let n = 2\n while (used.has(id)) {\n id = `${candidate}_${n}`\n n++\n }\n }\n used.add(id)\n return `export { default as ${id} } from './${name}.js'`\n }).join('\\n')\n\n return `// Icon data exports\n${dataExports}\n\nexport * from './types.js'\n`\n}\n\n/**\n * Generate types file\n */\nexport function generateTypesFile(prefix: string): string {\n return `import type { IconData, IconProps } from '@stacksjs/iconify-core'\n\nexport type { IconData, IconProps }\n\nexport type ${toPascalCase(prefix)}Icon = IconData\n`\n}\n\n/**\n * Generate package.json for a collection\n */\nexport function generatePackageJson(\n prefix: string,\n collectionInfo: IconifyCollection,\n _iconCount: number,\n): string {\n const packageJson = {\n name: `@stacksjs/iconify-${prefix}`,\n type: 'module',\n version: '0.0.1',\n description: `${collectionInfo.name} icons for stx from Iconify`,\n author: collectionInfo.author?.name || 'Iconify',\n license: collectionInfo.license?.spdx || 'MIT',\n repository: {\n type: 'git',\n url: 'https://github.com/stacksjs/stx.git',\n directory: `packages/iconify-${prefix}`,\n },\n keywords: [\n 'iconify',\n 'icons',\n 'svg',\n prefix,\n collectionInfo.name,\n 'stx',\n ],\n sideEffects: false,\n exports: {\n '.': {\n types: './dist/index.d.ts',\n import: './dist/index.js',\n },\n './*': './dist/*',\n },\n main: './dist/index.js',\n module: './dist/index.js',\n types: './dist/index.d.ts',\n files: [\n 'dist',\n ],\n scripts: {\n build: 'bun build.ts',\n prepublishOnly: 'bun build.ts',\n },\n dependencies: {\n '@stacksjs/iconify-core': 'workspace:*',\n },\n }\n\n return JSON.stringify(packageJson, null, 2)\n}\n\n/**\n * Generate build.ts file for a collection\n */\nexport function generateBuildFile(prefix: string): string {\n return `import { existsSync, readdirSync, statSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport dts from 'bun-plugin-dtsx'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst srcDir = join(__dirname, 'src')\nconst distDir = join(__dirname, 'dist')\nconst distEntry = join(distDir, 'index.js')\n\n// Skip rebuild when dist is already up to date. Makes prepublishOnly a\n// no-op when CI pre-built the package in parallel earlier in the\n// pipeline ā and a no-op for local re-runs that didn't touch src/.\n//\n// Walks src/ recursively so changes inside subdirectories (if we ever\n// add them) properly invalidate the cached dist.\nfunction isDistFresh() {\n if (!existsSync(distEntry)) return false\n const distMtime = statSync(distEntry).mtimeMs\n function newer(dir) {\n for (const name of readdirSync(dir)) {\n const p = join(dir, name)\n const s = statSync(p)\n if (s.isDirectory()) {\n if (newer(p)) return true\n } else if (s.mtimeMs > distMtime) {\n return true\n }\n }\n return false\n }\n return !newer(srcDir)\n}\n\nif (isDistFresh()) {\n console.log('ā @stacksjs/iconify-${prefix} dist is fresh, skipping rebuild')\n} else {\n await Bun.build({\n entrypoints: [join(srcDir, 'index.ts')],\n outdir: distDir,\n target: 'bun',\n format: 'esm',\n plugins: [dts()],\n minify: true,\n sourcemap: 'external',\n splitting: true,\n })\n console.log('ā Built @stacksjs/iconify-${prefix}')\n}\n`\n}\n\n/**\n * Generate README for a collection\n */\nexport function generateReadme(\n prefix: string,\n collectionInfo: IconifyCollection,\n iconCount: number,\n): string {\n return `# @stacksjs/iconify-${prefix}\n\n${collectionInfo.name} icons for stx from Iconify.\n\n## Installation\n\n\\`\\`\\`bash\nbun add @stacksjs/iconify-${prefix}\n\\`\\`\\`\n\n## Usage\n\n### In stx templates\n\n\\`\\`\\`html\n<script>\n import { home } from '@stacksjs/iconify-${prefix}'\n import { renderIcon } from '@stacksjs/iconify-core'\n\n export const homeIcon = renderIcon(home, { size: 24, color: 'currentColor' })\n</script>\n\n<div class=\"icon\">\n {!! homeIcon !!}\n</div>\n\\`\\`\\`\n\n### In TypeScript/JavaScript\n\n\\`\\`\\`typescript\nimport { home, account, settings } from '@stacksjs/iconify-${prefix}'\nimport { renderIcon } from '@stacksjs/iconify-core'\n\nconst svg = renderIcon(home, {\n size: 24,\n color: '#000000',\n})\n\\`\\`\\`\n\n## Available Icons\n\nThis package contains ${iconCount} icons from ${collectionInfo.name}.\n\n## License\n\n${collectionInfo.license?.title || 'MIT'}\n\n${collectionInfo.license?.url ? `License: ${collectionInfo.license.url}` : ''}\n\n## Credits\n\n- Icons: ${collectionInfo.author?.name || 'Iconify'}${collectionInfo.author?.url ? ` (${collectionInfo.author.url})` : ''}\n- Iconify: https://iconify.design/\n`\n}\n\n/**\n * Generate documentation file for a collection\n */\nexport function generateDocumentation(\n prefix: string,\n collectionInfo: IconifyCollection,\n iconNames: string[],\n): string {\n const iconCount = iconNames.length\n const exampleIcons = iconNames.slice(0, 5).map(toCamelCase)\n const exampleComponents = exampleIcons.map(name => `${name.charAt(0).toUpperCase()}${name.slice(1)}Icon`)\n\n // Generate full icon list\n const allIconsList = iconNames.map((name) => {\n const camelName = toCamelCase(name)\n return `- \\`${camelName}\\``\n }).join('\\n')\n\n return `# ${collectionInfo.name}\n\n> ${collectionInfo.name} icons for stx from Iconify\n\n## Overview\n\nThis package provides access to ${iconCount} icons from the ${collectionInfo.name} collection through the stx iconify integration.\n\n**Collection ID:** \\`${prefix}\\`\n**Total Icons:** ${iconCount}\n${collectionInfo.author?.name ? `**Author:** ${collectionInfo.author.name}${collectionInfo.author.url ? ` ([Website](${collectionInfo.author.url}))` : ''}` : ''}\n${collectionInfo.license?.title ? `**License:** ${collectionInfo.license.title}${collectionInfo.license.url ? ` ([Details](${collectionInfo.license.url}))` : ''}` : ''}\n${collectionInfo.category ? `**Category:** ${collectionInfo.category}` : ''}\n${collectionInfo.palette !== undefined ? `**Palette:** ${collectionInfo.palette ? 'Yes (color icons)' : 'No (monotone icons)'}` : ''}\n\n## Installation\n\n\\`\\`\\`bash\nbun add @stacksjs/iconify-${prefix}\n\\`\\`\\`\n\n## Quick Start\n\n### Component Usage (Recommended)\n\nIcons are available as .stx components that can be used directly in templates:\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'Icon'} height=\"1em\" />\n<${exampleComponents[0] || 'Icon'} width=\"1em\" height=\"1em\" />\n<${exampleComponents[0] || 'Icon'} height=\"24\" />\n\\`\\`\\`\n\n### With Properties\n\n\\`\\`\\`html\n<!-- Using size property -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" />\n<${exampleComponents[0] || 'Icon'} size=\"1em\" />\n\n<!-- Using width and height -->\n<${exampleComponents[0] || 'Icon'} width=\"24\" height=\"32\" />\n\n<!-- With color -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"red\" />\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n\n<!-- With CSS class -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" class=\"icon-primary\" />\n\n<!-- With all properties -->\n<${exampleComponents[0] || 'Icon'}\n size=\"32\"\n color=\"#4a90e2\"\n class=\"my-icon\"\n style=\"opacity: 0.8;\"\n/>\n\\`\\`\\`\n\n### In stx Templates\n\n\\`\\`\\`html\n<!DOCTYPE html>\n<html>\n<head>\n <title>Icon Demo</title>\n <style>\n .icon-grid {\n display: flex;\n gap: 1rem;\n align-items: center;\n }\n </style>\n</head>\n<body>\n <div class=\"icon-grid\">\n <${exampleComponents[0] || 'Icon'} size=\"24\" />\n <${exampleComponents[1] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n <${exampleComponents[2] || 'Icon'} size=\"32\" class=\"my-icon\" />\n </div>\n</body>\n</html>\n\\`\\`\\`\n\n### Data-Only Import\n\nYou can also import icon data and use the \\`renderIcon\\` function directly:\n\n\\`\\`\\`typescript\nimport { ${exampleIcons.slice(0, 3).join(', ')} } from '@stacksjs/iconify-${prefix}'\nimport { renderIcon } from '@stacksjs/iconify-core'\n\nconst svg = renderIcon(${exampleIcons[0] || 'icon'}, { size: 24 })\n\\`\\`\\`\n\n## Icon Properties\n\nAll icon component functions and \\`renderIcon\\` accept the following properties:\n\n| Property | Type | Default | Description |\n|----------|------|---------|-------------|\n| \\`size\\` | \\`string \\\\| number\\` | - | Icon size (sets both width and height) |\n| \\`width\\` | \\`string \\\\| number\\` | - | Icon width (overrides size) |\n| \\`height\\` | \\`string \\\\| number\\` | - | Icon height (overrides size) |\n| \\`color\\` | \\`string\\` | \\`'currentColor'\\` | Icon color (CSS color or hex) |\n| \\`hFlip\\` | \\`boolean\\` | \\`false\\` | Flip horizontally |\n| \\`vFlip\\` | \\`boolean\\` | \\`false\\` | Flip vertically |\n| \\`rotate\\` | \\`0 \\\\| 90 \\\\| 180 \\\\| 270\\` | \\`0\\` | Rotation in degrees |\n| \\`class\\` | \\`string\\` | - | Additional CSS classes |\n| \\`style\\` | \\`string\\` | - | Inline styles |\n\n## Color\n\n${collectionInfo.palette ? '### Color Icons\\n\\nThis 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:'}\n\n\\`\\`\\`html\n<!-- Via color property -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"red\" />\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n\n<!-- Via inline style -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" style=\"color: green;\" />\n\n<!-- Via CSS class -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" class=\"text-primary\" />\n\\`\\`\\`\n\n${!collectionInfo.palette\n ? `\\`\\`\\`css\n/* In your CSS */\n.text-primary {\n color: #4a90e2;\n}\n\n.icon:hover {\n color: #357abd;\n}\n\\`\\`\\``\n : ''}\n\n## Size\n\nUnlike other components, SVG + CSS components do not set icon size by default. This has advantages and disadvantages.\n\n**Disadvantages:**\n- You need to set size yourself.\n\n**Advantages:**\n- You have full control over icon size.\n\nYou can change icon size by:\n- Setting \\`width\\` and \\`height\\` properties\n- Using CSS\n\n### Properties\n\nAll icon components support \\`width\\` and \\`height\\` properties.\n\nValue is a string or number.\n\nYou 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.\n\n**Examples:**\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'DraftsIcon'} height=\"1em\" />\n<${exampleComponents[0] || 'DraftsIcon'} width=\"1em\" height=\"1em\" />\n<${exampleComponents[0] || 'DraftsIcon'} height=\"24\" />\n\\`\\`\\`\n\nYou can also use the \\`size\\` property as a shorthand for setting both width and height:\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'DraftsIcon'} size=\"24\" />\n<${exampleComponents[0] || 'DraftsIcon'} size=\"1em\" />\n\\`\\`\\`\n\n### CSS Sizing\n\nYou can also control icon size via CSS:\n\n\\`\\`\\`css\n.${toCamelCase(prefix)}-icon {\n width: 1em;\n height: 1em;\n}\n\\`\\`\\`\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'DraftsIcon'} class=\"${toCamelCase(prefix)}-icon\" />\n\\`\\`\\`\n\n## Available Icons\n\nThis package contains **${iconCount}** icons:\n\n${allIconsList}\n\n## Usage Examples\n\n### Navigation Menu\n\n\\`\\`\\`html\n<nav>\n <a href=\"/\"><${exampleComponents[0] || 'Icon'} size=\"20\" class=\"nav-icon\" /> Home</a>\n <a href=\"/about\"><${exampleComponents[1] || 'Icon'} size=\"20\" class=\"nav-icon\" /> About</a>\n <a href=\"/contact\"><${exampleComponents[2] || 'Icon'} size=\"20\" class=\"nav-icon\" /> Contact</a>\n <a href=\"/settings\"><${exampleComponents[3] || 'Icon'} size=\"20\" class=\"nav-icon\" /> Settings</a>\n</nav>\n\n<style>\n nav {\n display: flex;\n gap: 1rem;\n }\n nav a {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n .nav-icon {\n color: currentColor;\n }\n</style>\n\\`\\`\\`\n\n### Custom Styling\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'Icon'}\n size=\"24\"\n class=\"icon icon-primary\"\n style=\"opacity: 0.8; transition: opacity 0.2s;\"\n/>\n\n<style>\n .icon-primary {\n color: #4a90e2;\n }\n .icon-primary:hover {\n opacity: 1;\n }\n</style>\n\\`\\`\\`\n\n### Status Indicators\n\n\\`\\`\\`html\n<div class=\"status-grid\">\n <div class=\"status-item\">\n <${exampleComponents[0] || 'Icon'} size=\"16\" color=\"#22c55e\" />\n <span>Success</span>\n </div>\n <div class=\"status-item\">\n <${exampleComponents[1] || 'Icon'} size=\"16\" color=\"#f59e0b\" />\n <span>Warning</span>\n </div>\n <div class=\"status-item\">\n <${exampleComponents[2] || 'Icon'} size=\"16\" color=\"#ef4444\" />\n <span>Error</span>\n </div>\n</div>\n\\`\\`\\`\n\n## Best Practices\n\n1. **Use Components Directly**: Import and use icon components in your templates\n \\`\\`\\`html\n <!-- Recommended -->\n <${exampleComponents[0] || 'Icon'} size=\"24\" />\n <${exampleComponents[1] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n \\`\\`\\`\n\n2. **Use CSS for Theming**: Apply consistent styling through CSS classes\n \\`\\`\\`css\n .icon {\n color: currentColor;\n opacity: 0.8;\n transition: opacity 0.2s;\n }\n\n .icon:hover {\n opacity: 1;\n }\n \\`\\`\\`\n\n \\`\\`\\`html\n <${exampleComponents[0] || 'Icon'} size=\"24\" class=\"icon\" />\n \\`\\`\\`\n\n3. **Set Appropriate Sizes**: Use \\`1em\\` for inline icons, fixed pixel sizes for standalone icons\n \\`\\`\\`html\n <!-- Inline with text -->\n <p>Click the <${exampleComponents[0] || 'Icon'} height=\"1em\" /> icon to continue</p>\n\n <!-- Standalone -->\n <${exampleComponents[0] || 'Icon'} size=\"24\" />\n \\`\\`\\`\n\n4. **Use Data Import for Advanced Use Cases**: When you need more control\n \\`\\`\\`html\n @js\n import { ${exampleIcons[0] || 'icon'} } from '@stacksjs/iconify-${prefix}'\n import { renderIcon } from '@stacksjs/iconify-core'\n global.customIcon = renderIcon(${exampleIcons[0] || 'icon'}, { size: 24 })\n @endjs\n\n {!! customIcon !!}\n \\`\\`\\`\n\n## TypeScript Support\n\nThis package includes full TypeScript support with type definitions for all icons.\n\n\\`\\`\\`typescript\nimport type { IconData } from '@stacksjs/iconify-core'\nimport { ${exampleIcons[0] || 'icon'} } from '@stacksjs/iconify-${prefix}'\n\n// Icons are typed as IconData\nconst myIcon: IconData = ${exampleIcons[0] || 'icon'}\n\\`\\`\\`\n\n## Related Packages\n\n- [\\`@stacksjs/iconify-core\\`](../iconify#installation) - Core rendering functions and utilities\n- [Iconify Integration Guide](../iconify) - Complete guide to using Iconify with stx\n- [stx Documentation](../) - Main stx documentation\n\n## License\n\n${collectionInfo.license?.title || 'MIT'}\n\n${collectionInfo.license?.url ? `See [license details](${collectionInfo.license.url}) for more information.` : ''}\n\n## Credits\n\n- **Icons**: ${collectionInfo.author?.name || 'Iconify'}${collectionInfo.author?.url ? ` ([Website](${collectionInfo.author.url}))` : ''}\n- **Iconify**: [https://iconify.design/](https://iconify.design/)\n- **Icon Set**: [View on Iconify](https://icon-sets.iconify.design/${prefix}/)\n\n## Resources\n\n- [Browse all icons in this collection](https://icon-sets.iconify.design/${prefix}/)\n- [Iconify documentation](https://iconify.design/docs/)\n- [stx iconify integration guide](../../docs/iconify.md)\n`\n}\n\n/**\n * Generate a complete icon package\n */\nexport async function generatePackage(\n prefix: string,\n outputDir: string,\n icons?: string[],\n docsDir?: string,\n): Promise<void> {\n console.log(`\\nš¦ Generating package for ${prefix}...`)\n\n // Fetch collection info\n const collections = await fetchCollections()\n const collectionInfo = collections[prefix]\n\n if (!collectionInfo) {\n throw new Error(`Collection ${prefix} not found`)\n }\n\n console.log(` Collection: ${collectionInfo.name}`)\n console.log(` Total icons: ${collectionInfo.total}`)\n\n // Fetch icons\n const collectionData = await fetchCollectionIcons(prefix, icons)\n const iconNames = Object.keys(collectionData.icons)\n\n console.log(` Generating ${iconNames.length} icons...`)\n\n // Create package directory structure\n const packageDir = join(outputDir, `iconify-${prefix}`)\n const srcDir = join(packageDir, 'src')\n\n await mkdir(srcDir, { recursive: true })\n\n // Generate icon files\n const defaultWidth = collectionData.width || 24\n const defaultHeight = collectionData.height || 24\n\n for (const iconName of iconNames) {\n const iconData = collectionData.icons[iconName]\n const converted = convertIconData(iconData, defaultWidth, defaultHeight)\n\n // Generate data file (.ts)\n const dataFile = generateIconData(iconName, converted)\n await writeFile(join(srcDir, `${iconName}.ts`), dataFile)\n\n // Generate component file (.stx) with -icon suffix for PascalCase component names\n const componentFile = generateIconComponent(iconName, converted)\n await writeFile(join(srcDir, `${iconName}-icon.stx`), componentFile)\n }\n\n // Generate index file\n const indexContent = generateIndexFile(iconNames)\n await writeFile(join(srcDir, 'index.ts'), indexContent)\n\n // Generate types file\n const typesContent = generateTypesFile(prefix)\n await writeFile(join(srcDir, 'types.ts'), typesContent)\n\n // Generate package.json\n const packageJsonContent = generatePackageJson(prefix, collectionInfo, iconNames.length)\n await writeFile(join(packageDir, 'package.json'), packageJsonContent)\n\n // Generate build file\n const buildContent = generateBuildFile(prefix)\n await writeFile(join(packageDir, 'build.ts'), buildContent)\n\n // Generate README\n const readmeContent = generateReadme(prefix, collectionInfo, iconNames.length)\n await writeFile(join(packageDir, 'README.md'), readmeContent)\n\n // Generate documentation if docsDir is provided\n if (docsDir) {\n const docsPath = join(docsDir, `iconify-${prefix}.md`)\n const docContent = generateDocumentation(prefix, collectionInfo, iconNames)\n await mkdir(docsDir, { recursive: true })\n await writeFile(docsPath, docContent)\n console.log(` ā Generated documentation in ${docsPath}`)\n }\n\n console.log(` ā Generated ${iconNames.length} icons in ${packageDir}`)\n}\n\n/**\n * Convert kebab-case to a valid JS identifier in camelCase form.\n * Iconify allows names that start with digits (e.g. \"2\", \"3d-move\") and\n * names containing dots/slashes ā none of which are legal JS identifiers.\n * Prefix with `_` when the first char isn't [A-Za-z_$], and replace any\n * remaining illegal chars with `_` so downstream `export { default as X }`\n * always parses.\n */\nexport function toCamelCase(str: string): string {\n let camel = str.replace(/-([a-z0-9])/g, g => g[1].toUpperCase())\n camel = camel.replace(/[^a-zA-Z0-9_$]/g, '_')\n if (/^[0-9]/.test(camel))\n camel = `_${camel}`\n return camel\n}\n\n/**\n * Convert kebab-case to PascalCase\n */\nexport function toPascalCase(str: string): string {\n const camel = toCamelCase(str)\n return camel.charAt(0).toUpperCase() + camel.slice(1)\n}\n"
|
|
5
|
+
"/* eslint-disable no-console, style/max-statements-per-line, indent */\nimport type { IconData } from '@stacksjs/iconify-core'\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport interface IconifyCollection {\n prefix: string\n name: string\n total: number\n author?: {\n name: string\n url?: string\n }\n license?: {\n title: string\n spdx: string\n url?: string\n }\n height?: number\n category?: string\n palette?: boolean\n}\n\nexport interface IconifyIconData {\n body: string\n width?: number\n height?: number\n left?: number\n top?: number\n rotate?: number\n hFlip?: boolean\n vFlip?: boolean\n}\n\nexport interface IconifyCollectionData {\n prefix: string\n lastModified: number\n icons: Record<string, IconifyIconData>\n aliases?: Record<string, {\n parent: string\n hFlip?: boolean\n vFlip?: boolean\n rotate?: number\n }>\n width?: number\n height?: number\n}\n\nconst ICONIFY_API = 'https://api.iconify.design'\n\n/**\n * Fetch available icon collections from Iconify\n */\nexport async function fetchCollections(): Promise<Record<string, IconifyCollection>> {\n const response = await fetch(`${ICONIFY_API}/collections`)\n if (!response.ok) {\n throw new Error(`Failed to fetch collections: ${response.statusText}`)\n }\n return await response.json()\n}\n\n/**\n * Fetch icons from a specific collection\n */\nexport async function fetchCollectionIcons(\n prefix: string,\n icons?: string[],\n): Promise<IconifyCollectionData> {\n // Try to load from @iconify/json package first\n try {\n const iconifyJsonPath = require.resolve('@iconify/json')\n // The resolve gives us the main module path, get the package directory\n const basePath = `${iconifyJsonPath.substring(0, iconifyJsonPath.lastIndexOf('/node_modules/@iconify/json/'))}/node_modules/@iconify/json`\n const jsonPath = `${basePath}/json/${prefix}.json`\n\n const file = Bun.file(jsonPath)\n if (await file.exists()) {\n const data: IconifyCollectionData = await file.json()\n\n // If specific icons are requested, filter them\n if (icons && icons.length > 0) {\n const filteredIcons: Record<string, IconifyIconData> = {}\n for (const iconName of icons) {\n if (data.icons[iconName]) {\n filteredIcons[iconName] = data.icons[iconName]\n }\n }\n return {\n ...data,\n icons: filteredIcons,\n }\n }\n\n return data\n }\n }\n catch {\n // Fall through to API if local file not found\n }\n\n // Fallback to API (only works for specific icons, not full collections)\n const url = icons && icons.length > 0\n ? `${ICONIFY_API}/${prefix}.json?icons=${icons.join(',')}`\n : `${ICONIFY_API}/${prefix}.json`\n\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`Failed to fetch icons for ${prefix}: ${response.statusText}`)\n }\n return await response.json()\n}\n\n/**\n * Convert Iconify icon data to our IconData format\n */\nexport function convertIconData(data: IconifyIconData, defaultWidth = 24, defaultHeight = 24): IconData {\n return {\n body: data.body,\n width: data.width || defaultWidth,\n height: data.height || defaultHeight,\n viewBox: `0 0 ${data.width || defaultWidth} ${data.height || defaultHeight}`,\n }\n}\n\n/**\n * Generate TypeScript icon data file\n */\nexport function generateIconData(\n name: string,\n iconData: IconData,\n): string {\n const camelCaseName = toCamelCase(name)\n\n return `import type { IconData } from '@stacksjs/iconify-core'\n\nexport const ${camelCaseName}: IconData = ${JSON.stringify(iconData, null, 2)}\n\nexport default ${camelCaseName}\n`\n}\n\n/**\n * Generate stx icon component file\n */\nexport function generateIconComponent(\n _name: string,\n iconData: IconData,\n): string {\n return `<script>\n// Get props with defaults (handle undefined)\nconst iconWidth = (typeof width !== 'undefined' ? width : null) || (typeof size !== 'undefined' ? size : null) || ${iconData.width || 24}\nconst iconHeight = (typeof height !== 'undefined' ? height : null) || (typeof size !== 'undefined' ? size : null) || ${iconData.height || 24}\nconst iconColor = typeof color !== 'undefined' ? color : 'currentColor'\nconst viewBox = \"${iconData.viewBox || `0 0 ${iconData.width || 24} ${iconData.height || 24}`}\"\n\n// Build transform\nconst transforms = []\nif (typeof hFlip !== 'undefined' && hFlip) transforms.push('scaleX(-1)')\nif (typeof vFlip !== 'undefined' && vFlip) transforms.push('scaleY(-1)')\nif (typeof rotate !== 'undefined' && rotate) {\n const rotateNum = typeof rotate === 'string' ? parseInt(rotate, 10) : rotate\n const deg = typeof rotateNum === 'number' && rotateNum < 4 ? rotateNum * 90 : rotateNum\n transforms.push(\\`rotate(\\${deg}deg)\\`)\n}\n\nconst transform = transforms.length > 0 ? transforms.join(' ') : ''\nconst transformStyle = transform ? \\`transform: \\${transform};\\` : ''\n\n// Build style\nconst styles = []\nif (transformStyle) styles.push(transformStyle)\nif (typeof style !== 'undefined' && style) styles.push(style)\n\nconst styleAttr = styles.length > 0 ? \\` style=\"\\${styles.join(' ')}\"\\` : ''\nconst classAttr = typeof className !== 'undefined' && className ? \\` class=\"\\${className}\"\\` : ''\n\n// Icon body\nlet body = ${JSON.stringify(iconData.body)}\nif (iconColor && iconColor !== 'currentColor') {\n body = body.replace(/currentColor/g, iconColor)\n}\n\n// Generate SVG\nconst svg = \\`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"\\${iconWidth}\" height=\"\\${iconHeight}\" viewBox=\"\\${viewBox}\"\\${classAttr}\\${styleAttr}>\\${body}</svg>\\`\n</script>\n\n{!! svg !!}\n`\n}\n\n/**\n * Generate index file for a collection\n */\nexport function generateIndexFile(iconNames: string[]): string {\n // toCamelCase can produce collisions across distinct kebab names\n // (e.g. \"mp-401\" and \"mp-4-01\" both ā \"mp401\"). Track used identifiers\n // and disambiguate later occurrences with a fully-sanitized form of the\n // original kebab name, then a numeric suffix as a final fallback.\n const used = new Set<string>()\n const dataExports = iconNames.map((name) => {\n const primary = toCamelCase(name)\n let id = primary\n if (used.has(id)) {\n let candidate = name.replace(/[^a-zA-Z0-9]/g, '_')\n if (/^[0-9]/.test(candidate))\n candidate = `_${candidate}`\n id = candidate\n let n = 2\n while (used.has(id)) {\n id = `${candidate}_${n}`\n n++\n }\n }\n used.add(id)\n return `export { default as ${id} } from './${name}.js'`\n }).join('\\n')\n\n return `// Icon data exports\n${dataExports}\n\nexport * from './types.js'\n`\n}\n\n/**\n * Generate types file\n */\nexport function generateTypesFile(prefix: string): string {\n return `import type { IconData, IconProps } from '@stacksjs/iconify-core'\n\nexport type { IconData, IconProps }\n\nexport type ${toPascalCase(prefix)}Icon = IconData\n`\n}\n\n/**\n * Generate package.json for a collection\n */\nexport function generatePackageJson(\n prefix: string,\n collectionInfo: IconifyCollection,\n _iconCount: number,\n): string {\n const packageJson = {\n name: `@stacksjs/iconify-${prefix}`,\n type: 'module',\n version: '0.0.1',\n description: `${collectionInfo.name} icons for stx from Iconify`,\n author: collectionInfo.author?.name || 'Iconify',\n license: collectionInfo.license?.spdx || 'MIT',\n repository: {\n type: 'git',\n url: 'https://github.com/stacksjs/stx.git',\n directory: `packages/iconify-${prefix}`,\n },\n keywords: [\n 'iconify',\n 'icons',\n 'svg',\n prefix,\n collectionInfo.name,\n 'stx',\n ],\n sideEffects: false,\n exports: {\n '.': {\n types: './dist/index.d.ts',\n import: './dist/index.js',\n },\n './*': './dist/*',\n },\n main: './dist/index.js',\n module: './dist/index.js',\n types: './dist/index.d.ts',\n files: [\n 'dist',\n ],\n scripts: {\n build: 'bun build.ts',\n prepublishOnly: 'bun build.ts',\n },\n dependencies: {\n '@stacksjs/iconify-core': 'workspace:*',\n },\n }\n\n return JSON.stringify(packageJson, null, 2)\n}\n\n/**\n * Generate build.ts file for a collection\n */\nexport function generateBuildFile(prefix: string): string {\n return `import { existsSync, readdirSync, statSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport dts from 'bun-plugin-dtsx'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst srcDir = join(__dirname, 'src')\nconst distDir = join(__dirname, 'dist')\nconst distEntry = join(distDir, 'index.js')\n\n// Skip rebuild when dist is already up to date. Makes prepublishOnly a\n// no-op when CI pre-built the package in parallel earlier in the\n// pipeline ā and a no-op for local re-runs that didn't touch src/.\n//\n// Walks src/ recursively so changes inside subdirectories (if we ever\n// add them) properly invalidate the cached dist.\nfunction isDistFresh() {\n if (!existsSync(distEntry)) return false\n const distMtime = statSync(distEntry).mtimeMs\n function newer(dir) {\n for (const name of readdirSync(dir)) {\n const p = join(dir, name)\n const s = statSync(p)\n if (s.isDirectory()) {\n if (newer(p)) return true\n } else if (s.mtimeMs > distMtime) {\n return true\n }\n }\n return false\n }\n return !newer(srcDir)\n}\n\nif (isDistFresh()) {\n console.log('ā @stacksjs/iconify-${prefix} dist is fresh, skipping rebuild')\n} else {\n await Bun.build({\n entrypoints: [join(srcDir, 'index.ts')],\n outdir: distDir,\n target: 'bun',\n format: 'esm',\n plugins: [dts()],\n minify: true,\n sourcemap: 'external',\n splitting: true,\n })\n console.log('ā Built @stacksjs/iconify-${prefix}')\n}\n`\n}\n\n/**\n * Generate README for a collection\n */\nexport function generateReadme(\n prefix: string,\n collectionInfo: IconifyCollection,\n iconCount: number,\n): string {\n return `# @stacksjs/iconify-${prefix}\n\n${collectionInfo.name} icons for stx from Iconify.\n\n## Installation\n\n\\`\\`\\`bash\nbun add @stacksjs/iconify-${prefix}\n\\`\\`\\`\n\n## Usage\n\n### In stx templates\n\n\\`\\`\\`html\n<script>\n import { home } from '@stacksjs/iconify-${prefix}'\n import { renderIcon } from '@stacksjs/iconify-core'\n\n export const homeIcon = renderIcon(home, { size: 24, color: 'currentColor' })\n</script>\n\n<div class=\"icon\">\n {!! homeIcon !!}\n</div>\n\\`\\`\\`\n\n### In TypeScript/JavaScript\n\n\\`\\`\\`typescript\nimport { home, account, settings } from '@stacksjs/iconify-${prefix}'\nimport { renderIcon } from '@stacksjs/iconify-core'\n\nconst svg = renderIcon(home, {\n size: 24,\n color: '#000000',\n})\n\\`\\`\\`\n\n## Available Icons\n\nThis package contains ${iconCount} icons from ${collectionInfo.name}.\n\n## License\n\n${collectionInfo.license?.title || 'MIT'}\n\n${collectionInfo.license?.url ? `License: ${collectionInfo.license.url}` : ''}\n\n## Credits\n\n- Icons: ${collectionInfo.author?.name || 'Iconify'}${collectionInfo.author?.url ? ` (${collectionInfo.author.url})` : ''}\n- Iconify: https://iconify.design/\n`\n}\n\n/**\n * Generate documentation file for a collection\n */\nexport function generateDocumentation(\n prefix: string,\n collectionInfo: IconifyCollection,\n iconNames: string[],\n): string {\n const iconCount = iconNames.length\n const exampleIcons = iconNames.slice(0, 5).map(toCamelCase)\n const exampleComponents = exampleIcons.map(name => `${name.charAt(0).toUpperCase()}${name.slice(1)}Icon`)\n\n // Generate full icon list\n const allIconsList = iconNames.map((name) => {\n const camelName = toCamelCase(name)\n return `- \\`${camelName}\\``\n }).join('\\n')\n\n return `# ${collectionInfo.name}\n\n> ${collectionInfo.name} icons for stx from Iconify\n\n## Overview\n\nThis package provides access to ${iconCount} icons from the ${collectionInfo.name} collection through the stx iconify integration.\n\n**Collection ID:** \\`${prefix}\\`\n**Total Icons:** ${iconCount}\n${collectionInfo.author?.name ? `**Author:** ${collectionInfo.author.name}${collectionInfo.author.url ? ` ([Website](${collectionInfo.author.url}))` : ''}` : ''}\n${collectionInfo.license?.title ? `**License:** ${collectionInfo.license.title}${collectionInfo.license.url ? ` ([Details](${collectionInfo.license.url}))` : ''}` : ''}\n${collectionInfo.category ? `**Category:** ${collectionInfo.category}` : ''}\n${collectionInfo.palette !== undefined ? `**Palette:** ${collectionInfo.palette ? 'Yes (color icons)' : 'No (monotone icons)'}` : ''}\n\n## Installation\n\n\\`\\`\\`bash\nbun add @stacksjs/iconify-${prefix}\n\\`\\`\\`\n\n## Quick Start\n\n### Component Usage (Recommended)\n\nIcons are available as .stx components that can be used directly in templates:\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'Icon'} height=\"1em\" />\n<${exampleComponents[0] || 'Icon'} width=\"1em\" height=\"1em\" />\n<${exampleComponents[0] || 'Icon'} height=\"24\" />\n\\`\\`\\`\n\n### With Properties\n\n\\`\\`\\`html\n<!-- Using size property -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" />\n<${exampleComponents[0] || 'Icon'} size=\"1em\" />\n\n<!-- Using width and height -->\n<${exampleComponents[0] || 'Icon'} width=\"24\" height=\"32\" />\n\n<!-- With color -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"red\" />\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n\n<!-- With CSS class -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" class=\"icon-primary\" />\n\n<!-- With all properties -->\n<${exampleComponents[0] || 'Icon'}\n size=\"32\"\n color=\"#4a90e2\"\n class=\"my-icon\"\n style=\"opacity: 0.8;\"\n/>\n\\`\\`\\`\n\n### In stx Templates\n\n\\`\\`\\`html\n<!DOCTYPE html>\n<html>\n<head>\n <title>Icon Demo</title>\n <style>\n .icon-grid {\n display: flex;\n gap: 1rem;\n align-items: center;\n }\n </style>\n</head>\n<body>\n <div class=\"icon-grid\">\n <${exampleComponents[0] || 'Icon'} size=\"24\" />\n <${exampleComponents[1] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n <${exampleComponents[2] || 'Icon'} size=\"32\" class=\"my-icon\" />\n </div>\n</body>\n</html>\n\\`\\`\\`\n\n### Data-Only Import\n\nYou can also import icon data and use the \\`renderIcon\\` function directly:\n\n\\`\\`\\`typescript\nimport { ${exampleIcons.slice(0, 3).join(', ')} } from '@stacksjs/iconify-${prefix}'\nimport { renderIcon } from '@stacksjs/iconify-core'\n\nconst svg = renderIcon(${exampleIcons[0] || 'icon'}, { size: 24 })\n\\`\\`\\`\n\n## Icon Properties\n\nAll icon component functions and \\`renderIcon\\` accept the following properties:\n\n| Property | Type | Default | Description |\n|----------|------|---------|-------------|\n| \\`size\\` | \\`string \\\\| number\\` | - | Icon size (sets both width and height) |\n| \\`width\\` | \\`string \\\\| number\\` | - | Icon width (overrides size) |\n| \\`height\\` | \\`string \\\\| number\\` | - | Icon height (overrides size) |\n| \\`color\\` | \\`string\\` | \\`'currentColor'\\` | Icon color (CSS color or hex) |\n| \\`hFlip\\` | \\`boolean\\` | \\`false\\` | Flip horizontally |\n| \\`vFlip\\` | \\`boolean\\` | \\`false\\` | Flip vertically |\n| \\`rotate\\` | \\`0 \\\\| 90 \\\\| 180 \\\\| 270\\` | \\`0\\` | Rotation in degrees |\n| \\`class\\` | \\`string\\` | - | Additional CSS classes |\n| \\`style\\` | \\`string\\` | - | Inline styles |\n\n## Color\n\n${collectionInfo.palette ? '### Color Icons\\n\\nThis 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:'}\n\n\\`\\`\\`html\n<!-- Via color property -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"red\" />\n<${exampleComponents[0] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n\n<!-- Via inline style -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" style=\"color: green;\" />\n\n<!-- Via CSS class -->\n<${exampleComponents[0] || 'Icon'} size=\"24\" class=\"text-primary\" />\n\\`\\`\\`\n\n${!collectionInfo.palette\n ? `\\`\\`\\`css\n/* In your CSS */\n.text-primary {\n color: #4a90e2;\n}\n\n.icon:hover {\n color: #357abd;\n}\n\\`\\`\\``\n : ''}\n\n## Size\n\nUnlike other components, SVG + CSS components do not set icon size by default. This has advantages and disadvantages.\n\n**Disadvantages:**\n- You need to set size yourself.\n\n**Advantages:**\n- You have full control over icon size.\n\nYou can change icon size by:\n- Setting \\`width\\` and \\`height\\` properties\n- Using CSS\n\n### Properties\n\nAll icon components support \\`width\\` and \\`height\\` properties.\n\nValue is a string or number.\n\nYou 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.\n\n**Examples:**\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'DraftsIcon'} height=\"1em\" />\n<${exampleComponents[0] || 'DraftsIcon'} width=\"1em\" height=\"1em\" />\n<${exampleComponents[0] || 'DraftsIcon'} height=\"24\" />\n\\`\\`\\`\n\nYou can also use the \\`size\\` property as a shorthand for setting both width and height:\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'DraftsIcon'} size=\"24\" />\n<${exampleComponents[0] || 'DraftsIcon'} size=\"1em\" />\n\\`\\`\\`\n\n### CSS Sizing\n\nYou can also control icon size via CSS:\n\n\\`\\`\\`css\n.${toCamelCase(prefix)}-icon {\n width: 1em;\n height: 1em;\n}\n\\`\\`\\`\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'DraftsIcon'} class=\"${toCamelCase(prefix)}-icon\" />\n\\`\\`\\`\n\n## Available Icons\n\nThis package contains **${iconCount}** icons:\n\n${allIconsList}\n\n## Usage Examples\n\n### Navigation Menu\n\n\\`\\`\\`html\n<nav>\n <a href=\"/\"><${exampleComponents[0] || 'Icon'} size=\"20\" class=\"nav-icon\" /> Home</a>\n <a href=\"/about\"><${exampleComponents[1] || 'Icon'} size=\"20\" class=\"nav-icon\" /> About</a>\n <a href=\"/contact\"><${exampleComponents[2] || 'Icon'} size=\"20\" class=\"nav-icon\" /> Contact</a>\n <a href=\"/settings\"><${exampleComponents[3] || 'Icon'} size=\"20\" class=\"nav-icon\" /> Settings</a>\n</nav>\n\n<style>\n nav {\n display: flex;\n gap: 1rem;\n }\n nav a {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n .nav-icon {\n color: currentColor;\n }\n</style>\n\\`\\`\\`\n\n### Custom Styling\n\n\\`\\`\\`html\n<${exampleComponents[0] || 'Icon'}\n size=\"24\"\n class=\"icon icon-primary\"\n style=\"opacity: 0.8; transition: opacity 0.2s;\"\n/>\n\n<style>\n .icon-primary {\n color: #4a90e2;\n }\n .icon-primary:hover {\n opacity: 1;\n }\n</style>\n\\`\\`\\`\n\n### Status Indicators\n\n\\`\\`\\`html\n<div class=\"status-grid\">\n <div class=\"status-item\">\n <${exampleComponents[0] || 'Icon'} size=\"16\" color=\"#22c55e\" />\n <span>Success</span>\n </div>\n <div class=\"status-item\">\n <${exampleComponents[1] || 'Icon'} size=\"16\" color=\"#f59e0b\" />\n <span>Warning</span>\n </div>\n <div class=\"status-item\">\n <${exampleComponents[2] || 'Icon'} size=\"16\" color=\"#ef4444\" />\n <span>Error</span>\n </div>\n</div>\n\\`\\`\\`\n\n## Best Practices\n\n1. **Use Components Directly**: Import and use icon components in your templates\n \\`\\`\\`html\n <!-- Recommended -->\n <${exampleComponents[0] || 'Icon'} size=\"24\" />\n <${exampleComponents[1] || 'Icon'} size=\"24\" color=\"#4a90e2\" />\n \\`\\`\\`\n\n2. **Use CSS for Theming**: Apply consistent styling through CSS classes\n \\`\\`\\`css\n .icon {\n color: currentColor;\n opacity: 0.8;\n transition: opacity 0.2s;\n }\n\n .icon:hover {\n opacity: 1;\n }\n \\`\\`\\`\n\n \\`\\`\\`html\n <${exampleComponents[0] || 'Icon'} size=\"24\" class=\"icon\" />\n \\`\\`\\`\n\n3. **Set Appropriate Sizes**: Use \\`1em\\` for inline icons, fixed pixel sizes for standalone icons\n \\`\\`\\`html\n <!-- Inline with text -->\n <p>Click the <${exampleComponents[0] || 'Icon'} height=\"1em\" /> icon to continue</p>\n\n <!-- Standalone -->\n <${exampleComponents[0] || 'Icon'} size=\"24\" />\n \\`\\`\\`\n\n4. **Use Data Import for Advanced Use Cases**: When you need more control\n \\`\\`\\`html\n @js\n import { ${exampleIcons[0] || 'icon'} } from '@stacksjs/iconify-${prefix}'\n import { renderIcon } from '@stacksjs/iconify-core'\n global.customIcon = renderIcon(${exampleIcons[0] || 'icon'}, { size: 24 })\n @endjs\n\n {!! customIcon !!}\n \\`\\`\\`\n\n## TypeScript Support\n\nThis package includes full TypeScript support with type definitions for all icons.\n\n\\`\\`\\`typescript\nimport type { IconData } from '@stacksjs/iconify-core'\nimport { ${exampleIcons[0] || 'icon'} } from '@stacksjs/iconify-${prefix}'\n\n// Icons are typed as IconData\nconst myIcon: IconData = ${exampleIcons[0] || 'icon'}\n\\`\\`\\`\n\n## Related Packages\n\n- [\\`@stacksjs/iconify-core\\`](../iconify#installation) - Core rendering functions and utilities\n- [Iconify Integration Guide](../iconify) - Complete guide to using Iconify with stx\n- [stx Documentation](../) - Main stx documentation\n\n## License\n\n${collectionInfo.license?.title || 'MIT'}\n\n${collectionInfo.license?.url ? `See [license details](${collectionInfo.license.url}) for more information.` : ''}\n\n## Credits\n\n- **Icons**: ${collectionInfo.author?.name || 'Iconify'}${collectionInfo.author?.url ? ` ([Website](${collectionInfo.author.url}))` : ''}\n- **Iconify**: [https://iconify.design/](https://iconify.design/)\n- **Icon Set**: [View on Iconify](https://icon-sets.iconify.design/${prefix}/)\n\n## Resources\n\n- [Browse all icons in this collection](https://icon-sets.iconify.design/${prefix}/)\n- [Iconify documentation](https://iconify.design/docs/)\n- [stx iconify integration guide](../../docs/iconify.md)\n`\n}\n\n/**\n * Generate a complete icon package\n */\nexport async function generatePackage(\n prefix: string,\n outputDir: string,\n icons?: string[],\n docsDir?: string,\n): Promise<void> {\n console.log(`\\nš¦ Generating package for ${prefix}...`)\n\n // Fetch collection info\n const collections = await fetchCollections()\n const collectionInfo = collections[prefix]\n\n if (!collectionInfo) {\n throw new Error(`Collection ${prefix} not found`)\n }\n\n console.log(` Collection: ${collectionInfo.name}`)\n console.log(` Total icons: ${collectionInfo.total}`)\n\n // Fetch icons\n const collectionData = await fetchCollectionIcons(prefix, icons)\n const iconNames = Object.keys(collectionData.icons)\n\n console.log(` Generating ${iconNames.length} icons...`)\n\n // Create package directory structure\n const packageDir = join(outputDir, `iconify-${prefix}`)\n const srcDir = join(packageDir, 'src')\n\n await mkdir(srcDir, { recursive: true })\n\n // Generate icon files\n const defaultWidth = collectionData.width || 24\n const defaultHeight = collectionData.height || 24\n\n for (const iconName of iconNames) {\n const iconData = collectionData.icons[iconName]\n const converted = convertIconData(iconData, defaultWidth, defaultHeight)\n\n // Generate data file (.ts)\n const dataFile = generateIconData(iconName, converted)\n await writeFile(join(srcDir, `${iconName}.ts`), dataFile)\n\n // Generate component file (.stx) with -icon suffix for PascalCase component names\n const componentFile = generateIconComponent(iconName, converted)\n await writeFile(join(srcDir, `${iconName}-icon.stx`), componentFile)\n }\n\n // Generate index file\n const indexContent = generateIndexFile(iconNames)\n await writeFile(join(srcDir, 'index.ts'), indexContent)\n\n // Generate types file\n const typesContent = generateTypesFile(prefix)\n await writeFile(join(srcDir, 'types.ts'), typesContent)\n\n // Generate package.json\n const packageJsonContent = generatePackageJson(prefix, collectionInfo, iconNames.length)\n await writeFile(join(packageDir, 'package.json'), packageJsonContent)\n\n // Generate build file\n const buildContent = generateBuildFile(prefix)\n await writeFile(join(packageDir, 'build.ts'), buildContent)\n\n // Generate README\n const readmeContent = generateReadme(prefix, collectionInfo, iconNames.length)\n await writeFile(join(packageDir, 'README.md'), readmeContent)\n\n // Generate documentation if docsDir is provided\n if (docsDir) {\n const docsPath = join(docsDir, `iconify-${prefix}.md`)\n const docContent = generateDocumentation(prefix, collectionInfo, iconNames)\n await mkdir(docsDir, { recursive: true })\n await writeFile(docsPath, docContent)\n console.log(` ā Generated documentation in ${docsPath}`)\n }\n\n console.log(` ā Generated ${iconNames.length} icons in ${packageDir}`)\n}\n\n/**\n * Words that cannot be a binding name, so an icon named after one cannot be\n * exported under that name.\n *\n * Every reserved word, plus the ones reserved only in strict mode, because a\n * module is always strict. `eval` and `arguments` are in here for the same\n * reason: they are not reserved words, but binding either of them in strict\n * mode is a syntax error just the same.\n */\nconst RESERVED_WORDS = new Set([\n 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default',\n 'delete', 'do', 'else', 'enum', 'export', 'extends', 'false', 'finally',\n 'for', 'function', 'if', 'import', 'in', 'instanceof', 'new', 'null',\n 'return', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'var',\n 'void', 'while', 'with',\n 'let', 'static', 'yield', 'implements', 'interface', 'package', 'private',\n 'protected', 'public', 'await',\n 'eval', 'arguments',\n])\n\n/**\n * Convert kebab-case to a valid JS identifier in camelCase form.\n * Iconify allows names that start with digits (e.g. \"2\", \"3d-move\") and\n * names containing dots/slashes ā none of which are legal JS identifiers.\n * Prefix with `_` when the first char isn't [A-Za-z_$], and replace any\n * remaining illegal chars with `_` so downstream `export { default as X }`\n * always parses.\n *\n * A name that survives all of that and still lands on a reserved word gets a\n * trailing `_`. Iconify collections really do contain icons called `switch`,\n * `export`, `class` and `delete`, and each one generated\n * `export const switch: IconData` followed by `export default switch`, which\n * does not parse. The package's own prepublish build then failed, so the\n * collection never published: 95 of 218 were stuck this way, mdi among them.\n */\nexport function toCamelCase(str: string): string {\n let camel = str.replace(/-([a-z0-9])/g, g => g[1].toUpperCase())\n camel = camel.replace(/[^a-zA-Z0-9_$]/g, '_')\n if (/^[0-9]/.test(camel))\n camel = `_${camel}`\n if (RESERVED_WORDS.has(camel))\n camel = `${camel}_`\n return camel\n}\n\n/**\n * Convert kebab-case to PascalCase\n */\nexport function toPascalCase(str: string): string {\n const camel = toCamelCase(str)\n return camel.charAt(0).toUpperCase() + camel.slice(1)\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "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
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "C37D9DAFB4524F1764756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/iconify-generator",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.302",
|
|
5
5
|
"description": "Generator for Iconify icon packages",
|
|
6
6
|
"author": "Chris Breuer <chris@stacksjs.org>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -42,6 +42,6 @@
|
|
|
42
42
|
"prepublishOnly": "bun run build"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@stacksjs/iconify-core": "0.2.
|
|
45
|
+
"@stacksjs/iconify-core": "0.2.302"
|
|
46
46
|
}
|
|
47
47
|
}
|
package/src/index.ts
CHANGED
|
@@ -857,6 +857,26 @@ export async function generatePackage(
|
|
|
857
857
|
console.log(` ā Generated ${iconNames.length} icons in ${packageDir}`)
|
|
858
858
|
}
|
|
859
859
|
|
|
860
|
+
/**
|
|
861
|
+
* Words that cannot be a binding name, so an icon named after one cannot be
|
|
862
|
+
* exported under that name.
|
|
863
|
+
*
|
|
864
|
+
* Every reserved word, plus the ones reserved only in strict mode, because a
|
|
865
|
+
* module is always strict. `eval` and `arguments` are in here for the same
|
|
866
|
+
* reason: they are not reserved words, but binding either of them in strict
|
|
867
|
+
* mode is a syntax error just the same.
|
|
868
|
+
*/
|
|
869
|
+
const RESERVED_WORDS = new Set([
|
|
870
|
+
'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default',
|
|
871
|
+
'delete', 'do', 'else', 'enum', 'export', 'extends', 'false', 'finally',
|
|
872
|
+
'for', 'function', 'if', 'import', 'in', 'instanceof', 'new', 'null',
|
|
873
|
+
'return', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'var',
|
|
874
|
+
'void', 'while', 'with',
|
|
875
|
+
'let', 'static', 'yield', 'implements', 'interface', 'package', 'private',
|
|
876
|
+
'protected', 'public', 'await',
|
|
877
|
+
'eval', 'arguments',
|
|
878
|
+
])
|
|
879
|
+
|
|
860
880
|
/**
|
|
861
881
|
* Convert kebab-case to a valid JS identifier in camelCase form.
|
|
862
882
|
* Iconify allows names that start with digits (e.g. "2", "3d-move") and
|
|
@@ -864,12 +884,21 @@ export async function generatePackage(
|
|
|
864
884
|
* Prefix with `_` when the first char isn't [A-Za-z_$], and replace any
|
|
865
885
|
* remaining illegal chars with `_` so downstream `export { default as X }`
|
|
866
886
|
* always parses.
|
|
887
|
+
*
|
|
888
|
+
* A name that survives all of that and still lands on a reserved word gets a
|
|
889
|
+
* trailing `_`. Iconify collections really do contain icons called `switch`,
|
|
890
|
+
* `export`, `class` and `delete`, and each one generated
|
|
891
|
+
* `export const switch: IconData` followed by `export default switch`, which
|
|
892
|
+
* does not parse. The package's own prepublish build then failed, so the
|
|
893
|
+
* collection never published: 95 of 218 were stuck this way, mdi among them.
|
|
867
894
|
*/
|
|
868
895
|
export function toCamelCase(str: string): string {
|
|
869
896
|
let camel = str.replace(/-([a-z0-9])/g, g => g[1].toUpperCase())
|
|
870
897
|
camel = camel.replace(/[^a-zA-Z0-9_$]/g, '_')
|
|
871
898
|
if (/^[0-9]/.test(camel))
|
|
872
899
|
camel = `_${camel}`
|
|
900
|
+
if (RESERVED_WORDS.has(camel))
|
|
901
|
+
camel = `${camel}_`
|
|
873
902
|
return camel
|
|
874
903
|
}
|
|
875
904
|
|