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