vectify 2.0.5 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +12 -13
  2. package/README.zh-CN.md +12 -13
  3. package/dist/{chunk-CIKTK6HI.mjs → chunk-FS34P27H.mjs} +8 -0
  4. package/dist/{chunk-GY4VNET5.mjs → chunk-QYE23M3E.mjs} +625 -65
  5. package/dist/cli.js +676 -117
  6. package/dist/cli.mjs +3 -3
  7. package/dist/{helpers-UPZEBRGK.mjs → helpers-ZOR3OD66.mjs} +1 -1
  8. package/dist/index.d.mts +33 -2
  9. package/dist/index.d.ts +33 -2
  10. package/dist/index.js +669 -110
  11. package/dist/index.mjs +2 -2
  12. package/dist/templates/angular/component.ts.hbs +11 -2
  13. package/dist/templates/angular/createIcon.ts.hbs +11 -2
  14. package/dist/templates/astro/component.astro.hbs +12 -2
  15. package/dist/templates/astro/createIcon.astro.hbs +12 -2
  16. package/dist/templates/lit/component.js.hbs +1 -0
  17. package/dist/templates/lit/component.ts.hbs +1 -0
  18. package/dist/templates/lit/createIcon.js.hbs +12 -2
  19. package/dist/templates/lit/createIcon.ts.hbs +12 -2
  20. package/dist/templates/preact/component.jsx.hbs +1 -1
  21. package/dist/templates/preact/component.tsx.hbs +1 -1
  22. package/dist/templates/preact/createIcon.jsx.hbs +12 -3
  23. package/dist/templates/preact/createIcon.tsx.hbs +13 -3
  24. package/dist/templates/qwik/component.jsx.hbs +1 -1
  25. package/dist/templates/qwik/component.tsx.hbs +1 -1
  26. package/dist/templates/qwik/createIcon.jsx.hbs +12 -3
  27. package/dist/templates/qwik/createIcon.tsx.hbs +13 -3
  28. package/dist/templates/react/component.jsx.hbs +1 -1
  29. package/dist/templates/react/component.tsx.hbs +1 -1
  30. package/dist/templates/react/createIcon.jsx.hbs +12 -3
  31. package/dist/templates/react/createIcon.tsx.hbs +13 -3
  32. package/dist/templates/solid/component.tsx.hbs +1 -1
  33. package/dist/templates/solid/createIcon.jsx.hbs +13 -3
  34. package/dist/templates/solid/createIcon.tsx.hbs +14 -3
  35. package/dist/templates/svelte/component.js.svelte.hbs +4 -1
  36. package/dist/templates/svelte/component.ts.svelte.hbs +4 -1
  37. package/dist/templates/svelte/icon.js.svelte.hbs +23 -2
  38. package/dist/templates/svelte/icon.ts.svelte.hbs +23 -2
  39. package/dist/templates/vanilla/component.ts.hbs +1 -1
  40. package/dist/templates/vanilla/createIcon.js.hbs +12 -3
  41. package/dist/templates/vanilla/createIcon.ts.hbs +13 -3
  42. package/dist/templates/vue/component.js.vue.hbs +5 -2
  43. package/dist/templates/vue/component.ts.vue.hbs +5 -2
  44. package/dist/templates/vue/icon.js.vue.hbs +26 -2
  45. package/dist/templates/vue/icon.ts.vue.hbs +26 -2
  46. package/dist/templates/vue2/component.js.vue.hbs +4 -2
  47. package/dist/templates/vue2/component.ts.vue.hbs +5 -2
  48. package/dist/templates/vue2/icon.js.vue.hbs +25 -2
  49. package/dist/templates/vue2/icon.ts.vue.hbs +25 -2
  50. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -7,8 +7,8 @@ import {
7
7
  init,
8
8
  loadConfig,
9
9
  watch
10
- } from "./chunk-GY4VNET5.mjs";
11
- import "./chunk-CIKTK6HI.mjs";
10
+ } from "./chunk-QYE23M3E.mjs";
11
+ import "./chunk-FS34P27H.mjs";
12
12
 
13
13
  // src/types.ts
14
14
  function defineConfig(config) {
@@ -14,7 +14,7 @@ const iconNode: IconNode[] = [
14
14
  <svg
15
15
  [attr.width]="size"
16
16
  [attr.height]="size"
17
- viewBox="0 0 24 24"
17
+ [attr.viewBox]="viewBox"
18
18
  [attr.aria-hidden]="shouldHide"
19
19
  [attr.aria-label]="ariaLabel"
20
20
  [attr.role]="title || ariaLabel ? 'img' : null"
@@ -55,6 +55,7 @@ export class {{componentName}}Component {
55
55
 
56
56
  private iconNode: IconNode[] = iconNode
57
57
  private keepColors: boolean = {{keepColors}}
58
+ private viewBox: string = '{{viewBox}}'
58
59
 
59
60
  get shouldHide(): boolean {
60
61
  return this.ariaHidden !== undefined ? this.ariaHidden : (!this.title && !this.ariaLabel)
@@ -74,7 +75,15 @@ export class {{componentName}}Component {
74
75
  let cleanedAttrs: Record<string, any>
75
76
 
76
77
  if (this.keepColors) {
77
- cleanedAttrs = attrs
78
+ // Keep original colors, but use currentColor for elements without fill/stroke
79
+ cleanedAttrs = { ...attrs }
80
+ const hasFill = 'fill' in attrs
81
+ const hasStroke = 'stroke' in attrs
82
+
83
+ // If element has neither fill nor stroke, apply currentColor as fill
84
+ if (!hasFill && !hasStroke) {
85
+ cleanedAttrs.fill = this.color
86
+ }
78
87
  } else {
79
88
  // Track color attributes to determine icon type
80
89
  let hasFill = false
@@ -10,7 +10,7 @@ import type { IconNode } from 'vectify'
10
10
  <svg
11
11
  [attr.width]="size"
12
12
  [attr.height]="size"
13
- viewBox="0 0 24 24"
13
+ [attr.viewBox]="viewBox"
14
14
  [attr.aria-hidden]="shouldHide"
15
15
  [attr.aria-label]="ariaLabel"
16
16
  [attr.role]="title || ariaLabel ? 'img' : null"
@@ -50,6 +50,7 @@ export class IconBaseComponent {
50
50
  @Input() ariaHidden?: boolean
51
51
  @Input() iconNode: IconNode[] = []
52
52
  @Input() keepColors: boolean = false
53
+ @Input() viewBox: string = '0 0 24 24'
53
54
 
54
55
  get shouldHide(): boolean {
55
56
  return this.ariaHidden !== undefined ? this.ariaHidden : (!this.title && !this.ariaLabel)
@@ -69,7 +70,15 @@ export class IconBaseComponent {
69
70
  let cleanedAttrs: Record<string, any>
70
71
 
71
72
  if (this.keepColors) {
72
- cleanedAttrs = attrs
73
+ // Keep original colors, but use currentColor for elements without fill/stroke
74
+ cleanedAttrs = { ...attrs }
75
+ const hasFill = 'fill' in attrs
76
+ const hasStroke = 'stroke' in attrs
77
+
78
+ // If element has neither fill nor stroke, apply currentColor as fill
79
+ if (!hasFill && !hasStroke) {
80
+ cleanedAttrs.fill = this.color
81
+ }
73
82
  } else {
74
83
  // Track color attributes to determine icon type
75
84
  let hasFill = false
@@ -7,6 +7,7 @@ export interface Props {
7
7
  strokeWidth?: number | string
8
8
  class?: string
9
9
  title?: string
10
+ viewBox?: string
10
11
  'aria-label'?: string
11
12
  'aria-hidden'?: boolean | 'true' | 'false'
12
13
  }
@@ -21,6 +22,7 @@ const {
21
22
  strokeWidth = 2,
22
23
  class: className,
23
24
  title,
25
+ viewBox = '{{viewBox}}',
24
26
  'aria-label': ariaLabel,
25
27
  'aria-hidden': ariaHidden,
26
28
  ...props
@@ -39,7 +41,15 @@ function renderNode(node: IconNode): any {
39
41
  let cleanedAttrs: Record<string, any>
40
42
 
41
43
  if (keepColors) {
42
- cleanedAttrs = attrs
44
+ // Keep original colors, but use currentColor for elements without fill/stroke
45
+ cleanedAttrs = { ...attrs }
46
+ const hasFill = 'fill' in attrs
47
+ const hasStroke = 'stroke' in attrs
48
+
49
+ // If element has neither fill nor stroke, apply currentColor as fill
50
+ if (!hasFill && !hasStroke) {
51
+ cleanedAttrs.fill = color
52
+ }
43
53
  } else {
44
54
  // Track color attributes to determine icon type
45
55
  let hasFill = false
@@ -90,7 +100,7 @@ const processedNodes = iconNode.map(renderNode)
90
100
  <svg
91
101
  width={size}
92
102
  height={size}
93
- viewBox="0 0 24 24"
103
+ viewBox={viewBox}
94
104
  aria-hidden={shouldHide}
95
105
  aria-label={ariaLabel}
96
106
  role={title || ariaLabel ? 'img' : undefined}
@@ -7,6 +7,7 @@ export interface Props {
7
7
  strokeWidth?: number | string
8
8
  class?: string
9
9
  title?: string
10
+ viewBox?: string
10
11
  'aria-label'?: string
11
12
  'aria-hidden'?: boolean | 'true' | 'false'
12
13
  }
@@ -22,6 +23,7 @@ const {
22
23
  strokeWidth = 2,
23
24
  class: className,
24
25
  title,
26
+ viewBox = '0 0 24 24',
25
27
  'aria-label': ariaLabel,
26
28
  'aria-hidden': ariaHidden,
27
29
  iconNode,
@@ -40,7 +42,15 @@ function renderNode(node: IconNode): any {
40
42
  let cleanedAttrs: Record<string, any>
41
43
 
42
44
  if (keepColors) {
43
- cleanedAttrs = attrs
45
+ // Keep original colors, but use currentColor for elements without fill/stroke
46
+ cleanedAttrs = { ...attrs }
47
+ const hasFill = 'fill' in attrs
48
+ const hasStroke = 'stroke' in attrs
49
+
50
+ // If element has neither fill nor stroke, apply currentColor as fill
51
+ if (!hasFill && !hasStroke) {
52
+ cleanedAttrs.fill = color
53
+ }
44
54
  } else {
45
55
  // Track color attributes to determine icon type
46
56
  let hasFill = false
@@ -91,7 +101,7 @@ const processedNodes = iconNode.map(renderNode)
91
101
  <svg
92
102
  width={size}
93
103
  height={size}
94
- viewBox="0 0 24 24"
104
+ viewBox={viewBox}
95
105
  aria-hidden={shouldHide}
96
106
  aria-label={ariaLabel}
97
107
  role={title || ariaLabel ? 'img' : undefined}
@@ -9,4 +9,5 @@ export const iconNode = [
9
9
  export class {{componentName}} extends IconBase {
10
10
  iconNode = iconNode
11
11
  keepColors = {{keepColors}}
12
+ viewBox = '{{viewBox}}'
12
13
  }
@@ -10,6 +10,7 @@ export const iconNode: IconNode[] = [
10
10
  export class {{componentName}} extends IconBase {
11
11
  iconNode = iconNode
12
12
  keepColors = {{keepColors}}
13
+ viewBox = '{{viewBox}}'
13
14
  }
14
15
 
15
16
  declare global {
@@ -7,6 +7,7 @@ export class IconBase extends LitElement {
7
7
  color: { type: String },
8
8
  strokeWidth: { type: Number },
9
9
  title: { type: String },
10
+ viewBox: { type: String },
10
11
  ariaLabel: { type: String },
11
12
  ariaHidden: { type: Boolean }
12
13
  }
@@ -17,6 +18,7 @@ export class IconBase extends LitElement {
17
18
  this.color = 'currentColor'
18
19
  this.strokeWidth = 2
19
20
  this.title = ''
21
+ this.viewBox = '0 0 24 24'
20
22
  this.ariaLabel = ''
21
23
  this.ariaHidden = false
22
24
  }
@@ -34,7 +36,15 @@ export class IconBase extends LitElement {
34
36
  let cleanedAttrs
35
37
 
36
38
  if (this.keepColors) {
37
- cleanedAttrs = attrs
39
+ // Keep original colors, but use currentColor for elements without fill/stroke
40
+ cleanedAttrs = { ...attrs }
41
+ const hasFill = 'fill' in attrs
42
+ const hasStroke = 'stroke' in attrs
43
+
44
+ // If element has neither fill nor stroke, apply currentColor as fill
45
+ if (!hasFill && !hasStroke) {
46
+ cleanedAttrs.fill = this.color
47
+ }
38
48
  } else {
39
49
  // Track color attributes
40
50
  let hasFill = false
@@ -84,7 +94,7 @@ export class IconBase extends LitElement {
84
94
  <svg
85
95
  width="${this.size}"
86
96
  height="${this.size}"
87
- viewBox="0 0 24 24"
97
+ viewBox="${this.viewBox}"
88
98
  class="vectify-icon"
89
99
  aria-hidden="${shouldHide}"
90
100
  aria-label="${this.ariaLabel || undefined}"
@@ -7,6 +7,7 @@ export interface IconOptions {
7
7
  color?: string
8
8
  strokeWidth?: number | string
9
9
  title?: string
10
+ viewBox?: string
10
11
  ariaLabel?: string
11
12
  ariaHidden?: boolean
12
13
  }
@@ -16,6 +17,7 @@ export abstract class IconBase extends LitElement {
16
17
  @property({ type: String }) color = 'currentColor'
17
18
  @property({ type: Number }) strokeWidth = 2
18
19
  @property({ type: String }) title = ''
20
+ @property({ type: String }) viewBox = '0 0 24 24'
19
21
  @property({ type: String }) ariaLabel = ''
20
22
  @property({ type: Boolean }) ariaHidden = false
21
23
 
@@ -35,7 +37,15 @@ export abstract class IconBase extends LitElement {
35
37
  let cleanedAttrs: Record<string, any>
36
38
 
37
39
  if (this.keepColors) {
38
- cleanedAttrs = attrs
40
+ // Keep original colors, but use currentColor for elements without fill/stroke
41
+ cleanedAttrs = { ...attrs }
42
+ const hasFill = 'fill' in attrs
43
+ const hasStroke = 'stroke' in attrs
44
+
45
+ // If element has neither fill nor stroke, apply currentColor as fill
46
+ if (!hasFill && !hasStroke) {
47
+ cleanedAttrs.fill = this.color
48
+ }
39
49
  } else {
40
50
  // Track color attributes
41
51
  let hasFill = false
@@ -85,7 +95,7 @@ export abstract class IconBase extends LitElement {
85
95
  <svg
86
96
  width="${this.size}"
87
97
  height="${this.size}"
88
- viewBox="0 0 24 24"
98
+ viewBox="${this.viewBox}"
89
99
  class="vectify-icon"
90
100
  aria-hidden="${shouldHide}"
91
101
  aria-label="${this.ariaLabel || undefined}"
@@ -4,5 +4,5 @@ export const iconNode = [
4
4
  {{{formattedNodes}}}
5
5
  ]
6
6
 
7
- const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}})
7
+ const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}}, '{{viewBox}}')
8
8
  export default {{componentName}}
@@ -7,5 +7,5 @@ export const iconNode{{#if typescript}}: IconNode[]{{/if}} = [
7
7
  {{{formattedNodes}}}
8
8
  ]
9
9
 
10
- const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}})
10
+ const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}}, '{{viewBox}}')
11
11
  export default {{componentName}}
@@ -1,6 +1,6 @@
1
1
  import { createElement } from 'preact'
2
2
 
3
- export function createIcon(name, iconNode, keepColors = false) {
3
+ export function createIcon(name, iconNode, keepColors = false, defaultViewBox = '0 0 24 24') {
4
4
  const Icon = ({
5
5
  size = 24,
6
6
  color = 'currentColor',
@@ -8,6 +8,7 @@ export function createIcon(name, iconNode, keepColors = false) {
8
8
  class: classAttr,
9
9
  className,
10
10
  title,
11
+ viewBox = defaultViewBox,
11
12
  'aria-label': ariaLabel,
12
13
  'aria-hidden': ariaHidden,
13
14
  ref,
@@ -24,7 +25,7 @@ export function createIcon(name, iconNode, keepColors = false) {
24
25
  ref={ref}
25
26
  width={size}
26
27
  height={size}
27
- viewBox="0 0 24 24"
28
+ viewBox={viewBox}
28
29
  aria-hidden={shouldHide}
29
30
  aria-label={ariaLabel}
30
31
  role={title || ariaLabel ? 'img' : undefined}
@@ -48,7 +49,15 @@ function renderIconNode(nodes, keepColors, color, strokeWidth) {
48
49
  let cleanedAttrs
49
50
 
50
51
  if (keepColors) {
51
- cleanedAttrs = attrs
52
+ // Keep original colors, but use currentColor for elements without fill/stroke
53
+ cleanedAttrs = { ...attrs }
54
+ const hasFill = 'fill' in attrs
55
+ const hasStroke = 'stroke' in attrs
56
+
57
+ // If element has neither fill nor stroke, apply currentColor as fill
58
+ if (!hasFill && !hasStroke) {
59
+ cleanedAttrs.fill = color
60
+ }
52
61
  } else {
53
62
  // Track color attributes to determine icon type
54
63
  let hasFill = false
@@ -9,13 +9,14 @@ export interface CreateIconProps extends IconProps {
9
9
  class?: string
10
10
  className?: string
11
11
  title?: string
12
+ viewBox?: string
12
13
  'aria-label'?: string
13
14
  'aria-hidden'?: boolean | 'true' | 'false'
14
15
  ref?: any
15
16
  [key: string]: any
16
17
  }
17
18
 
18
- export function createIcon(name: string, iconNode: IconNode[], keepColors = false) {
19
+ export function createIcon(name: string, iconNode: IconNode[], keepColors = false, defaultViewBox = '0 0 24 24') {
19
20
  const Icon = ({
20
21
  size = 24,
21
22
  color = 'currentColor',
@@ -23,6 +24,7 @@ export function createIcon(name: string, iconNode: IconNode[], keepColors = fals
23
24
  class: classAttr,
24
25
  className,
25
26
  title,
27
+ viewBox = defaultViewBox,
26
28
  'aria-label': ariaLabel,
27
29
  'aria-hidden': ariaHidden,
28
30
  ref,
@@ -39,7 +41,7 @@ export function createIcon(name: string, iconNode: IconNode[], keepColors = fals
39
41
  ref={ref}
40
42
  width={size}
41
43
  height={size}
42
- viewBox="0 0 24 24"
44
+ viewBox={viewBox}
43
45
  aria-hidden={shouldHide}
44
46
  aria-label={ariaLabel}
45
47
  role={title || ariaLabel ? 'img' : undefined}
@@ -68,7 +70,15 @@ function renderIconNode(
68
70
  let cleanedAttrs: Record<string, any>
69
71
 
70
72
  if (keepColors) {
71
- cleanedAttrs = attrs
73
+ // Keep original colors, but use currentColor for elements without fill/stroke
74
+ cleanedAttrs = { ...attrs }
75
+ const hasFill = 'fill' in attrs
76
+ const hasStroke = 'stroke' in attrs
77
+
78
+ // If element has neither fill nor stroke, apply currentColor as fill
79
+ if (!hasFill && !hasStroke) {
80
+ cleanedAttrs.fill = color
81
+ }
72
82
  } else {
73
83
  // Track color attributes to determine icon type
74
84
  let hasFill = false
@@ -4,4 +4,4 @@ export const iconNode = [
4
4
  {{{formattedNodes}}}
5
5
  ]
6
6
 
7
- export const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}})
7
+ export const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}}, '{{viewBox}}')
@@ -5,4 +5,4 @@ export const iconNode: IconNode[] = [
5
5
  {{{formattedNodes}}}
6
6
  ]
7
7
 
8
- export const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}})
8
+ export const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}}, '{{viewBox}}')
@@ -1,12 +1,13 @@
1
1
  import { component$ } from '@builder.io/qwik'
2
2
 
3
- export function createIcon(name, iconNode, keepColors = false) {
3
+ export function createIcon(name, iconNode, keepColors = false, defaultViewBox = '0 0 24 24') {
4
4
  return component$(({
5
5
  size = 24,
6
6
  color = 'currentColor',
7
7
  strokeWidth = 2,
8
8
  class: className,
9
9
  title,
10
+ viewBox = defaultViewBox,
10
11
  'aria-label': ariaLabel,
11
12
  'aria-hidden': ariaHidden,
12
13
  ...props
@@ -20,7 +21,7 @@ export function createIcon(name, iconNode, keepColors = false) {
20
21
  <svg
21
22
  width={size}
22
23
  height={size}
23
- viewBox="0 0 24 24"
24
+ viewBox={viewBox}
24
25
  aria-hidden={shouldHide}
25
26
  aria-label={ariaLabel}
26
27
  role={title || ariaLabel ? 'img' : undefined}
@@ -46,7 +47,15 @@ function renderIconNode(
46
47
  let cleanedAttrs
47
48
 
48
49
  if (keepColors) {
49
- cleanedAttrs = attrs
50
+ // Keep original colors, but use currentColor for elements without fill/stroke
51
+ cleanedAttrs = { ...attrs }
52
+ const hasFill = 'fill' in attrs
53
+ const hasStroke = 'stroke' in attrs
54
+
55
+ // If element has neither fill nor stroke, apply currentColor as fill
56
+ if (!hasFill && !hasStroke) {
57
+ cleanedAttrs.fill = color
58
+ }
50
59
  } else {
51
60
  // Track color attributes to determine icon type
52
61
  let hasFill = false
@@ -7,17 +7,19 @@ export interface CreateIconProps extends IconProps, Omit<QwikIntrinsicElements['
7
7
  strokeWidth?: number | string
8
8
  class?: string
9
9
  title?: string
10
+ viewBox?: string
10
11
  'aria-label'?: string
11
12
  'aria-hidden'?: boolean | 'true' | 'false'
12
13
  }
13
14
 
14
- export function createIcon(name: string, iconNode: IconNode[], keepColors = false) {
15
+ export function createIcon(name: string, iconNode: IconNode[], keepColors = false, defaultViewBox = '0 0 24 24') {
15
16
  return component$<CreateIconProps>(({
16
17
  size = 24,
17
18
  color = 'currentColor',
18
19
  strokeWidth = 2,
19
20
  class: className,
20
21
  title,
22
+ viewBox = defaultViewBox,
21
23
  'aria-label': ariaLabel,
22
24
  'aria-hidden': ariaHidden,
23
25
  ...props
@@ -31,7 +33,7 @@ export function createIcon(name: string, iconNode: IconNode[], keepColors = fals
31
33
  <svg
32
34
  width={size}
33
35
  height={size}
34
- viewBox="0 0 24 24"
36
+ viewBox={viewBox}
35
37
  aria-hidden={shouldHide}
36
38
  aria-label={ariaLabel}
37
39
  role={title || ariaLabel ? 'img' : undefined}
@@ -57,7 +59,15 @@ function renderIconNode(
57
59
  let cleanedAttrs: Record<string, any>
58
60
 
59
61
  if (keepColors) {
60
- cleanedAttrs = attrs
62
+ // Keep original colors, but use currentColor for elements without fill/stroke
63
+ cleanedAttrs = { ...attrs }
64
+ const hasFill = 'fill' in attrs
65
+ const hasStroke = 'stroke' in attrs
66
+
67
+ // If element has neither fill nor stroke, apply currentColor as fill
68
+ if (!hasFill && !hasStroke) {
69
+ cleanedAttrs.fill = color
70
+ }
61
71
  } else {
62
72
  // Track color attributes to determine icon type
63
73
  let hasFill = false
@@ -6,5 +6,5 @@ export const iconNode = [
6
6
  {{{formattedNodes}}}
7
7
  ]
8
8
 
9
- const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}})
9
+ const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}}, '{{viewBox}}')
10
10
  export default {{componentName}}
@@ -9,5 +9,5 @@ export const iconNode{{#if typescript}}: IconNode[]{{/if}} = [
9
9
  {{{formattedNodes}}},
10
10
  ]
11
11
 
12
- const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}})
12
+ const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}}, '{{viewBox}}')
13
13
  export default {{componentName}}
@@ -2,13 +2,14 @@
2
2
 
3
3
  import { createElement, forwardRef } from 'react'
4
4
 
5
- export function createIcon(name, iconNode, keepColors = false) {
5
+ export function createIcon(name, iconNode, keepColors = false, defaultViewBox = '0 0 24 24') {
6
6
  const Icon = forwardRef(({
7
7
  size = 24,
8
8
  color = 'currentColor',
9
9
  strokeWidth = 2,
10
10
  className,
11
11
  title,
12
+ viewBox = defaultViewBox,
12
13
  'aria-label': ariaLabel,
13
14
  'aria-hidden': ariaHidden,
14
15
  ...props
@@ -25,7 +26,7 @@ export function createIcon(name, iconNode, keepColors = false) {
25
26
  ref={ref}
26
27
  width={size}
27
28
  height={size}
28
- viewBox="0 0 24 24"
29
+ viewBox={viewBox}
29
30
  aria-hidden={shouldHide}
30
31
  aria-label={ariaLabel}
31
32
  role={title || ariaLabel ? 'img' : undefined}
@@ -49,7 +50,15 @@ function renderIconNode(nodes, keepColors, color, strokeWidth) {
49
50
  let cleanedAttrs
50
51
 
51
52
  if (keepColors) {
52
- cleanedAttrs = attrs
53
+ // Keep original colors, but use currentColor for elements without fill/stroke
54
+ cleanedAttrs = { ...attrs }
55
+ const hasFill = 'fill' in attrs
56
+ const hasStroke = 'stroke' in attrs
57
+
58
+ // If element has neither fill nor stroke, apply currentColor as fill
59
+ if (!hasFill && !hasStroke) {
60
+ cleanedAttrs.fill = color
61
+ }
53
62
  } else {
54
63
  // Track color attributes to determine icon type
55
64
  let hasFill = false
@@ -10,17 +10,19 @@ export interface CreateIconProps extends IconProps, Omit<SVGProps<SVGSVGElement>
10
10
  'strokeWidth'?: number | string
11
11
  'className'?: string
12
12
  'title'?: string
13
+ 'viewBox'?: string
13
14
  'aria-label'?: string
14
15
  'aria-hidden'?: boolean | 'true' | 'false'
15
16
  }
16
17
 
17
- export function createIcon(name: string, iconNode: IconNode[], keepColors = false): ForwardRefExoticComponent<CreateIconProps & RefAttributes<SVGSVGElement>> {
18
+ export function createIcon(name: string, iconNode: IconNode[], keepColors = false, defaultViewBox = '0 0 24 24'): ForwardRefExoticComponent<CreateIconProps & RefAttributes<SVGSVGElement>> {
18
19
  const Icon = forwardRef<SVGSVGElement, CreateIconProps>(({
19
20
  size = 24,
20
21
  color = 'currentColor',
21
22
  strokeWidth = 2,
22
23
  className,
23
24
  title,
25
+ viewBox = defaultViewBox,
24
26
  'aria-label': ariaLabel,
25
27
  'aria-hidden': ariaHidden,
26
28
  ...props
@@ -37,7 +39,7 @@ export function createIcon(name: string, iconNode: IconNode[], keepColors = fals
37
39
  ref={ref}
38
40
  width={size}
39
41
  height={size}
40
- viewBox="0 0 24 24"
42
+ viewBox={viewBox}
41
43
  aria-hidden={shouldHide}
42
44
  aria-label={ariaLabel}
43
45
  role={title || ariaLabel ? 'img' : undefined}
@@ -66,7 +68,15 @@ function renderIconNode(
66
68
  let cleanedAttrs: Record<string, any>
67
69
 
68
70
  if (keepColors) {
69
- cleanedAttrs = attrs
71
+ // Keep original colors, but use currentColor for elements without fill/stroke
72
+ cleanedAttrs = { ...attrs }
73
+ const hasFill = 'fill' in attrs
74
+ const hasStroke = 'stroke' in attrs
75
+
76
+ // If element has neither fill nor stroke, apply currentColor as fill
77
+ if (!hasFill && !hasStroke) {
78
+ cleanedAttrs.fill = color
79
+ }
70
80
  }
71
81
  else {
72
82
  // Track color attributes to determine icon type
@@ -7,4 +7,4 @@ export const iconNode{{#if typescript}}: IconNode[]{{/if}} = [
7
7
  {{{formattedNodes}}}
8
8
  ]
9
9
 
10
- export const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}})
10
+ export const {{componentName}} = createIcon('{{componentName}}', iconNode, {{keepColors}}, '{{viewBox}}')
@@ -1,6 +1,6 @@
1
1
  import { splitProps } from 'solid-js'
2
2
 
3
- export function createIcon(name, iconNode, keepColors = false) {
3
+ export function createIcon(name, iconNode, keepColors = false, defaultViewBox = '0 0 24 24') {
4
4
  return (props) => {
5
5
  const [local, others] = splitProps(props, [
6
6
  'size',
@@ -8,6 +8,7 @@ export function createIcon(name, iconNode, keepColors = false) {
8
8
  'strokeWidth',
9
9
  'class',
10
10
  'title',
11
+ 'viewBox',
11
12
  'aria-label',
12
13
  'aria-hidden'
13
14
  ])
@@ -15,6 +16,7 @@ export function createIcon(name, iconNode, keepColors = false) {
15
16
  const size = () => local.size ?? 24
16
17
  const color = () => local.color ?? 'currentColor'
17
18
  const strokeWidth = () => local.strokeWidth ?? 2
19
+ const viewBox = () => local.viewBox ?? defaultViewBox
18
20
 
19
21
  // Determine if icon should be hidden from screen readers
20
22
  const shouldHide = () => local['aria-hidden'] !== undefined
@@ -29,7 +31,15 @@ export function createIcon(name, iconNode, keepColors = false) {
29
31
  let cleanedAttrs
30
32
 
31
33
  if (keepColors) {
32
- cleanedAttrs = attrs
34
+ // Keep original colors, but use currentColor for elements without fill/stroke
35
+ cleanedAttrs = { ...attrs }
36
+ const hasFill = 'fill' in attrs
37
+ const hasStroke = 'stroke' in attrs
38
+
39
+ // If element has neither fill nor stroke, apply currentColor as fill
40
+ if (!hasFill && !hasStroke) {
41
+ cleanedAttrs.fill = color()
42
+ }
33
43
  } else {
34
44
  // Track color attributes to determine icon type
35
45
  let hasFill = false
@@ -112,7 +122,7 @@ export function createIcon(name, iconNode, keepColors = false) {
112
122
  <svg
113
123
  width={size()}
114
124
  height={size()}
115
- viewBox="0 0 24 24"
125
+ viewBox={viewBox()}
116
126
  aria-hidden={shouldHide()}
117
127
  aria-label={local['aria-label']}
118
128
  role={local.title || local['aria-label'] ? 'img' : undefined}