vectify 2.0.5 → 2.1.0

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 (46) hide show
  1. package/dist/{chunk-GY4VNET5.mjs → chunk-5RWOYQAG.mjs} +87 -47
  2. package/dist/cli.js +87 -47
  3. package/dist/cli.mjs +1 -1
  4. package/dist/index.d.mts +1 -1
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.js +87 -47
  7. package/dist/index.mjs +1 -1
  8. package/dist/templates/angular/component.ts.hbs +11 -2
  9. package/dist/templates/angular/createIcon.ts.hbs +11 -2
  10. package/dist/templates/astro/component.astro.hbs +12 -2
  11. package/dist/templates/astro/createIcon.astro.hbs +12 -2
  12. package/dist/templates/lit/component.js.hbs +1 -0
  13. package/dist/templates/lit/component.ts.hbs +1 -0
  14. package/dist/templates/lit/createIcon.js.hbs +12 -2
  15. package/dist/templates/lit/createIcon.ts.hbs +12 -2
  16. package/dist/templates/preact/component.jsx.hbs +1 -1
  17. package/dist/templates/preact/component.tsx.hbs +1 -1
  18. package/dist/templates/preact/createIcon.jsx.hbs +12 -3
  19. package/dist/templates/preact/createIcon.tsx.hbs +13 -3
  20. package/dist/templates/qwik/component.jsx.hbs +1 -1
  21. package/dist/templates/qwik/component.tsx.hbs +1 -1
  22. package/dist/templates/qwik/createIcon.jsx.hbs +12 -3
  23. package/dist/templates/qwik/createIcon.tsx.hbs +13 -3
  24. package/dist/templates/react/component.jsx.hbs +1 -1
  25. package/dist/templates/react/component.tsx.hbs +1 -1
  26. package/dist/templates/react/createIcon.jsx.hbs +12 -3
  27. package/dist/templates/react/createIcon.tsx.hbs +13 -3
  28. package/dist/templates/solid/component.tsx.hbs +1 -1
  29. package/dist/templates/solid/createIcon.jsx.hbs +13 -3
  30. package/dist/templates/solid/createIcon.tsx.hbs +14 -3
  31. package/dist/templates/svelte/component.js.svelte.hbs +4 -1
  32. package/dist/templates/svelte/component.ts.svelte.hbs +4 -1
  33. package/dist/templates/svelte/icon.js.svelte.hbs +23 -2
  34. package/dist/templates/svelte/icon.ts.svelte.hbs +23 -2
  35. package/dist/templates/vanilla/component.ts.hbs +1 -1
  36. package/dist/templates/vanilla/createIcon.js.hbs +12 -3
  37. package/dist/templates/vanilla/createIcon.ts.hbs +13 -3
  38. package/dist/templates/vue/component.js.vue.hbs +5 -2
  39. package/dist/templates/vue/component.ts.vue.hbs +5 -2
  40. package/dist/templates/vue/icon.js.vue.hbs +26 -2
  41. package/dist/templates/vue/icon.ts.vue.hbs +26 -2
  42. package/dist/templates/vue2/component.js.vue.hbs +4 -2
  43. package/dist/templates/vue2/component.ts.vue.hbs +5 -2
  44. package/dist/templates/vue2/icon.js.vue.hbs +25 -2
  45. package/dist/templates/vue2/icon.ts.vue.hbs +25 -2
  46. package/package.json +1 -1
@@ -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}
@@ -7,12 +7,13 @@ export interface CreateIconProps {
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
  [key: string]: any
13
14
  }
14
15
 
15
- export function createIcon(name: string, iconNode: IconNode[], keepColors = false) {
16
+ export function createIcon(name: string, iconNode: IconNode[], keepColors = false, defaultViewBox = '0 0 24 24') {
16
17
  return (props: CreateIconProps): JSX.Element => {
17
18
  const [local, others] = splitProps(props, [
18
19
  'size',
@@ -20,6 +21,7 @@ export function createIcon(name: string, iconNode: IconNode[], keepColors = fals
20
21
  'strokeWidth',
21
22
  'class',
22
23
  'title',
24
+ 'viewBox',
23
25
  'aria-label',
24
26
  'aria-hidden'
25
27
  ])
@@ -27,6 +29,7 @@ export function createIcon(name: string, iconNode: IconNode[], keepColors = fals
27
29
  const size = () => local.size ?? 24
28
30
  const color = () => local.color ?? 'currentColor'
29
31
  const strokeWidth = () => local.strokeWidth ?? 2
32
+ const viewBox = () => local.viewBox ?? defaultViewBox
30
33
 
31
34
  // Determine if icon should be hidden from screen readers
32
35
  const shouldHide = () => local['aria-hidden'] !== undefined
@@ -41,7 +44,15 @@ export function createIcon(name: string, iconNode: IconNode[], keepColors = fals
41
44
  let cleanedAttrs: Record<string, any>
42
45
 
43
46
  if (keepColors) {
44
- cleanedAttrs = attrs
47
+ // Keep original colors, but use currentColor for elements without fill/stroke
48
+ cleanedAttrs = { ...attrs }
49
+ const hasFill = 'fill' in attrs
50
+ const hasStroke = 'stroke' in attrs
51
+
52
+ // If element has neither fill nor stroke, apply currentColor as fill
53
+ if (!hasFill && !hasStroke) {
54
+ cleanedAttrs.fill = color()
55
+ }
45
56
  } else {
46
57
  // Track color attributes to determine icon type
47
58
  let hasFill = false
@@ -124,7 +135,7 @@ export function createIcon(name: string, iconNode: IconNode[], keepColors = fals
124
135
  <svg
125
136
  width={size()}
126
137
  height={size()}
127
- viewBox="0 0 24 24"
138
+ viewBox={viewBox()}
128
139
  aria-hidden={shouldHide()}
129
140
  aria-label={local['aria-label']}
130
141
  role={local.title || local['aria-label'] ? 'img' : undefined}
@@ -4,6 +4,9 @@
4
4
  const iconNode = [
5
5
  {{{formattedNodes}}}
6
6
  ]
7
+
8
+ const keepColors = {{keepColors}}
9
+ const viewBox = '{{viewBox}}'
7
10
  </script>
8
11
 
9
- <Icon {iconNode} {...$$restProps} />
12
+ <Icon {iconNode} {keepColors} {viewBox} {...$$restProps} />
@@ -5,6 +5,9 @@
5
5
  const iconNode: IconNode[] = [
6
6
  {{{formattedNodes}}}
7
7
  ]
8
+
9
+ const keepColors = {{keepColors}}
10
+ const viewBox = '{{viewBox}}'
8
11
  </script>
9
12
 
10
- <Icon {iconNode} {...$$restProps} />
13
+ <Icon {iconNode} {keepColors} {viewBox} {...$$restProps} />
@@ -10,6 +10,7 @@
10
10
  export let ariaLabel = ''
11
11
  export let ariaHidden = undefined
12
12
  export let keepColors = false
13
+ export let viewBox = '0 0 24 24'
13
14
 
14
15
  let svgElement
15
16
 
@@ -20,7 +21,27 @@
20
21
  $: shouldHide = ariaHidden !== undefined ? ariaHidden : (!title && !ariaLabel)
21
22
 
22
23
  // Clean icon node to apply color
23
- $: cleanedIconNode = keepColors ? iconNode : cleanIconNodes(iconNode, color, strokeWidth)
24
+ $: cleanedIconNode = keepColors ? cleanIconNodesKeepColors(iconNode, color) : cleanIconNodes(iconNode, color, strokeWidth)
25
+
26
+ function cleanIconNodesKeepColors(nodes, color) {
27
+ return nodes.map(node => {
28
+ const [type, attrs, children] = node
29
+
30
+ const cleanedAttrs = { ...attrs }
31
+
32
+ // For elements without fill or stroke, use currentColor
33
+ const hasFill = 'fill' in attrs
34
+ const hasStroke = 'stroke' in attrs
35
+
36
+ if (!hasFill && !hasStroke) {
37
+ cleanedAttrs.fill = color
38
+ }
39
+
40
+ const cleanedChildren = children ? cleanIconNodesKeepColors(children, color) : undefined
41
+
42
+ return cleanedChildren ? [type, cleanedAttrs, cleanedChildren] : [type, cleanedAttrs]
43
+ })
44
+ }
24
45
 
25
46
  function cleanIconNodes(nodes, color, strokeWidth) {
26
47
  return nodes.map(node => {
@@ -110,7 +131,7 @@
110
131
  bind:this={svgElement}
111
132
  width={size}
112
133
  height={size}
113
- viewBox="0 0 24 24"
134
+ viewBox={viewBox}
114
135
  aria-hidden={shouldHide}
115
136
  aria-label={ariaLabel || undefined}
116
137
  role={title || ariaLabel ? 'img' : undefined}
@@ -11,6 +11,7 @@
11
11
  export let ariaLabel: string = ''
12
12
  export let ariaHidden: boolean | 'true' | 'false' | undefined = undefined
13
13
  export let keepColors: boolean = false
14
+ export let viewBox: string = '0 0 24 24'
14
15
 
15
16
  let svgElement: SVGSVGElement
16
17
 
@@ -21,7 +22,27 @@
21
22
  $: shouldHide = ariaHidden !== undefined ? ariaHidden : (!title && !ariaLabel)
22
23
 
23
24
  // Clean icon node to apply color
24
- $: cleanedIconNode = keepColors ? iconNode : cleanIconNodes(iconNode, color, strokeWidth)
25
+ $: cleanedIconNode = keepColors ? cleanIconNodesKeepColors(iconNode, color) : cleanIconNodes(iconNode, color, strokeWidth)
26
+
27
+ function cleanIconNodesKeepColors(nodes: IconNode[], color: string): IconNode[] {
28
+ return nodes.map(node => {
29
+ const [type, attrs, children] = node
30
+
31
+ const cleanedAttrs: Record<string, any> = { ...attrs }
32
+
33
+ // For elements without fill or stroke, use currentColor
34
+ const hasFill = 'fill' in attrs
35
+ const hasStroke = 'stroke' in attrs
36
+
37
+ if (!hasFill && !hasStroke) {
38
+ cleanedAttrs.fill = color
39
+ }
40
+
41
+ const cleanedChildren = children ? cleanIconNodesKeepColors(children, color) : undefined
42
+
43
+ return cleanedChildren ? [type, cleanedAttrs, cleanedChildren] : [type, cleanedAttrs]
44
+ }) as IconNode[]
45
+ }
25
46
 
26
47
  function cleanIconNodes(nodes: IconNode[], color: string, strokeWidth: number | string): IconNode[] {
27
48
  return nodes.map(node => {
@@ -111,7 +132,7 @@
111
132
  bind:this={svgElement}
112
133
  width={size}
113
134
  height={size}
114
- viewBox="0 0 24 24"
135
+ viewBox={viewBox}
115
136
  aria-hidden={shouldHide}
116
137
  aria-label={ariaLabel || undefined}
117
138
  role={title || ariaLabel ? 'img' : undefined}
@@ -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,4 +1,4 @@
1
- export function createIcon(name, iconNode, keepColors = false) {
1
+ export function createIcon(name, iconNode, keepColors = false, defaultViewBox = '0 0 24 24') {
2
2
  return (options = {}) => {
3
3
  const {
4
4
  size = 24,
@@ -6,6 +6,7 @@ export function createIcon(name, iconNode, keepColors = false) {
6
6
  strokeWidth = 2,
7
7
  className = '',
8
8
  title,
9
+ viewBox = defaultViewBox,
9
10
  ariaLabel,
10
11
  ariaHidden,
11
12
  ...attrs
@@ -14,7 +15,7 @@ export function createIcon(name, iconNode, keepColors = false) {
14
15
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
15
16
  svg.setAttribute('width', String(size))
16
17
  svg.setAttribute('height', String(size))
17
- svg.setAttribute('viewBox', '0 0 24 24')
18
+ svg.setAttribute('viewBox', viewBox)
18
19
  svg.setAttribute('class', className ? `vectify-icon ${className}` : 'vectify-icon')
19
20
 
20
21
  // Accessibility
@@ -49,7 +50,15 @@ export function createIcon(name, iconNode, keepColors = false) {
49
50
  let cleanedAttrs
50
51
 
51
52
  if (keepColors) {
52
- cleanedAttrs = nodeAttrs
53
+ // Keep original colors, but use currentColor for elements without fill/stroke
54
+ cleanedAttrs = { ...nodeAttrs }
55
+ const hasFill = 'fill' in nodeAttrs
56
+ const hasStroke = 'stroke' in nodeAttrs
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
55
64
  let hasFill = false
@@ -4,6 +4,7 @@ export interface IconOptions {
4
4
  strokeWidth?: number | string
5
5
  className?: string
6
6
  title?: string
7
+ viewBox?: string
7
8
  ariaLabel?: string
8
9
  ariaHidden?: boolean
9
10
  [key: string]: any
@@ -11,7 +12,7 @@ export interface IconOptions {
11
12
 
12
13
  export type IconNode = [string, Record<string, any>, IconNode[]?]
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 (options: IconOptions = {}): SVGSVGElement => {
16
17
  const {
17
18
  size = 24,
@@ -19,6 +20,7 @@ export function createIcon(name: string, iconNode: IconNode[], keepColors = fals
19
20
  strokeWidth = 2,
20
21
  className = '',
21
22
  title,
23
+ viewBox = defaultViewBox,
22
24
  ariaLabel,
23
25
  ariaHidden,
24
26
  ...attrs
@@ -27,7 +29,7 @@ export function createIcon(name: string, iconNode: IconNode[], keepColors = fals
27
29
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
28
30
  svg.setAttribute('width', String(size))
29
31
  svg.setAttribute('height', String(size))
30
- svg.setAttribute('viewBox', '0 0 24 24')
32
+ svg.setAttribute('viewBox', viewBox)
31
33
  svg.setAttribute('class', className ? `vectify-icon ${className}` : 'vectify-icon')
32
34
 
33
35
  // Accessibility
@@ -62,7 +64,15 @@ export function createIcon(name: string, iconNode: IconNode[], keepColors = fals
62
64
  let cleanedAttrs: Record<string, any>
63
65
 
64
66
  if (keepColors) {
65
- cleanedAttrs = nodeAttrs
67
+ // Keep original colors, but use currentColor for elements without fill/stroke
68
+ cleanedAttrs = { ...nodeAttrs }
69
+ const hasFill = 'fill' in nodeAttrs
70
+ const hasStroke = 'stroke' in nodeAttrs
71
+
72
+ // If element has neither fill nor stroke, apply currentColor as fill
73
+ if (!hasFill && !hasStroke) {
74
+ cleanedAttrs.fill = color
75
+ }
66
76
  } else {
67
77
  // Track color attributes
68
78
  let hasFill = false
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <Icon :iconNode="iconNode" v-bind="$attrs" />
2
+ <Icon :iconNode="iconNode" :keepColors="keepColors" :viewBox="viewBox" v-bind="$attrs" />
3
3
  </template>
4
4
 
5
5
  <script>
@@ -15,7 +15,10 @@ export default defineComponent({
15
15
  {{{formattedNodes}}}
16
16
  ]
17
17
 
18
- return { iconNode }
18
+ const keepColors = {{keepColors}}
19
+ const viewBox = '{{viewBox}}'
20
+
21
+ return { iconNode, keepColors, viewBox }
19
22
  }
20
23
  })
21
24
  </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <Icon :iconNode="iconNode" v-bind="$attrs" />
2
+ <Icon :iconNode="iconNode" :keepColors="keepColors" :viewBox="viewBox" v-bind="$attrs" />
3
3
  </template>
4
4
 
5
5
  <script lang="ts">
@@ -16,7 +16,10 @@ export default defineComponent({
16
16
  {{{formattedNodes}}}
17
17
  ]
18
18
 
19
- return { iconNode }
19
+ const keepColors = {{keepColors}}
20
+ const viewBox = '{{viewBox}}'
21
+
22
+ return { iconNode, keepColors, viewBox }
20
23
  }
21
24
  })
22
25
  </script>