Merged in chore/icons-to-components (pull request #3420)
Convert all material symbols to react components * convert all material symbols to react components * remove svgr Approved-by: Linus Flood
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
import { writeFile } from "node:fs/promises"
|
||||
import { resolve } from "node:path"
|
||||
import {
|
||||
writeFile,
|
||||
readFile,
|
||||
mkdir,
|
||||
rmdir,
|
||||
readdir,
|
||||
rm,
|
||||
} from "node:fs/promises"
|
||||
import { resolve, join } from "node:path"
|
||||
import { existsSync } from "node:fs"
|
||||
|
||||
// Your full list of Material Symbol icon names
|
||||
@@ -219,13 +226,18 @@ const ICONS = [
|
||||
"yard",
|
||||
].sort()
|
||||
|
||||
const STYLES = ["outlined", "rounded", "sharp"] as const
|
||||
const STYLES = ["outlined"] as const
|
||||
|
||||
const OUT = resolve(
|
||||
__dirname,
|
||||
"../packages/design-system/lib/components/Icons/MaterialIcon/generated.tsx"
|
||||
)
|
||||
|
||||
const REACT_OUT = resolve(
|
||||
__dirname,
|
||||
"../packages/design-system/lib/components/Icons/MaterialIcon/generated"
|
||||
)
|
||||
|
||||
const PACKAGE_BASE = resolve(
|
||||
__dirname,
|
||||
"../node_modules/@material-symbols/svg-400"
|
||||
@@ -235,7 +247,15 @@ function camelCase(str: string) {
|
||||
return str.replace(/[-_](\w)/g, (_, c: string) => c.toUpperCase())
|
||||
}
|
||||
|
||||
function pascalCase(str: string) {
|
||||
const camel = camelCase(str)
|
||||
return camel.charAt(0).toUpperCase() + camel.slice(1)
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await rm(REACT_OUT, { recursive: true, force: true })
|
||||
await mkdir(REACT_OUT, { recursive: true })
|
||||
|
||||
const imports: string[] = []
|
||||
const registryEntries: string[] = []
|
||||
|
||||
@@ -247,28 +267,64 @@ async function main() {
|
||||
for (const style of STYLES) {
|
||||
const parts: string[] = []
|
||||
|
||||
const fill0Path = resolve(PACKAGE_BASE, style, `${icon}.svg`)
|
||||
const fill1Path = resolve(PACKAGE_BASE, style, `${icon}-fill.svg`)
|
||||
const variants = [
|
||||
{
|
||||
suffix: "",
|
||||
varNameSuffix: "Outlined",
|
||||
path: resolve(PACKAGE_BASE, style, `${icon}.svg`),
|
||||
key: "outlined",
|
||||
},
|
||||
{
|
||||
suffix: "-fill",
|
||||
varNameSuffix: "Filled",
|
||||
path: resolve(PACKAGE_BASE, style, `${icon}-fill.svg`),
|
||||
key: "filled",
|
||||
},
|
||||
]
|
||||
|
||||
let outlinedVar: string | undefined
|
||||
let filledVar: string | undefined
|
||||
for (const variant of variants) {
|
||||
if (existsSync(variant.path)) {
|
||||
const content = await readFile(variant.path, "utf8")
|
||||
const svgMatch = content.match(
|
||||
/<svg[^>]*viewBox="([^"]*)"[^>]*>([\s\S]*?)<\/svg>/
|
||||
)
|
||||
|
||||
if (existsSync(fill0Path)) {
|
||||
outlinedVar = `${camelCase(icon)}${camelCase(style)}Outlined`
|
||||
imports.push(
|
||||
`import ${outlinedVar} from "@material-symbols/svg-400/${style}/${icon}.svg"`
|
||||
)
|
||||
parts.push(`outlined: ${outlinedVar}`)
|
||||
} else {
|
||||
missing.push(`${style}/${icon}.svg`)
|
||||
}
|
||||
if (svgMatch) {
|
||||
const viewBox = svgMatch[1]
|
||||
const inner = svgMatch[2]
|
||||
|
||||
if (existsSync(fill1Path)) {
|
||||
filledVar = `${camelCase(icon)}${camelCase(style)}Filled`
|
||||
imports.push(
|
||||
`import ${filledVar} from "@material-symbols/svg-400/${style}/${icon}-fill.svg"`
|
||||
)
|
||||
parts.push(`filled: ${filledVar}`)
|
||||
const componentName = `${pascalCase(icon)}${variant.varNameSuffix}`
|
||||
const fileName = `${componentName}.tsx`
|
||||
const filePath = join(REACT_OUT, fileName)
|
||||
|
||||
const componentContent =
|
||||
`
|
||||
/* AUTO-GENERATED — DO NOT EDIT */
|
||||
import type { SVGProps } from "react"
|
||||
|
||||
const ${componentName} = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg viewBox="${viewBox}" {...props}>
|
||||
${inner.trim()}
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default ${componentName}
|
||||
`.trim() + "\n"
|
||||
|
||||
await writeFile(filePath, componentContent, "utf8")
|
||||
|
||||
imports.push(
|
||||
`const ${componentName} = lazy(() => import("./generated/${componentName}"))`
|
||||
)
|
||||
parts.push(`${variant.key}: ${componentName}`)
|
||||
} else {
|
||||
console.warn(`Could not parse SVG for ${variant.path}`)
|
||||
}
|
||||
} else {
|
||||
if (variant.key === "outlined") {
|
||||
missing.push(`${style}/${icon}.svg`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parts.length) {
|
||||
@@ -289,6 +345,7 @@ async function main() {
|
||||
/* AUTO-GENERATED — DO NOT EDIT */
|
||||
|
||||
import type { FunctionComponent, SVGProps } from "react"
|
||||
import { lazy } from "react"
|
||||
|
||||
${imports.join("\n")}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user