-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcomponent-generator.ts
More file actions
62 lines (53 loc) · 2.15 KB
/
Copy pathcomponent-generator.ts
File metadata and controls
62 lines (53 loc) · 2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import type { LinesDocument } from "../types/lines";
import { pointsToPathData } from "./path-data";
export function generateComponentSource(document: LinesDocument): string {
const componentName = sanitize(document.export.componentName);
const { width, height } = document.canvas;
const layerBlocks = document.layers
.filter((layer) => layer.visible && layer.paths.length > 0)
.map((layer) => {
const gAttrs: string[] = [];
if (layer.opacity < 1) gAttrs.push(`opacity={${layer.opacity}}`);
if (layer.blendMode !== "normal") gAttrs.push(`style={{ mixBlendMode: "${layer.blendMode}" }}`);
const pathLines = layer.paths.map((path) => {
const d = pointsToPathData(path.points, path.closed);
const attrs: string[] = [
`d="${d}"`,
`fill="${path.fill}"`,
`stroke="${path.stroke}"`,
`strokeWidth={${path.strokeWidth} * strokeWidthScale}`,
];
if (path.strokeLinecap !== "round") attrs.push(`strokeLinecap="${path.strokeLinecap}"`);
if (path.strokeLinejoin !== "round") attrs.push(`strokeLinejoin="${path.strokeLinejoin}"`);
if (path.opacity < 1) attrs.push(`opacity={${path.opacity}}`);
attrs.push(`vectorEffect="non-scaling-stroke"`);
return ` <path ${attrs.join(" ")} />`;
});
const open = gAttrs.length ? ` <g ${gAttrs.join(" ")}>` : ` <g>`;
return `${open}\n${pathLines.join("\n")}\n </g>`;
});
const body = layerBlocks.length
? layerBlocks.join("\n")
: ` {/* Add traced paths in lines */}`;
return `import type { SVGProps } from 'react'
// Generated by lines. Do not edit manually.
export type ${componentName}Props = SVGProps<SVGSVGElement> & {
strokeWidthScale?: number
}
export function ${componentName}({
strokeWidthScale = 1,
...props
}: ${componentName}Props) {
return (
<svg viewBox="0 0 ${width} ${height}" fill="none" {...props}>
${body}
</svg>
)
}
`;
}
function sanitize(name: string): string {
const compact = name.trim().replace(/[^A-Za-z0-9_$]/g, "");
if (!compact) return "UntitledLines";
return /^[A-Za-z_$]/.test(compact) ? compact : `Lines${compact}`;
}