You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/contributor-docs/adding-icons.md
+30-70Lines changed: 30 additions & 70 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,92 +4,52 @@ category: Contributor Guides
4
4
order: 9
5
5
---
6
6
7
-
## Adding and Modifying Icons
7
+
## Lucide Icons
8
8
9
-
- Use dashes in the name of the .svg files (e.g `calendar-month`).
10
-
- Use the same name for the "Line" and "Solid" variants, and save them in the respective folder, e.g. `instructure-ui/packages/ui-icons/svg/Line/calendar-month.svg` and `instructure-ui/packages/ui-icons/svg/Solid/calendar-month.svg`.
11
-
- Double-check that the SVG size is 1920x1920.
9
+
The bulk of the icon set comes from [Lucide](https://lucide.dev). These are not manually maintained
10
+
— they are automatically picked up from the `lucide-react` npm package at build time.
12
11
13
-
```js
14
-
---
15
-
type: code
16
-
---
17
-
<svg
18
-
width="1920"
19
-
height="1920"
20
-
viewBox="0 0 1920 1920"
21
-
fill="none"
22
-
xmlns="http://www.w3.org/2000/svg"
23
-
>
24
-
{...}
25
-
</svg>
26
-
```
27
-
28
-
- The files cannot contain [clipping paths](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/clipPath)! Sadly, when the Designers export icons from Figma, most of the time they have a clipping path around the whole canvas. When an SVG includes clipping paths, the `Icon Font` variant may not render correctly. Specifically, the use of `<g clip-path="...">` and `<clipPath id="...">` elements can cause rendering issues. If the source code has them, manually refactor the code, e.g:
29
-
30
-
```js
31
-
---
32
-
type: code
33
-
---
12
+
**To get a new or updated Lucide icon**, bump the `lucide-react` version in
13
+
`packages/ui-icons/package.json`. The index is regenerated automatically as part of
14
+
`pnpm run bootstrap` (via `build-icons`), so no manual step is needed.
15
+
16
+
Every icon exported by `lucide-react` becomes `<LucideIconName>InstUIIcon` in `@instructure/ui-icons`,
17
+
**except** for icons that are shadowed by a custom icon of the same name (see below).
18
+
19
+
If a Lucide icon is missing or looks wrong, check whether it exists in the installed version of
20
+
`lucide-react` first — if not, the only path is to add it as a custom icon.
34
21
35
-
// Before:
36
-
<svg
37
-
width="1920"
38
-
height="1920"
39
-
viewBox="0 0 1920 1920"
40
-
fill="none"
41
-
xmlns="http://www.w3.org/2000/svg"
42
-
>
43
-
<g clip-path="url(#clip0_1007_24)">
44
-
<path d="..." fill="#2D3B45"/>
45
-
</g>
46
-
<defs>
47
-
<clipPath id="clip0_1007_24">
48
-
<rect width="1920" height="1920" fill="white"/>
49
-
</clipPath>
50
-
</defs>
51
-
</svg>
22
+
## Adding Custom Icons
52
23
53
-
// After:
54
-
<svg
55
-
width="1920"
56
-
height="1920"
57
-
viewBox="0 0 1920 1920"
58
-
fill="none"
59
-
xmlns="http://www.w3.org/2000/svg"
60
-
>
61
-
<path d="..." fill="#2D3B45"/>
62
-
</svg>
63
-
```
24
+
Custom icons live in `packages/ui-icons/svg/Custom/` and are consumed directly by the build script (`scripts/generateCustomIndex.ts`).
64
25
65
-
-If the icon has to be bidirectional (being mirrored in RTL mode, typically arrow icons), add the icon name to the bidirectional list in `packages/ui-icons/icons.config.js`. Deprecated icons are handled here as well.
26
+
-Use kebab-case filenames ending in `.svg`. The filename becomes the React export name: `ai-info.svg` → `AiInfoInstUIIcon`, `canvas-logo.svg` → `CanvasLogoInstUIIcon`.
66
27
67
-
-Run `pnpm run bootstrap`.
28
+
-For solid/filled icons, the filename must end in `-solid.svg` (e.g. `bell-solid.svg`).
68
29
69
-
-Finally, run `pnpm run dev` and verify that the icons are displayed correctly under [Icons](/#icons). Check all 3 versions (React, SVG and icon font).
30
+
-If a custom icon has the same name as a Lucide icon (e.g. `message-square-check.svg`), the custom version takes precedence and the Lucide one is hidden from the package.
70
31
71
-
(Note: The fonts are sometimes not rendered correctly, but we decided not to fix them, because they are not really used anywhere, and we might stop supporting icon fonts in the future in general.)
32
+
- After dropping the file into `svg/Custom/`, the index is regenerated automatically as part of
33
+
`pnpm run bootstrap` (via `build-icons`).
72
34
73
-
### Guidelines for Drawing Icons
35
+
- Run `pnpm run dev` and verify the icon looks correct in the Icons gallery.
74
36
75
-
- Draw your icons on the 1920 x 1920 art-boards.
37
+
### Drawing Guidelines
76
38
77
-
- Before you flatten shapes or vectorize strokes as described below, make a hidden copy of the original paths off
78
-
to the side so that you can more easily come back and make changes later.
39
+
- Uncheck "Clip content" on the frame before exporting. Otherwise Figma wraps every layer in `<g clip-path="url(#…)">` and adds a `<defs><clipPath>…</clipPath></defs>` block, which can cause rendering issues
79
40
80
-
-Flatten your shapes.
41
+
-Use `currentColor` for all path fills and strokes. The build script reads the SVG as-is — no color replacement happens. If you exported with a hardcoded hex value, replace it manually before regenerating the index
81
42
82
-
-Export strokes to vector.
43
+
-Stroke icons: set `fill="none"` on every path, not just on the root `<svg>`. Select all shape layers and set Fill to None in the Design panel
83
44
84
-
-Don’t use borders on vectors, especially not inside/outside borders which aren’t supported in SVG. Do not use clipping paths.
45
+
-Remove `width` and `height` from the `<svg>` root — keep only `viewBox` and `xmlns`. Export at 1× in Figma
85
46
86
-
- Make sure none of the paths go outside of the art-board. If so, the glyph in the icon font will be misaligned.
87
-
Draw inside the lines.
47
+
- Flatten all transforms before exporting (Object → Flatten Selection)
88
48
89
-
-Fill the space edge-to-edge as much as possible. The build process will add margins as needed.
49
+
-Standard icons use `viewBox="0 0 24 24"`. Brand/logo icons can use any square viewBox (e.g. `0 0 1920 1920`)
90
50
91
-
-Don't use inline styles
51
+
-Mixed stroke + fill icons are supported. Paths with `fill="currentColor"` render filled; paths with `fill="none"` and a `stroke` render as outlines
92
52
93
-
-Don't use `class` or `for` attributes
53
+
-Do not use per-element `stroke-width`. The wrapper applies a uniform stroke width derived from the icon size
94
54
95
-
-Always have `<svg>`as the root tag
55
+
-Do not use `<mask>`or `<use>` elements. These are not supported — flatten or redesign the layer
Copy file name to clipboardExpand all lines: docs/guides/upgrade-guide.md
+4-5Lines changed: 4 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,25 +12,24 @@ TODO add details
12
12
13
13
## New icons
14
14
15
-
InstUI has switched to a new icon set, [Lucide](https://lucide.dev/icons/). We are still keeping some Instructure-specific icons, like product logos. We have a codemod that will help you migrate your code to the new icon set (see below).
15
+
InstUI has switched to a new icon set based on [Lucide](https://lucide.dev/icons/). We are still keeping some Instructure-specific icons, like product logos, also new custom icons are added. We have a codemod that will help you migrate your code to the new icon set.
16
16
17
17
### Lucide Icons Package
18
18
19
-
InstUI v12 introduces a new icon package **`@instructure/ui-icons-lucide`** based on the [Lucide](https://lucide.dev/icons/) icon library, providing 1,700+ icons with improved theming and RTL support. The new Lucide icons are wrapped with `wrapLucideIcon` to integrate with InstUI's theming system while maintaining access to all native Lucide props.
19
+
InstUI introduces new icons based on the [Lucide](https://lucide.dev/icons/) icon library, providing 1,900+ stroke-based icons with improved theming and RTL support. The icons are wrapped with `wrapLucideIcon` to integrate with InstUI's theming system while maintaining access to all native icon props.
20
20
21
21
**Key differences from `SVGIcon`/`InlineSVG`:**
22
22
23
-
| Property | Old API (SVGIcon) | New API (Lucide)|
|**color**| Limited tokens: `'primary'`\|`'secondary'`\|`'success'`\|`'error'`\|`'warning'`\| etc. | 60+ theme tokens (`'baseColor'`, `'successColor'`, `'actionPrimaryBaseColor'`, etc.) or any CSS color |
27
-
|**strokeWidth**| ❌ Not available |`'xs'`\|`'sm'`\|`'md'`\|`'lg'`\|`'xl'`\|`'2xl'`\|`number`\|`string`|
The new icons automatically sync with theme changes, support all InstUI color tokens, and provide better TypeScript integration. All standard HTML and SVG attributes can be passed directly to Lucide icons and will be spread onto the nested SVG element. Existing `@instructure/ui-icons` package remains available for legacy Instructure-specific icons.
32
+
The new icons automatically sync with theme changes, support all InstUI color tokens, and provide better TypeScript integration. All standard HTML and SVG attributes can be passed directly to Lucide icons and will be spread onto the nested SVG element.
By default, the icon's `role` is set to `presentation`. However, when the `title` prop is set, the role attribute is set to `img`. Include the `description` prop to further describe the icon.
0 commit comments