Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ✨ clone and recolorize icons #2305

Merged
merged 26 commits into from May 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7df7eb9
feat: ✨ clone and recolorize icons
lucas-labs Apr 25, 2024
bc6abd7
feat: ✨ integrate icon cloning with the the extension
lucas-labs Apr 25, 2024
d931fc4
chore: 🧹 update vscode-test dependency
lucas-labs Apr 25, 2024
c1fafe6
test: 🧪 fix failing tests
lucas-labs Apr 25, 2024
f4634a5
refactor: 🔨 improve in-code docs & comments
lucas-labs Apr 25, 2024
9e1ba79
feat: ✨ config to create light variants of the icon
lucas-labs Apr 25, 2024
8522d4d
feat: ✨ improve recolorization
lucas-labs Apr 25, 2024
8d399c4
feat: ✨ edge cases: support ignoring recolorizing paths
lucas-labs Apr 25, 2024
8445f2f
feat: ✨ do not recolor some paths in some edge-case icons
lucas-labs Apr 25, 2024
77d76a9
feat: ✨ jsconfig edge-case
lucas-labs Apr 25, 2024
15ba192
refactor: 🔨 simplify cloning process
lucas-labs Apr 26, 2024
400d0cf
feat: ✨ allow creating clones at build time
lucas-labs Apr 26, 2024
32f2e48
test: 🧪 test clone configuration generation
lucas-labs Apr 27, 2024
8eebc00
chore: 🧹 fix file names to camelCase to match project style
lucas-labs Apr 28, 2024
efa6ea1
test: 🧪 test clone data config generation
lucas-labs Apr 28, 2024
f8329a0
test: 🧪 color manipulation tests
lucas-labs Apr 28, 2024
796d096
test: 🧪 test svg cloning and recolor
lucas-labs Apr 28, 2024
dc53094
test: 🧪 json config generation from user options
lucas-labs Apr 28, 2024
73f68e0
docs: 📝 update contributing guide and readme
lucas-labs Apr 29, 2024
0f66d17
Merge branch 'main' into feat/custom-color-clones
PKief May 4, 2024
caf78ff
feat: ✨ documentation for `mit-no-recolor` attribute
lucas-labs May 5, 2024
c5565bb
fix: 🚑 icon availability check failing on clone icons
lucas-labs May 5, 2024
49f6e7b
fix: 🚑 broken links when generating icons preview png
lucas-labs May 5, 2024
c1b7796
fix: 🚑 icon usage check failing for clone icons
lucas-labs May 5, 2024
636503c
docs: 📝 CONTRIBUTING.md - add missing section to the TOC
lucas-labs May 5, 2024
f5edca0
fix: 🚑 filter out cloned icons from README preview pngs
lucas-labs May 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.