@cyberalien/svg-utils 1.2.5 → 1.2.6
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/helpers/ts/jsx.js +3 -4
- package/lib/components/helpers/ts/solid.d.ts +9 -0
- package/lib/components/helpers/ts/solid.js +20 -0
- package/lib/components/helpers/ts/wrapper.d.ts +5 -1
- package/lib/components/helpers/ts/wrapper.js +5 -1
- package/lib/components/jsx.d.ts +1 -1
- package/lib/components/jsx.js +2 -3
- package/lib/components/solid.d.ts +11 -0
- package/lib/components/solid.js +170 -0
- package/package.json +1 -1
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { addComponentTypes } from "./wrapper.js";
|
|
1
|
+
import { addComponentTypes, omitComponentSVGProps } from "./wrapper.js";
|
|
2
2
|
|
|
3
3
|
const iconPropsTemplate = `interface IconProps {
|
|
4
4
|
/* PROPS */
|
|
5
5
|
}`;
|
|
6
6
|
const exportTemplate = `export { type IconProps };
|
|
7
7
|
export default Component;`;
|
|
8
|
-
const omitProps = `'viewBox' | 'width' | 'height' | 'xmlns'`;
|
|
9
8
|
/**
|
|
10
9
|
* Add JSX component types
|
|
11
10
|
*/
|
|
@@ -18,7 +17,7 @@ function addJSXComponentTypes(data, options, assets, props) {
|
|
|
18
17
|
${iconPropsTemplate}
|
|
19
18
|
|
|
20
19
|
const Component: ForwardRefExoticComponent<
|
|
21
|
-
Omit<SVGProps<SVGSVGElement>, ${
|
|
20
|
+
Omit<SVGProps<SVGSVGElement>, ${omitComponentSVGProps}> & IconProps
|
|
22
21
|
>;
|
|
23
22
|
|
|
24
23
|
${exportTemplate}
|
|
@@ -28,7 +27,7 @@ ${exportTemplate}
|
|
|
28
27
|
|
|
29
28
|
${iconPropsTemplate}
|
|
30
29
|
|
|
31
|
-
const Component: (props: Omit<JSX.SVGAttributes<SVGSVGElement>, ${
|
|
30
|
+
const Component: (props: Omit<JSX.SVGAttributes<SVGSVGElement>, ${omitComponentSVGProps}> & IconProps) => JSX.Element;
|
|
32
31
|
|
|
33
32
|
${exportTemplate}
|
|
34
33
|
`;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GeneratedAssetFile } from "../../types/component.js";
|
|
2
|
+
import { FactoryIconData } from "../../types/data.js";
|
|
3
|
+
import { ComponentFactoryOptions } from "../../types/options.js";
|
|
4
|
+
import { FactoryComponentProps } from "../props/types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Add Solid component types
|
|
7
|
+
*/
|
|
8
|
+
declare const addSolidComponentTypes: (data: FactoryIconData, options: ComponentFactoryOptions, assets: GeneratedAssetFile[], props: FactoryComponentProps) => string;
|
|
9
|
+
export { addSolidComponentTypes };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { addComponentTypes, omitComponentSVGProps } from "./wrapper.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Add Solid component types
|
|
5
|
+
*/
|
|
6
|
+
const addSolidComponentTypes = addComponentTypes.bind(null, `import { JSX } from 'solid-js';
|
|
7
|
+
|
|
8
|
+
interface IconProps {
|
|
9
|
+
/* PROPS */
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
declare const Component: (
|
|
13
|
+
props: Omit<JSX.SvgSVGAttributes<SVGSVGElement>, ${omitComponentSVGProps}> & IconProps
|
|
14
|
+
) => JSX.Element;
|
|
15
|
+
|
|
16
|
+
export { type IconProps };
|
|
17
|
+
export default Component;
|
|
18
|
+
`);
|
|
19
|
+
|
|
20
|
+
export { addSolidComponentTypes };
|
|
@@ -2,8 +2,12 @@ import { GeneratedAssetFile } from "../../types/component.js";
|
|
|
2
2
|
import { FactoryIconData } from "../../types/data.js";
|
|
3
3
|
import { ComponentFactoryOptions } from "../../types/options.js";
|
|
4
4
|
import { FactoryComponentProps } from "../props/types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Properties to omit
|
|
7
|
+
*/
|
|
8
|
+
declare const omitComponentSVGProps = "'viewBox' | 'width' | 'height' | 'xmlns'";
|
|
5
9
|
/**
|
|
6
10
|
* Add component types
|
|
7
11
|
*/
|
|
8
12
|
declare function addComponentTypes(template: string, data: FactoryIconData, options: ComponentFactoryOptions, assets: GeneratedAssetFile[], props: FactoryComponentProps): string;
|
|
9
|
-
export { addComponentTypes };
|
|
13
|
+
export { addComponentTypes, omitComponentSVGProps };
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { stringifyFactoryPropTypes } from "../props/ts.js";
|
|
2
2
|
import { getGeneratedComponentTypesFilename } from "../filenames/types.js";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Properties to omit
|
|
6
|
+
*/
|
|
7
|
+
const omitComponentSVGProps = `'viewBox' | 'width' | 'height' | 'xmlns'`;
|
|
4
8
|
/**
|
|
5
9
|
* Add component types
|
|
6
10
|
*/
|
|
@@ -15,4 +19,4 @@ function addComponentTypes(template, data, options, assets, props) {
|
|
|
15
19
|
return filename.filename;
|
|
16
20
|
}
|
|
17
21
|
|
|
18
|
-
export { addComponentTypes };
|
|
22
|
+
export { addComponentTypes, omitComponentSVGProps };
|
package/lib/components/jsx.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ interface Options extends ComponentFactoryOptions {
|
|
|
8
8
|
ts?: boolean;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
* Create
|
|
11
|
+
* Create React component code
|
|
12
12
|
*/
|
|
13
13
|
declare function createJSXComponent(data: FactoryIconData, options: Options): FactoryGeneratedComponent;
|
|
14
14
|
export { createJSXComponent };
|
package/lib/components/jsx.js
CHANGED
|
@@ -16,7 +16,7 @@ import { addFallbackFunctionAsset } from "./helpers/functions/fallback.js";
|
|
|
16
16
|
import { addInnerHTMLFunctionAsset } from "./helpers/functions/innerhtml.js";
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* Create
|
|
19
|
+
* Create React component code
|
|
20
20
|
*/
|
|
21
21
|
function createJSXComponent(data, options) {
|
|
22
22
|
const icon = data.icon;
|
|
@@ -178,8 +178,7 @@ function createJSXComponent(data, options) {
|
|
|
178
178
|
const propTypes = stringifyFactoryPropTypes(props);
|
|
179
179
|
const typesCode = useTS ? `interface Props {\n${propTypes}\n};\n\n` : propTypes ? `/** @type {{${propTypes.replace(/\s*\n\s*/g, " ").trim()}}} */\n` : "";
|
|
180
180
|
const usedProps = getUsedFactoryProps(props);
|
|
181
|
-
const
|
|
182
|
-
const componentFunction = `${typesCode}function Component${useTS ? `<Props>` : ""}(${propsDestricturing}) {
|
|
181
|
+
const componentFunction = `${typesCode}function Component(${usedProps.length ? `{${[...usedProps, "...props"].join(", ")}}` : "props"}${useTS ? `: Props` : ""}) {
|
|
183
182
|
\t${componentInternalCode.join("\n ")}
|
|
184
183
|
}
|
|
185
184
|
`;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FactoryGeneratedComponent } from "./types/component.js";
|
|
2
|
+
import { FactoryIconData } from "./types/data.js";
|
|
3
|
+
import { ComponentFactoryOptions } from "./types/options.js";
|
|
4
|
+
interface Options extends ComponentFactoryOptions {
|
|
5
|
+
ts?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Create Solid component code
|
|
9
|
+
*/
|
|
10
|
+
declare function createSolidComponent(data: FactoryIconData, options: Options): FactoryGeneratedComponent;
|
|
11
|
+
export { createSolidComponent };
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { getComponentSizeValues } from "./helpers/content/size.js";
|
|
2
|
+
import { stringifyFactoryIconContent } from "./helpers/content/stringify.js";
|
|
3
|
+
import { stringifyIconViewBox } from "../svg/viewbox/value.js";
|
|
4
|
+
import { createFactoryImports } from "./helpers/imports/create.js";
|
|
5
|
+
import { generateCSSFilesForComponent } from "./helpers/css/generate.js";
|
|
6
|
+
import { addSizeFunctionAsset } from "./helpers/functions/size.js";
|
|
7
|
+
import { stringifyFactoryProps } from "./helpers/props/stringify.js";
|
|
8
|
+
import { stringifyFactoryImports } from "./helpers/imports/stringify.js";
|
|
9
|
+
import { makeSquareViewBox } from "../svg/viewbox/square.js";
|
|
10
|
+
import { getUsedFactoryProps, stringifyFactoryPropTypes } from "./helpers/props/ts.js";
|
|
11
|
+
import { minifyViewBox } from "../svg/viewbox/minify.js";
|
|
12
|
+
import { getViewBoxRatio } from "./helpers/content/ratio.js";
|
|
13
|
+
import { addCustomFunctionAsset } from "./helpers/functions/custom.js";
|
|
14
|
+
import { addFallbackFunctionAsset } from "./helpers/functions/fallback.js";
|
|
15
|
+
import { addSolidComponentTypes } from "./helpers/ts/solid.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create Solid component code
|
|
19
|
+
*/
|
|
20
|
+
function createSolidComponent(data, options) {
|
|
21
|
+
const icon = data.icon;
|
|
22
|
+
const viewBox = icon.viewBox;
|
|
23
|
+
const fallback = icon.defaultFallback;
|
|
24
|
+
const statefulData = icon.statefulData;
|
|
25
|
+
const useTS = options.ts ?? false;
|
|
26
|
+
const assets = [];
|
|
27
|
+
const imports = createFactoryImports();
|
|
28
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
29
|
+
if (fallback) {
|
|
30
|
+
imports.named["@iconify/css-solid"] = new Set(["Icon"]);
|
|
31
|
+
dependencies.add("@iconify/css-solid");
|
|
32
|
+
}
|
|
33
|
+
const solidNamedImports = /* @__PURE__ */ new Set([]);
|
|
34
|
+
imports.named["solid-js"] = solidNamedImports;
|
|
35
|
+
const style = generateCSSFilesForComponent(icon, imports, assets, options);
|
|
36
|
+
const isEmbeddedCSS = options.cssMode === "embed";
|
|
37
|
+
let hasFixedSize = !!options.width && !!options.height;
|
|
38
|
+
const hasComputedViewbox = options.square && !hasFixedSize && viewBox.width !== viewBox.height;
|
|
39
|
+
const isStringViewBox = !fallback;
|
|
40
|
+
const hasComputedRatio = hasComputedViewbox && isStringViewBox;
|
|
41
|
+
if (!hasComputedViewbox && (options.width || options.height)) hasFixedSize = true;
|
|
42
|
+
const componentExternalCode = [];
|
|
43
|
+
const componentInternalCode = [];
|
|
44
|
+
const props = {};
|
|
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}': local['${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(local['${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
|
+
componentInternalCode.push(`const states = createMemo(() => ({ ${computedStates.join(", ")} }));`);
|
|
85
|
+
if (fallback && statefulData.fallback) {
|
|
86
|
+
computedFallback = true;
|
|
87
|
+
const func = addFallbackFunctionAsset(imports, assets, options, statefulData.defaultStateValues);
|
|
88
|
+
componentInternalCode.push(`const fallback = createMemo(() => ${func}(${JSON.stringify(statefulData.fallback)},states()));`);
|
|
89
|
+
}
|
|
90
|
+
componentInternalCode.push(`const className = createMemo(() => 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
|
+
}
|
|
98
|
+
const getViewBox = (viewBox) => isStringViewBox ? `'${stringifyIconViewBox(viewBox)}'` : JSON.stringify(minifyViewBox(viewBox));
|
|
99
|
+
if (hasComputedViewbox) {
|
|
100
|
+
componentExternalCode.push(`const baseViewBox = ${getViewBox(viewBox)};`, `const squareViewBox = ${getViewBox(makeSquareViewBox(viewBox))};`);
|
|
101
|
+
componentInternalCode.push(`const viewBox = createMemo(() => local.square ? squareViewBox : baseViewBox);`);
|
|
102
|
+
} else componentExternalCode.push(`const viewBox = ${getViewBox(viewBox)};`);
|
|
103
|
+
const ratioValue = getViewBoxRatio(viewBox);
|
|
104
|
+
if (hasComputedRatio) componentInternalCode.push(`const ratio = createMemo(() => local.square ? 1 : ${ratioValue});`);
|
|
105
|
+
if (hasFixedSize) {
|
|
106
|
+
const sizeProps = getComponentSizeValues(options, viewBox);
|
|
107
|
+
if (!sizeProps) throw new Error("Fixed size expected, but could not be determined");
|
|
108
|
+
props.width = sizeProps.width;
|
|
109
|
+
props.height = sizeProps.height;
|
|
110
|
+
} else if (fallback) {
|
|
111
|
+
props.width = {
|
|
112
|
+
type: "string",
|
|
113
|
+
value: "width",
|
|
114
|
+
template: "width={local.width}"
|
|
115
|
+
};
|
|
116
|
+
props.height = {
|
|
117
|
+
type: "string",
|
|
118
|
+
value: "height",
|
|
119
|
+
template: "height={local.height}"
|
|
120
|
+
};
|
|
121
|
+
} else {
|
|
122
|
+
const getSizeProps = addSizeFunctionAsset(imports, assets, options);
|
|
123
|
+
componentInternalCode.push(`const size = createMemo(() => ${getSizeProps}(local.width, local.height, ${hasComputedRatio ? "ratio()" : ratioValue}));`);
|
|
124
|
+
props.width = {
|
|
125
|
+
type: "string",
|
|
126
|
+
value: "width",
|
|
127
|
+
template: "{...size()}"
|
|
128
|
+
};
|
|
129
|
+
props.height = {
|
|
130
|
+
type: "string",
|
|
131
|
+
value: "height",
|
|
132
|
+
template: ""
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (componentInternalCode.some((line) => line.includes("createMemo"))) solidNamedImports.add("createMemo");
|
|
136
|
+
if (options.square) props.square = { type: "boolean" };
|
|
137
|
+
props.viewBox = {
|
|
138
|
+
value: "viewBox",
|
|
139
|
+
template: `viewBox={viewBox${hasComputedViewbox ? "()" : ""}}`
|
|
140
|
+
};
|
|
141
|
+
componentExternalCode.push(`const content = ${stringifyFactoryIconContent(icon, isEmbeddedCSS ? style : void 0)};`);
|
|
142
|
+
props.content = {
|
|
143
|
+
value: "content",
|
|
144
|
+
template: fallback ? `content={content} fallback={${computedFallback ? "fallback()" : `"${fallback}"`}}` : "innerHTML={content}"
|
|
145
|
+
};
|
|
146
|
+
const usedProps = getUsedFactoryProps(props);
|
|
147
|
+
if (usedProps.length) {
|
|
148
|
+
componentInternalCode.unshift(`const [local, others] = splitProps(props, ${JSON.stringify(usedProps)});\n`);
|
|
149
|
+
solidNamedImports.add("splitProps");
|
|
150
|
+
}
|
|
151
|
+
const template = `<${fallback ? "Icon" : "svg"} ${stringifyFactoryProps(props, "{prop}={{value}}")} {...${usedProps.length ? "others" : "props"}} />`;
|
|
152
|
+
componentInternalCode.push(`return (${template});`);
|
|
153
|
+
const beforeFunction = componentExternalCode.length ? componentExternalCode.join("\n") + "\n\n" : "";
|
|
154
|
+
const propTypes = stringifyFactoryPropTypes(props);
|
|
155
|
+
const componentFunction = `${useTS ? `interface Props {\n${propTypes}\n};\n\n` : propTypes ? `/** @param props {{${propTypes.replace(/\s*\n\s*/g, " ").trim()}}} */\n` : ""}function Component(props${useTS ? `: Props` : ""}) {
|
|
156
|
+
\t${componentInternalCode.join("\n ")}
|
|
157
|
+
}
|
|
158
|
+
`;
|
|
159
|
+
const content = `${stringifyFactoryImports(imports)}\n${beforeFunction}${componentFunction}\nexport default Component;\n`;
|
|
160
|
+
const types = addSolidComponentTypes(data, options, assets, props);
|
|
161
|
+
return {
|
|
162
|
+
assets,
|
|
163
|
+
content,
|
|
164
|
+
style: isEmbeddedCSS ? void 0 : style,
|
|
165
|
+
types,
|
|
166
|
+
dependencies: dependencies.size ? dependencies : void 0
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export { createSolidComponent };
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"type": "module",
|
|
4
4
|
"description": "Common functions for working with SVG used by various packages.",
|
|
5
5
|
"author": "Vjacheslav Trushkin",
|
|
6
|
-
"version": "1.2.
|
|
6
|
+
"version": "1.2.6",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"bugs": "https://github.com/cyberalien/svg-utils/issues",
|
|
9
9
|
"homepage": "https://cyberalien.dev/",
|