|
|
|
@ -6,12 +6,23 @@ import { stringify } from 'svgson'; |
|
|
|
/** |
|
|
|
* Build icons |
|
|
|
* |
|
|
|
* @param name |
|
|
|
* @param componentTemplate |
|
|
|
* @param indexIconTemplate |
|
|
|
* @param indexTypeTemplate |
|
|
|
* @param extension |
|
|
|
* @param pretty |
|
|
|
* @param name package directory name inside `packages/`, e.g. `icons-react` |
|
|
|
* @param componentTemplate returns the source of a single icon module; called |
|
|
|
* with `{ type, name, namePascal, children, stringify, svg }` |
|
|
|
* @param indexItemTemplate returns the line re-exporting an icon from the |
|
|
|
* icons index; called with `{ type, name, namePascal, svg }` |
|
|
|
* @param aliasTemplate returns the line exporting an alias in |
|
|
|
* `src/aliases.ts`; called with `{ from, to, fromPascal, toPascal }`. When |
|
|
|
* omitted, the aliases file is left empty |
|
|
|
* @param extension extension of the generated icon modules |
|
|
|
* @param key add a `key` attribute (`svg-0`, `svg-1`, …) to every icon node |
|
|
|
* @param pascalCase rename `stroke-width` to `strokeWidth` in icon nodes |
|
|
|
* @param pascalName name icon modules `Icon<PascalName>` instead of the |
|
|
|
* kebab-case icon name |
|
|
|
* @param indexFile file name of the icons index inside `src/icons` |
|
|
|
* @param dtsEntry generate `src/icons-dts`, a single-module stand-in for the |
|
|
|
* icon modules that the declaration bundle is built from (see `iconsDts` |
|
|
|
* in rollup-plugins.mjs) |
|
|
|
*/ |
|
|
|
export const buildJsIcons = ({ |
|
|
|
name, |
|
|
|
@ -23,12 +34,14 @@ export const buildJsIcons = ({ |
|
|
|
pascalCase = false, |
|
|
|
pascalName = true, |
|
|
|
indexFile = 'icons.ts', |
|
|
|
dtsEntry = false, |
|
|
|
}) => { |
|
|
|
const DIST_DIR = path.resolve(PACKAGES_DIR, name); |
|
|
|
const aliases = getAliases(), |
|
|
|
allIcons = getAllIcons(true, true); |
|
|
|
|
|
|
|
let index = []; |
|
|
|
let dtsIcons = []; |
|
|
|
Object.entries(allIcons).forEach(([type, icons]) => { |
|
|
|
icons.forEach((icon, i) => { |
|
|
|
// process.stdout.write(
|
|
|
|
@ -72,6 +85,13 @@ export const buildJsIcons = ({ |
|
|
|
); |
|
|
|
fs.writeFileSync(filePath, component, 'utf-8'); |
|
|
|
|
|
|
|
dtsIcons.push({ |
|
|
|
exportName: `Icon${iconNamePascal}`, |
|
|
|
module: path.basename(filePath, `.${extension}`), |
|
|
|
// the JSDoc block documenting the component, if the template has one
|
|
|
|
doc: component.match(/\/\*\*(?:(?!\*\/)[^])*\*\/(?=\s*const )/)?.[0], |
|
|
|
}); |
|
|
|
|
|
|
|
index.push( |
|
|
|
indexItemTemplate({ |
|
|
|
type, |
|
|
|
@ -99,6 +119,37 @@ export const buildJsIcons = ({ |
|
|
|
} |
|
|
|
|
|
|
|
fs.writeFileSync(path.resolve(DIST_DIR, `./src/aliases.ts`), aliasesStr || `export {};`, 'utf-8'); |
|
|
|
|
|
|
|
if (dtsEntry) { |
|
|
|
buildDtsEntry({ dir: path.resolve(DIST_DIR, 'src/icons-dts'), icons: dtsIcons, aliases }); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Every icon module has the same type, but emitting declarations for each of |
|
|
|
* them separately dominates the bundle build time. Instead, write one module |
|
|
|
* that re-declares all icons with the type inferred from a real icon module, |
|
|
|
* and one that maps aliases onto it. |
|
|
|
*/ |
|
|
|
const buildDtsEntry = ({ dir, icons, aliases }) => { |
|
|
|
fs.ensureDirSync(dir); |
|
|
|
|
|
|
|
const index = [`import Icon from '../icons/${icons[0].module}';`, '']; |
|
|
|
icons.forEach(({ exportName, doc }) => { |
|
|
|
if (doc) { |
|
|
|
index.push(doc); |
|
|
|
} |
|
|
|
index.push(`export const ${exportName} = Icon;`); |
|
|
|
}); |
|
|
|
fs.writeFileSync(path.resolve(dir, 'index.ts'), index.join('\n'), 'utf-8'); |
|
|
|
|
|
|
|
const aliasesStr = Object.entries(aliases || {}) |
|
|
|
.map( |
|
|
|
([from, to]) => |
|
|
|
`export { Icon${toPascalCase(to)} as Icon${toPascalCase(from)} } from './index';\n`, |
|
|
|
) |
|
|
|
.join(''); |
|
|
|
fs.writeFileSync(path.resolve(dir, 'aliases.ts'), aliasesStr || `export {};`, 'utf-8'); |
|
|
|
}; |
|
|
|
|
|
|
|
export const buildIconsList = (name) => { |
|
|
|
|