@cyberalien/svg-utils 1.1.4 → 1.2.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.
- package/lib/components/export/merge.js +3 -1
- package/lib/components/helpers/content/stringify.d.ts +2 -2
- package/lib/components/helpers/content/stringify.js +4 -10
- package/lib/components/helpers/css/generate.d.ts +2 -1
- package/lib/components/helpers/css/generate.js +43 -46
- package/lib/components/helpers/filenames/css.d.ts +1 -1
- package/lib/components/helpers/filenames/css.js +2 -3
- package/lib/components/helpers/functions/custom.d.ts +14 -0
- package/lib/components/helpers/functions/custom.js +17 -0
- package/lib/components/helpers/functions/fallback.d.ts +8 -0
- package/lib/components/helpers/functions/fallback.js +53 -0
- package/lib/components/helpers/functions/innerhtml.d.ts +8 -0
- package/lib/components/helpers/functions/innerhtml.js +35 -0
- package/lib/components/helpers/functions/size.js +1 -1
- package/lib/components/helpers/imports/create.js +1 -2
- package/lib/components/helpers/imports/stringify.js +0 -2
- package/lib/components/helpers/imports/types.d.ts +0 -1
- package/lib/components/jsx.js +79 -8
- package/lib/components/prepare/iconify.d.ts +1 -1
- package/lib/components/prepare/iconify.js +6 -4
- package/lib/components/prepare/states.d.ts +8 -0
- package/lib/components/prepare/states.js +73 -0
- package/lib/components/raw.js +10 -7
- package/lib/components/svelte.js +73 -14
- package/lib/components/types/component.d.ts +2 -1
- package/lib/components/types/css.d.ts +1 -2
- package/lib/components/types/data.d.ts +0 -3
- package/lib/components/types/options.d.ts +9 -2
- package/lib/components/types/source.d.ts +21 -6
- package/lib/components/vue-func.js +71 -12
- package/lib/components/vue.js +70 -13
- package/lib/css/find/animations.d.ts +10 -0
- package/lib/css/find/animations.js +35 -0
- package/lib/css/find/classname.d.ts +5 -0
- package/lib/css/find/classname.js +14 -0
- package/lib/css/find/prop.d.ts +5 -0
- package/lib/css/find/prop.js +12 -0
- package/lib/css/minify.d.ts +2 -0
- package/lib/css/minify.js +5 -0
- package/lib/css/rules.d.ts +10 -0
- package/lib/css/rules.js +26 -0
- package/lib/css/stringify.d.ts +8 -2
- package/lib/css/stringify.js +16 -8
- package/lib/css/stylesheet.d.ts +0 -2
- package/lib/css/stylesheet.js +3 -3
- package/lib/css/types.d.ts +1 -1
- package/lib/helpers/data/compact.d.ts +20 -0
- package/lib/helpers/data/compact.js +38 -0
- package/lib/helpers/data/expand.d.ts +5 -0
- package/lib/helpers/data/expand.js +9 -0
- package/lib/helpers/reduce-motion.d.ts +2 -0
- package/lib/helpers/reduce-motion.js +3 -0
- package/lib/index.d.ts +15 -2
- package/lib/index.js +11 -2
- package/lib/svg-css/icon/css.d.ts +25 -0
- package/lib/svg-css/icon/css.js +57 -0
- package/lib/svg-css/icon/types.d.ts +45 -0
- package/lib/svg-css/icon/types.js +1 -0
- package/lib/svg-css/icon-set/add.d.ts +7 -0
- package/lib/svg-css/icon-set/add.js +52 -0
- package/lib/svg-css/icon-set/create.d.ts +6 -0
- package/lib/svg-css/icon-set/create.js +8 -0
- package/lib/svg-css/icon-set/get.d.ts +4 -0
- package/lib/svg-css/icon-set/get.js +92 -0
- package/lib/svg-css/icon-set/minify/expand.d.ts +10 -0
- package/lib/svg-css/icon-set/minify/expand.js +35 -0
- package/lib/svg-css/icon-set/minify/keys.d.ts +5 -0
- package/lib/svg-css/icon-set/minify/keys.js +9 -0
- package/lib/svg-css/icon-set/minify/minify.d.ts +19 -0
- package/lib/svg-css/icon-set/minify/minify.js +74 -0
- package/lib/svg-css/icon-set/types.d.ts +43 -0
- package/lib/svg-css/icon-set/types.js +1 -0
- package/lib/svg-css/states/cleanup-values.d.ts +6 -0
- package/lib/svg-css/states/cleanup-values.js +15 -0
- package/lib/svg-css/states/fallback/parse.d.ts +7 -0
- package/lib/svg-css/states/fallback/parse.js +46 -0
- package/lib/svg-css/states/fallback/stringify.d.ts +6 -0
- package/lib/svg-css/states/fallback/stringify.js +9 -0
- package/lib/svg-css/states/fallback/test.d.ts +9 -0
- package/lib/svg-css/states/fallback/test.js +21 -0
- package/lib/svg-css/states/fallback/types.d.ts +20 -0
- package/lib/svg-css/states/fallback/types.js +1 -0
- package/lib/svg-css/states/focus.d.ts +10 -0
- package/lib/svg-css/states/focus.js +14 -0
- package/lib/svg-css/states/generator.d.ts +19 -0
- package/lib/svg-css/states/generator.js +31 -0
- package/lib/svg-css/states/key.d.ts +6 -0
- package/lib/svg-css/states/key.js +22 -0
- package/lib/svg-css/states/object.d.ts +6 -0
- package/lib/svg-css/states/object.js +13 -0
- package/lib/svg-css/states/selector/helpers/iterate.d.ts +10 -0
- package/lib/svg-css/states/selector/helpers/iterate.js +71 -0
- package/lib/svg-css/states/selector/merge.d.ts +6 -0
- package/lib/svg-css/states/selector/merge.js +29 -0
- package/lib/svg-css/states/selector/parse.d.ts +13 -0
- package/lib/svg-css/states/selector/parse.js +74 -0
- package/lib/svg-css/states/selector/part/merge.d.ts +10 -0
- package/lib/svg-css/states/selector/part/merge.js +37 -0
- package/lib/svg-css/states/selector/part/split.d.ts +13 -0
- package/lib/svg-css/states/selector/part/split.js +60 -0
- package/lib/svg-css/states/selector/part/stringify.d.ts +9 -0
- package/lib/svg-css/states/selector/part/stringify.js +32 -0
- package/lib/svg-css/states/selector/split.d.ts +6 -0
- package/lib/svg-css/states/selector/split.js +29 -0
- package/lib/svg-css/states/selector/stringify.d.ts +8 -0
- package/lib/svg-css/states/selector/stringify.js +143 -0
- package/lib/svg-css/states/selector/sub/merge.d.ts +6 -0
- package/lib/svg-css/states/selector/sub/merge.js +36 -0
- package/lib/svg-css/states/selector/sub/split.d.ts +10 -0
- package/lib/svg-css/states/selector/sub/split.js +61 -0
- package/lib/svg-css/states/selector/sub/stringify.d.ts +6 -0
- package/lib/svg-css/states/selector/sub/stringify.js +17 -0
- package/lib/svg-css/states/selector/types.d.ts +37 -0
- package/lib/svg-css/states/selector/types.js +1 -0
- package/lib/svg-css/states/types.d.ts +9 -0
- package/lib/svg-css/states/types.js +1 -0
- package/lib/svg-css/states/validate.d.ts +6 -0
- package/lib/svg-css/states/validate.js +55 -0
- package/lib/svg-css/states/value.d.ts +10 -0
- package/lib/svg-css/states/value.js +15 -0
- package/package.json +8 -8
- package/lib/components/helpers/css/name.d.ts +0 -7
- package/lib/components/helpers/css/name.js +0 -12
package/lib/components/raw.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { stringifyStylesheet } from "../css/stylesheet.js";
|
|
1
2
|
import { getComponentSizeValues } from "./helpers/content/size.js";
|
|
2
3
|
import { stringifyFactoryIconContent } from "./helpers/content/stringify.js";
|
|
3
4
|
import { stringifyIconViewBox } from "../svg/viewbox/value.js";
|
|
@@ -11,21 +12,23 @@ import { getGeneratedComponentTypesFilename } from "./helpers/filenames/types.js
|
|
|
11
12
|
* Create raw component code
|
|
12
13
|
*/
|
|
13
14
|
function createRawComponent(data, options) {
|
|
15
|
+
const icon = data.icon;
|
|
16
|
+
const viewBox = icon.viewBox;
|
|
14
17
|
const assets = [];
|
|
15
18
|
const imports = createFactoryImports();
|
|
16
19
|
const codeLines = [];
|
|
17
|
-
const style = generateCSSFilesForComponent(
|
|
20
|
+
const style = generateCSSFilesForComponent(icon, imports, assets, options);
|
|
18
21
|
const isEmbeddedCSS = options.cssMode === "embed";
|
|
19
22
|
const props = {
|
|
20
23
|
xmlns: "http://www.w3.org/2000/svg",
|
|
21
|
-
...getComponentSizeValues(options,
|
|
22
|
-
viewBox: stringifyIconViewBox(
|
|
24
|
+
...getComponentSizeValues(options, viewBox),
|
|
25
|
+
viewBox: stringifyIconViewBox(viewBox)
|
|
23
26
|
};
|
|
24
|
-
const
|
|
25
|
-
...
|
|
26
|
-
content: `<svg ${stringifyFactoryProps(props, factoryPropTemplate)}>${isEmbeddedCSS && style ? `<style>${style}</style>` : ""}${
|
|
27
|
+
const iconContent = {
|
|
28
|
+
...icon,
|
|
29
|
+
content: `<svg ${stringifyFactoryProps(props, factoryPropTemplate)}>${isEmbeddedCSS && style ? `<style>${stringifyStylesheet(style)}</style>` : ""}${icon.content}</svg>`
|
|
27
30
|
};
|
|
28
|
-
codeLines.push(`const icon = ${stringifyFactoryIconContent(
|
|
31
|
+
codeLines.push(`const icon = ${stringifyFactoryIconContent(iconContent)};\n`);
|
|
29
32
|
codeLines.push("export default icon;\n");
|
|
30
33
|
const importsCode = stringifyFactoryImports(imports);
|
|
31
34
|
if (importsCode) codeLines.unshift(importsCode);
|
package/lib/components/svelte.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { stringifyStylesheet } from "../css/stylesheet.js";
|
|
1
2
|
import { getComponentSizeValues } from "./helpers/content/size.js";
|
|
2
3
|
import { stringifyFactoryIconContent } from "./helpers/content/stringify.js";
|
|
3
4
|
import { stringifyIconViewBox } from "../svg/viewbox/value.js";
|
|
@@ -10,34 +11,90 @@ import { makeSquareViewBox } from "../svg/viewbox/square.js";
|
|
|
10
11
|
import { getUsedFactoryProps, stringifyFactoryPropTypes } from "./helpers/props/ts.js";
|
|
11
12
|
import { minifyViewBox } from "../svg/viewbox/minify.js";
|
|
12
13
|
import { getViewBoxRatio } from "./helpers/content/ratio.js";
|
|
14
|
+
import { addCustomFunctionAsset } from "./helpers/functions/custom.js";
|
|
15
|
+
import { addFallbackFunctionAsset } from "./helpers/functions/fallback.js";
|
|
13
16
|
import { addSvelteComponentTypes } from "./helpers/ts/svelte.js";
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* Create Svelte component code
|
|
17
20
|
*/
|
|
18
21
|
function createSvelteComponent(data, options) {
|
|
22
|
+
const icon = data.icon;
|
|
23
|
+
const viewBox = icon.viewBox;
|
|
24
|
+
const fallback = icon.defaultFallback;
|
|
25
|
+
const statefulData = icon.statefulData;
|
|
19
26
|
const useTS = options.ts ?? false;
|
|
20
27
|
const assets = [];
|
|
21
28
|
const imports = createFactoryImports();
|
|
22
29
|
const dependencies = /* @__PURE__ */ new Set();
|
|
23
|
-
|
|
24
|
-
if (hasFallback) {
|
|
30
|
+
if (fallback) {
|
|
25
31
|
imports.default["@iconify/css-svelte"] = "Icon";
|
|
26
32
|
dependencies.add("@iconify/css-svelte");
|
|
27
33
|
}
|
|
28
|
-
const styleContent = generateCSSFilesForComponent(
|
|
34
|
+
const styleContent = generateCSSFilesForComponent(icon, imports, assets, {
|
|
29
35
|
...options,
|
|
30
36
|
componentType: "svelte"
|
|
31
37
|
});
|
|
32
38
|
let hasFixedSize = !!options.width && !!options.height;
|
|
33
|
-
const viewBox = data.viewBox;
|
|
34
39
|
const hasComputedViewbox = options.square && !hasFixedSize && viewBox.width !== viewBox.height;
|
|
35
|
-
const isStringViewBox = !
|
|
40
|
+
const isStringViewBox = !fallback;
|
|
36
41
|
const hasComputedRatio = hasComputedViewbox && isStringViewBox;
|
|
37
42
|
if (!hasComputedViewbox && (options.width || options.height)) hasFixedSize = true;
|
|
38
43
|
const componentCode = [];
|
|
39
44
|
const props = {};
|
|
40
|
-
if (!
|
|
45
|
+
if (!fallback) props.xmlns = "http://www.w3.org/2000/svg";
|
|
46
|
+
let computedFallback = false;
|
|
47
|
+
if (statefulData) {
|
|
48
|
+
const { supportedStates, allStates } = statefulData;
|
|
49
|
+
if (supportedStates.size) {
|
|
50
|
+
const computedStates = [];
|
|
51
|
+
let addedStateFunc = false;
|
|
52
|
+
for (const state of allStates) if (typeof state === "string") {
|
|
53
|
+
if (supportedStates.has(state)) {
|
|
54
|
+
props[state] = {
|
|
55
|
+
type: "boolean",
|
|
56
|
+
value: state,
|
|
57
|
+
template: ""
|
|
58
|
+
};
|
|
59
|
+
computedStates.push(`'${state}': ${state}`);
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
const stateName = state[0];
|
|
63
|
+
if (supportedStates.has(stateName)) {
|
|
64
|
+
const stateValues = state[1];
|
|
65
|
+
const defaultStateValue = state[2] ?? stateValues[0];
|
|
66
|
+
props[stateName] = {
|
|
67
|
+
type: stateValues.map((value) => `'${value}'`).join(" | "),
|
|
68
|
+
value: stateName,
|
|
69
|
+
template: ""
|
|
70
|
+
};
|
|
71
|
+
computedStates.push(`'${stateName}': namedStateValue(${stateName}, '${defaultStateValue}')`);
|
|
72
|
+
if (!addedStateFunc) {
|
|
73
|
+
addedStateFunc = true;
|
|
74
|
+
addCustomFunctionAsset(imports, assets, options, {
|
|
75
|
+
functionName: "namedStateValue",
|
|
76
|
+
content: `export function namedStateValue(value, defaultValue) {
|
|
77
|
+
return value && value !== defaultValue ? value : undefined;
|
|
78
|
+
}`
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (computedStates.length) {
|
|
84
|
+
componentCode.push(`let states = $derived(({ ${computedStates.join(", ")} }));`);
|
|
85
|
+
if (fallback && statefulData.fallback) {
|
|
86
|
+
computedFallback = true;
|
|
87
|
+
const func = addFallbackFunctionAsset(imports, assets, options, statefulData.defaultStateValues);
|
|
88
|
+
componentCode.push(`let fallback = $derived(${func}(${JSON.stringify(statefulData.fallback)},states));`);
|
|
89
|
+
}
|
|
90
|
+
componentCode.push(`let className = $derived(Object.entries(states).map(([key, value]) => value ? \`state-\${value === true ? key : value}\` : '').join(' ').trim() || undefined);`);
|
|
91
|
+
props.class = {
|
|
92
|
+
value: "className",
|
|
93
|
+
template: "class={className}"
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
41
98
|
const viewBoxPropValue = `viewBox${hasComputedViewbox ? "Computed" : ""}`;
|
|
42
99
|
const getViewBox = (viewBox) => isStringViewBox ? `'${stringifyIconViewBox(viewBox)}'` : JSON.stringify(minifyViewBox(viewBox));
|
|
43
100
|
if (hasComputedViewbox) componentCode.push(`const baseViewBox = ${getViewBox(viewBox)};`, `const squareViewBox = ${getViewBox(makeSquareViewBox(viewBox))};`, `let ${viewBoxPropValue} = $derived(square ? squareViewBox : baseViewBox);`);
|
|
@@ -45,11 +102,11 @@ function createSvelteComponent(data, options) {
|
|
|
45
102
|
const ratioValue = getViewBoxRatio(viewBox);
|
|
46
103
|
if (hasComputedRatio) componentCode.push(`let ratio = $derived(square ? 1 : ${ratioValue});`);
|
|
47
104
|
if (hasFixedSize) {
|
|
48
|
-
const sizeProps = getComponentSizeValues(options,
|
|
105
|
+
const sizeProps = getComponentSizeValues(options, viewBox);
|
|
49
106
|
if (!sizeProps) throw new Error("Fixed size expected, but could not be determined");
|
|
50
107
|
props.width = sizeProps.width;
|
|
51
108
|
props.height = sizeProps.height;
|
|
52
|
-
} else if (
|
|
109
|
+
} else if (fallback) {
|
|
53
110
|
props.width = {
|
|
54
111
|
type: "string",
|
|
55
112
|
value: "width",
|
|
@@ -79,17 +136,19 @@ function createSvelteComponent(data, options) {
|
|
|
79
136
|
value: "viewBox",
|
|
80
137
|
template: `viewBox={${viewBoxPropValue}}`
|
|
81
138
|
};
|
|
82
|
-
componentCode.push(`const content = ${stringifyFactoryIconContent(
|
|
83
|
-
const innerHTML =
|
|
139
|
+
componentCode.push(`const content = ${stringifyFactoryIconContent(icon)};`);
|
|
140
|
+
const innerHTML = fallback ? "" : "{@html content}";
|
|
84
141
|
props.content = {
|
|
85
142
|
value: "content",
|
|
86
|
-
template:
|
|
143
|
+
template: fallback ? `content={content} fallback=${computedFallback ? "{fallback}" : `"${fallback}"`}` : ""
|
|
87
144
|
};
|
|
88
145
|
const usedProps = getUsedFactoryProps(props);
|
|
89
146
|
const propsDestricturing = usedProps.length ? `{${[...usedProps, "...props"].join(", ")}}` : "props";
|
|
90
147
|
componentCode.unshift(`let ${propsDestricturing}${useTS ? ": Props" : ""} = $props();\n`);
|
|
91
|
-
|
|
92
|
-
|
|
148
|
+
const propTypes = stringifyFactoryPropTypes(props);
|
|
149
|
+
if (useTS) componentCode.unshift(`interface Props {\n${propTypes}\n};\n`);
|
|
150
|
+
else if (propTypes.trim()) componentCode.unshift(`/** @type {{${propTypes.replace(/\s*\n\s*/g, " ").trim()}}} */`);
|
|
151
|
+
const tag = fallback ? "Icon" : "svg";
|
|
93
152
|
const template = `<${tag} ${stringifyFactoryProps(props, "{prop}={{value}}")} {...props}>${innerHTML}</${tag}>`;
|
|
94
153
|
let content = `<script${useTS ? " lang=\"ts\"" : ""}>
|
|
95
154
|
${stringifyFactoryImports(imports)}
|
|
@@ -98,7 +157,7 @@ ${componentCode.join("\n")}
|
|
|
98
157
|
${template}
|
|
99
158
|
`;
|
|
100
159
|
const style = options.cssMode === "prop" ? styleContent : void 0;
|
|
101
|
-
if (styleContent && !style) content += `<style>\n${styleContent}\n</style>\n`;
|
|
160
|
+
if (styleContent && !style) content += `<style>\n${stringifyStylesheet(styleContent)}\n</style>\n`;
|
|
102
161
|
const types = addSvelteComponentTypes(data, options, assets, props);
|
|
103
162
|
return {
|
|
104
163
|
assets,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CSSGeneratedStylesheet } from "../../css/types.js";
|
|
1
2
|
/**
|
|
2
3
|
* File generated by component factory
|
|
3
4
|
*/
|
|
@@ -17,7 +18,7 @@ interface GeneratedAssetFile extends GeneratedComponentFile {
|
|
|
17
18
|
interface FactoryGeneratedComponent {
|
|
18
19
|
assets: GeneratedAssetFile[];
|
|
19
20
|
content: string;
|
|
20
|
-
style?:
|
|
21
|
+
style?: CSSGeneratedStylesheet;
|
|
21
22
|
types?: string;
|
|
22
23
|
dependencies?: Set<string>;
|
|
23
24
|
}
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* Method of importing CSS in generated components
|
|
3
3
|
*
|
|
4
4
|
* 'import' - Create external CSS file and import it in component
|
|
5
|
-
* 'module' - Create CSS module and import it in component
|
|
6
5
|
* 'embed' - Embed CSS styles in component (if supported by component, throws error otherwise)
|
|
7
6
|
* 'prop' - Export CSS as separate property in generated data, do not import in component, do not create asset
|
|
8
7
|
*/
|
|
9
|
-
type CSSExportMode = 'import' | '
|
|
8
|
+
type CSSExportMode = 'import' | 'embed' | 'prop';
|
|
10
9
|
export { CSSExportMode };
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { IconViewBox } from "../../svg/viewbox/types.js";
|
|
2
1
|
import { ComponentFactorySource } from "./source.js";
|
|
3
2
|
/**
|
|
4
3
|
* Icon data
|
|
@@ -7,7 +6,5 @@ interface FactoryIconData {
|
|
|
7
6
|
prefix: string;
|
|
8
7
|
name: string;
|
|
9
8
|
icon: ComponentFactorySource;
|
|
10
|
-
viewBox: IconViewBox;
|
|
11
|
-
fallback?: string;
|
|
12
9
|
}
|
|
13
10
|
export { FactoryIconData };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { UniqueHashPartialOptions } from "../../helpers/hash/types.js";
|
|
2
|
+
import { StatefulIconSelectorsConfig } from "../../svg-css/states/selector/types.js";
|
|
2
3
|
import { CSSExportMode } from "./css.js";
|
|
3
4
|
/**
|
|
4
5
|
* Asset path, generated from configuration
|
|
@@ -19,10 +20,16 @@ interface ComponentFactoryFileSystemOptions {
|
|
|
19
20
|
helpersDirectory?: string;
|
|
20
21
|
sharedTypes?: boolean;
|
|
21
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Rendering options for stateful icons
|
|
25
|
+
*/
|
|
26
|
+
interface ComponentFactoryStatefulIconRenderingOptions {
|
|
27
|
+
stateSelectors?: StatefulIconSelectorsConfig;
|
|
28
|
+
}
|
|
22
29
|
/**
|
|
23
30
|
* Rendering options for component factory
|
|
24
31
|
*/
|
|
25
|
-
interface ComponentFactoryRenderingOptions {
|
|
32
|
+
interface ComponentFactoryRenderingOptions extends ComponentFactoryStatefulIconRenderingOptions {
|
|
26
33
|
square?: boolean;
|
|
27
34
|
cssMode: CSSExportMode;
|
|
28
35
|
mergeCSS?: GeneratedAssetPath;
|
|
@@ -33,4 +40,4 @@ interface ComponentFactoryRenderingOptions {
|
|
|
33
40
|
* Options for component factory
|
|
34
41
|
*/
|
|
35
42
|
interface ComponentFactoryOptions extends ComponentFactoryFileSystemOptions, ComponentFactoryRenderingOptions, Pick<UniqueHashPartialOptions, 'context'> {}
|
|
36
|
-
export { ComponentFactoryFileSystemOptions, ComponentFactoryOptions, ComponentFactoryRenderingOptions, GeneratedAssetPath };
|
|
43
|
+
export { ComponentFactoryFileSystemOptions, ComponentFactoryOptions, ComponentFactoryRenderingOptions, ComponentFactoryStatefulIconRenderingOptions, GeneratedAssetPath };
|
|
@@ -1,10 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { IconViewBox } from "../../svg/viewbox/types.js";
|
|
2
|
+
import { IconStatesList } from "../../svg-css/states/types.js";
|
|
3
|
+
import { SVGCSSStatefulIcon } from "../../svg-css/icon/types.js";
|
|
4
|
+
import { IconFallbackTemplate } from "../../svg-css/states/fallback/types.js";
|
|
5
|
+
import { StatefulIconSelectorsContext } from "../../svg-css/states/selector/types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Generated data for stateful icon
|
|
8
|
+
*/
|
|
9
|
+
interface StatefulComponentFactorySource {
|
|
10
|
+
fallback?: IconFallbackTemplate;
|
|
11
|
+
allStates: IconStatesList;
|
|
12
|
+
supportedStates: Set<string>;
|
|
13
|
+
defaultStateValues: Record<string, string | boolean>;
|
|
14
|
+
supportedStateValues: Record<string, string | boolean>;
|
|
15
|
+
context: StatefulIconSelectorsContext;
|
|
16
|
+
}
|
|
3
17
|
/**
|
|
4
18
|
* Content for component factory
|
|
5
19
|
*/
|
|
6
|
-
interface ComponentFactorySource extends Omit<
|
|
7
|
-
|
|
8
|
-
|
|
20
|
+
interface ComponentFactorySource extends Omit<SVGCSSStatefulIcon, 'viewBox' | 'fallback' | 'states'> {
|
|
21
|
+
viewBox: IconViewBox;
|
|
22
|
+
defaultFallback?: string;
|
|
23
|
+
statefulData?: StatefulComponentFactorySource;
|
|
9
24
|
}
|
|
10
|
-
export { ComponentFactorySource };
|
|
25
|
+
export { ComponentFactorySource, StatefulComponentFactorySource };
|
|
@@ -10,44 +10,100 @@ import { makeSquareViewBox } from "../svg/viewbox/square.js";
|
|
|
10
10
|
import { getUsedFactoryProps } from "./helpers/props/ts.js";
|
|
11
11
|
import { minifyViewBox } from "../svg/viewbox/minify.js";
|
|
12
12
|
import { getViewBoxRatio } from "./helpers/content/ratio.js";
|
|
13
|
+
import { addCustomFunctionAsset } from "./helpers/functions/custom.js";
|
|
14
|
+
import { addFallbackFunctionAsset } from "./helpers/functions/fallback.js";
|
|
13
15
|
import { addVueComponentTypes } from "./helpers/ts/vue.js";
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Create functional Vue component code
|
|
17
19
|
*/
|
|
18
20
|
function createVueFunctionalComponent(data, options) {
|
|
21
|
+
const icon = data.icon;
|
|
22
|
+
const viewBox = icon.viewBox;
|
|
23
|
+
const fallback = icon.defaultFallback;
|
|
24
|
+
const statefulData = icon.statefulData;
|
|
19
25
|
const assets = [];
|
|
20
26
|
const imports = createFactoryImports();
|
|
21
27
|
const dependencies = /* @__PURE__ */ new Set();
|
|
22
|
-
|
|
23
|
-
if (hasFallback) {
|
|
28
|
+
if (fallback) {
|
|
24
29
|
imports.named["@iconify/css-vue"] = new Set(["Icon"]);
|
|
25
30
|
dependencies.add("@iconify/css-vue");
|
|
26
31
|
}
|
|
27
32
|
const vueNamedImports = new Set(["defineComponent", "h"]);
|
|
28
33
|
imports.named["vue"] = vueNamedImports;
|
|
29
|
-
const style = generateCSSFilesForComponent(
|
|
34
|
+
const style = generateCSSFilesForComponent(icon, imports, assets, options);
|
|
30
35
|
const isEmbeddedCSS = options.cssMode === "embed";
|
|
31
36
|
let hasFixedSize = !!options.width && !!options.height;
|
|
32
|
-
const viewBox = data.viewBox;
|
|
33
37
|
const hasComputedViewbox = options.square && !hasFixedSize && viewBox.width !== viewBox.height;
|
|
34
|
-
const isStringViewBox = !
|
|
38
|
+
const isStringViewBox = !fallback;
|
|
35
39
|
const hasComputedRatio = hasComputedViewbox && isStringViewBox;
|
|
36
40
|
if (!hasComputedViewbox && (options.width || options.height)) hasFixedSize = true;
|
|
37
41
|
const componentCode = [];
|
|
38
42
|
const props = {};
|
|
39
|
-
if (!
|
|
43
|
+
if (!fallback) props.xmlns = "http://www.w3.org/2000/svg";
|
|
44
|
+
let computedFallback = false;
|
|
45
|
+
if (statefulData) {
|
|
46
|
+
const { supportedStates, allStates } = statefulData;
|
|
47
|
+
if (supportedStates.size) {
|
|
48
|
+
const computedStates = [];
|
|
49
|
+
let addedStateFunc = false;
|
|
50
|
+
for (const state of allStates) if (typeof state === "string") {
|
|
51
|
+
if (supportedStates.has(state)) {
|
|
52
|
+
props[state] = {
|
|
53
|
+
type: "boolean",
|
|
54
|
+
value: state,
|
|
55
|
+
template: ""
|
|
56
|
+
};
|
|
57
|
+
computedStates.push(`'${state}': props['${state}']`);
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
const stateName = state[0];
|
|
61
|
+
if (supportedStates.has(stateName)) {
|
|
62
|
+
const stateValues = state[1];
|
|
63
|
+
const defaultStateValue = state[2] ?? stateValues[0];
|
|
64
|
+
props[stateName] = {
|
|
65
|
+
type: stateValues.map((value) => `'${value}'`).join(" | "),
|
|
66
|
+
value: stateName,
|
|
67
|
+
template: ""
|
|
68
|
+
};
|
|
69
|
+
computedStates.push(`'${stateName}': namedStateValue(props['${stateName}'], '${defaultStateValue}')`);
|
|
70
|
+
if (!addedStateFunc) {
|
|
71
|
+
addedStateFunc = true;
|
|
72
|
+
addCustomFunctionAsset(imports, assets, options, {
|
|
73
|
+
functionName: "namedStateValue",
|
|
74
|
+
content: `export function namedStateValue(value, defaultValue) {
|
|
75
|
+
return value && value !== defaultValue ? value : undefined;
|
|
76
|
+
}`
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (computedStates.length) {
|
|
82
|
+
componentCode.push(`const states = computed(() => ({ ${computedStates.join(", ")} }));`);
|
|
83
|
+
if (fallback && statefulData.fallback) {
|
|
84
|
+
computedFallback = true;
|
|
85
|
+
const func = addFallbackFunctionAsset(imports, assets, options, statefulData.defaultStateValues);
|
|
86
|
+
componentCode.push(`const fallback = computed(() => ${func}(${JSON.stringify(statefulData.fallback)},states.value));`);
|
|
87
|
+
}
|
|
88
|
+
componentCode.push(`const className = computed(() => Object.entries(states.value).map(([key, value]) => value ? \`state-\${value === true ? key : value}\` : '').join(' ').trim() || undefined);`);
|
|
89
|
+
props["class"] = {
|
|
90
|
+
value: "class",
|
|
91
|
+
template: `'class': className.value,`
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
40
96
|
const getViewBox = (viewBox) => isStringViewBox ? `'${stringifyIconViewBox(viewBox)}'` : JSON.stringify(minifyViewBox(viewBox));
|
|
41
97
|
if (hasComputedViewbox) componentCode.push(`const baseViewBox = ${getViewBox(viewBox)};`, `const squareViewBox = ${getViewBox(makeSquareViewBox(viewBox))};`, `const viewBox = computed(() => props.square ? squareViewBox : baseViewBox);`);
|
|
42
98
|
else componentCode.push(`const viewBox = ${getViewBox(viewBox)};`);
|
|
43
99
|
const ratioValue = getViewBoxRatio(viewBox);
|
|
44
100
|
if (hasComputedRatio) componentCode.push(`const ratio = computed(() => props.square ? 1 : ${ratioValue});`);
|
|
45
101
|
if (hasFixedSize) {
|
|
46
|
-
const sizeProps = getComponentSizeValues(options,
|
|
102
|
+
const sizeProps = getComponentSizeValues(options, viewBox);
|
|
47
103
|
if (!sizeProps) throw new Error("Fixed size expected, but could not be determined");
|
|
48
104
|
props.width = sizeProps.width;
|
|
49
105
|
props.height = sizeProps.height;
|
|
50
|
-
} else if (
|
|
106
|
+
} else if (fallback) {
|
|
51
107
|
props.width = {
|
|
52
108
|
type: "string",
|
|
53
109
|
value: "width",
|
|
@@ -61,7 +117,6 @@ function createVueFunctionalComponent(data, options) {
|
|
|
61
117
|
} else {
|
|
62
118
|
const getSizeProps = addSizeFunctionAsset(imports, assets, options);
|
|
63
119
|
componentCode.push(`const size = computed(() => ${getSizeProps}(props.width, props.height, ${hasComputedRatio ? "ratio.value" : ratioValue}));`);
|
|
64
|
-
vueNamedImports.add("computed");
|
|
65
120
|
props.width = {
|
|
66
121
|
type: "string",
|
|
67
122
|
value: "width",
|
|
@@ -73,15 +128,19 @@ function createVueFunctionalComponent(data, options) {
|
|
|
73
128
|
template: ""
|
|
74
129
|
};
|
|
75
130
|
}
|
|
131
|
+
if (componentCode.some((line) => line.includes("computed("))) vueNamedImports.add("computed");
|
|
76
132
|
if (options.square) props.square = { type: "boolean" };
|
|
77
133
|
props.viewBox = {
|
|
78
134
|
value: "viewBox",
|
|
79
135
|
template: hasComputedViewbox ? "viewBox: viewBox.value," : "viewBox,"
|
|
80
136
|
};
|
|
81
|
-
props[
|
|
82
|
-
if (
|
|
137
|
+
props[fallback ? "content" : "innerHTML"] = { value: stringifyFactoryIconContent(icon, isEmbeddedCSS ? style : void 0) };
|
|
138
|
+
if (fallback) props.fallback = computedFallback ? {
|
|
139
|
+
value: "fallback",
|
|
140
|
+
template: "fallback: fallback.value,"
|
|
141
|
+
} : fallback;
|
|
83
142
|
const types = addVueComponentTypes(data, options, assets, props);
|
|
84
|
-
componentCode.push(`return () => h(${
|
|
143
|
+
componentCode.push(`return () => h(${fallback ? "Icon" : "'svg'"}, {
|
|
85
144
|
${stringifyFactoryPropsAsJSON(props, "\n ")}
|
|
86
145
|
});`);
|
|
87
146
|
const usedProps = getUsedFactoryProps(props);
|
package/lib/components/vue.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { stringifyStylesheet } from "../css/stylesheet.js";
|
|
1
2
|
import { getComponentSizeValues } from "./helpers/content/size.js";
|
|
2
3
|
import { stringifyFactoryIconContent } from "./helpers/content/stringify.js";
|
|
3
4
|
import { stringifyIconViewBox } from "../svg/viewbox/value.js";
|
|
@@ -10,44 +11,100 @@ import { makeSquareViewBox } from "../svg/viewbox/square.js";
|
|
|
10
11
|
import { getUsedFactoryProps, stringifyFactoryPropTypes } from "./helpers/props/ts.js";
|
|
11
12
|
import { minifyViewBox } from "../svg/viewbox/minify.js";
|
|
12
13
|
import { getViewBoxRatio } from "./helpers/content/ratio.js";
|
|
14
|
+
import { addCustomFunctionAsset } from "./helpers/functions/custom.js";
|
|
15
|
+
import { addFallbackFunctionAsset } from "./helpers/functions/fallback.js";
|
|
13
16
|
import { addVueComponentTypes } from "./helpers/ts/vue.js";
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* Create Vue component code
|
|
17
20
|
*/
|
|
18
21
|
function createVueComponent(data, options) {
|
|
22
|
+
const icon = data.icon;
|
|
23
|
+
const viewBox = icon.viewBox;
|
|
24
|
+
const fallback = icon.defaultFallback;
|
|
25
|
+
const statefulData = icon.statefulData;
|
|
19
26
|
const useTS = options.ts ?? false;
|
|
20
27
|
const assets = [];
|
|
21
28
|
const imports = createFactoryImports();
|
|
22
29
|
const dependencies = /* @__PURE__ */ new Set();
|
|
23
|
-
|
|
24
|
-
if (hasFallback) {
|
|
30
|
+
if (fallback) {
|
|
25
31
|
imports.named["@iconify/css-vue"] = new Set(["Icon"]);
|
|
26
32
|
dependencies.add("@iconify/css-vue");
|
|
27
33
|
}
|
|
28
34
|
const vueNamedImports = /* @__PURE__ */ new Set();
|
|
29
35
|
imports.named["vue"] = vueNamedImports;
|
|
30
|
-
const styleContent = generateCSSFilesForComponent(
|
|
36
|
+
const styleContent = generateCSSFilesForComponent(icon, imports, assets, options);
|
|
31
37
|
let hasFixedSize = !!options.width && !!options.height;
|
|
32
|
-
const viewBox = data.viewBox;
|
|
33
38
|
const hasComputedViewbox = options.square && !hasFixedSize && viewBox.width !== viewBox.height;
|
|
34
|
-
const isStringViewBox = !
|
|
39
|
+
const isStringViewBox = !fallback;
|
|
35
40
|
const hasComputedRatio = hasComputedViewbox && isStringViewBox;
|
|
36
41
|
if (!hasComputedViewbox && (options.width || options.height)) hasFixedSize = true;
|
|
37
42
|
const componentCode = [];
|
|
38
43
|
const props = {};
|
|
39
|
-
if (!
|
|
44
|
+
if (!fallback) props.xmlns = "http://www.w3.org/2000/svg";
|
|
45
|
+
let computedFallback = false;
|
|
46
|
+
if (statefulData) {
|
|
47
|
+
const { supportedStates, allStates } = statefulData;
|
|
48
|
+
if (supportedStates.size) {
|
|
49
|
+
const computedStates = [];
|
|
50
|
+
let addedStateFunc = false;
|
|
51
|
+
for (const state of allStates) if (typeof state === "string") {
|
|
52
|
+
if (supportedStates.has(state)) {
|
|
53
|
+
props[state] = {
|
|
54
|
+
type: "boolean",
|
|
55
|
+
value: state,
|
|
56
|
+
template: ""
|
|
57
|
+
};
|
|
58
|
+
computedStates.push(`'${state}': props['${state}']`);
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
const stateName = state[0];
|
|
62
|
+
if (supportedStates.has(stateName)) {
|
|
63
|
+
const stateValues = state[1];
|
|
64
|
+
const defaultStateValue = state[2] ?? stateValues[0];
|
|
65
|
+
props[stateName] = {
|
|
66
|
+
type: stateValues.map((value) => `'${value}'`).join(" | "),
|
|
67
|
+
value: stateName,
|
|
68
|
+
template: ""
|
|
69
|
+
};
|
|
70
|
+
computedStates.push(`'${stateName}': namedStateValue(props['${stateName}'], '${defaultStateValue}')`);
|
|
71
|
+
if (!addedStateFunc) {
|
|
72
|
+
addedStateFunc = true;
|
|
73
|
+
addCustomFunctionAsset(imports, assets, options, {
|
|
74
|
+
functionName: "namedStateValue",
|
|
75
|
+
content: `export function namedStateValue(value, defaultValue) {
|
|
76
|
+
return value && value !== defaultValue ? value : undefined;
|
|
77
|
+
}`
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (computedStates.length) {
|
|
83
|
+
componentCode.push(`const states = computed(() => ({ ${computedStates.join(", ")} }));`);
|
|
84
|
+
if (fallback && statefulData.fallback) {
|
|
85
|
+
computedFallback = true;
|
|
86
|
+
const func = addFallbackFunctionAsset(imports, assets, options, statefulData.defaultStateValues);
|
|
87
|
+
componentCode.push(`const fallback = computed(() => ${func}(${JSON.stringify(statefulData.fallback)},states.value));`);
|
|
88
|
+
}
|
|
89
|
+
componentCode.push(`const className = computed(() => Object.entries(states.value).map(([key, value]) => value ? \`state-\${value === true ? key : value}\` : '').join(' ').trim() || undefined);`);
|
|
90
|
+
props.className = {
|
|
91
|
+
value: "className",
|
|
92
|
+
template: ":class=\"className\""
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
40
97
|
const getViewBox = (viewBox) => isStringViewBox ? `'${stringifyIconViewBox(viewBox)}'` : JSON.stringify(minifyViewBox(viewBox));
|
|
41
98
|
if (hasComputedViewbox) componentCode.push(`const baseViewBox = ${getViewBox(viewBox)};`, `const squareViewBox = ${getViewBox(makeSquareViewBox(viewBox))};`, `const viewBox = computed(() => props.square ? squareViewBox : baseViewBox);`);
|
|
42
99
|
else componentCode.push(`const viewBox = ${getViewBox(viewBox)};`);
|
|
43
100
|
const ratioValue = getViewBoxRatio(viewBox);
|
|
44
101
|
if (hasComputedRatio) componentCode.push(`const ratio = computed(() => props.square ? 1 : ${ratioValue});`);
|
|
45
102
|
if (hasFixedSize) {
|
|
46
|
-
const sizeProps = getComponentSizeValues(options,
|
|
103
|
+
const sizeProps = getComponentSizeValues(options, viewBox);
|
|
47
104
|
if (!sizeProps) throw new Error("Fixed size expected, but could not be determined");
|
|
48
105
|
props.width = sizeProps.width;
|
|
49
106
|
props.height = sizeProps.height;
|
|
50
|
-
} else if (
|
|
107
|
+
} else if (fallback) {
|
|
51
108
|
props.width = {
|
|
52
109
|
type: "string",
|
|
53
110
|
value: "width",
|
|
@@ -61,7 +118,6 @@ function createVueComponent(data, options) {
|
|
|
61
118
|
} else {
|
|
62
119
|
const getSizeProps = addSizeFunctionAsset(imports, assets, options);
|
|
63
120
|
componentCode.push(`const size = computed(() => ${getSizeProps}(props.width, props.height, ${hasComputedRatio ? "ratio.value" : ratioValue}));`);
|
|
64
|
-
vueNamedImports.add("computed");
|
|
65
121
|
props.width = {
|
|
66
122
|
type: "string",
|
|
67
123
|
value: "width",
|
|
@@ -73,22 +129,23 @@ function createVueComponent(data, options) {
|
|
|
73
129
|
template: ""
|
|
74
130
|
};
|
|
75
131
|
}
|
|
132
|
+
if (componentCode.some((line) => line.includes("computed("))) vueNamedImports.add("computed");
|
|
76
133
|
if (options.square) props.square = { type: "boolean" };
|
|
77
134
|
props.viewBox = {
|
|
78
135
|
value: "viewBox",
|
|
79
136
|
template: ":viewBox=\"viewBox\""
|
|
80
137
|
};
|
|
81
|
-
componentCode.push(`const content = ${stringifyFactoryIconContent(
|
|
138
|
+
componentCode.push(`const content = ${stringifyFactoryIconContent(icon)};`);
|
|
82
139
|
props.content = {
|
|
83
140
|
value: "content",
|
|
84
|
-
template:
|
|
141
|
+
template: fallback ? `:content="content" ${computedFallback ? ":fallback=\"fallback\"" : `fallback="${fallback}"`}` : "v-html=\"content\""
|
|
85
142
|
};
|
|
86
143
|
const usedProps = getUsedFactoryProps(props);
|
|
87
144
|
if (usedProps.length) {
|
|
88
145
|
const tsCode = useTS ? `<{\n${stringifyFactoryPropTypes(props)}\n}>` : "";
|
|
89
146
|
componentCode.unshift(`const props = defineProps${tsCode}(${tsCode ? "" : JSON.stringify(usedProps)});\n`);
|
|
90
147
|
}
|
|
91
|
-
const template = `<template><${
|
|
148
|
+
const template = `<template><${fallback ? "Icon" : "svg"} ${stringifyFactoryProps(props, ":{prop}=\"{value}\"")} /></template>`;
|
|
92
149
|
let content = `<script setup${useTS ? " lang=\"ts\"" : ""}>
|
|
93
150
|
${stringifyFactoryImports(imports)}
|
|
94
151
|
${componentCode.join("\n")}
|
|
@@ -96,7 +153,7 @@ ${componentCode.join("\n")}
|
|
|
96
153
|
${template}
|
|
97
154
|
`;
|
|
98
155
|
const style = options.cssMode === "prop" ? styleContent : void 0;
|
|
99
|
-
if (styleContent && !style) content += `<style>\n${styleContent}\n</style>\n`;
|
|
156
|
+
if (styleContent && !style) content += `<style>\n${stringifyStylesheet(styleContent)}\n</style>\n`;
|
|
100
157
|
const types = addVueComponentTypes(data, options, assets, props);
|
|
101
158
|
return {
|
|
102
159
|
assets,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find used animation names in content
|
|
3
|
+
*
|
|
4
|
+
* This function is opinionated, it is designed to find animation names in typical CSS content, but it may not cover all edge cases.
|
|
5
|
+
* Assumes animation name uses only the following characters: a-z, 0-9, -, _ and starts with a letter.
|
|
6
|
+
*
|
|
7
|
+
* Might return false positives
|
|
8
|
+
*/
|
|
9
|
+
declare function findUsedKeyframes(content: string): string[];
|
|
10
|
+
export { findUsedKeyframes };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { findCSSPropertyValues } from "./prop.js";
|
|
2
|
+
|
|
3
|
+
const reservedAnimationNames = new Set([
|
|
4
|
+
"none",
|
|
5
|
+
"inherit",
|
|
6
|
+
"initial",
|
|
7
|
+
"revert",
|
|
8
|
+
"revert-layer",
|
|
9
|
+
"forwards",
|
|
10
|
+
"infinite",
|
|
11
|
+
"unset",
|
|
12
|
+
"linear",
|
|
13
|
+
"ease",
|
|
14
|
+
"ease-in",
|
|
15
|
+
"ease-out",
|
|
16
|
+
"ease-in-out"
|
|
17
|
+
]);
|
|
18
|
+
/**
|
|
19
|
+
* Find used animation names in content
|
|
20
|
+
*
|
|
21
|
+
* This function is opinionated, it is designed to find animation names in typical CSS content, but it may not cover all edge cases.
|
|
22
|
+
* Assumes animation name uses only the following characters: a-z, 0-9, -, _ and starts with a letter.
|
|
23
|
+
*
|
|
24
|
+
* Might return false positives
|
|
25
|
+
*/
|
|
26
|
+
function findUsedKeyframes(content) {
|
|
27
|
+
const keyframes = /* @__PURE__ */ new Set();
|
|
28
|
+
findCSSPropertyValues(content, "animation-name").forEach((name) => keyframes.add(name));
|
|
29
|
+
findCSSPropertyValues(content, "animation").forEach((value) => {
|
|
30
|
+
value.split(/\s+/).filter((part) => !reservedAnimationNames.has(part) && part.match(/^[a-z]+[a-z0-9_-]*$/)).forEach((part) => keyframes.add(part));
|
|
31
|
+
});
|
|
32
|
+
return Array.from(keyframes);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { findUsedKeyframes };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { splitClassName } from "../../classname/toggle.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Find class names in content
|
|
5
|
+
*/
|
|
6
|
+
function findUsedClassNames(content) {
|
|
7
|
+
const classNames = /* @__PURE__ */ new Set();
|
|
8
|
+
content.matchAll(/class=["']([^"']+)["']/g).forEach((match) => {
|
|
9
|
+
splitClassName(match[1]).forEach((className) => classNames.add(className));
|
|
10
|
+
});
|
|
11
|
+
return Array.from(classNames);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { findUsedClassNames };
|