-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: [HOP-48] Create svg-icons (#93)
Co-authored-by: alexandre.asselin <[email protected]> Co-authored-by: Alexandre Asselin <[email protected]>
- Loading branch information
1 parent
ee14db8
commit 59d57e2
Showing
463 changed files
with
5,103 additions
and
2,537 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@hopper-ui/svg-icons": major | ||
--- | ||
|
||
Initial release of the package |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
lts/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/eslintrc", | ||
"root": true, | ||
"extends": "plugin:@workleap/typescript-library" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# @hopper-ui/svg-icons | ||
|
||
A set of icons handcrafted by Workleap. | ||
|
||
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](../../LICENSE) | ||
[![npm version](https://img.shields.io/npm/v/@hopper-ui/svg-icons)](https://www.npmjs.com/package/@hopper-ui/svg-icons) | ||
|
||
## Installation | ||
|
||
Install the following packages: | ||
|
||
**With pnpm** | ||
|
||
```shell | ||
pnpm add @hopper-ui/svg-icons | ||
``` | ||
|
||
**With yarn** | ||
|
||
```shell | ||
yarn add -D @hopper-ui/svg-icons | ||
``` | ||
|
||
**With npm** | ||
|
||
```shell | ||
npm install -D @hopper-ui/svg-icons | ||
``` | ||
|
||
## Usage | ||
|
||
View the [user's documentation](https://hopper.workleap.design/). | ||
|
||
## 🤝 Contributing | ||
|
||
View the [contributor's documentation](https://github.com/gsoft-inc/wl-hopper/blob/main/CONTRIBUTING.md). | ||
|
||
## License | ||
|
||
Copyright © 2023, Workleap. This code is licensed under the Apache License, Version 2.0. You may obtain a copy of this license at https://github.com/gsoft-inc/workleap-license/blob/master/LICENSE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import type { Config } from "jest"; | ||
import { swcConfig } from "./swc.jest.ts"; | ||
|
||
const config: Config = { | ||
testEnvironment: "node", | ||
transform: { | ||
"^.+\\.(js|ts|tsx)$": ["@swc/jest", swcConfig as Record<string, unknown>] | ||
}, | ||
extensionsToTreatAsEsm: [".ts"] | ||
}; | ||
|
||
export default config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
{ | ||
"name": "@hopper-ui/svg-icons", | ||
"author": "Workleap", | ||
"version": "0.0.0", | ||
"description": "A set of icons handcrafted by Workleap", | ||
"license": "Apache-2.0", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/gsoft-inc/wl-hopper.git", | ||
"directory": "packages/svg-icons" | ||
}, | ||
"publishConfig": { | ||
"access": "public", | ||
"provenance": true | ||
}, | ||
"type": "module", | ||
"sideEffects": "*.svg", | ||
"files": [ | ||
"/dist", | ||
"CHANGELOG.md", | ||
"README.md" | ||
], | ||
"exports": { | ||
"./icons/*.svg": "./dist/icons/*.svg" | ||
}, | ||
"scripts": { | ||
"build": "tsx scripts/build.ts" | ||
}, | ||
"devDependencies": { | ||
"@swc/core": "1.3.96", | ||
"@swc/helpers": "0.5.3", | ||
"@swc/jest": "0.2.29", | ||
"@types/jest": "29.5.9", | ||
"@types/node": "^20.9.3", | ||
"@workleap/eslint-plugin": "3.0.0", | ||
"@workleap/swc-configs": "2.1.2", | ||
"@workleap/typescript-configs": "3.0.2", | ||
"hast-util-select": "6.0.2", | ||
"jest": "29.7.0", | ||
"rehype-parse": "9.0.0", | ||
"svgo": "^3.0.4", | ||
"tsx": "4.1.4", | ||
"typescript": "5.3.2", | ||
"unified": "11.0.4" | ||
|
||
}, | ||
"engines": { | ||
"node": ">=18.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import path from "path"; | ||
import { IconSizes, IconsDistDirectory, IconsSourceDirectory } from "./constants.ts"; | ||
import { generateIcons } from "./generate-icons.ts"; | ||
|
||
/** | ||
* Converts a file path to a file name. | ||
* @example fileNameConverter("C:\\Dev\\wl-hopper\\packages\\svgs\\src\\icons\\16px\\Add.svg") // add-16.svg | ||
*/ | ||
function fileNameConverter(filePath: string) { | ||
const dirName = path.dirname(filePath); | ||
const size = path.basename(dirName).replace("px", ""); | ||
|
||
if ((IconSizes as readonly number[]).includes(Number(size)) === false) { | ||
throw new Error(`Invalid icon size: ${size}`); | ||
} | ||
|
||
const fileName = path.basename(filePath, ".svg"); | ||
|
||
const kebabCaseName = fileName | ||
.replace(/([a-z])([A-Z])/g, "$1-$2") | ||
.replace(/[\s_]+/g, "-") | ||
.toLowerCase(); | ||
|
||
return `${kebabCaseName}-${size}.svg`; | ||
} | ||
|
||
console.log("⚙️ Optimizing icons...\n"); | ||
|
||
generateIcons(IconsSourceDirectory, IconsDistDirectory, fileNameConverter); | ||
|
||
console.log("✨ The icons have been optimized!\n"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export const IconsSourceDirectory = "src/icons"; | ||
export const IconsDistDirectory = "dist/icons"; | ||
export const IconSizes = [16, 24, 32] as const; | ||
export const NeutralIconColor = "#3C3C3C"; // --hop-neutral-icon | ||
export const PrimaryIconColor = "#3B57FF"; // --hop-primary-icon |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import fs from "fs"; | ||
import path from "path"; | ||
import { optimize } from "svgo"; | ||
import config from "./svgo-config.ts"; | ||
|
||
function ensureDirSync(dir: string) { | ||
if (!fs.existsSync(dir)) { | ||
fs.mkdirSync(dir, { recursive: true }); | ||
} | ||
} | ||
|
||
export function generateIcons(srcDir: string, outputDir: string, fileNameConverter?: (filePath: string) => string) { | ||
ensureDirSync(outputDir); | ||
|
||
// This line requires Node.js 20.5.2 or higher to execute properly | ||
// https://github.com/nodejs/node/issues/48858 | ||
const files = fs.readdirSync(srcDir, { recursive: true, withFileTypes: true }); | ||
|
||
const svgFiles = files.filter(file => file.isFile() && file.name.endsWith(".svg")); | ||
|
||
const iconFiles = svgFiles.map(file => { | ||
const srcPath = path.resolve(file.path, file.name); | ||
const dstPath = path.resolve(outputDir, fileNameConverter ? fileNameConverter(srcPath) : file.name); | ||
|
||
return { | ||
srcPath: srcPath, | ||
dstPath | ||
}; | ||
}); | ||
|
||
// If it's possible to rename a file with the same name, then we need to validate that there are no duplicates | ||
if (fileNameConverter) { | ||
validateNoNameDuplicate(iconFiles.map(x => x.dstPath)); | ||
} | ||
|
||
iconFiles.forEach(iconFile => { | ||
const contents = fs.readFileSync(iconFile.srcPath, "utf8"); | ||
const { data } = optimize(contents, { | ||
path: iconFile.srcPath, | ||
...config | ||
}); | ||
|
||
fs.writeFileSync(iconFile.dstPath, Buffer.from(data)); | ||
}); | ||
} | ||
|
||
function validateNoNameDuplicate(names: string[]) { | ||
const duplicateNames: string[] = []; | ||
const nameSet = new Set<string>(); | ||
|
||
for (const name of names) { | ||
if (nameSet.has(name)) { | ||
duplicateNames.push(name); | ||
} else { | ||
nameSet.add(name); | ||
} | ||
} | ||
|
||
if (duplicateNames.length > 0) { | ||
throw new Error(`Duplicate icon names detected: ${duplicateNames.join(", ")}`); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import type { Config } from "svgo"; | ||
import { NeutralIconColor } from "./constants.ts"; | ||
|
||
const config: Config = { | ||
multipass: true, | ||
plugins: [ | ||
{ | ||
name: "preset-default", | ||
params: { | ||
overrides: { | ||
/** | ||
* viewBox is needed in order to produce 20px by 20px containers | ||
* with smaller icons inside. | ||
*/ | ||
removeViewBox: false, | ||
/** | ||
* Some of our icons have multiple fill colors. We want to keep them, but replace the main icon color | ||
* with the currentColor value. This allows us to change the color of the icon with the color CSS property. | ||
*/ | ||
convertColors: { | ||
currentColor: NeutralIconColor | ||
} | ||
|
||
} | ||
} | ||
}, | ||
/** | ||
* Converts presentation attributes in element styles to the equivalent XML attribute. | ||
* Presentation attributes can be used in both attributes and styles, but in most cases it'll take fewer bytes to use attributes | ||
*/ | ||
{ name: "convertStyleToAttrs" }, | ||
/** | ||
* Remove all <style> elements from the document. | ||
*/ | ||
{ name: "removeStyleElement" }, | ||
/** | ||
* Sorts attributes in all elements in the document. This does not reduce the size of the SVG, but improves readability | ||
*/ | ||
{ name: "sortAttrs" }, | ||
/** | ||
* SVGs can be interactive through JavaScript. | ||
* However, unless the SVG is coming from a trusted source, it's strongly advised to strip off JavaScript to avoid XSS attacks. | ||
* | ||
* Since we're not using JavaScript in our SVGs, we can safely remove the script element. | ||
*/ | ||
{ name: "removeScriptElement" }, | ||
/** | ||
* Removes the clip-rule attribute from all elements. | ||
* In the unit tests, we make sure that there is no clipPath in our svgs. Yet for some reason | ||
* clip-rule are in almost all of our svgs. So to save some extra bytes, we remove them. | ||
*/ | ||
{ | ||
name: "removeAttrs", | ||
params: { | ||
attrs: "clip-rule" | ||
} | ||
} | ||
] | ||
}; | ||
|
||
export default config; |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.