Beautiful
1import fs from 'fs';
2import path from 'path';
3import { parseSync } from 'svgson';
4import {
5 shuffleArray,
6 readSvgDirectory,
7 getCurrentDirPath,
8 minifySvg,
9 toPascalCase,
10} from '../tools/build-helpers/helpers.mjs';
11
12const currentDir = getCurrentDirPath(import.meta.url);
13const ICONS_DIR = path.resolve(currentDir, '../icons');
14const BASE_URL = 'https://lucide.dev/api/gh-icon';
15
16const changedFilesPathString = process.env.CHANGED_FILES;
17
18const changedFiles = changedFilesPathString
19 .split(' ')
20 .map((file) => file.replace('.json', '.svg'))
21 .filter((file, idx, arr) => arr.indexOf(file) === idx);
22
23const getImageTagsByFiles = (files, getBaseUrl, width) =>
24 files.map((file) => {
25 const svgContent = fs.readFileSync(path.join(process.cwd(), file), 'utf-8');
26 const strippedAttrsSVG = svgContent.replace(/<svg[^>]*>/, '<svg>');
27 const minifiedSvg = minifySvg(strippedAttrsSVG);
28
29 const base64 = Buffer.from(minifiedSvg).toString('base64');
30 const url = getBaseUrl(file);
31 const widthAttr = width ? `width="${width}"` : '';
32
33 return `<img title="${file}" alt="${file}" ${widthAttr} src="${url}/${base64}.svg"/>`;
34 });
35
36const svgFiles = readSvgDirectory(ICONS_DIR).map((file) => `icons/${file}`);
37
38const iconsFilteredByName = (search) => svgFiles.filter((file) => file.includes(search));
39
40const cohesionRandomImageTags = getImageTagsByFiles(
41 shuffleArray(svgFiles).slice(0, changedFiles.length),
42 () => `${BASE_URL}/stroke-width/2`,
43).join('');
44
45const cohesionSquaresImageTags = getImageTagsByFiles(
46 shuffleArray(iconsFilteredByName('square')).slice(0, changedFiles.length),
47 () => `${BASE_URL}/stroke-width/2`,
48).join('');
49
50const changeFiles1pxStrokeImageTags = getImageTagsByFiles(
51 changedFiles,
52 () => `${BASE_URL}/stroke-width/1`,
53).join('');
54
55const changeFiles2pxStrokeImageTags = getImageTagsByFiles(
56 changedFiles,
57 () => `${BASE_URL}/stroke-width/2`,
58).join('');
59
60const changeFiles3pxStrokeImageTags = getImageTagsByFiles(
61 changedFiles,
62 () => `${BASE_URL}/stroke-width/3`,
63).join('');
64
65const changeFilesLowDPIImageTags = getImageTagsByFiles(
66 changedFiles,
67 () => `${BASE_URL}/dpi/24`,
68).join(' ');
69
70const changeFilesXRayImageTags = getImageTagsByFiles(
71 changedFiles,
72 (file) => {
73 const iconName = path.basename(file, '.svg');
74
75 return `${BASE_URL}/${iconName}`;
76 },
77 400,
78).join(' ');
79
80const changeFilesDiffImageTags = getImageTagsByFiles(
81 changedFiles,
82 (file) => {
83 const iconName = path.basename(file, '.svg');
84
85 return `${BASE_URL}/diff/${iconName}`;
86 },
87 400,
88).join(' ');
89
90const readyToUseCode = changedFiles
91 .map((changedFile) => {
92 const svgContent = fs.readFileSync(path.join(process.cwd(), changedFile), 'utf-8');
93 const name = path.basename(changedFile, '.svg');
94 return `const ${toPascalCase(name)}Icon = createLucideIcon('${toPascalCase(name)}', [
95 ${parseSync(svgContent)
96 .children.map(({ name, attributes }) => JSON.stringify([name, attributes]))
97 .join(',\n ')}
98])`;
99 })
100 .join('\n\n');
101
102const commentMarkup = `\
103### Added or changed icons
104${changeFiles2pxStrokeImageTags}
105<details>
106<summary>Preview cohesion</summary>
107${cohesionSquaresImageTags}<br/>
108${changeFiles2pxStrokeImageTags}<br/>
109${cohesionRandomImageTags}<br/>
110</details>
111<details>
112<summary>Preview stroke widths</summary>
113${changeFiles1pxStrokeImageTags}<br/>
114${changeFiles2pxStrokeImageTags}<br/>
115${changeFiles3pxStrokeImageTags}<br/>
116</details>
117<details>
118<summary>DPI Preview (24px)</summary>
119${changeFilesLowDPIImageTags}<br/>
120</details>
121<details>
122<summary>Icon X-rays</summary>
123${changeFilesXRayImageTags}
124</details>
125<details>
126<summary>Icon Diffs</summary>
127${changeFilesDiffImageTags}
128</details>
129<details>
130<summary>Icons as code</summary>
131
132Works for: \`lucide-react\`, \`lucide-react-native\`, \`lucide-preact\`, \`lucide-vue-next\`
133\`\`\`ts
134${readyToUseCode}
135\`\`\`
136
137</details>`;
138
139console.log(commentMarkup);