diff --git a/lowercase.sh b/lowercase.sh new file mode 100755 index 00000000..a17d3671 --- /dev/null +++ b/lowercase.sh @@ -0,0 +1,10 @@ +#!/bin/zsh + +directory=$1 + +for file in "$directory"/*; do + filename=$(echo "$file" | tr '[:upper:]' '[:lower:]') # convert to lowercase + filename="${filename// /-}" # replace spaces with dashes + filename="${filename//_/-}" # replace underscores with dashes + mv "$file" "$filename" +done diff --git a/packages/icons/scripts/build.js b/packages/icons/scripts/build.js new file mode 100644 index 00000000..301e8db9 --- /dev/null +++ b/packages/icons/scripts/build.js @@ -0,0 +1,135 @@ +const fs = require('fs').promises +const camelcase = require('camelcase') +const { promisify } = require('util') +const rimraf = promisify(require('rimraf')) +const svgr = require('@svgr/core').default +const babel = require('@babel/core') +const { compile: compileVue } = require('@vue/compiler-dom') +const { dirname } = require('path') + +let transform = { + react: async (svg, componentName, format) => { + let component = await svgr( + svg, + { ref: true, titleProp: true }, + { componentName } + ) + let { code } = await babel.transformAsync(component, { + plugins: [ + [require('@babel/plugin-transform-react-jsx'), { useBuiltIns: true }], + ], + }) + + if (format === 'esm') { + return code + } + + return code + .replace( + 'import * as React from "react"', + 'const React = require("react")' + ) + .replace('export default', 'module.exports =') + }, +} + +async function getIcons(style) { + let files = await fs.readdir(`./optimized/${style}`) + return Promise.all( + files.map(async file => ({ + svg: await fs.readFile(`./optimized/${style}/${file}`, 'utf8'), + componentName: `${camelcase(file.replace(/\.svg$/, ''), { + pascalCase: true, + })}Icon`, + })) + ) +} + +function exportAll(icons, format, includeExtension = true) { + return icons + .map(({ componentName }) => { + let extension = includeExtension ? '.js' : '' + if (format === 'esm') { + return `export { default as ${componentName} } from './${componentName}${extension}'` + } + return `module.exports.${componentName} = require("./${componentName}${extension}")` + }) + .join('\n') +} + +async function ensureWrite(file, text) { + await fs.mkdir(dirname(file), { recursive: true }) + await fs.writeFile(file, text, 'utf8') +} + +async function ensureWriteJson(file, json) { + await ensureWrite(file, JSON.stringify(json, null, 2)) +} + +async function buildIcons(package, style, format) { + let outDir = `./${package}/${style}` + if (format === 'esm') { + outDir += '/esm' + } + + let icons = await getIcons(style) + + await Promise.all( + icons.flatMap(async ({ componentName, svg }) => { + let content = await transform[package](svg, componentName, format) + let types = + package === 'react' + ? `import * as React from 'react';\ndeclare function ${componentName}(props: React.ComponentProps<'svg'> & { title?: string, titleId?: string }): JSX.Element;\nexport default ${componentName};\n` + : `import type { FunctionalComponent, HTMLAttributes, VNodeProps } from 'vue';\ndeclare const ${componentName}: FunctionalComponent;\nexport default ${componentName};\n` + + return [ + ensureWrite(`${outDir}/${componentName}.js`, content), + ...(types + ? [ensureWrite(`${outDir}/${componentName}.d.ts`, types)] + : []), + ] + }) + ) + + await ensureWrite(`${outDir}/index.js`, exportAll(icons, format)) + + await ensureWrite(`${outDir}/index.d.ts`, exportAll(icons, 'esm', false)) +} + +async function main(package) { + const cjsPackageJson = { module: './esm/index.js', sideEffects: false } + const esmPackageJson = { type: 'module', sideEffects: false } + + console.log(`Building ${package} package...`) + + await Promise.all([ + rimraf(`./${package}/20/solid/*`), + rimraf(`./${package}/24/outline/*`), + rimraf(`./${package}/24/solid/*`), + ]) + + await Promise.all([ + buildIcons(package, '20/solid', 'cjs'), + buildIcons(package, '20/solid', 'esm'), + buildIcons(package, '24/outline', 'cjs'), + buildIcons(package, '24/outline', 'esm'), + buildIcons(package, '24/solid', 'cjs'), + buildIcons(package, '24/solid', 'esm'), + ensureWriteJson(`./${package}/20/solid/esm/package.json`, esmPackageJson), + ensureWriteJson(`./${package}/20/solid/package.json`, cjsPackageJson), + ensureWriteJson(`./${package}/24/outline/esm/package.json`, esmPackageJson), + ensureWriteJson(`./${package}/24/outline/package.json`, cjsPackageJson), + ensureWriteJson(`./${package}/24/solid/esm/package.json`, esmPackageJson), + ensureWriteJson(`./${package}/24/solid/package.json`, cjsPackageJson), + ]) + + return console.log(`Finished building ${package} package.`) +} + +let [package] = process.argv.slice(2) + +if (!package) { + throw new Error('Please specify a package') +} + +main(package)