@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
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find all values of a CSS property in content
|
|
3
|
+
*/
|
|
4
|
+
function findCSSPropertyValues(content, property) {
|
|
5
|
+
const values = [];
|
|
6
|
+
content.matchAll(new RegExp(`${property}\\s*:\\s*([^;]+);`, "g")).forEach((match) => {
|
|
7
|
+
values.push(...match[1].split(",").map((part) => part.trim()));
|
|
8
|
+
});
|
|
9
|
+
return values;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { findCSSPropertyValues };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CSSRules } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Split rules string into object
|
|
4
|
+
*/
|
|
5
|
+
declare function splitCSSRules(rules: CSSRules | string): CSSRules;
|
|
6
|
+
/**
|
|
7
|
+
* Merge rules
|
|
8
|
+
*/
|
|
9
|
+
declare function mergeCSSRules(rules: CSSRules | string, oldRules?: CSSRules | string): CSSRules;
|
|
10
|
+
export { mergeCSSRules, splitCSSRules };
|
package/lib/css/rules.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split rules string into object
|
|
3
|
+
*/
|
|
4
|
+
function splitCSSRules(rules) {
|
|
5
|
+
if (typeof rules === "string") {
|
|
6
|
+
const result = Object.create(null);
|
|
7
|
+
const parts = rules.split(";");
|
|
8
|
+
for (const part of parts) {
|
|
9
|
+
const [key, value] = part.split(":").map((s) => s.trim());
|
|
10
|
+
if (key && value) result[key] = value;
|
|
11
|
+
}
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
14
|
+
return rules;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Merge rules
|
|
18
|
+
*/
|
|
19
|
+
function mergeCSSRules(rules, oldRules) {
|
|
20
|
+
return {
|
|
21
|
+
...splitCSSRules(oldRules || {}),
|
|
22
|
+
...splitCSSRules(rules)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { mergeCSSRules, splitCSSRules };
|
package/lib/css/stringify.d.ts
CHANGED
|
@@ -7,8 +7,14 @@ declare function stringifyCSSRules(rules: CSSRules, depth?: number): string;
|
|
|
7
7
|
* Stringify CSS selector with rules
|
|
8
8
|
*/
|
|
9
9
|
declare function stringifyCSSSelector(selector: string, rules: string | CSSRules, depth?: number): string;
|
|
10
|
+
/**
|
|
11
|
+
* Convert animation frames to CSS string
|
|
12
|
+
*
|
|
13
|
+
* Does not include @keyframes block, only the content
|
|
14
|
+
*/
|
|
15
|
+
declare function stringifyCSSAnimationFrames(keyframes: CSSKeyframes, depth?: number): string;
|
|
10
16
|
/**
|
|
11
17
|
* Stringify CSS keyframes
|
|
12
18
|
*/
|
|
13
|
-
declare function stringifyCSSKeyframes(animationName: string, keyframes: CSSKeyframes, depth?: number): string;
|
|
14
|
-
export { stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector };
|
|
19
|
+
declare function stringifyCSSKeyframes(animationName: string, keyframes: CSSKeyframes | string, depth?: number): string;
|
|
20
|
+
export { stringifyCSSAnimationFrames, stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector };
|
package/lib/css/stringify.js
CHANGED
|
@@ -17,15 +17,18 @@ function stringifyCSSRules(rules, depth = 1) {
|
|
|
17
17
|
* Stringify CSS selector with rules
|
|
18
18
|
*/
|
|
19
19
|
function stringifyCSSSelector(selector, rules, depth = 0) {
|
|
20
|
-
const content = typeof rules === "string" ? rules : stringifyCSSRules(rules, depth + 1);
|
|
20
|
+
const content = typeof rules === "string" ? indent(depth + 1) + rules + "\n" : stringifyCSSRules(rules, depth + 1);
|
|
21
21
|
if (!content.length) return "";
|
|
22
22
|
const tab = indent(depth);
|
|
23
23
|
return `${tab}${selector} {\n${content}${tab}}\n`;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* Convert animation frames to CSS string
|
|
27
|
+
*
|
|
28
|
+
* Does not include @keyframes block, only the content
|
|
27
29
|
*/
|
|
28
|
-
function
|
|
30
|
+
function stringifyCSSAnimationFrames(keyframes, depth = 0) {
|
|
31
|
+
const lines = [];
|
|
29
32
|
const prop = keyframes.prop;
|
|
30
33
|
const values = /* @__PURE__ */ new Map();
|
|
31
34
|
keyframes.frames.forEach((frame) => {
|
|
@@ -34,13 +37,18 @@ function stringifyCSSKeyframes(animationName, keyframes, depth = 0) {
|
|
|
34
37
|
if (item) item.push(frame.time);
|
|
35
38
|
else values.set(css, [frame.time]);
|
|
36
39
|
});
|
|
37
|
-
const lines = [];
|
|
38
|
-
lines.push(`${indent(depth)}@keyframes ${animationName} {\n`);
|
|
39
40
|
values.forEach((times, css) => {
|
|
40
41
|
lines.push(`${indent(depth + 1)}${times.map((time) => `${(time * 100).toFixed(2).replace(/\.?0+$/, "")}%`).join(", ")} {\n${css}${indent(depth + 1)}}\n`);
|
|
41
42
|
});
|
|
42
|
-
lines.
|
|
43
|
-
|
|
43
|
+
return lines.join("").trim();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Stringify CSS keyframes
|
|
47
|
+
*/
|
|
48
|
+
function stringifyCSSKeyframes(animationName, keyframes, depth = 0) {
|
|
49
|
+
const content = typeof keyframes === "string" ? keyframes : stringifyCSSAnimationFrames(keyframes, depth);
|
|
50
|
+
if (content.includes("@keyframes")) return content;
|
|
51
|
+
return `${indent(depth)}@keyframes ${animationName} {\n${indent(depth + 1)}${content}\n}\n`;
|
|
44
52
|
}
|
|
45
53
|
|
|
46
|
-
export { stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector };
|
|
54
|
+
export { stringifyCSSAnimationFrames, stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector };
|
package/lib/css/stylesheet.d.ts
CHANGED
|
@@ -5,8 +5,6 @@ import { CSSGeneratedStylesheet, CSSRules } from "./types.js";
|
|
|
5
5
|
declare function createEmptyStylesheet(): CSSGeneratedStylesheet;
|
|
6
6
|
/**
|
|
7
7
|
* Add generated selector to stylesheet
|
|
8
|
-
*
|
|
9
|
-
* If item exists, it will be overwritten. Class names should be hashed to avoid conflicts, so this should not cause issues.
|
|
10
8
|
*/
|
|
11
9
|
declare function addGeneratedSelector(stylesheet: CSSGeneratedStylesheet, tree: string[], rules: CSSRules | string): void;
|
|
12
10
|
/**
|
package/lib/css/stylesheet.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { stringifyCSSKeyframes, stringifyCSSSelector } from "./stringify.js";
|
|
2
|
+
import { mergeCSSRules } from "./rules.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Create empty stylesheet
|
|
@@ -11,17 +12,16 @@ function createEmptyStylesheet() {
|
|
|
11
12
|
}
|
|
12
13
|
/**
|
|
13
14
|
* Add generated selector to stylesheet
|
|
14
|
-
*
|
|
15
|
-
* If item exists, it will be overwritten. Class names should be hashed to avoid conflicts, so this should not cause issues.
|
|
16
15
|
*/
|
|
17
16
|
function addGeneratedSelector(stylesheet, tree, rules) {
|
|
17
|
+
tree = tree.filter((item, index) => item.startsWith("@") ? tree.indexOf(item) === index : true);
|
|
18
18
|
let parent = stylesheet.selectors;
|
|
19
19
|
for (let i = 0; i < tree.length; i++) {
|
|
20
20
|
const selector = tree[i];
|
|
21
21
|
if (!parent[selector]) parent[selector] = {};
|
|
22
22
|
const parentItem = parent[selector];
|
|
23
23
|
if (i === tree.length - 1) {
|
|
24
|
-
parentItem.rules = rules;
|
|
24
|
+
parentItem.rules = mergeCSSRules(rules, parentItem.rules);
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
if (!parentItem.nested) parentItem.nested = Object.create(null);
|
package/lib/css/types.d.ts
CHANGED
|
@@ -28,6 +28,6 @@ interface CSSGeneratedSelector {
|
|
|
28
28
|
type CSSGeneratedSelectors = Record<string, CSSGeneratedSelector>;
|
|
29
29
|
interface CSSGeneratedStylesheet {
|
|
30
30
|
selectors: CSSGeneratedSelectors;
|
|
31
|
-
keyframes: Record<string, CSSKeyframes>;
|
|
31
|
+
keyframes: Record<string, CSSKeyframes | string>;
|
|
32
32
|
}
|
|
33
33
|
export { CSSGeneratedSelector, CSSGeneratedSelectors, CSSGeneratedStylesheet, CSSHashOptions, CSSKeyframe, CSSKeyframes, CSSRules };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface ContextItemData<T> {
|
|
2
|
+
parent: Record<string, unknown>;
|
|
3
|
+
key: string;
|
|
4
|
+
actualValue?: T;
|
|
5
|
+
}
|
|
6
|
+
interface ContextItem<T> {
|
|
7
|
+
map: Map<string, ContextItemData<T> | number>;
|
|
8
|
+
data: T[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Create context item for minification
|
|
12
|
+
*/
|
|
13
|
+
declare function createCompactContext<T>(): ContextItem<T>;
|
|
14
|
+
/**
|
|
15
|
+
* Minify item
|
|
16
|
+
*
|
|
17
|
+
* If value is not a string, set it in `actualValue` and string `value` for comparison
|
|
18
|
+
*/
|
|
19
|
+
declare function compactItem<T>(context: ContextItem<T>, stringifiedValue: string, parent: Record<string, unknown>, key: string, actualValue?: T): void;
|
|
20
|
+
export { compactItem, createCompactContext };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create context item for minification
|
|
3
|
+
*/
|
|
4
|
+
function createCompactContext() {
|
|
5
|
+
return {
|
|
6
|
+
map: /* @__PURE__ */ new Map(),
|
|
7
|
+
data: []
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Minify item
|
|
12
|
+
*
|
|
13
|
+
* If value is not a string, set it in `actualValue` and string `value` for comparison
|
|
14
|
+
*/
|
|
15
|
+
function compactItem(context, stringifiedValue, parent, key, actualValue) {
|
|
16
|
+
const { map, data } = context;
|
|
17
|
+
const existing = map.get(stringifiedValue);
|
|
18
|
+
if (typeof existing === "number") {
|
|
19
|
+
parent[key] = existing;
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const value = actualValue ?? stringifiedValue;
|
|
23
|
+
if (existing) {
|
|
24
|
+
const index = data.length;
|
|
25
|
+
data.push(value);
|
|
26
|
+
map.set(stringifiedValue, index);
|
|
27
|
+
parent[key] = index;
|
|
28
|
+
existing.parent[existing.key] = index;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
map.set(stringifiedValue, {
|
|
32
|
+
parent,
|
|
33
|
+
key
|
|
34
|
+
});
|
|
35
|
+
parent[key] = value;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { compactItem, createCompactContext };
|
package/lib/index.d.ts
CHANGED
|
@@ -2,10 +2,15 @@ import { ClassProp, classProps, defaultClassProp } from "./classname/const.js";
|
|
|
2
2
|
import { splitClassName, toggleClassName } from "./classname/toggle.js";
|
|
3
3
|
import { HashContext, UniqueHashOptions, UniqueHashPartialOptions } from "./helpers/hash/types.js";
|
|
4
4
|
import { CSSGeneratedSelector, CSSGeneratedSelectors, CSSGeneratedStylesheet, CSSHashOptions, CSSKeyframe, CSSKeyframes, CSSRules } from "./css/types.js";
|
|
5
|
+
import { IconStatesAdvancedState, IconStatesAdvancedStateValues, IconStatesList, IconStatesSimpleState, IconStatesState } from "./svg-css/states/types.js";
|
|
6
|
+
import { ExtendedSVGCSSIconClass, SVGCSSIcon, SVGCSSIconRules, SVGCSSStatefulIcon, SVGCSSStatefulIconRules } from "./svg-css/icon/types.js";
|
|
7
|
+
import { IconFallbackAdvancedState, IconFallbackBooleanState, IconFallbackTemplate } from "./svg-css/states/fallback/types.js";
|
|
5
8
|
import { ParsedXMLNode, ParsedXMLTagElement, ParsedXMLTextElement, StringifyXMLOptions } from "./xml/types.js";
|
|
6
9
|
import { BaseConvertSVGContentOptions, ConvertSVGContentOptions, ConvertedSVGContent } from "./svg-css/types.js";
|
|
7
10
|
import { createCSSClassName } from "./css/hash.js";
|
|
8
|
-
import {
|
|
11
|
+
import { minifyCSS } from "./css/minify.js";
|
|
12
|
+
import { mergeCSSRules, splitCSSRules } from "./css/rules.js";
|
|
13
|
+
import { stringifyCSSAnimationFrames, stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector } from "./css/stringify.js";
|
|
9
14
|
import { addGeneratedSelector, createEmptyStylesheet, stringifyStylesheet } from "./css/stylesheet.js";
|
|
10
15
|
import { createUniqueHashContext } from "./helpers/hash/context.js";
|
|
11
16
|
import { hashString } from "./helpers/hash/hash.js";
|
|
@@ -27,4 +32,12 @@ import { changeSVGIDs } from "./svg/ids/change.js";
|
|
|
27
32
|
import { createUniqueIDs } from "./svg/ids/unique.js";
|
|
28
33
|
import { convertSVGRootToCSS } from "./svg-css/root.js";
|
|
29
34
|
import { convertSVGContentToCSSRules } from "./svg-css/content.js";
|
|
30
|
-
|
|
35
|
+
import { getIconFallback } from "./svg-css/states/fallback/stringify.js";
|
|
36
|
+
import { getStatesFromKey } from "./svg-css/states/key.js";
|
|
37
|
+
import { getObjectFromStates } from "./svg-css/states/object.js";
|
|
38
|
+
import { getAdvancedStateDefaultValue, getStateValue } from "./svg-css/states/value.js";
|
|
39
|
+
import { SVGCSSIconSet, SVGCSSIconSetClassData, SVGCSSIconSetIcon, SVGCSSIconSetSharedData } from "./svg-css/icon-set/types.js";
|
|
40
|
+
import { getSVGCSSIconFromIconSet } from "./svg-css/icon-set/get.js";
|
|
41
|
+
import { addIconToSVGCSSIconSet } from "./svg-css/icon-set/add.js";
|
|
42
|
+
import { createEmptySVGCSSIconSet } from "./svg-css/icon-set/create.js";
|
|
43
|
+
export { BaseConvertSVGContentOptions, CSSGeneratedSelector, CSSGeneratedSelectors, CSSGeneratedStylesheet, CSSHashOptions, CSSKeyframe, CSSKeyframes, CSSRules, ChangeIDResult, ClassProp, ComparisonKey, ConvertSVGContentOptions, ConvertedSVGContent, ExtendedSVGCSSIconClass, HashContext, IconFallbackAdvancedState, IconFallbackBooleanState, IconFallbackTemplate, IconStatesAdvancedState, IconStatesAdvancedStateValues, IconStatesList, IconStatesSimpleState, IconStatesState, ParsedXMLNode, ParsedXMLTagElement, ParsedXMLTextElement, SVGCSSIcon, SVGCSSIconRules, SVGCSSIconSet, SVGCSSIconSetClassData, SVGCSSIconSetIcon, SVGCSSIconSetSharedData, SVGCSSStatefulIcon, SVGCSSStatefulIconRules, StringifyXMLOptions, UniqueHashOptions, UniqueHashPartialOptions, UniqueIDOptions, addGeneratedSelector, addIconToSVGCSSIconSet, changeIDInString, changeSVGIDs, classProps, cloneObject, compareKeys, compareSets, compareValues, convertSVGContentToCSSRules, convertSVGRootToCSS, createCSSClassName, createEmptySVGCSSIconSet, createEmptyStylesheet, createUniqueHashContext, createUniqueIDs, defaultClassProp, getAdvancedStateDefaultValue, getIconFallback, getObjectFromStates, getSVGCSSIconFromIconSet, getStateValue, getStatesFromKey, getUniqueHash, hashString, hashToString, iterateXMLContent, mergeCSSRules, minifyCSS, parseXMLContent, removeDuplicateIDs, removeUnusedIDs, sortObject, splitCSSRules, splitClassName, stringifyCSSAnimationFrames, stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector, stringifyStylesheet, stringifyXMLContent, toggleClassName, uniquePromise };
|
package/lib/index.js
CHANGED
|
@@ -11,7 +11,9 @@ import { iterateXMLContent } from "./xml/iterate.js";
|
|
|
11
11
|
import { parseXMLContent } from "./xml/parse.js";
|
|
12
12
|
import { stringifyXMLContent } from "./xml/stringify.js";
|
|
13
13
|
import { createCSSClassName } from "./css/hash.js";
|
|
14
|
-
import { stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector } from "./css/stringify.js";
|
|
14
|
+
import { stringifyCSSAnimationFrames, stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector } from "./css/stringify.js";
|
|
15
|
+
import { mergeCSSRules, splitCSSRules } from "./css/rules.js";
|
|
16
|
+
import { minifyCSS } from "./css/minify.js";
|
|
15
17
|
import { addGeneratedSelector, createEmptyStylesheet, stringifyStylesheet } from "./css/stylesheet.js";
|
|
16
18
|
import { classProps, defaultClassProp } from "./classname/const.js";
|
|
17
19
|
import { splitClassName, toggleClassName } from "./classname/toggle.js";
|
|
@@ -22,5 +24,12 @@ import { changeSVGIDs } from "./svg/ids/change.js";
|
|
|
22
24
|
import { createUniqueIDs } from "./svg/ids/unique.js";
|
|
23
25
|
import { convertSVGRootToCSS } from "./svg-css/root.js";
|
|
24
26
|
import { convertSVGContentToCSSRules } from "./svg-css/content.js";
|
|
27
|
+
import { getIconFallback } from "./svg-css/states/fallback/stringify.js";
|
|
28
|
+
import { getStatesFromKey } from "./svg-css/states/key.js";
|
|
29
|
+
import { getAdvancedStateDefaultValue, getStateValue } from "./svg-css/states/value.js";
|
|
30
|
+
import { getObjectFromStates } from "./svg-css/states/object.js";
|
|
31
|
+
import { getSVGCSSIconFromIconSet } from "./svg-css/icon-set/get.js";
|
|
32
|
+
import { addIconToSVGCSSIconSet } from "./svg-css/icon-set/add.js";
|
|
33
|
+
import { createEmptySVGCSSIconSet } from "./svg-css/icon-set/create.js";
|
|
25
34
|
|
|
26
|
-
export { addGeneratedSelector, changeIDInString, changeSVGIDs, classProps, cloneObject, compareKeys, compareSets, compareValues, convertSVGContentToCSSRules, convertSVGRootToCSS, createCSSClassName, createEmptyStylesheet, createUniqueHashContext, createUniqueIDs, defaultClassProp, getUniqueHash, hashString, hashToString, iterateXMLContent, parseXMLContent, removeDuplicateIDs, removeUnusedIDs, sortObject, splitClassName, stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector, stringifyStylesheet, stringifyXMLContent, toggleClassName, uniquePromise };
|
|
35
|
+
export { addGeneratedSelector, addIconToSVGCSSIconSet, changeIDInString, changeSVGIDs, classProps, cloneObject, compareKeys, compareSets, compareValues, convertSVGContentToCSSRules, convertSVGRootToCSS, createCSSClassName, createEmptySVGCSSIconSet, createEmptyStylesheet, createUniqueHashContext, createUniqueIDs, defaultClassProp, getAdvancedStateDefaultValue, getIconFallback, getObjectFromStates, getSVGCSSIconFromIconSet, getStateValue, getStatesFromKey, getUniqueHash, hashString, hashToString, iterateXMLContent, mergeCSSRules, minifyCSS, parseXMLContent, removeDuplicateIDs, removeUnusedIDs, sortObject, splitCSSRules, splitClassName, stringifyCSSAnimationFrames, stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector, stringifyStylesheet, stringifyXMLContent, toggleClassName, uniquePromise };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CSSGeneratedStylesheet } from "../../css/types.js";
|
|
2
|
+
import { SVGCSSIconRules, SVGCSSStatefulIconRules } from "./types.js";
|
|
3
|
+
import { StatefulIconSelectorsContext } from "../states/selector/types.js";
|
|
4
|
+
type StylesheetParam = CSSGeneratedStylesheet | ((selector: string) => CSSGeneratedStylesheet);
|
|
5
|
+
/**
|
|
6
|
+
* Add styles for stateful icon to stylesheet
|
|
7
|
+
*
|
|
8
|
+
* If commonStylesheet is an object, all styles will be added to it and result
|
|
9
|
+
* will contain the same stylesheet for all classes.
|
|
10
|
+
*
|
|
11
|
+
* If commonStylesheet is not an object, styles will be separated into different
|
|
12
|
+
* stylesheets for classes and keyframes, which can be reused across icons.
|
|
13
|
+
*/
|
|
14
|
+
declare function renderStatefulSVGCSSIconStyle(icon: SVGCSSStatefulIconRules, context: StatefulIconSelectorsContext | null, commonStylesheet?: StylesheetParam): Record<string, CSSGeneratedStylesheet>;
|
|
15
|
+
/**
|
|
16
|
+
* Add styles for icon to stylesheet
|
|
17
|
+
*
|
|
18
|
+
* If commonStylesheet is an object, all styles will be added to it and result
|
|
19
|
+
* will contain the same stylesheet for all classes.
|
|
20
|
+
*
|
|
21
|
+
* If commonStylesheet is not an object, styles will be separated into different
|
|
22
|
+
* stylesheets for classes and keyframes, which can be reused across icons.
|
|
23
|
+
*/
|
|
24
|
+
declare function renderSVGCSSIconStyle(icon: SVGCSSIconRules, commonStylesheet?: StylesheetParam): Record<string, CSSGeneratedStylesheet>;
|
|
25
|
+
export { renderSVGCSSIconStyle, renderStatefulSVGCSSIconStyle };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { addGeneratedSelector, createEmptyStylesheet } from "../../css/stylesheet.js";
|
|
2
|
+
import { prefersReduceMotion } from "../../helpers/reduce-motion.js";
|
|
3
|
+
import { getSelectorsForStateValues } from "../states/selector/parse.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Add styles for stateful icon to stylesheet
|
|
7
|
+
*
|
|
8
|
+
* If commonStylesheet is an object, all styles will be added to it and result
|
|
9
|
+
* will contain the same stylesheet for all classes.
|
|
10
|
+
*
|
|
11
|
+
* If commonStylesheet is not an object, styles will be separated into different
|
|
12
|
+
* stylesheets for classes and keyframes, which can be reused across icons.
|
|
13
|
+
*/
|
|
14
|
+
function renderStatefulSVGCSSIconStyle(icon, context, commonStylesheet = createEmptyStylesheet) {
|
|
15
|
+
const stylesheets = Object.create(null);
|
|
16
|
+
const getStylesheet = (className) => {
|
|
17
|
+
if (typeof commonStylesheet === "object") return commonStylesheet;
|
|
18
|
+
if (!stylesheets[className]) stylesheets[className] = commonStylesheet(className);
|
|
19
|
+
return stylesheets[className];
|
|
20
|
+
};
|
|
21
|
+
for (const className in icon.classes) addGeneratedSelector(getStylesheet(className), [`.${className}`], icon.classes[className]);
|
|
22
|
+
for (const className in icon.animations) addGeneratedSelector(getStylesheet(className), [prefersReduceMotion, `.${className}`], icon.animations[className]);
|
|
23
|
+
for (const keyframeName in icon.keyframes) getStylesheet(keyframeName).keyframes[keyframeName] = icon.keyframes[keyframeName];
|
|
24
|
+
if (context) for (const className in icon.statefulClasses) {
|
|
25
|
+
const baseClassName = `.${className}`;
|
|
26
|
+
const stylesheet = getStylesheet(className);
|
|
27
|
+
const classData = icon.statefulClasses[className];
|
|
28
|
+
if (classData.transition) addGeneratedSelector(getStylesheet(className), [prefersReduceMotion, baseClassName], classData.transition);
|
|
29
|
+
for (const stateKey in classData.stateRules) {
|
|
30
|
+
const selectors = getSelectorsForStateValues(context, stateKey);
|
|
31
|
+
if (selectors) for (const tree of selectors) addGeneratedSelector(stylesheet, [...tree, baseClassName], classData.stateRules[stateKey]);
|
|
32
|
+
}
|
|
33
|
+
for (const stateKey in classData.stateTransition) {
|
|
34
|
+
const selectors = getSelectorsForStateValues(context, stateKey);
|
|
35
|
+
if (selectors) for (const tree of selectors) addGeneratedSelector(stylesheet, [
|
|
36
|
+
prefersReduceMotion,
|
|
37
|
+
...tree,
|
|
38
|
+
baseClassName
|
|
39
|
+
], classData.stateTransition[stateKey]);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return stylesheets;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Add styles for icon to stylesheet
|
|
46
|
+
*
|
|
47
|
+
* If commonStylesheet is an object, all styles will be added to it and result
|
|
48
|
+
* will contain the same stylesheet for all classes.
|
|
49
|
+
*
|
|
50
|
+
* If commonStylesheet is not an object, styles will be separated into different
|
|
51
|
+
* stylesheets for classes and keyframes, which can be reused across icons.
|
|
52
|
+
*/
|
|
53
|
+
function renderSVGCSSIconStyle(icon, commonStylesheet) {
|
|
54
|
+
return renderStatefulSVGCSSIconStyle(icon, null, commonStylesheet);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { renderSVGCSSIconStyle, renderStatefulSVGCSSIconStyle };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { CSSKeyframes, CSSRules } from "../../css/types.js";
|
|
2
|
+
import { IconViewBox } from "../../svg/viewbox/types.js";
|
|
3
|
+
import { IconStatesList } from "../states/types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Main properties
|
|
6
|
+
*/
|
|
7
|
+
interface MainProps {
|
|
8
|
+
viewBox: IconViewBox | string;
|
|
9
|
+
fallback?: string;
|
|
10
|
+
content: string;
|
|
11
|
+
}
|
|
12
|
+
interface StatefulMainProps extends MainProps {
|
|
13
|
+
states?: IconStatesList;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* CSS data
|
|
17
|
+
*/
|
|
18
|
+
interface SVGCSSIconRules {
|
|
19
|
+
classes?: Record<string, CSSRules | string>;
|
|
20
|
+
animations?: Record<string, CSSRules | string>;
|
|
21
|
+
keyframes?: Record<string, CSSKeyframes | string>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Extended class interface for stateful icons
|
|
25
|
+
*/
|
|
26
|
+
interface ExtendedSVGCSSIconClass {
|
|
27
|
+
stateRules?: Record<string, CSSRules | string>;
|
|
28
|
+
transition?: CSSRules | string;
|
|
29
|
+
stateTransition?: Record<string, CSSRules | string>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Stateful CSS data
|
|
33
|
+
*/
|
|
34
|
+
interface SVGCSSStatefulIconRules extends SVGCSSIconRules {
|
|
35
|
+
statefulClasses?: Record<string, ExtendedSVGCSSIconClass>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Icon data
|
|
39
|
+
*/
|
|
40
|
+
interface SVGCSSIcon extends MainProps, SVGCSSIconRules {}
|
|
41
|
+
/**
|
|
42
|
+
* Icon with states
|
|
43
|
+
*/
|
|
44
|
+
interface SVGCSSStatefulIcon extends StatefulMainProps, SVGCSSStatefulIconRules {}
|
|
45
|
+
export { ExtendedSVGCSSIconClass, SVGCSSIcon, SVGCSSIconRules, SVGCSSStatefulIcon, SVGCSSStatefulIconRules };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SVGCSSIcon, SVGCSSStatefulIcon } from "../icon/types.js";
|
|
2
|
+
import { SVGCSSIconSet } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Add icon to an icon set
|
|
5
|
+
*/
|
|
6
|
+
declare function addIconToSVGCSSIconSet(iconSet: SVGCSSIconSet, iconName: string, icon: SVGCSSIcon | SVGCSSStatefulIcon): void;
|
|
7
|
+
export { addIconToSVGCSSIconSet };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { stringifyCSSAnimationFrames, stringifyCSSRules } from "../../css/stringify.js";
|
|
2
|
+
import { minifyCSS } from "../../css/minify.js";
|
|
3
|
+
|
|
4
|
+
function minifyRules(value) {
|
|
5
|
+
return (value ? minifyCSS(typeof value === "string" ? value : stringifyCSSRules(value)) : void 0) || void 0;
|
|
6
|
+
}
|
|
7
|
+
function stringifyObject(data) {
|
|
8
|
+
if (data) {
|
|
9
|
+
const result = Object.create(null);
|
|
10
|
+
for (const key in data) result[key] = minifyCSS(typeof data[key] === "string" ? data[key] : stringifyCSSRules(data[key]));
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Add icon to an icon set
|
|
16
|
+
*/
|
|
17
|
+
function addIconToSVGCSSIconSet(iconSet, iconName, icon) {
|
|
18
|
+
iconSet.icons[iconName] = {
|
|
19
|
+
content: icon.content,
|
|
20
|
+
fallback: icon.fallback,
|
|
21
|
+
states: icon.states,
|
|
22
|
+
viewBox: icon.viewBox
|
|
23
|
+
};
|
|
24
|
+
const { classes, animations, statefulClasses, keyframes } = icon;
|
|
25
|
+
const classNames = new Set([...Object.keys(classes || {}), ...Object.keys(statefulClasses || {})]);
|
|
26
|
+
for (const className of classNames) if (!iconSet.classes?.[className]) {
|
|
27
|
+
const classData = {};
|
|
28
|
+
iconSet.classes = iconSet.classes || Object.create(null);
|
|
29
|
+
iconSet.classes[className] = classData;
|
|
30
|
+
const r = classes?.[className];
|
|
31
|
+
if (r) classData.r = minifyRules(r);
|
|
32
|
+
const a = animations?.[className];
|
|
33
|
+
if (a) classData.a = minifyRules(a);
|
|
34
|
+
const statefulClass = statefulClasses?.[className];
|
|
35
|
+
if (statefulClass) {
|
|
36
|
+
const { stateRules, transition, stateTransition } = statefulClass;
|
|
37
|
+
if (stateRules) classData.sr = stringifyObject(stateRules);
|
|
38
|
+
if (transition) classData.t = minifyRules(transition);
|
|
39
|
+
if (stateTransition) classData.st = stringifyObject(stateTransition);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (keyframes) {
|
|
43
|
+
iconSet.keyframes = iconSet.keyframes || Object.create(null);
|
|
44
|
+
const iconSetKeyframes = iconSet.keyframes;
|
|
45
|
+
for (const keyframeName in keyframes) if (!iconSetKeyframes[keyframeName]) {
|
|
46
|
+
const value = keyframes[keyframeName];
|
|
47
|
+
iconSetKeyframes[keyframeName] = typeof value === "string" ? value : minifyCSS(stringifyCSSAnimationFrames(value));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { addIconToSVGCSSIconSet };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { SVGCSSIcon, SVGCSSStatefulIcon } from "../icon/types.js";
|
|
2
|
+
import { SVGCSSIconSet } from "./types.js";
|
|
3
|
+
declare function getSVGCSSIconFromIconSet(iconSet: SVGCSSIconSet, name: string): SVGCSSIcon | SVGCSSStatefulIcon | undefined;
|
|
4
|
+
export { getSVGCSSIconFromIconSet };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { findUsedKeyframes } from "../../css/find/animations.js";
|
|
2
|
+
import { findUsedClassNames } from "../../css/find/classname.js";
|
|
3
|
+
import { expandSVGCSSIconSetClass } from "./minify/expand.js";
|
|
4
|
+
|
|
5
|
+
function getSVGCSSIconFromIconSet(iconSet, name) {
|
|
6
|
+
const fullName = iconSet.aliases?.[name] || name;
|
|
7
|
+
const data = iconSet.icons[fullName];
|
|
8
|
+
if (!data) return;
|
|
9
|
+
const { viewBoxes, css, fallbackPrefix = "", fallbackSuffix = "" } = iconSet;
|
|
10
|
+
let viewBox = data.viewBox;
|
|
11
|
+
if (typeof viewBox === "number") viewBox = viewBoxes?.[viewBox];
|
|
12
|
+
if (!viewBox) return;
|
|
13
|
+
let states = data.states;
|
|
14
|
+
if (typeof states === "number") states = iconSet.statesList?.[states];
|
|
15
|
+
const content = data.content;
|
|
16
|
+
const classNames = findUsedClassNames(content);
|
|
17
|
+
const classes = Object.create(null);
|
|
18
|
+
const animations = Object.create(null);
|
|
19
|
+
const statefulClasses = Object.create(null);
|
|
20
|
+
const cssLines = [];
|
|
21
|
+
classNames.forEach((className) => {
|
|
22
|
+
const classContent = iconSet.classes?.[className];
|
|
23
|
+
if (classContent) {
|
|
24
|
+
if (css) expandSVGCSSIconSetClass(css, classContent);
|
|
25
|
+
const { r, a, t, sr, st } = classContent;
|
|
26
|
+
const statefulClass = Object.create(null);
|
|
27
|
+
if (r) {
|
|
28
|
+
classes[className] = r;
|
|
29
|
+
cssLines.push(r);
|
|
30
|
+
}
|
|
31
|
+
if (a) {
|
|
32
|
+
animations[className] = a;
|
|
33
|
+
cssLines.push(a);
|
|
34
|
+
}
|
|
35
|
+
if (sr) {
|
|
36
|
+
const stateRules = Object.create(null);
|
|
37
|
+
statefulClass.stateRules = stateRules;
|
|
38
|
+
for (const state in sr) {
|
|
39
|
+
stateRules[state] = sr[state];
|
|
40
|
+
cssLines.push(sr[state]);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (t) {
|
|
44
|
+
statefulClass.transition = t;
|
|
45
|
+
cssLines.push(t);
|
|
46
|
+
}
|
|
47
|
+
if (st) {
|
|
48
|
+
const stateTransition = Object.create(null);
|
|
49
|
+
statefulClass.stateTransition = stateTransition;
|
|
50
|
+
for (const state in st) {
|
|
51
|
+
stateTransition[state] = st[state];
|
|
52
|
+
cssLines.push(st[state]);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
for (const key in statefulClass) {
|
|
56
|
+
statefulClasses[className] = statefulClass;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
const keyframes = Object.create(null);
|
|
62
|
+
if (iconSet.keyframes) findUsedKeyframes(cssLines.join(";")).forEach((animationName) => {
|
|
63
|
+
const keyframeContent = iconSet.keyframes[animationName];
|
|
64
|
+
if (keyframeContent) keyframes[animationName] = keyframeContent;
|
|
65
|
+
});
|
|
66
|
+
const result = {
|
|
67
|
+
content,
|
|
68
|
+
viewBox,
|
|
69
|
+
states,
|
|
70
|
+
fallback: typeof data.fallback === "string" ? `${fallbackPrefix}${data.fallback}${fallbackSuffix}` : void 0
|
|
71
|
+
};
|
|
72
|
+
let _key;
|
|
73
|
+
for (_key in classes) {
|
|
74
|
+
result.classes = classes;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
for (_key in animations) {
|
|
78
|
+
result.animations = animations;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
for (_key in keyframes) {
|
|
82
|
+
result.keyframes = keyframes;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
for (_key in statefulClasses) {
|
|
86
|
+
result.statefulClasses = statefulClasses;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export { getSVGCSSIconFromIconSet };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SVGCSSIconSet, SVGCSSIconSetClassData } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Expand class content from icon set
|
|
4
|
+
*/
|
|
5
|
+
declare function expandSVGCSSIconSetClass(css: Required<SVGCSSIconSet>['css'], classContent: SVGCSSIconSetClassData): void;
|
|
6
|
+
/**
|
|
7
|
+
* Unminify icon set
|
|
8
|
+
*/
|
|
9
|
+
declare function expandSVGCSSIconSet(iconSet: SVGCSSIconSet): void;
|
|
10
|
+
export { expandSVGCSSIconSet, expandSVGCSSIconSetClass };
|