Skip to content

Commit

Permalink
refactor: generate-icon-font to use it as bin executable and update d… (
Browse files Browse the repository at this point in the history
#1754)

* refactor: generate-icon-font to use it as bin executable and update documentation

* chore: update package-lock.json

* fix: issues with all for generate-icon-fonts

* docs: added hints for using with scss and separate folder

---------

Co-authored-by: Anna Schoderer <[email protected]>
  • Loading branch information
nmerget and annsch authored Oct 31, 2023
1 parent dd509f3 commit 03a2295
Show file tree
Hide file tree
Showing 12 changed files with 735 additions and 68 deletions.
582 changes: 582 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

80 changes: 80 additions & 0 deletions packages/foundations/docs/CustomIcons.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Custom Icons

If you have custom icons and want to use them for foundations and/or in components, you need to generate a `woff2` file.

## Generate

For this run:

```shell
npx -p @db-ui/foundations generate-icon-fonts --src ./my-path-to/icons --fontName my-name
```

We search for all `**/*.svg` files inside the `src` directory and create a new icon font with the provided name. You can preview all generated icons here: `./my-path-to/icons/fonts/all/index.html`.

> **_NOTE:_** We use four different sizes for components (16, 20, 24, 32) to show more or less details. You can do the same by providing another file with a size suffix for example "icon_file_name_16.svg".
For more information run:

```shell
npx -p @db-ui/foundations generate-icon-fonts --help
```

## How to use

In your app you need to include some of the generated files:

```html
./my-path-to/icons/fonts/my-name.woff2 ./my-path-to/icons/fonts/font-face.css
```

> **_NOTE:_** In case you put the files in a separate folder of your `public` directory be aware to adopt the path in your generated `font-face.css` file: `url("/{YOUR_FOLDER}}/my-name.woff2?t=1698750286189") format("woff2");`
Now you can use your icons with your `font-family: my-name`, e.g.:

```html
<!--example.html-->
<i class="my-name">icon_file_name</i>
```

### SCSS

When using `scss` you can also use `@forward` to include the generated files:

```scss
@forward "public/font-face";
```

### data-icon

If you like to use a custom icon in one of our components you can do it by overwriting the default font-family like this:

```html
<!--example.html-->
<p class="icon-family-my-name" data-icon="icon_file_name">Test</p>

<!-- or -->
<p data-icon-family="my-name" data-icon="icon_file_name">Test</p>
```

### CSS

You can overwrite custom-icons for our components with CSS as well:

```css
.db-button {
--db-icon-font-family: "my-name";
}
```

## Foundation Developer

If you update a `svg` inside `assets/icons/functional/images` you need to recreate the `woff2` file.

For this you just need to run

```shell
npm run generate:icon-fonts
```

Your new icon should be inside `assets/icons/functional/fonts/info.json` and you should see it inside `assets/icons/functional/fonts/index.html` in the browser.
47 changes: 1 addition & 46 deletions packages/foundations/docs/Icons.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,49 +23,4 @@ You can add an icon before or after a tag, by adding an `data-` attribute to you

If you have custom icons and want to use them for foundations and/or in components, you need to generate a `woff2` file.

For this run:

```shell
node node_modules/@db-ui/foundations/scripts/generate-icon-fonts/index.js --src ./my-path-to/icons --fontName my-name
```

We search for all `**/*.svg` files inside the `src` directory and create a new icon font with the provided name.

> **_NOTE:_** We use four different sizes for components (16, 20, 24, 32) to show more or less details. You can do the same by providing another file with a size suffix for example "icon_file_name_16.svg".
In your app you need to include some of the generated files:

`./my-path-to/icons/fonts/my-name.woff2`

`./my-path-to/icons/fonts/font-face.css`

Now you can use your icons with your `font-family: my-name`, e.g.:

```html
<!--example.html-->
<i class="my-name">icon_file_name</i>
```

### data-icon

If you like to use a custom icon in one of our components you can do it by overwriting the default font-family like this:

```html
<!--example.html-->

<p class="icon-family-my-name" data-icon="icon_file_name">Test</p>
<!-- or -->
<p data-icon-family="my-name" data-icon="icon_file_name">Test</p>
```

### Foundation Developer

If you update a `svg` inside `assets/icons/functional/images` you need to recreate the `woff2` file.

For this you just need to run

```shell
npm run generate:icon-fonts
```

Your new icon should be inside `assets/icons/functional/fonts/info.json` and you should see it inside `assets/icons/functional/fonts/index.html` in the browser.
[More information](./CustomIcons.md)
14 changes: 10 additions & 4 deletions packages/foundations/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
"name": "@db-ui/foundations",
"version": "0.0.0",
"description": "Provides basic tokens and assets based on DB UX Design System Core.",
"bin": {
"generate-icon-fonts": "build/scripts/generate-icon-fonts/index.js"
},
"repository": {
"type": "git",
"url": "https://github.com/db-ui/mono.git"
Expand All @@ -10,8 +13,7 @@
"main": "build.js",
"files": [
"assets",
"build",
"scripts"
"build"
],
"scripts": {
"build": "npm-run-all build:*",
Expand All @@ -20,15 +22,17 @@
"build:03_css": "sass --no-source-map --load-path=node_modules/ --load-path=../../node_modules/ build/scss/:build/css/ --future-deprecation=import",
"build:04_tailwind": "node scripts/tailwind-config-generator.mjs false true && cpr scripts/tailwind-config-generator.mjs build/tailwind/tailwind-config-generator.mjs -o",
"build:05_postcss": "postcss build/css/**/*.css --replace",
"build:06_icon_fonts_common": "esbuild scripts/generate-icon-fonts/index.js --bundle --outdir=build/scripts/generate-icon-fonts --platform=node --packages=external",
"build:07_icon_fonts_styles": "cpr scripts/generate-icon-fonts/styles build/scripts/generate-icon-fonts/styles -o",
"build:08_icon_fonts_templates": "cpr scripts/generate-icon-fonts/templates build/scripts/generate-icon-fonts/templates -o",
"clean": "rm -rf build",
"copy-build": "npm-run-all copy-build:*",
"copy-build:assets": "cpr assets ../../build-outputs/foundations/assets -o",
"copy-build:package.json": "cpr package.json ../../build-outputs/foundations/package.json -o",
"copy-build:readme": "cpr README.md ../../build-outputs/foundations/README.md -o",
"copy-build:scripts": "cpr scripts ../../build-outputs/foundations/scripts -o",
"copy-build:web": "cpr build ../../build-outputs/foundations/build -o -f \"(compose|ios-swift)\"",
"copy:scss": "cpr scss build/scss -o",
"generate:icon-fonts": "node scripts/generate-icon-fonts/index.js --src ./assets/icons/functional --variants solid inverted --prefix db_ic_ --fontName db-ux --withSizes true --debug true",
"generate:icon-fonts": "node scripts/generate-icon-fonts/index.js --src ./assets/icons/functional --variants solid inverted --cleanIgnoreVariants default,all --prefix db_ic_ --fontName db-ux --withSizes true --debug true",
"start": "nodemon --watch tokens/ --watch scss --watch scripts -e json,scss,js -x \"npm run build:01_style-dictionary\"",
"zeplin:tokens": "node scripts/zeplin-styleguide.js"
},
Expand All @@ -39,6 +43,8 @@
"@zeplin/sdk": "^1.18.0",
"cpr": "3.0.1",
"dotenv": "^16.3.1",
"esbuild": "0.19.5",
"glob": "^10.3.10",
"nodemon": "3.0.1",
"oslllo-svg-fixer": "^3.0.0",
"sass": "^1.69.5",
Expand Down
9 changes: 7 additions & 2 deletions packages/foundations/scripts/clean-icons/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@ const options = [
name: 'src',
description: 'Src folder with all svgs',
required: true
},
{
name: 'debug',
description: 'Extra logging',
defaultValue: false
}
];

const action = async (string_, options) => {
const { src, ignoreGlobs } = options._optionValues;
await cleanIcons(src, ignoreGlobs);
const { src, ignoreGlobs, debug } = options._optionValues;
await cleanIcons(src, ignoreGlobs, debug);
};

startProgram(
Expand Down
4 changes: 2 additions & 2 deletions packages/foundations/scripts/clean-icons/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { globSync } = require('glob');
const SVGFixer = require('oslllo-svg-fixer');

const cleanIcons = async (src, ignoreGlobs) => {
const cleanIcons = async (src, ignoreGlobs, debug) => {
const paths = `${src}/**/*.svg`;
const options = {};
if (ignoreGlobs) {
Expand All @@ -15,7 +15,7 @@ const cleanIcons = async (src, ignoreGlobs) => {

for (const path of globPaths) {
// eslint-disable-next-line no-await-in-loop,new-cap
await SVGFixer(path, path, { showProgressBar: true }).fix();
await SVGFixer(path, path, { showProgressBar: debug }).fix();
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ const allTemporaryDir = 'all';
* @param values {{ src: string, prefix: string, ignoreGlobs:string|string[], variants:string[], dryRun:boolean, withSizes: boolean }}
*/
const gatherIcons = (temporaryDirectory, values) => {
const { src, ignoreGlobs, prefix, dryRun, variants, withSizes } = values;
const { src, ignoreGlobs, prefix, dryRun, variants, withSizes, debug } =
values;
const paths = `${src}/**/*.svg`;

// We use this to generate all combinations of variants and sizes as fonts
Expand Down Expand Up @@ -63,6 +64,11 @@ const gatherIcons = (temporaryDirectory, values) => {
}
}

if (debug) {
// eslint-disable-next-line no-console
console.log(`Found ${foundIconFiles.length} icons`);
}

for (const iconFileName of foundIconFiles) {
const defaultFileExists = FSE.existsSync(
`${temporaryDirectory}/${allTemporaryDir}/${generalPrefix}${iconFileName}.svg`
Expand Down
43 changes: 31 additions & 12 deletions packages/foundations/scripts/generate-icon-fonts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,22 @@ const { svgToFont } = require('./svg-to-font.js');
const options = [
{
name: 'ignoreGlobs',
short: 'ig',
description: 'Path icon glob to exclude from the fonts',
array: true
},
{
name: 'variants',
description: 'Font variants e.g. solid, inverted, etc.',
array: true
description:
'Font variants e.g. solid, inverted, etc. We always add a "default" variant for icons.',
array: true,
defaultValue: []
},
{
name: 'cleanIgnoreVariants',
description:
'Ignore variants which should not be cleaned automatically',
array: true,
defaultValue: []
},
{
name: 'withSizes',
Expand Down Expand Up @@ -58,14 +66,23 @@ const fileEndingsToDelete = [
'woff'
];

const debugLog = (debug, message) => {
if (debug) {
// eslint-disable-next-line no-console
console.log(message);
}
};

const action = async (string_, options) => {
const values = options._optionValues;
const dist = `${values.src}/fonts`;
const fontName = values.fontName;
const temporaryDirectory = `${values.src}/tmp`;
const variants = values.variants;
const { src, fontName, dryRun, cleanIgnoreVariants, debug } = values;
const dist = `${src}/fonts`;
const temporaryDirectory = `${src}/tmp`;
const ignoreVariants = [...cleanIgnoreVariants].map(
(igVar) => `**/${igVar}*/**`
);

if (values.dryRun) {
if (dryRun) {
// eslint-disable-next-line no-console
console.log('values:', values);
gatherIcons(temporaryDirectory, values);
Expand All @@ -78,16 +95,18 @@ const action = async (string_, options) => {
FSE.removeSync(dist);
}

debugLog(debug, '---Start gathering icon---');
gatherIcons(temporaryDirectory, values);

for (const variant of variants) {
await cleanIcons(`${temporaryDirectory}/${variant}*`);
}
debugLog(debug, '---Start cleaning icon---');
await cleanIcons(`${temporaryDirectory}/*`, ignoreVariants, debug);

debugLog(debug, '---Start svg to font ---');
const allTemporaryDirectories = FSE.readdirSync(temporaryDirectory);
for (const directory of allTemporaryDirectories) {
const subDist = `${dist}/${directory}`;
const subTemporaryDir = `${temporaryDirectory}/${directory}`;
debugLog(debug, `svgToFont for ${subTemporaryDir}`);
await svgToFont(subTemporaryDir, subDist, values);
for (const ending of fileEndingsToDelete) {
FSE.removeSync(`${subDist}/${fontName}.${ending}`);
Expand All @@ -97,7 +116,7 @@ const action = async (string_, options) => {
FSE.removeSync(`${subDist}/unicode.html`);
}

if (!values.debug) {
if (!debug) {
FSE.removeSync(temporaryDirectory);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ const svgToFont = async (temporaryDirectory, dist, values) => {
},
website: {
index: 'font-class',
template: path.resolve(generateIconFontsDir, 'template.ejs')
template: path.resolve(
generateIconFontsDir,
'templates/template.ejs'
)
},
styleTemplates: path.resolve(generateIconFontsDir, 'styles')
});
Expand Down
4 changes: 4 additions & 0 deletions showcases/patternhub/data/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ export const ROUTES: NavigationItem[] = [
path: '/foundations/icons',
subNavigation: [
{ label: 'Readme', path: '/foundations/icons/readme' },
{
label: 'Custom Icons',
path: '/foundations/icons/custom-icons'
},
{ label: 'Overview', path: '/foundations/icons/overview' }
]
},
Expand Down
7 changes: 7 additions & 0 deletions showcases/patternhub/pages/foundations/icons/custom-icons.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import DefaultPage from "../../../components/default-page";

import CustomIcons from "../../../../../packages/foundations/docs/CustomIcons.md";

<CustomIcons />

export default ({ children }) => <DefaultPage>{children}</DefaultPage>;

0 comments on commit 03a2295

Please sign in to comment.