Skip to content

Commit

Permalink
feat: add new iconset
Browse files Browse the repository at this point in the history
BREAKING CHANGE: use rol="image"& aria-labelledby intead of svg title

- [x] use SVGO as an optimizer
- [x] add test
- [x] improve accessibility by remove hardcoded title from SVG and
use rol="image"& aria-labelledby intead
- [x] use `font-size` instead of `width, height` to control size
- [x] auto generate icons component, names
- [x] add new icons
- [x] update storybook with the new icons
  • Loading branch information
AliKdhim87 authored and Robbert committed Jul 1, 2022
1 parent b1ad9b1 commit 5e2215e
Show file tree
Hide file tree
Showing 102 changed files with 11,300 additions and 7,949 deletions.
26 changes: 26 additions & 0 deletions components/icon/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
dist/
www/
loader/

*~
*.sw[mnpcod]
*.log
*.lock
*.tmp
*.tmp.*
log.txt
*.sublime-project
*.sublime-workspace

.stencil/
.idea/
.vscode/
.sass-cache/
.versions/
node_modules/
$RECYCLE.BIN/

.DS_Store
Thumbs.db
UserInterfaceState.xcuserstate
.env
25 changes: 0 additions & 25 deletions components/icon/icon-set.json

This file was deleted.

46 changes: 35 additions & 11 deletions components/icon/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,47 @@
"description": "Icons for the Municipality of Utrecht based on the NL Design System architecture",
"license": "EUPL-1.2",
"name": "@utrecht/icon",
"main": "dist/index.cjs.js",
"module": "dist/index.js",
"es2015": "dist/esm/index.mjs",
"es2017": "dist/esm/index.mjs",
"types": "./dist/types/components.d.ts",
"collection": "dist/collection/collection-manifest.json",
"collection:main": "dist/collection/index.js",
"unpkg": "dist/icon/icon.esm.js",
"repository": {
"type": "git",
"url": "https://github.com/ionic-team/stencil-component-starter.git"
},
"files": [
"dist"
],
"keywords": [
"nl-design-system"
"dist/",
"loader/"
],
"private": false,
"scripts": {
"prebuild": "make-dir dist/",
"build": "svgo -f svg/ -o dist/"
"prebuild": "npm run clean",
"build": "npm run build:svg && npm run build:components",
"build:components": "node src/build.js $1 --prefix utrecht-icon --path tmp/components",
"build:svg": "svgo --recursive --folder ./src/svg --output ./tmp/optimized-svgs",
"clean": "rimraf tmp dist loader www",
"test": "stencil test --spec --e2e",
"test.watch": "stencil test --spec --e2e --watchAll"
},
"publishConfig": {
"access": "public"
"dependencies": {
"@stencil/core": "2.15.2"
},
"devDependencies": {
"@gemeente-denhaag/process-steps": "0.1.0-alpha.34",
"make-dir-cli": "3.0.0",
"@types/jest": "27.0.3",
"jest": "27.0.3",
"jest-cli": "27.0.3",
"lodash": "4.17.21",
"minimist": "1.2.6",
"puppeteer": "10.0.0",
"svgo": "2.8.0"
},
"keywords": [
"nl-design-system"
],
"publishConfig": {
"access": "public"
}
}
88 changes: 88 additions & 0 deletions components/icon/src/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/* eslint-env node */
const fs = require('fs');
const lodash = require('lodash');
const argv = require('minimist')(process.argv.slice(2), {
string: ['prefix', 'path'],
});
const path = require('path');
const {
component,
test,
generateIconsName,
generateIcons,
style,
iconContainerComponent,
} = require('./component_templates.js');

const { kebabCase } = lodash;
const componentPrefix = `${argv.prefix}-`;
const componentsPath = argv.path;
const iconRapperComponent = `${componentPrefix}container`;

if (fs.existsSync(componentsPath)) throw new Error(`A component with this name already exists: ${componentsPath}`);

if (!componentsPath) throw new Error('You must include a components path name.');

fs.mkdirSync(componentsPath, { recursive: true });

function writeFileErrorHandler(err) {
if (err) throw err;
}

const directoryPath = path.join(__dirname, '../tmp/optimized-svgs');

fs.readdir(directoryPath, function (err, files) {
//handling error
if (err) {
console.error('Unable to scan directory: ' + err);
return;
}

const iconsNames = files.map((file) => `${componentPrefix}${kebabCase(file.replace('.svg', ''))}`);

files.forEach(function (file) {
const fileName = `${componentPrefix}${kebabCase(file.replace('.svg', ''))}`;
const formattedName = kebabCase(fileName);
const dir = `${componentsPath}/${formattedName}`;

fs.readFile(path.join(directoryPath, file), 'utf8', function (err, svg) {
if (err) {
console.error(err);
return;
}

// throw an error if the file already exists
if (fs.existsSync(dir)) throw new Error('A component with that name already exists.');

// create the folder
fs.mkdirSync(dir);
fs.writeFile(
`${dir}/${formattedName}.stencil.tsx`,
component(fileName, svg, iconRapperComponent),
writeFileErrorHandler,
);
fs.writeFile(`${dir}/${formattedName}.spec.tsx`, test(fileName), writeFileErrorHandler);
});
});

fs.writeFile(`${componentsPath}/icon-set.json`, generateIconsName(iconsNames), writeFileErrorHandler);
fs.writeFile(`${componentsPath}/icons.js`, generateIcons(iconsNames), writeFileErrorHandler);
});

const createIconWrapperComponent = () => {
const dir = `${componentsPath}/${iconRapperComponent}`;
const cssValue = `.${iconRapperComponent} {
display: inline-block;
color: var(--${componentPrefix}color);
font-size: var(--${componentPrefix}size);
}`;
fs.mkdirSync(dir);
fs.writeFile(
`${dir}/${iconRapperComponent}.stencil.tsx`,
iconContainerComponent(iconRapperComponent, '<slot/>'),
writeFileErrorHandler,
);
fs.writeFile(`${dir}/${iconRapperComponent}.space.tsx`, test(iconRapperComponent), writeFileErrorHandler);
fs.writeFile(`${dir}/${iconRapperComponent}.scss`, style(cssValue), writeFileErrorHandler);
};
createIconWrapperComponent();
72 changes: 72 additions & 0 deletions components/icon/src/component_templates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* eslint-disable no-undef */
const lodash = require('lodash');
const { camelCase, kebabCase, upperFirst } = lodash;

exports.component = (name, children, container) => {
const ComponentName = upperFirst(camelCase(name));
const webComponentName = kebabCase(name);

return `import { Component, h } from '@stencil/core';
@Component({
tag: '${webComponentName}',
shadow: true,
})
export class ${ComponentName} {
render() {
return (
<${container}>
${children}
</${container}>
);
}
}
`;
};

exports.iconContainerComponent = (name, children) => {
const ComponentName = upperFirst(camelCase(name));
const webComponentName = kebabCase(name);

return `import { Component, h } from '@stencil/core';
@Component({
tag: '${webComponentName}',
styleUrl: './${webComponentName}.scss',
shadow: true,
})
export class ${ComponentName} {
render() {
return (
<div class='${webComponentName}'>
${children}
</div>
);
}
}
`;
};

exports.test = (name) => {
const ComponentName = upperFirst(camelCase(name));
const webComponentName = kebabCase(name);
return `import { ${ComponentName} } from './${webComponentName}.stencil';
describe('${ComponentName}', () => {
it('builds', () => {
expect(new ${ComponentName}()).toBeTruthy();
});
});
`;
};

exports.generateIconsName = (iconsNames) => {
return JSON.stringify(iconsNames);
};

exports.generateIcons = (iconsNames) => {
return `const icons = {
${iconsNames.map((icon) => `\n${upperFirst(camelCase(icon))}`)}
}`;
};

exports.style = (value) => value;
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
21 changes: 21 additions & 0 deletions components/icon/stencil.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Config } from '@stencil/core';

export const config: Config = {
namespace: 'utrecht',
outputTargets: [
{
type: 'dist',
esmLoaderPath: '../loader',
},
{
type: 'dist-custom-elements',
},
{
type: 'docs-readme',
},
{
type: 'www',
serviceWorker: null, // disable service workers
},
],
};
41 changes: 41 additions & 0 deletions components/icon/svgo.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
export default {
multipass: true,
js2svg: {
indent: 2,
pretty: true,
},
plugins: [
"preset-default",
"removeDimensions",
"removeTitle",
"convertStyleToAttrs",
{
name: "removeAttrs",
params: {
attrs: ["path:(fill|stroke)", "fill"],
},
},
{
name: "sortAttrs",
params: {
xmlnsOrder: "alphabetical",
},
},
{
name: "addAttributesToSVGElement",
params: {
attributes: [
{
fill: "CurrentColor",
},
{
width: "1em",
},
{
height: "1em",
},
],
},
},
],
};
19 changes: 19 additions & 0 deletions components/icon/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"allowUnreachableCode": false,
"declaration": false,
"experimentalDecorators": true,
"skipLibCheck": true,
"lib": ["dom", "es2017"],
"moduleResolution": "node",
"module": "esnext",
"target": "es2017",
"noUnusedLocals": true,
"noUnusedParameters": true,
"jsx": "react",
"jsxFactory": "h"
},
"include": ["src"],
"exclude": ["node_modules"]
}
35 changes: 0 additions & 35 deletions components/icon/web-component/afval.stencil.tsx

This file was deleted.

Loading

0 comments on commit 5e2215e

Please sign in to comment.