@stacksjs/iconify-core 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +88 -0
  2. package/package.json +32 -0
  3. package/src/index.ts +141 -0
package/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # @stacksjs/iconify-core
2
+
3
+ Core utilities for using Iconify icons in stx templates.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @stacksjs/iconify-core
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ This package provides the core utilities for rendering icons. You'll typically use it alongside a specific icon collection package like `@stacksjs/iconify-lucide` or `@stacksjs/iconify-mdi`.
14
+
15
+ ```typescript
16
+ import { renderIcon } from '@stacksjs/iconify-core'
17
+ import type { IconData, IconProps } from '@stacksjs/iconify-core'
18
+
19
+ const iconData: IconData = {
20
+ body: '<path fill="currentColor" d="..."/>',
21
+ width: 24,
22
+ height: 24,
23
+ viewBox: '0 0 24 24'
24
+ }
25
+
26
+ const svg = renderIcon(iconData, {
27
+ size: 32,
28
+ color: '#4a90e2'
29
+ })
30
+ ```
31
+
32
+ ## API
33
+
34
+ ### `renderIcon(iconData: IconData, props?: IconProps): string`
35
+
36
+ Renders an icon to an SVG string.
37
+
38
+ #### Parameters
39
+
40
+ - `iconData`: Icon data object containing SVG body and dimensions
41
+ - `props`: Optional rendering options
42
+
43
+ #### Icon Props
44
+
45
+ ```typescript
46
+ interface IconProps {
47
+ size?: string | number // Icon size (width and height)
48
+ width?: string | number // Icon width
49
+ height?: string | number // Icon height
50
+ color?: string // Icon color (default: 'currentColor')
51
+ hFlip?: boolean // Flip horizontally
52
+ vFlip?: boolean // Flip vertically
53
+ rotate?: 0 | 90 | 180 | 270 // Rotation in degrees
54
+ class?: string // Additional CSS classes
55
+ style?: string // Additional inline styles
56
+ }
57
+ ```
58
+
59
+ ## Example
60
+
61
+ ```typescript
62
+ import { home } from '@stacksjs/iconify-lucide'
63
+ import { renderIcon } from '@stacksjs/iconify-core'
64
+
65
+ // Basic usage
66
+ const icon1 = renderIcon(home, { size: 24 })
67
+
68
+ // With color
69
+ const icon2 = renderIcon(home, { size: 24, color: '#ff0000' })
70
+
71
+ // With transformations
72
+ const icon3 = renderIcon(home, {
73
+ size: 24,
74
+ rotate: 90,
75
+ hFlip: true
76
+ })
77
+
78
+ // With custom classes and styles
79
+ const icon4 = renderIcon(home, {
80
+ size: 24,
81
+ class: 'my-icon',
82
+ style: 'opacity: 0.8;'
83
+ })
84
+ ```
85
+
86
+ ## License
87
+
88
+ MIT
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@stacksjs/iconify-core",
3
+ "type": "module",
4
+ "version": "0.1.3",
5
+ "description": "Core utilities for Iconify SVG icons in stx",
6
+ "author": "Chris Breuer <chris@stacksjs.org>",
7
+ "license": "MIT",
8
+ "keywords": [
9
+ "iconify",
10
+ "icons",
11
+ "svg",
12
+ "stx",
13
+ "ui"
14
+ ],
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ }
20
+ },
21
+ "main": "./dist/index.js",
22
+ "module": "./dist/index.js",
23
+ "types": "./dist/index.d.ts",
24
+ "files": [
25
+ "dist",
26
+ "src"
27
+ ],
28
+ "scripts": {
29
+ "build": "bun build.ts",
30
+ "dev": "bun build.ts --watch"
31
+ }
32
+ }
package/src/index.ts ADDED
@@ -0,0 +1,141 @@
1
+ export interface IconProps {
2
+ /**
3
+ * Icon name
4
+ */
5
+ name?: string
6
+ /**
7
+ * Icon size (width and height)
8
+ * @default "1em"
9
+ */
10
+ size?: string | number
11
+ /**
12
+ * Icon width
13
+ */
14
+ width?: string | number
15
+ /**
16
+ * Icon height
17
+ */
18
+ height?: string | number
19
+ /**
20
+ * Icon color
21
+ * @default "currentColor"
22
+ */
23
+ color?: string
24
+ /**
25
+ * Horizontal flip
26
+ */
27
+ hFlip?: boolean
28
+ /**
29
+ * Vertical flip
30
+ */
31
+ vFlip?: boolean
32
+ /**
33
+ * Rotation in degrees
34
+ */
35
+ rotate?: 0 | 90 | 180 | 270 | 1 | 2 | 3
36
+ /**
37
+ * Additional CSS classes
38
+ */
39
+ class?: string
40
+ /**
41
+ * Additional inline styles
42
+ */
43
+ style?: string
44
+ }
45
+
46
+ export interface IconData {
47
+ /**
48
+ * Icon body (SVG path data)
49
+ */
50
+ body: string
51
+ /**
52
+ * Icon width (default: 24)
53
+ */
54
+ width?: number
55
+ /**
56
+ * Icon height (default: 24)
57
+ */
58
+ height?: number
59
+ /**
60
+ * Icon viewBox
61
+ */
62
+ viewBox?: string
63
+ /**
64
+ * Whether the icon uses currentColor
65
+ */
66
+ currentColor?: boolean
67
+ }
68
+
69
+ /**
70
+ * Generate SVG string from icon data
71
+ */
72
+ export function renderIcon(iconData: IconData, props: IconProps = {}): string {
73
+ const {
74
+ size,
75
+ width: propWidth,
76
+ height: propHeight,
77
+ color = 'currentColor',
78
+ hFlip = false,
79
+ vFlip = false,
80
+ rotate = 0,
81
+ class: className = '',
82
+ style: customStyle = '',
83
+ } = props
84
+
85
+ const width = propWidth || size || iconData.width || 24
86
+ const height = propHeight || size || iconData.height || 24
87
+ const viewBox = iconData.viewBox || `0 0 ${iconData.width || 24} ${iconData.height || 24}`
88
+
89
+ // Build transform
90
+ const transforms: string[] = []
91
+ if (hFlip)
92
+ transforms.push('scaleX(-1)')
93
+ if (vFlip)
94
+ transforms.push('scaleY(-1)')
95
+ if (rotate) {
96
+ const deg = typeof rotate === 'number' && rotate < 4 ? rotate * 90 : rotate
97
+ transforms.push(`rotate(${deg}deg)`)
98
+ }
99
+
100
+ const transform = transforms.length > 0 ? transforms.join(' ') : ''
101
+ const transformStyle = transform ? `transform: ${transform};` : ''
102
+
103
+ // Build style
104
+ const styles: string[] = []
105
+ if (transformStyle)
106
+ styles.push(transformStyle)
107
+ if (customStyle)
108
+ styles.push(customStyle)
109
+
110
+ const style = styles.length > 0 ? ` style="${styles.join(' ')}"` : ''
111
+ const classAttr = className ? ` class="${className}"` : ''
112
+
113
+ // Replace currentColor in body if color is specified
114
+ let body = iconData.body
115
+ if (color && color !== 'currentColor') {
116
+ body = body.replace(/currentColor/g, color)
117
+ }
118
+
119
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="${viewBox}"${classAttr}${style}>${body}</svg>`
120
+ }
121
+
122
+ /**
123
+ * Generate icon component CSS
124
+ */
125
+ export function generateIconCSS(prefix: string): string {
126
+ return `
127
+ .icon-${prefix} {
128
+ display: inline-block;
129
+ width: 1em;
130
+ height: 1em;
131
+ vertical-align: -0.125em;
132
+ }
133
+
134
+ .icon-${prefix} svg {
135
+ width: 100%;
136
+ height: 100%;
137
+ }
138
+ `.trim()
139
+ }
140
+
141
+ export { type IconData as Icon }