Skip to content

Commit

Permalink
feat: ✨ clone and recolorize icons (#2305)
Browse files Browse the repository at this point in the history
* feat: ✨ clone and recolorize icons

* feat: ✨ integrate icon cloning with the the extension

* chore: 🧹 update vscode-test dependency

vscode-test was renamed to @vscode/test-electron and
the former package was unable to run tests on windows.
this commit removes vscode-test and updates it to the
last version of @vscode/test-electron

* test: 🧪 fix failing tests

* refactor: 🔨 improve in-code docs & comments

* feat: ✨ config to create light variants of the icon

* feat: ✨ improve recolorization

improves recolorization logic, keeping originally darker
colors dark and lighter colors light even after recolor

* feat: ✨ edge cases: support ignoring recolorizing paths

adds support for a custom svg attribute `mit-no-recolor`
that, when set to true, will keep the original color of
the svg node on which is applied

* feat: ✨ do not recolor some paths in some edge-case icons

* feat: ✨ jsconfig edge-case

* refactor: 🔨 simplify cloning process

* feat: ✨ allow creating clones at build time

support for creating clones by configuring them
in the fileIcons.ts and folderIcons.ts files
so that the icons are created at build time
allowing contributors to create clones that are
shipped with the extension

* test: 🧪 test clone configuration generation

* chore: 🧹 fix file names to camelCase to match project style

* test: 🧪 test clone data config generation

* test: 🧪 color manipulation tests

* test: 🧪 test svg cloning and recolor

* test: 🧪 json config generation from user options

* docs: 📝 update contributing guide and readme

* feat: ✨ documentation for `mit-no-recolor` attribute

* fix: 🚑 icon availability check failing on clone icons

* fix: 🚑 broken links when generating icons preview png

* fix: 🚑 icon usage check failing for clone icons

* docs: 📝 CONTRIBUTING.md - add missing section to the TOC

* fix: 🚑 filter out cloned icons from README preview pngs

---------

Co-authored-by: Philipp Kief <philipp.kief@gmx.de>
  • Loading branch information
lucas-labs and PKief committed May 5, 2024
1 parent b94dbc4 commit 493d235
Show file tree
Hide file tree
Showing 58 changed files with 2,976 additions and 495 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -11,6 +11,8 @@ icons/folder.svg
icons/folder-open.svg
icons/folder-root.svg
icons/folder-root-open.svg
icons/*.clone.svg
icons/clones

src/scripts/preview/*.html
src/scripts/contributors/*.html
101 changes: 101 additions & 0 deletions CONTRIBUTING.md
Expand Up @@ -15,6 +15,7 @@ Glad you're here and interested in expanding this project 🎉 In order to make
- [Unique assignment to file and folder names](#icon-assignments)
- [Create icon packs](#icon-packs)
- [Designing Pixel Perfect Icons](#pixel-perfect-icons)
- [Cloning existing icons](#icon-cloning)
- [Add translations](#add-translations)
- [Update API](#update-api)

Expand All @@ -33,6 +34,17 @@ A new icon for a file name, file extension or folder name is needed? Please crea

It is always welcome to add new icons to the extension. However, there are a few things you should take into account so that the icon can be included in the extension.

```mermaid
flowchart LR
B{Shape already exists\nwith different colors?}
B ---->|No| E
B ---->|Yes| C
C[<a href="#cloning-workflow">Cloning Workflow</a>]
E[<a href="#creating-new-icons-workflow">Creating New Icons Workflow</a>]
```

### Creating New Icons Workflow

**Checklist**

1. [ ] Create icon as SVG ([how to](#create-icon-as-svg))
Expand All @@ -41,6 +53,16 @@ It is always welcome to add new icons to the extension. However, there are a few
4. [ ] Unique assignment to file and folder names ([how to](#icon-assignments))
5. [ ] Provide separate icons for color themes if necessary ([how to](#icons-for-color-themes))

### Cloning Workflow

There are times when we just need to create a variant of an existing icon.

For example, we might want to create an icon using the shape of the `typescript` icon, but we want it to be green and associated with the `library.ts` file name. In that case, we don't need to create a new svg. This can be done by configuration.

**Checklist**

1. [ ] Clone the existing icon adjusting its color ([how to](#icon-cloning))

## How tos

<h3 id="create-icon-as-svg">Create icon as SVG</h3>
Expand Down Expand Up @@ -299,6 +321,85 @@ The following are some tips to help you design nice and sharp-looking icons. The

- **Curves vs straight lines**: Let's face it, pixels are square, there's nothing we can do about it. And since pixels are square, drawing a curve actually involves drawing a series of... squares. Consequently, when rendering a curve, we're essentially asking the display to render a fraction of a pixel, which is impossible. As a result, curves tend to appear blurry. This is normal. However, it's perfectly fine to use curves, circles, and rounded edges in your icons. Just keep in mind these limitations if you're wondering why your icon doesn't look as sharp as you'd like.

<h3 id="icon-cloning">Cloning existing icons</h3>

The extension allows you to clone existing icons and adjust their colors through configuration. This enables you to create new color variants of an existing icon without having to create new SVG files.

As we mentioned previously, icons are assigned to filenames, file extensions, and folder names in the following files:

- [fileIcons.ts](src/icons/fileIcons.ts)
- [folderIcons.ts](src/icons/folderIcons.ts)

The following example demonstrates how the shapes of the `rust` file icon can be reused to create a clone of it, utilizing different colors and associated with different file names than the original icon.

```ts
{
name: 'rust-library',
fileNames: ['lib.rs'],
light: true, // needed if a `lightColor` is provided
clone: {
base: 'rust',
color: 'green-400',
lightColor: 'green-700', // optional
},
},
```

This will generate a new icon assignment for the file name `lib.rs` with the same shape as the already existing `rust` icon but with a green color instead. Additionally, it will create a light theme variant of the icon with a darker green color for better contrast when using a light theme.

That's it. We don't need to create a new SVG file. The extension will automatically adjust the colors of the existing icon.

<img src="./images/how-tos/cloned-rust-icon-example.png" />

The same technique can be applied to folder icons by using the `clone` attribute in the folder icon configuration.

You might have noticed that we are using aliases for the colors. These aliases correspond to the Material Design color palette.

You can find a list of all available color aliases in the [materialPalette.ts](./src/icons/generator/clones/utils/color/materialPalette.ts) file.

#### Preventing recoloring in cloned icons

When cloning icons, recoloring works by replacing each color attribute in each path/shape of the SVG with a new color, which is determined by the selected color in the configuration.

However, there are cases where you might want to prevent certain parts of the icon from being recolored.

Let's see an example:

![gitlab icon](./images/how-tos/cloned-icon-no-recolor.png)

In this example, we have the `folder-gitlab` folder icon. If we were to clone it, we might want to prevent recoloring from happening over the gitlab logo and only allow recoloring of the folder shape itself.

To do this, we need to set the attribute `mit-no-recolor="true"` to the paths, shapes, or groups we do not want to be recolored.

```svg
<svg ...>
<path d="M13...Z" style="fill: #757575"/>
<g mit-no-recolor="true"> <!-- prevent recolor of the gitlab logo -->
<path d="M31...Z" style="fill: #e53935"/>
<path d="M31...Z" style="fill: #ef6c00"/>
<path d="M19...Z" style="fill: #f9a825"/>
<path d="M17...Z" style="fill: #ef6c00"/>
</g>
</svg>
```

Now if we create a clone of this icon, the paths, shapes, or groups marked with `mit-no-recolor="true"` will retain their original colors. Recoloring will only affect paths not marked with this attribute.

```typescript
{ name: 'folder-gitlab', folderNames: ['gitlab'] },
{
name: 'folder-green-gitlab',
clone: {
base: 'folder-gitlab',
color: 'blue-300'
},
}
```

Will result in:

![result of cloning gitlab icon with selective recoloring](./images/how-tos/cloned-icon-no-recolor-result.png)

## Add translations

This project offers translations into different languages. If you notice an error here, please help to fix it. You can do this as follows:
Expand Down
58 changes: 58 additions & 0 deletions README.md
Expand Up @@ -108,6 +108,35 @@ In the settings.json (User Settings only!) the icon can be associated to a file

_Note: The custom file name must be configured in the settings without the file ending `.svg` as shown in the example above._

#### Custom clones

It's also possible to clone existing file icons and change their colors to create new icons that can be associated with file names or file extensions. The following example shows how to clone the `rust` icon:

```json
"material-icon-theme.files.customClones": [
{
"name": "rust-mod",
"base": "rust",
"color": "blue-400",
"fileNames": ["mod.rs"]
},
{
"name": "rust-lib",
"base": "rust",
"color": "light-green-300",
"lightColor": "light-green-600",
"fileNames": ["lib.rs"]
}
]
```

This will create two new icons called `rust-mod` and `rust-lib` that are associated with the file names `mod.rs` and `lib.rs` respectively. The `base` property defines the icon that should be cloned (in this case the `rust` icon). The `color` property defines the color of the new icon. The `lightColor` property is optional and defines the color of the icon when Visual Studio Code is running with a light color theme. The `fileNames` property defines the file names that should be associated with the new icon. There's also a `fileExtensions` property, which can be used to associate the new icon with file extensions (`"fileExtensions": ["ext", "ext2"]`).

<img src="https://raw.githubusercontent.com/PKief/vscode-material-icon-theme/main/images/how-tos/cloned-file-icons-example.png" alt="cloned file icons">

- Although you can use any `#RRGGBB` color for the `color` and `lightColor` properties, if you want to stick with colors from the material palette, you can check the full list of allowed aliases [here](https://github.com/PKief/vscode-material-icon-theme/tree/main/icons/generator/clones/utils/color/materialPalette.ts#L7).
- You can check the full list of available icons to be used as the `base` [here](https://github.com/PKief/vscode-material-icon-theme/blob/main/src/icons/fileIcons.ts).

### Folder associations

The following configuration can customize the folder icons. It is also possible to overwrite existing associations and create nice combinations. For example you could change the folder theme to "classic" and define icons only for the folder names you like.
Expand Down Expand Up @@ -141,6 +170,35 @@ In the settings.json (User Settings only!) the folder icons can be associated to
}
```

#### Custom clones

It's also possible to clone existing folder icons and change their colors to create new icons that can be associated with folder names. The following example shows how to clone the `admin` folder icon:

```json
"material-icon-theme.folders.customClones": [
{
"name": "users-admin",
"base": "admin",
"color": "light-green-500",
"lightColor": "light-green-700",
"folderNames": ["users"]
},
{
"name": "roles-admin",
"base": "admin",
"color": "purple-400",
"folderNames": ["roles"]
}
]
```

This will create two new icons called `users-admin` and `roles-admin` that are associated with the folder names `users` and `roles` respectively. The `base` property defines the icon that should be cloned (in this case the `admin` folder icon). The `color` property defines the color of the new icon. The `lightColor` property is optional and defines the color of the icon when Visual Studio Code is running with a light color theme. The `folderNames` property defines the folder names that should be associated with the new icon.

<img src="https://raw.githubusercontent.com/PKief/vscode-material-icon-theme/main/images/how-tos/cloned-folder-icons-example.png" alt="cloned folder icons">

- Although you can use any `#RRGGBB` color for the `color` and `lightColor` properties, if you want to stick with colors from the material palette, you can check the full list of allowed aliases [here](https://github.com/PKief/vscode-material-icon-theme/tree/main/icons/generator/clones/utils/color/materialPalette.ts#L7).
- You can check the full list of available icon to be used as the `base` [here](https://github.com/PKief/vscode-material-icon-theme/blob/main/src/icons/folderIcons.ts).

### Language associations

With the following configuration you can customize the language icons. It is also possible to overwrite existing associations.
Expand Down
2 changes: 0 additions & 2 deletions icons/azure-pipelines.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion icons/blink_light.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion icons/browserlist_light.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion icons/folder-gitlab-open.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 493d235

Please sign in to comment.