vectify 2.0.2 → 2.0.4
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/{chunk-XHYCGABW.mjs → chunk-GY4VNET5.mjs} +53 -2
- package/dist/cli.js +53 -2
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +53 -2
- package/dist/index.mjs +1 -1
- package/dist/templates/template-engine.ts +8 -0
- package/dist/templates/vue2/component.js.vue.hbs +20 -0
- package/dist/templates/vue2/component.ts.vue.hbs +22 -0
- package/dist/templates/vue2/icon.js.vue.hbs +135 -0
- package/dist/templates/vue2/icon.ts.vue.hbs +138 -0
- package/package.json +1 -1
|
@@ -135,6 +135,10 @@ function getVueTemplatePath(typescript, type) {
|
|
|
135
135
|
const suffix = typescript ? "ts" : "js";
|
|
136
136
|
return `vue/${type}.${suffix}.vue.hbs`;
|
|
137
137
|
}
|
|
138
|
+
function getVue2TemplatePath(typescript, type) {
|
|
139
|
+
const suffix = typescript ? "ts" : "js";
|
|
140
|
+
return `vue2/${type}.${suffix}.vue.hbs`;
|
|
141
|
+
}
|
|
138
142
|
function getSvelteTemplatePath(typescript, type) {
|
|
139
143
|
const suffix = typescript ? "ts" : "js";
|
|
140
144
|
return `svelte/${type}.${suffix}.svelte.hbs`;
|
|
@@ -324,6 +328,21 @@ function generateVueIcon(typescript) {
|
|
|
324
328
|
return renderTemplate(templatePath, { typescript });
|
|
325
329
|
}
|
|
326
330
|
|
|
331
|
+
// src/generators/vue2.ts
|
|
332
|
+
function generateVue2Component(componentName, iconNode, typescript) {
|
|
333
|
+
const formattedNodes = iconNode.map((node) => formatIconNode(node, 4)).join(",\n");
|
|
334
|
+
const templatePath = getVue2TemplatePath(typescript, "component");
|
|
335
|
+
return renderTemplate(templatePath, {
|
|
336
|
+
typescript,
|
|
337
|
+
componentName,
|
|
338
|
+
formattedNodes
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
function generateVue2Icon(typescript) {
|
|
342
|
+
const templatePath = getVue2TemplatePath(typescript, "icon");
|
|
343
|
+
return renderTemplate(templatePath, { typescript });
|
|
344
|
+
}
|
|
345
|
+
|
|
327
346
|
// src/generators/framework-strategy.ts
|
|
328
347
|
var ReactStrategy = class {
|
|
329
348
|
constructor() {
|
|
@@ -365,6 +384,26 @@ var VueStrategy = class {
|
|
|
365
384
|
};
|
|
366
385
|
}
|
|
367
386
|
};
|
|
387
|
+
var Vue2Strategy = class {
|
|
388
|
+
constructor() {
|
|
389
|
+
this.name = "vue2";
|
|
390
|
+
this.getComponentExtension = (_typescript) => {
|
|
391
|
+
return "vue";
|
|
392
|
+
};
|
|
393
|
+
this.getIndexExtension = (typescript) => {
|
|
394
|
+
return typescript ? "ts" : "js";
|
|
395
|
+
};
|
|
396
|
+
this.generateComponent = (componentName, iconNode, typescript) => {
|
|
397
|
+
return generateVue2Component(componentName, iconNode, typescript);
|
|
398
|
+
};
|
|
399
|
+
this.generateBaseComponent = (typescript) => {
|
|
400
|
+
return {
|
|
401
|
+
code: generateVue2Icon(typescript),
|
|
402
|
+
fileName: "Icon.vue"
|
|
403
|
+
};
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
};
|
|
368
407
|
var SvelteStrategy = class {
|
|
369
408
|
constructor() {
|
|
370
409
|
this.name = "svelte";
|
|
@@ -509,6 +548,7 @@ var FrameworkRegistry = class {
|
|
|
509
548
|
this.strategies = /* @__PURE__ */ new Map();
|
|
510
549
|
this.register(new ReactStrategy());
|
|
511
550
|
this.register(new VueStrategy());
|
|
551
|
+
this.register(new Vue2Strategy());
|
|
512
552
|
this.register(new SvelteStrategy());
|
|
513
553
|
this.register(new SolidStrategy());
|
|
514
554
|
this.register(new PreactStrategy());
|
|
@@ -872,7 +912,7 @@ async function generateIndexFile(svgFiles, config, dryRun = false) {
|
|
|
872
912
|
const typescript = config.typescript ?? true;
|
|
873
913
|
const strategy = getFrameworkStrategy(config.framework);
|
|
874
914
|
const ext = strategy.getIndexExtension(typescript);
|
|
875
|
-
const usesDefaultExport = ["vue", "svelte", "react", "preact"].includes(config.framework);
|
|
915
|
+
const usesDefaultExport = ["vue", "vue2", "svelte", "react", "preact"].includes(config.framework);
|
|
876
916
|
const exports = svgFiles.map((svgFile) => {
|
|
877
917
|
const fileName = path4.basename(svgFile);
|
|
878
918
|
const componentName = getComponentName(
|
|
@@ -1231,6 +1271,16 @@ Note: Project root detected at ${chalk2.cyan(projectRoot)}`));
|
|
|
1231
1271
|
message: "Which framework are you using?",
|
|
1232
1272
|
choices: frameworkChoices
|
|
1233
1273
|
},
|
|
1274
|
+
{
|
|
1275
|
+
type: "list",
|
|
1276
|
+
name: "vueVersion",
|
|
1277
|
+
message: "Which Vue version?",
|
|
1278
|
+
choices: [
|
|
1279
|
+
{ name: "Vue 3", value: "vue" },
|
|
1280
|
+
{ name: "Vue 2", value: "vue2" }
|
|
1281
|
+
],
|
|
1282
|
+
when: (answers2) => answers2.framework === "vue"
|
|
1283
|
+
},
|
|
1234
1284
|
{
|
|
1235
1285
|
type: "input",
|
|
1236
1286
|
name: "input",
|
|
@@ -1276,7 +1326,8 @@ Note: Project root detected at ${chalk2.cyan(projectRoot)}`));
|
|
|
1276
1326
|
await ensureDir(outputPath);
|
|
1277
1327
|
spinner.succeed(`Created output directory: ${chalk2.cyan(answers.output)}`);
|
|
1278
1328
|
const relativeConfigDir = path5.relative(configDir, projectRoot) || ".";
|
|
1279
|
-
const
|
|
1329
|
+
const finalFramework = answers.vueVersion || answers.framework;
|
|
1330
|
+
const configContent = generateConfigContent({ ...answers, framework: finalFramework }, relativeConfigDir);
|
|
1280
1331
|
spinner.start("Creating config file...");
|
|
1281
1332
|
await writeFile(configPath, configContent);
|
|
1282
1333
|
spinner.succeed(`Config file created at ${chalk2.green(configPath)}`);
|
package/dist/cli.js
CHANGED
|
@@ -276,6 +276,10 @@ function getVueTemplatePath(typescript, type) {
|
|
|
276
276
|
const suffix = typescript ? "ts" : "js";
|
|
277
277
|
return `vue/${type}.${suffix}.vue.hbs`;
|
|
278
278
|
}
|
|
279
|
+
function getVue2TemplatePath(typescript, type) {
|
|
280
|
+
const suffix = typescript ? "ts" : "js";
|
|
281
|
+
return `vue2/${type}.${suffix}.vue.hbs`;
|
|
282
|
+
}
|
|
279
283
|
function getSvelteTemplatePath(typescript, type) {
|
|
280
284
|
const suffix = typescript ? "ts" : "js";
|
|
281
285
|
return `svelte/${type}.${suffix}.svelte.hbs`;
|
|
@@ -465,6 +469,21 @@ function generateVueIcon(typescript) {
|
|
|
465
469
|
return renderTemplate(templatePath, { typescript });
|
|
466
470
|
}
|
|
467
471
|
|
|
472
|
+
// src/generators/vue2.ts
|
|
473
|
+
function generateVue2Component(componentName, iconNode, typescript) {
|
|
474
|
+
const formattedNodes = iconNode.map((node) => formatIconNode(node, 4)).join(",\n");
|
|
475
|
+
const templatePath = getVue2TemplatePath(typescript, "component");
|
|
476
|
+
return renderTemplate(templatePath, {
|
|
477
|
+
typescript,
|
|
478
|
+
componentName,
|
|
479
|
+
formattedNodes
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
function generateVue2Icon(typescript) {
|
|
483
|
+
const templatePath = getVue2TemplatePath(typescript, "icon");
|
|
484
|
+
return renderTemplate(templatePath, { typescript });
|
|
485
|
+
}
|
|
486
|
+
|
|
468
487
|
// src/generators/framework-strategy.ts
|
|
469
488
|
var ReactStrategy = class {
|
|
470
489
|
constructor() {
|
|
@@ -506,6 +525,26 @@ var VueStrategy = class {
|
|
|
506
525
|
};
|
|
507
526
|
}
|
|
508
527
|
};
|
|
528
|
+
var Vue2Strategy = class {
|
|
529
|
+
constructor() {
|
|
530
|
+
this.name = "vue2";
|
|
531
|
+
this.getComponentExtension = (_typescript) => {
|
|
532
|
+
return "vue";
|
|
533
|
+
};
|
|
534
|
+
this.getIndexExtension = (typescript) => {
|
|
535
|
+
return typescript ? "ts" : "js";
|
|
536
|
+
};
|
|
537
|
+
this.generateComponent = (componentName, iconNode, typescript) => {
|
|
538
|
+
return generateVue2Component(componentName, iconNode, typescript);
|
|
539
|
+
};
|
|
540
|
+
this.generateBaseComponent = (typescript) => {
|
|
541
|
+
return {
|
|
542
|
+
code: generateVue2Icon(typescript),
|
|
543
|
+
fileName: "Icon.vue"
|
|
544
|
+
};
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
};
|
|
509
548
|
var SvelteStrategy = class {
|
|
510
549
|
constructor() {
|
|
511
550
|
this.name = "svelte";
|
|
@@ -650,6 +689,7 @@ var FrameworkRegistry = class {
|
|
|
650
689
|
this.strategies = /* @__PURE__ */ new Map();
|
|
651
690
|
this.register(new ReactStrategy());
|
|
652
691
|
this.register(new VueStrategy());
|
|
692
|
+
this.register(new Vue2Strategy());
|
|
653
693
|
this.register(new SvelteStrategy());
|
|
654
694
|
this.register(new SolidStrategy());
|
|
655
695
|
this.register(new PreactStrategy());
|
|
@@ -1012,7 +1052,7 @@ async function generateIndexFile(svgFiles, config, dryRun = false) {
|
|
|
1012
1052
|
const typescript = config.typescript ?? true;
|
|
1013
1053
|
const strategy = getFrameworkStrategy(config.framework);
|
|
1014
1054
|
const ext = strategy.getIndexExtension(typescript);
|
|
1015
|
-
const usesDefaultExport = ["vue", "svelte", "react", "preact"].includes(config.framework);
|
|
1055
|
+
const usesDefaultExport = ["vue", "vue2", "svelte", "react", "preact"].includes(config.framework);
|
|
1016
1056
|
const exports2 = svgFiles.map((svgFile) => {
|
|
1017
1057
|
const fileName = import_node_path4.default.basename(svgFile);
|
|
1018
1058
|
const componentName = getComponentName(
|
|
@@ -1370,6 +1410,16 @@ Note: Project root detected at ${import_chalk2.default.cyan(projectRoot)}`));
|
|
|
1370
1410
|
message: "Which framework are you using?",
|
|
1371
1411
|
choices: frameworkChoices
|
|
1372
1412
|
},
|
|
1413
|
+
{
|
|
1414
|
+
type: "list",
|
|
1415
|
+
name: "vueVersion",
|
|
1416
|
+
message: "Which Vue version?",
|
|
1417
|
+
choices: [
|
|
1418
|
+
{ name: "Vue 3", value: "vue" },
|
|
1419
|
+
{ name: "Vue 2", value: "vue2" }
|
|
1420
|
+
],
|
|
1421
|
+
when: (answers2) => answers2.framework === "vue"
|
|
1422
|
+
},
|
|
1373
1423
|
{
|
|
1374
1424
|
type: "input",
|
|
1375
1425
|
name: "input",
|
|
@@ -1415,7 +1465,8 @@ Note: Project root detected at ${import_chalk2.default.cyan(projectRoot)}`));
|
|
|
1415
1465
|
await ensureDir(outputPath);
|
|
1416
1466
|
spinner.succeed(`Created output directory: ${import_chalk2.default.cyan(answers.output)}`);
|
|
1417
1467
|
const relativeConfigDir = import_node_path5.default.relative(configDir, projectRoot) || ".";
|
|
1418
|
-
const
|
|
1468
|
+
const finalFramework = answers.vueVersion || answers.framework;
|
|
1469
|
+
const configContent = generateConfigContent({ ...answers, framework: finalFramework }, relativeConfigDir);
|
|
1419
1470
|
spinner.start("Creating config file...");
|
|
1420
1471
|
await writeFile(configPath, configContent);
|
|
1421
1472
|
spinner.succeed(`Config file created at ${import_chalk2.default.green(configPath)}`);
|
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -53,7 +53,7 @@ interface IconProps {
|
|
|
53
53
|
/**
|
|
54
54
|
* Framework types supported
|
|
55
55
|
*/
|
|
56
|
-
type Framework = 'react' | 'vue' | 'svelte' | 'solid' | 'preact' | 'lit' | 'angular' | 'qwik' | 'astro' | 'vanilla';
|
|
56
|
+
type Framework = 'react' | 'vue' | 'vue2' | 'svelte' | 'solid' | 'preact' | 'lit' | 'angular' | 'qwik' | 'astro' | 'vanilla';
|
|
57
57
|
/**
|
|
58
58
|
* Formatter tool types
|
|
59
59
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ interface IconProps {
|
|
|
53
53
|
/**
|
|
54
54
|
* Framework types supported
|
|
55
55
|
*/
|
|
56
|
-
type Framework = 'react' | 'vue' | 'svelte' | 'solid' | 'preact' | 'lit' | 'angular' | 'qwik' | 'astro' | 'vanilla';
|
|
56
|
+
type Framework = 'react' | 'vue' | 'vue2' | 'svelte' | 'solid' | 'preact' | 'lit' | 'angular' | 'qwik' | 'astro' | 'vanilla';
|
|
57
57
|
/**
|
|
58
58
|
* Formatter tool types
|
|
59
59
|
*/
|
package/dist/index.js
CHANGED
|
@@ -284,6 +284,10 @@ function getVueTemplatePath(typescript, type) {
|
|
|
284
284
|
const suffix = typescript ? "ts" : "js";
|
|
285
285
|
return `vue/${type}.${suffix}.vue.hbs`;
|
|
286
286
|
}
|
|
287
|
+
function getVue2TemplatePath(typescript, type) {
|
|
288
|
+
const suffix = typescript ? "ts" : "js";
|
|
289
|
+
return `vue2/${type}.${suffix}.vue.hbs`;
|
|
290
|
+
}
|
|
287
291
|
function getSvelteTemplatePath(typescript, type) {
|
|
288
292
|
const suffix = typescript ? "ts" : "js";
|
|
289
293
|
return `svelte/${type}.${suffix}.svelte.hbs`;
|
|
@@ -473,6 +477,21 @@ function generateVueIcon(typescript) {
|
|
|
473
477
|
return renderTemplate(templatePath, { typescript });
|
|
474
478
|
}
|
|
475
479
|
|
|
480
|
+
// src/generators/vue2.ts
|
|
481
|
+
function generateVue2Component(componentName, iconNode, typescript) {
|
|
482
|
+
const formattedNodes = iconNode.map((node) => formatIconNode(node, 4)).join(",\n");
|
|
483
|
+
const templatePath = getVue2TemplatePath(typescript, "component");
|
|
484
|
+
return renderTemplate(templatePath, {
|
|
485
|
+
typescript,
|
|
486
|
+
componentName,
|
|
487
|
+
formattedNodes
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
function generateVue2Icon(typescript) {
|
|
491
|
+
const templatePath = getVue2TemplatePath(typescript, "icon");
|
|
492
|
+
return renderTemplate(templatePath, { typescript });
|
|
493
|
+
}
|
|
494
|
+
|
|
476
495
|
// src/generators/framework-strategy.ts
|
|
477
496
|
var ReactStrategy = class {
|
|
478
497
|
constructor() {
|
|
@@ -514,6 +533,26 @@ var VueStrategy = class {
|
|
|
514
533
|
};
|
|
515
534
|
}
|
|
516
535
|
};
|
|
536
|
+
var Vue2Strategy = class {
|
|
537
|
+
constructor() {
|
|
538
|
+
this.name = "vue2";
|
|
539
|
+
this.getComponentExtension = (_typescript) => {
|
|
540
|
+
return "vue";
|
|
541
|
+
};
|
|
542
|
+
this.getIndexExtension = (typescript) => {
|
|
543
|
+
return typescript ? "ts" : "js";
|
|
544
|
+
};
|
|
545
|
+
this.generateComponent = (componentName, iconNode, typescript) => {
|
|
546
|
+
return generateVue2Component(componentName, iconNode, typescript);
|
|
547
|
+
};
|
|
548
|
+
this.generateBaseComponent = (typescript) => {
|
|
549
|
+
return {
|
|
550
|
+
code: generateVue2Icon(typescript),
|
|
551
|
+
fileName: "Icon.vue"
|
|
552
|
+
};
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
};
|
|
517
556
|
var SvelteStrategy = class {
|
|
518
557
|
constructor() {
|
|
519
558
|
this.name = "svelte";
|
|
@@ -658,6 +697,7 @@ var FrameworkRegistry = class {
|
|
|
658
697
|
this.strategies = /* @__PURE__ */ new Map();
|
|
659
698
|
this.register(new ReactStrategy());
|
|
660
699
|
this.register(new VueStrategy());
|
|
700
|
+
this.register(new Vue2Strategy());
|
|
661
701
|
this.register(new SvelteStrategy());
|
|
662
702
|
this.register(new SolidStrategy());
|
|
663
703
|
this.register(new PreactStrategy());
|
|
@@ -1020,7 +1060,7 @@ async function generateIndexFile(svgFiles, config, dryRun = false) {
|
|
|
1020
1060
|
const typescript = config.typescript ?? true;
|
|
1021
1061
|
const strategy = getFrameworkStrategy(config.framework);
|
|
1022
1062
|
const ext = strategy.getIndexExtension(typescript);
|
|
1023
|
-
const usesDefaultExport = ["vue", "svelte", "react", "preact"].includes(config.framework);
|
|
1063
|
+
const usesDefaultExport = ["vue", "vue2", "svelte", "react", "preact"].includes(config.framework);
|
|
1024
1064
|
const exports2 = svgFiles.map((svgFile) => {
|
|
1025
1065
|
const fileName = import_node_path4.default.basename(svgFile);
|
|
1026
1066
|
const componentName = getComponentName(
|
|
@@ -1378,6 +1418,16 @@ Note: Project root detected at ${import_chalk2.default.cyan(projectRoot)}`));
|
|
|
1378
1418
|
message: "Which framework are you using?",
|
|
1379
1419
|
choices: frameworkChoices
|
|
1380
1420
|
},
|
|
1421
|
+
{
|
|
1422
|
+
type: "list",
|
|
1423
|
+
name: "vueVersion",
|
|
1424
|
+
message: "Which Vue version?",
|
|
1425
|
+
choices: [
|
|
1426
|
+
{ name: "Vue 3", value: "vue" },
|
|
1427
|
+
{ name: "Vue 2", value: "vue2" }
|
|
1428
|
+
],
|
|
1429
|
+
when: (answers2) => answers2.framework === "vue"
|
|
1430
|
+
},
|
|
1381
1431
|
{
|
|
1382
1432
|
type: "input",
|
|
1383
1433
|
name: "input",
|
|
@@ -1423,7 +1473,8 @@ Note: Project root detected at ${import_chalk2.default.cyan(projectRoot)}`));
|
|
|
1423
1473
|
await ensureDir(outputPath);
|
|
1424
1474
|
spinner.succeed(`Created output directory: ${import_chalk2.default.cyan(answers.output)}`);
|
|
1425
1475
|
const relativeConfigDir = import_node_path5.default.relative(configDir, projectRoot) || ".";
|
|
1426
|
-
const
|
|
1476
|
+
const finalFramework = answers.vueVersion || answers.framework;
|
|
1477
|
+
const configContent = generateConfigContent({ ...answers, framework: finalFramework }, relativeConfigDir);
|
|
1427
1478
|
spinner.start("Creating config file...");
|
|
1428
1479
|
await writeFile(configPath, configContent);
|
|
1429
1480
|
spinner.succeed(`Config file created at ${import_chalk2.default.green(configPath)}`);
|
package/dist/index.mjs
CHANGED
|
@@ -66,6 +66,14 @@ export function getVueTemplatePath(typescript: boolean, type: 'component' | 'ico
|
|
|
66
66
|
return `vue/${type}.${suffix}.vue.hbs`
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Get template path for Vue 2 components
|
|
71
|
+
*/
|
|
72
|
+
export function getVue2TemplatePath(typescript: boolean, type: 'component' | 'icon'): string {
|
|
73
|
+
const suffix = typescript ? 'ts' : 'js'
|
|
74
|
+
return `vue2/${type}.${suffix}.vue.hbs`
|
|
75
|
+
}
|
|
76
|
+
|
|
69
77
|
/**
|
|
70
78
|
* Get template path for Svelte components
|
|
71
79
|
*/
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Icon :iconNode="iconNode" v-bind="$attrs" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script>
|
|
6
|
+
import Icon from './Icon.vue'
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
name: '{{componentName}}',
|
|
10
|
+
components: { Icon },
|
|
11
|
+
inheritAttrs: false,
|
|
12
|
+
data() {
|
|
13
|
+
return {
|
|
14
|
+
iconNode: [
|
|
15
|
+
{{{formattedNodes}}}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Icon :iconNode="iconNode" v-bind="$attrs" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import Vue from 'vue'
|
|
7
|
+
import Icon from './Icon.vue'
|
|
8
|
+
import type { IconNode } from 'vectify'
|
|
9
|
+
|
|
10
|
+
export default Vue.extend({
|
|
11
|
+
name: '{{componentName}}',
|
|
12
|
+
components: { Icon },
|
|
13
|
+
inheritAttrs: false,
|
|
14
|
+
data() {
|
|
15
|
+
const iconNode: IconNode[] = [
|
|
16
|
+
{{{formattedNodes}}}
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
return { iconNode }
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
</script>
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg
|
|
3
|
+
:width="size"
|
|
4
|
+
:height="size"
|
|
5
|
+
viewBox="0 0 24 24"
|
|
6
|
+
:aria-hidden="shouldHide"
|
|
7
|
+
:aria-label="ariaLabel"
|
|
8
|
+
:role="title || ariaLabel ? 'img' : undefined"
|
|
9
|
+
v-bind="$attrs"
|
|
10
|
+
:class="mergedClass"
|
|
11
|
+
>
|
|
12
|
+
<title v-if="title">{{ title }}</title>
|
|
13
|
+
<component
|
|
14
|
+
v-for="(node, index) in cleanedIconNode"
|
|
15
|
+
:key="index"
|
|
16
|
+
:is="renderNode(node)"
|
|
17
|
+
/>
|
|
18
|
+
</svg>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script>
|
|
22
|
+
export default {
|
|
23
|
+
name: 'Icon',
|
|
24
|
+
inheritAttrs: false,
|
|
25
|
+
props: {
|
|
26
|
+
iconNode: {
|
|
27
|
+
type: Array,
|
|
28
|
+
required: true
|
|
29
|
+
},
|
|
30
|
+
size: {
|
|
31
|
+
type: [Number, String],
|
|
32
|
+
default: 24
|
|
33
|
+
},
|
|
34
|
+
color: {
|
|
35
|
+
type: String,
|
|
36
|
+
default: 'currentColor'
|
|
37
|
+
},
|
|
38
|
+
strokeWidth: {
|
|
39
|
+
type: [Number, String],
|
|
40
|
+
default: 2
|
|
41
|
+
},
|
|
42
|
+
className: {
|
|
43
|
+
type: String,
|
|
44
|
+
default: ''
|
|
45
|
+
},
|
|
46
|
+
title: {
|
|
47
|
+
type: String,
|
|
48
|
+
default: ''
|
|
49
|
+
},
|
|
50
|
+
ariaLabel: {
|
|
51
|
+
type: String,
|
|
52
|
+
default: ''
|
|
53
|
+
},
|
|
54
|
+
ariaHidden: {
|
|
55
|
+
type: [Boolean, String],
|
|
56
|
+
default: undefined
|
|
57
|
+
},
|
|
58
|
+
keepColors: {
|
|
59
|
+
type: Boolean,
|
|
60
|
+
default: false
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
computed: {
|
|
64
|
+
mergedClass() {
|
|
65
|
+
return this.className ? `vectify-icon ${this.className}` : 'vectify-icon'
|
|
66
|
+
},
|
|
67
|
+
shouldHide() {
|
|
68
|
+
return this.ariaHidden !== undefined ? this.ariaHidden : (!this.title && !this.ariaLabel)
|
|
69
|
+
},
|
|
70
|
+
cleanedIconNode() {
|
|
71
|
+
if (this.keepColors) {
|
|
72
|
+
return this.iconNode
|
|
73
|
+
}
|
|
74
|
+
return this.cleanIconNodes(this.iconNode, this.color, this.strokeWidth)
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
methods: {
|
|
78
|
+
cleanIconNodes(nodes, color, strokeWidth) {
|
|
79
|
+
return nodes.map(node => {
|
|
80
|
+
const [type, attrs, children] = node
|
|
81
|
+
|
|
82
|
+
const cleanedAttrs = {}
|
|
83
|
+
let hasFill = false
|
|
84
|
+
let hasStroke = false
|
|
85
|
+
let originalStrokeWidth
|
|
86
|
+
|
|
87
|
+
Object.entries(attrs).forEach(([key, value]) => {
|
|
88
|
+
if (key === 'fill') {
|
|
89
|
+
if (value !== 'none') {
|
|
90
|
+
hasFill = true
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (key === 'stroke') {
|
|
94
|
+
hasStroke = true
|
|
95
|
+
}
|
|
96
|
+
if (key === 'strokeWidth' || key === 'stroke-width') {
|
|
97
|
+
originalStrokeWidth = value
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!['stroke', 'fill', 'strokeWidth', 'stroke-width'].includes(key)) {
|
|
101
|
+
cleanedAttrs[key] = value
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
if (hasFill) {
|
|
106
|
+
cleanedAttrs.fill = color
|
|
107
|
+
} else if (hasStroke) {
|
|
108
|
+
cleanedAttrs.fill = 'none'
|
|
109
|
+
cleanedAttrs.stroke = color
|
|
110
|
+
cleanedAttrs.strokeWidth = originalStrokeWidth ?? strokeWidth
|
|
111
|
+
cleanedAttrs.strokeLinecap = 'round'
|
|
112
|
+
cleanedAttrs.strokeLinejoin = 'round'
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const cleanedChildren = children ? this.cleanIconNodes(children, color, strokeWidth) : undefined
|
|
116
|
+
|
|
117
|
+
return [type, cleanedAttrs, cleanedChildren]
|
|
118
|
+
})
|
|
119
|
+
},
|
|
120
|
+
renderNode(node) {
|
|
121
|
+
const [type, attrs, children] = node
|
|
122
|
+
|
|
123
|
+
if (children && children.length > 0) {
|
|
124
|
+
return this.$createElement(
|
|
125
|
+
type,
|
|
126
|
+
{ attrs },
|
|
127
|
+
children.map(child => this.renderNode(child))
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return this.$createElement(type, { attrs })
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
</script>
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg
|
|
3
|
+
:width="size"
|
|
4
|
+
:height="size"
|
|
5
|
+
viewBox="0 0 24 24"
|
|
6
|
+
:aria-hidden="shouldHide"
|
|
7
|
+
:aria-label="ariaLabel"
|
|
8
|
+
:role="title || ariaLabel ? 'img' : undefined"
|
|
9
|
+
v-bind="$attrs"
|
|
10
|
+
:class="mergedClass"
|
|
11
|
+
>
|
|
12
|
+
<title v-if="title">{{ title }}</title>
|
|
13
|
+
<component
|
|
14
|
+
v-for="(node, index) in cleanedIconNode"
|
|
15
|
+
:key="index"
|
|
16
|
+
:is="renderNode(node)"
|
|
17
|
+
/>
|
|
18
|
+
</svg>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script lang="ts">
|
|
22
|
+
import Vue, { VNode } from 'vue'
|
|
23
|
+
import type { IconNode } from 'vectify'
|
|
24
|
+
|
|
25
|
+
export default Vue.extend({
|
|
26
|
+
name: 'Icon',
|
|
27
|
+
inheritAttrs: false,
|
|
28
|
+
props: {
|
|
29
|
+
iconNode: {
|
|
30
|
+
type: Array as () => IconNode[],
|
|
31
|
+
required: true
|
|
32
|
+
},
|
|
33
|
+
size: {
|
|
34
|
+
type: [Number, String] as Vue.PropType<number | string>,
|
|
35
|
+
default: 24
|
|
36
|
+
},
|
|
37
|
+
color: {
|
|
38
|
+
type: String,
|
|
39
|
+
default: 'currentColor'
|
|
40
|
+
},
|
|
41
|
+
strokeWidth: {
|
|
42
|
+
type: [Number, String] as Vue.PropType<number | string>,
|
|
43
|
+
default: 2
|
|
44
|
+
},
|
|
45
|
+
className: {
|
|
46
|
+
type: String,
|
|
47
|
+
default: ''
|
|
48
|
+
},
|
|
49
|
+
title: {
|
|
50
|
+
type: String,
|
|
51
|
+
default: ''
|
|
52
|
+
},
|
|
53
|
+
ariaLabel: {
|
|
54
|
+
type: String,
|
|
55
|
+
default: ''
|
|
56
|
+
},
|
|
57
|
+
ariaHidden: {
|
|
58
|
+
type: [Boolean, String] as Vue.PropType<boolean | 'true' | 'false'>,
|
|
59
|
+
default: undefined
|
|
60
|
+
},
|
|
61
|
+
keepColors: {
|
|
62
|
+
type: Boolean,
|
|
63
|
+
default: false
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
computed: {
|
|
67
|
+
mergedClass(): string {
|
|
68
|
+
return this.className ? `vectify-icon ${this.className}` : 'vectify-icon'
|
|
69
|
+
},
|
|
70
|
+
shouldHide(): boolean | 'true' | 'false' {
|
|
71
|
+
return this.ariaHidden !== undefined ? this.ariaHidden : (!this.title && !this.ariaLabel)
|
|
72
|
+
},
|
|
73
|
+
cleanedIconNode(): IconNode[] {
|
|
74
|
+
if (this.keepColors) {
|
|
75
|
+
return this.iconNode
|
|
76
|
+
}
|
|
77
|
+
return this.cleanIconNodes(this.iconNode, this.color, this.strokeWidth)
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
methods: {
|
|
81
|
+
cleanIconNodes(nodes: IconNode[], color: string, strokeWidth: number | string): IconNode[] {
|
|
82
|
+
return nodes.map(node => {
|
|
83
|
+
const [type, attrs, children] = node
|
|
84
|
+
|
|
85
|
+
const cleanedAttrs: Record<string, any> = {}
|
|
86
|
+
let hasFill = false
|
|
87
|
+
let hasStroke = false
|
|
88
|
+
let originalStrokeWidth: number | string | undefined
|
|
89
|
+
|
|
90
|
+
Object.entries(attrs).forEach(([key, value]) => {
|
|
91
|
+
if (key === 'fill') {
|
|
92
|
+
if (value !== 'none') {
|
|
93
|
+
hasFill = true
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (key === 'stroke') {
|
|
97
|
+
hasStroke = true
|
|
98
|
+
}
|
|
99
|
+
if (key === 'strokeWidth' || key === 'stroke-width') {
|
|
100
|
+
originalStrokeWidth = value
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (!['stroke', 'fill', 'strokeWidth', 'stroke-width'].includes(key)) {
|
|
104
|
+
cleanedAttrs[key] = value
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
if (hasFill) {
|
|
109
|
+
cleanedAttrs.fill = color
|
|
110
|
+
} else if (hasStroke) {
|
|
111
|
+
cleanedAttrs.fill = 'none'
|
|
112
|
+
cleanedAttrs.stroke = color
|
|
113
|
+
cleanedAttrs.strokeWidth = originalStrokeWidth ?? strokeWidth
|
|
114
|
+
cleanedAttrs.strokeLinecap = 'round'
|
|
115
|
+
cleanedAttrs.strokeLinejoin = 'round'
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const cleanedChildren = children ? this.cleanIconNodes(children, color, strokeWidth) : undefined
|
|
119
|
+
|
|
120
|
+
return [type, cleanedAttrs, cleanedChildren] as IconNode
|
|
121
|
+
})
|
|
122
|
+
},
|
|
123
|
+
renderNode(node: IconNode): VNode {
|
|
124
|
+
const [type, attrs, children] = node
|
|
125
|
+
|
|
126
|
+
if (children && children.length > 0) {
|
|
127
|
+
return this.$createElement(
|
|
128
|
+
type,
|
|
129
|
+
{ attrs },
|
|
130
|
+
children.map(child => this.renderNode(child))
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return this.$createElement(type, { attrs })
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
</script>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vectify",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"packageManager": "pnpm@9.15.9",
|
|
5
5
|
"description": "A powerful command-line tool to generate React, Vue, and Svelte icon components from SVG files",
|
|
6
6
|
"author": "Xiaobing Zhu <hellozxb252@gmail.com>",
|