Compare commits

..
Author SHA1 Message Date
Eric Fennis 458ea3429b Merge branch 'package/extract-build-logic' into plan-lucide-react-integration-tests 2026-09-04 13:41:38 +02:00
Eric Fennis 4e5b528958 Merge branch 'main' of https://github.com/lucide-icons/lucide into plan-lucide-react-integration-tests 2026-09-04 13:40:51 +02:00
Eric Fennis 2157983c0f Add Lucide React integration tests 2026-09-04 12:30:27 +02:00
Karsa 78ef931b50 fix(packages/astro,react-native,vue): fix iconNode type
fix(packages/vue): fix hasA11yProp
2026-07-14 17:40:34 +02:00
Karsa 3041de00a1 chore(icons): revert git hook changes made to icons 2026-07-14 17:05:38 +02:00
Karsa 3df4e2ba2c Merge branch 'main' into package/extract-build-logic 2026-07-14 17:02:55 +02:00
Karsa 782c0ee791 Merge remote-tracking branch 'origin/package/extract-build-logic' into package/extract-build-logic 2026-07-14 16:29:07 +02:00
Karsa 3d4b0e0878 feat(): unify icon build logic some more, add nonScalingStroke option, marking absoluteStrokeWidth as deprecated 2026-06-05 16:49:09 +02:00
Karsa 8d0fa2e218 feat(): unify icon build logic some more, add nonScalingStroke option, marking absoluteStrokeWidth as deprecated 2026-06-05 16:49:09 +02:00
Karsa f5437f0a4c feat(packages): extract build logic to @lucide/shared, still wip 2026-06-05 16:49:09 +02:00
Karsa 06e962e44b feat(): unify icon build logic some more, add nonScalingStroke option, marking absoluteStrokeWidth as deprecated 2026-05-22 23:42:17 +02:00
Karsa a23c4b45cd feat(): unify icon build logic some more, add nonScalingStroke option, marking absoluteStrokeWidth as deprecated 2026-05-22 21:59:52 +02:00
Karsa 2189ae0f55 feat(packages): extract build logic to @lucide/shared, still wip 2026-05-22 21:59:12 +02:00
334 changed files with 8800 additions and 8488 deletions
-1
View File
@@ -10,4 +10,3 @@ touchpad
ungroup
toc
sunlounger
monstera
@@ -298,11 +298,11 @@ Link text should describe the destination or concept.
**Do:**
> See the [Icon Design Guide](./design-principles) for exact dimensions and spacing requirements.
> See the [Icon Design Specification](./specification) for exact dimensions and spacing requirements.
**Don't:**
> For more information, [click here](./design-principles).
> For more information, [click here](./specification).
Avoid generic link text such as:
-29
View File
@@ -64,7 +64,6 @@ jobs:
contents: write # Required to create the release and tag
outputs:
VERSION: ${{ steps.new-version.outputs.NEW_VERSION }}
RELEASE_URL: ${{ steps.create-release.outputs.url }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
@@ -103,7 +102,6 @@ jobs:
echo '${{ steps.change-log.outputs.CHANGE_LOG }}'
- name: Create Release
id: create-release
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
with:
tag_name: ${{ steps.new-version.outputs.NEW_VERSION }}
@@ -131,30 +129,3 @@ jobs:
with:
version: ${{ inputs.version }}
tag: ${{ inputs.tag }}
post-release:
name: Trigger post-release automation
if: >-
always() &&
github.repository == 'lucide-icons/lucide' &&
(needs.start-release.result == 'success' || needs.dispatch-release.result == 'success')
needs: [create-release, start-release, dispatch-release]
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Dispatch post_release event
env:
GH_TOKEN: ${{ secrets.POST_RELEASE_TOKEN }}
RELEASE_TAG: ${{ needs.create-release.outputs.VERSION || inputs.version }}
RELEASE_URL: ${{ needs.create-release.outputs.RELEASE_URL }}
run: |
if [ -z "$RELEASE_URL" ]; then
RELEASE_URL="https://github.com/lucide-icons/lucide/releases/tag/$RELEASE_TAG"
fi
gh api \
--method POST \
repos/lucide-icons/post-release/dispatches \
--field event_type=post_release \
--field "client_payload[release_tag]=$RELEASE_TAG" \
--field "client_payload[release_url]=$RELEASE_URL"
+3
View File
@@ -1,2 +1,5 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm lint-staged
pnpm checkIcons
-1
View File
@@ -98,7 +98,6 @@ export default defineConfig({
text: 'Resources',
items: [
...resourcesSidebar[0].items,
{ text: 'How to use icons', link: '/how-to/' },
{ text: 'Contributing icons', link: '/contribute/icons/' },
],
},
@@ -119,7 +119,8 @@ const highlighter = await createHighlighter({
});
export type ThemeOptions =
ThemeRegistration | { light: ThemeRegistration; dark: ThemeRegistration };
| ThemeRegistration
| { light: ThemeRegistration; dark: ThemeRegistration };
export const highLightCode = async (code: string, lang: string, active?: boolean) => {
const highlightedCode = highlighter
@@ -2,7 +2,8 @@ import { bundledLanguages, type ThemeRegistration } from 'shiki';
import { createHighlighter } from 'shiki';
export type ThemeOptions =
ThemeRegistration | { light: ThemeRegistration; dark: ThemeRegistration };
| ThemeRegistration
| { light: ThemeRegistration; dark: ThemeRegistration };
const highLightCode = async (code: string, lang: string, active?: boolean) => {
const highlighter = await createHighlighter({
+9 -24
View File
@@ -5,17 +5,6 @@ import type { RenderRule } from 'markdown-it/lib/renderer.mjs';
import container from 'markdown-it-container';
type ContainerArgs = [typeof container, string, { render: RenderRule }];
type GuidanceType = 'do' | 'dont' | 'caution';
const isGuidanceOpenToken = (type: string) =>
type === 'container_do_open' ||
type === 'container_dont_open' ||
type === 'container_caution_open';
const isGuidanceCloseToken = (type: string) =>
type === 'container_do_close' ||
type === 'container_dont_close' ||
type === 'container_caution_close';
const parseInfo = (info: string, marker: string) => info.trim().slice(marker.length).trim();
@@ -92,12 +81,12 @@ const hasTopLevelContent = (tokens: Parameters<RenderRule>[0], index: number) =>
return false;
}
if (isGuidanceOpenToken(token.type)) {
if (token.type === 'container_do_open' || token.type === 'container_dont_open') {
guidanceDepth += 1;
continue;
}
if (isGuidanceCloseToken(token.type)) {
if (token.type === 'container_do_close' || token.type === 'container_dont_close') {
guidanceDepth -= 1;
continue;
}
@@ -118,7 +107,7 @@ const hasGuidance = (tokens: Parameters<RenderRule>[0], index: number) => {
return false;
}
if (isGuidanceOpenToken(token.type)) {
if (token.type === 'container_do_open' || token.type === 'container_dont_open') {
return true;
}
}
@@ -134,7 +123,7 @@ const isFirstGuidance = (tokens: Parameters<RenderRule>[0], index: number) => {
return true;
}
if (isGuidanceOpenToken(token.type)) {
if (token.type === 'container_do_open' || token.type === 'container_dont_open') {
return false;
}
}
@@ -152,12 +141,6 @@ const getExampleOpenIndex = (tokens: Parameters<RenderRule>[0], index: number) =
return index;
};
const labels: Record<GuidanceType, string> = {
do: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check-icon lucide-check"><path d="M20 6 9 17l-5-5"/></svg> Do`,
dont: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x-icon lucide-x"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg> Don't`,
caution: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-exclamation-point"><path d="M12 20 L12 20" /><path d="M12 4 L12 15" /></svg> Caution`,
};
export default function examplePlugin(md: MarkdownIt) {
const escapeHtml = md.utils.escapeHtml;
@@ -187,7 +170,7 @@ export default function examplePlugin(md: MarkdownIt) {
},
];
const createGuidanceContainer = (type: GuidanceType): ContainerArgs => [
const createGuidanceContainer = (type: 'do' | 'dont'): ContainerArgs => [
container,
type,
{
@@ -202,7 +185,10 @@ export default function examplePlugin(md: MarkdownIt) {
hasTopLevelContent(tokens, exampleOpenIndex) && isFirstGuidance(tokens, idx)
? '</div>\n'
: '';
const label = labels[type];
const label =
type === 'do'
? `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check-icon lucide-check"><path d="M20 6 9 17l-5-5"/></svg> Do`
: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x-icon lucide-x"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg> Don't`;
return `${contentClose}<figure class="example-guidance example-guidance--${type}">${media}<figcaption class="example-guidance__caption"><div class="example-guidance__label">${label}</div>\n`;
}
@@ -215,5 +201,4 @@ export default function examplePlugin(md: MarkdownIt) {
md.use(...createExampleContainer());
md.use(...createGuidanceContainer('do'));
md.use(...createGuidanceContainer('dont'));
md.use(...createGuidanceContainer('caution'));
}
+1 -1
View File
@@ -94,7 +94,7 @@ export const angularSidebar = [
items: [
{
text: 'Accessibility in depth',
link: '/how-to/accessibility',
link: '/guide/accessibility',
desc: 'Accessibility best practices',
},
{
+1 -1
View File
@@ -69,7 +69,7 @@ export const astroSidebar = [
items: [
{
text: 'Accessibility in depth',
link: '/how-to/accessibility',
link: '/guide/accessibility',
desc: 'Accessibility best practices',
},
{
-1
View File
@@ -36,7 +36,6 @@ const sidebar: Sidebar = {
'/guide/react-native/': reactNativeSidebar,
'/guide/angular/': angularSidebar,
'/guide/static/': lucideStaticSidebar,
'/how-to': resourcesSidebar,
'/community': resourcesSidebar,
'/contribute': resourcesSidebar,
'/license': resourcesSidebar,
+1 -1
View File
@@ -79,7 +79,7 @@ export const lucideSidebar = [
items: [
{
text: 'Accessibility in depth',
link: '/how-to/accessibility',
link: '/guide/accessibility',
desc: 'Accessibility best practices',
},
],
+1 -1
View File
@@ -89,7 +89,7 @@ export const preactSidebar = [
items: [
{
text: 'Accessibility in depth',
link: '/how-to/accessibility',
link: '/guide/accessibility',
desc: 'Accessibility best practices',
},
{
+1 -1
View File
@@ -100,7 +100,7 @@ export const reactSidebar = [
items: [
{
text: 'Accessibility in depth',
link: '/how-to/accessibility',
link: '/guide/accessibility',
desc: 'Accessibility best practices',
},
{
+5 -19
View File
@@ -29,25 +29,6 @@ export const resourcesSidebar = [
},
],
},
{
text: 'How to use Lucide icons',
items: [
{
text: 'Getting started',
link: '/how-to/',
},
{
text: 'Accessibility guide',
link: '/how-to/accessibility',
desc: 'Learn how to make icons readable, understandable, and usable with assistive technology.',
},
{
text: 'How to pick the right icon',
link: '/how-to/icon-guide',
desc: 'Learn how to decide when icons belong in an interface and how to pick symbols people are likely to recognize.',
},
],
},
{
text: 'Contributing icons',
items: [
@@ -60,6 +41,11 @@ export const resourcesSidebar = [
link: '/contribute/icons/design-principles',
desc: 'Learn the visual principles that shape Lucide icons with side-by-side examples.',
},
{
text: 'Design specification',
link: '/contribute/icons/specification',
desc: 'Review the technical requirements every Lucide icon must meet.',
},
{
text: 'Naming conventions',
link: '/contribute/icons/naming-conventions',
+1 -1
View File
@@ -90,7 +90,7 @@ export const solidSidebar = [
items: [
{
text: 'Accessibility in depth',
link: '/how-to/accessibility',
link: '/guide/accessibility',
desc: 'Accessibility best practices',
},
{
+1 -1
View File
@@ -75,7 +75,7 @@ export const lucideStaticSidebar = [
items: [
{
text: 'Accessibility in depth',
link: '/how-to/accessibility',
link: '/guide/accessibility',
desc: 'Accessibility best practices',
},
{
+1 -1
View File
@@ -79,7 +79,7 @@ export const svelteSidebar = [
items: [
{
text: 'Accessibility in depth',
link: '/how-to/accessibility',
link: '/guide/accessibility',
desc: 'Accessibility best practices',
},
{
+1 -1
View File
@@ -85,7 +85,7 @@ export const vueSidebar = [
items: [
{
text: 'Accessibility in depth',
link: '/how-to/accessibility',
link: '/guide/accessibility',
desc: 'Accessibility best practices',
},
{
@@ -18,7 +18,7 @@ const pickIcons = [
'clapperboard',
'tool-case',
'printer',
'square-bookmark',
'album',
'pencil-ruler',
'calendar',
'brain',
@@ -53,7 +53,7 @@ const pickIcons = [
'terminal',
'thermometer',
'thumbs-up',
'trash',
'trash-2',
'umbrella',
'watch',
'sparkles',
@@ -122,7 +122,7 @@ const categoriesList = computed(() => {
});
const searchPlaceholder = useSearchPlaceholder(searchQuery, searchResults);
const isSearchMetadataLoading = computed(
() => searchQuery.value.length > 0 && !isFetchingTags && !isFetchingCategories,
() => searchQuery.value.length > 0 && (tags.value == null || categoriesMap.value == null),
);
const { list, containerProps, wrapperProps, scrollTo } = useVirtualList(categoriesList, {
@@ -88,13 +88,9 @@ const mappedIcons = computed(() => {
return sortedIcons.value;
}
if (categories.value == null) {
return sortedIcons.value;
}
return sortedIcons.value.map((icon) => {
const iconTags = tags.value[icon.name];
const iconCategories = categories.value[icon.name] ?? [];
const iconCategories = categories.value?.[icon.name] ?? [];
return {
...icon,
@@ -119,7 +115,7 @@ const searchResults = useSearch(searchQueryDebounced, mappedIcons, [
const searchPlaceholder = useSearchPlaceholder(searchQuery, searchResults);
const isSearchMetadataLoading = computed(
() => searchQuery.value.length > 0 && !isFetchingTags && !isFetchingCategories,
() => searchQuery.value.length > 0 && (tags.value == null || categories.value == null),
);
const chunkedIcons = computed(() => {
@@ -32,8 +32,7 @@
color: rgb(var(--text-color) / 1);
display: none;
top: -85%;
background-image:
radial-gradient(circle, var(--confetti-color) 20%, transparent 20%),
background-image: radial-gradient(circle, var(--confetti-color) 20%, transparent 20%),
radial-gradient(circle, transparent 20%, var(--confetti-color) 20%, transparent 30%),
radial-gradient(circle, var(--confetti-color) 20%, transparent 20%),
radial-gradient(circle, var(--confetti-color) 20%, transparent 20%),
@@ -57,8 +56,7 @@
.confetti-button:after {
display: none;
bottom: -75%;
background-image:
radial-gradient(circle, var(--confetti-color) 20%, transparent 20%),
background-image: radial-gradient(circle, var(--confetti-color) 20%, transparent 20%),
radial-gradient(circle, var(--confetti-color) 20%, transparent 20%),
radial-gradient(circle, transparent 10%, var(--confetti-color) 15%, transparent 20%),
radial-gradient(circle, var(--confetti-color) 20%, transparent 20%),
@@ -9,7 +9,6 @@ const useSearch = <T>(
const index = shallowRef(
new Fuse(collection.value, {
threshold: 0.2,
useExtendedSearch: true,
keys,
}),
);
@@ -18,9 +17,7 @@ const useSearch = <T>(
index.value.setCollection(collection.value);
if (query.value) {
return index.value
.search({ $and: query.value.split(' ').filter((t) => !!t) })
.map((result) => result.item);
return index.value.search(query.value).map((result) => result.item);
}
return collection.value;
-4
View File
@@ -286,10 +286,6 @@ html {
--example-guidance-label-bg: var(--vp-c-danger-1);
}
.example-guidance--caution {
--example-guidance-label-bg: var(--vp-c-warning-1);
}
@media (min-width: 640px) {
.example-block {
display: grid;
@@ -29,7 +29,7 @@ export default function useSearchPlaceholder(
}
}
state.value = {
isNoResults: query !== '' && searchResults.length === 0,
isNoResults: query in BRAND_STOPWORDS && searchResults.length === 0 && query !== '',
isBrand: query in BRAND_STOPWORDS,
query: BRAND_STOPWORDS[query] ?? query,
};
+23 -58
View File
@@ -8,9 +8,7 @@ Lucide is a consistent icon set, not a collection of unrelated icons. Every icon
This guide explains the visual rules behind Lucide icons and how to use them when designing new icons.
::: info Requirement levels
This guide uses normative terms such as **must**, **should**, and **may** as defined in [RFC 2119](https://www.rfc-editor.org/info/rfc2119/).
:::
For the full rule list, see the [icon design specification](./specification)
## 1. Use a 24 × 24-pixel canvas
@@ -96,9 +94,7 @@ Don't use **inside or outside** strokes. They change how line joins appear, crea
## 7. Use consistent corner radii
Corner radius depends on the size and angle of the element.
### 7.1. Sharp corners **should** be rounded unless the geometry of the icon requires otherwise
Almost every sharp corner **should** be rounded.
:::: example
::: do ../../images/border-radius-correct.svg?raw=true
@@ -109,44 +105,29 @@ Don't use **sharp corners**.
:::
::::
### 7.2. Elements at least 8 pixels wide or tall **should** use a 2-pixel corner radius for 90° corners
Corner radius depends on the size of the element and the angle. For 90° angles:
:::: example
::: do ../../images/2px-border-radius.svg?raw=true
Use a **2-pixel corner radius** for shapes that are at least 8 pixels wide or tall.
:::
::::
### 7.3. Elements smaller than 8 pixels **should** use a 1-pixel corner radius for 90° corners
Use a **1-pixel corner radius** for shapes smaller than 8 pixels.
:::: example
::: do ../../images/1px-border-radius.svg?raw=true
Use a **1-pixel corner radius** for shapes smaller than 8 pixels.
:::
::::
### 7.4. Diagonal lines meeting at a 90° angle **should** use a radius that preserves pixel-grid alignment
Diagonal lines that meet at a right angle usually need a **2.41 pixel** radius (1+√2) to stay aligned to the grid.
There are exceptions:
:::: example
::: do ../../images/border-radius-90deg.svg?raw=true
Diagonal lines that meet at a right angle usually need a **2.41 pixel** radius (1+√2) to stay aligned to the grid.
:::
::::
### 7.5. Other acute corners **should** use an appropriate amount of rounding based on their geometry
Even **very sharp corners** usually need a small amount of rounding. The exact amount depends on the shape.
:::: example
::: do ../../images/border-radius-arbitrary.svg?raw=true
Even **very sharp corners** usually need a small amount of rounding. The exact amount depends on the shape.
:::
::::
### 7.6. Corners where lines cross **must not** be rounded
Corners where multiple lines meet **must not** be rounded. Keep corners sharp where multiple lines meet so the icon scales well.
Avoid rounding corners **where multiple lines meet**.
:::: example
::: do ../../images/border-radius-line-join.svg?raw=true
@@ -157,15 +138,9 @@ Don't round corners where more than two lines meet. This can make the icon scale
:::
::::
### 7.7. Non-outlined arrows **must not** be rounded
Non-outlined arrows **must not** be rounded.
If the arrow is an outline shape, it **should** be rounded.
## 8. Keep at least 2 pixels between elements
### 8.1. Distinct elements **must** have at least 2 pixels of visual spacing between them
Distinct elements **must** have at least 2 pixels of visual spacing between them.
:::: example
::: do ../../images/2px-element-spacing.svg?raw=true
@@ -176,9 +151,7 @@ Don't use gaps smaller than **2 pixels** between distinct elements.
:::
::::
### 8.2. Inner gaps **should** be at least 2 pixels wide
The 2-pixel gap rule also applies inside shapes. Most inner gaps **should** be at least 2 pixels wide.
This also applies inside shapes. Most inner gaps **should** be at least 2 pixels wide.
:::: example
::: do ../../images/2px-inner-spacing.svg?raw=true
@@ -200,9 +173,7 @@ If the circle **overlaps** the shape, the gap should be **wider**.
:::
::::
### 8.3. Visual spacing **should** remain consistent when elements connect or intersect
Spacing **should** remain visually consistent where elements connect or intersect. Elements **must not** connect without keeping at least 2 pixels of spacing, and **should not** terminate with an abrupt cut.
The 2 pixel spacing also applies when elements visually connect or intersect.
:::: example
::: dont ../../images/2px-element-spacing-connected.svg?raw=true
@@ -213,13 +184,9 @@ Don't use **abrupt cuts** where one element meets another.
:::
::::
### 8.4. Off-variants **may** omit the 2-pixel gap rule
The `-off` variants have their own design language and **may** omit the 2-pixel gap rule.
## 9. Aim for consistent visual weight
Icons **should** have a similar visual weight when viewed alongside each other.
Icons should have a similar visual weight when viewed alongside each other.
:::: example
@@ -241,7 +208,7 @@ Place your icon next to `circle` or `square`, then blur both icons. Your icon sh
## 10. Balance icons visually
Icons **should** be visually centered within the canvas.
Icons should look centered and balanced within the canvas.
:::: example
::: do ../../images/visually-centered-do.svg?raw=true
@@ -254,7 +221,7 @@ This icon feels shifted toward the top left.
:::: example
::: do ../../images/visually-centered-symmetrical-do.svg?raw=true
Symmetrical icons **should** remain geometrically centered.
Symmetrical icons should remain geometrically centered.
:::
::: dont ../../images/visually-centered-symmetrical-dont.svg?raw=true
Don't place symmetrical icons off-center for no good reason.
@@ -262,14 +229,14 @@ Don't place symmetrical icons off-center for no good reason.
::::
::: tip
Geometric centering does not always look centered. Asymmetrical icons **may** be moved slightly off center so they look visually centered.
Geometric centering does not always look centered. Asymmetrical shapes may need a small adjustment.
Compare your icon with `circle` or `square` side by side and stacked vertically. If it looks shifted, adjust it.
:::
## 11. Keep density low
Icons **should** have a level of detail similar to other Lucide icons.
Lucide icons should have a similar level of detail.
:::: example
::: do ../../images/density-optimal.svg?raw=true
@@ -290,7 +257,7 @@ View the icon at its intended size and blur it. Areas that turn dark may have to
## 12. Use smooth, simple curves
Curves **should** be smooth and as simple as the shape allows. Arcs and quadratic Bézier curves **should** be preferred where possible. Cubic Bézier curves **may** be used where necessary.
Curves should be smooth and as simple as the shape allows.
:::: example
::: do ../../images/curvature-smooth.svg?raw=true
@@ -309,7 +276,7 @@ Avoid extra control points. They make shapes harder to edit and can create small
## 13. Design for the pixel grid
Lucide icons **should** look sharp at small sizes, including on low-density displays. Coordinates and centers of arcs and other geometric elements **should** align to the pixel grid where possible.
Lucide icons should look sharp at small sizes, including on low-density displays.
:::: example
::: do ../../images/pixel-perfection-ideal.svg?raw=true
@@ -339,14 +306,12 @@ Avoid placing diagonal lines off-grid. They will appear blurry and optically wid
::::
::: tip
Pixel alignment **should** support the icon. Off-grid geometry **may** be used when required for visual balance, recognizable geometry, or smooth curvature. Pixel alignment **should not** take precedence over the visual quality of the icon.
Pixel alignment should support the icon. Do not let it harm shape recognition, smooth curves, or visual balance.
:::
## 14. Reuse established shapes
### 14.1. Variants **should** preserve base icon geometry
When creating a variant, the base icon geometry, placement, and orientation **should** be preserved unless the new icon requires a change.
When creating a variant, keep the base icon geometry unless the new idea needs a change.
:::: example
::: do ../../images/established-shapes-base-do.svg?raw=true
@@ -357,7 +322,7 @@ Don't change the **geometry, placement, or orientation** of base shapes.
:::
::::
### 14.2. Related icons **should** share shapes and visual patterns when possible
Related icons should share shapes and visual patterns when possible.
:::: example
::: do ../../images/established-shapes-sub-do.svg?raw=true
@@ -368,7 +333,7 @@ Don't redesign **existing elements**.
:::
::::
### 14.3. Common modifiers and elements **should** look consistent across the library
Common modifiers and elements should look consistent across the library.
:::: example
::: do ../../images/established-shapes-consistency-do.svg?raw=true
@@ -382,7 +347,7 @@ Don't use **irregular placement or size** compared to existing icons.
::: tip
Preserving the base shape makes related icons work better when users switch between them.
Existing geometry **may** be modified when necessary to satisfy other Lucide design language rules. Consistency with an existing icon **should not** override clarity, balance, or readability.
Consistency with an existing icon should not override clarity, balance, or readability. Adjust the shape when needed.
:::
## Summary
+1 -1
View File
@@ -17,7 +17,7 @@ This guide explains how to design and prepare icons for Lucide.
## What this guide covers
<OverviewLinkGrid>
<OverviewLink v-for="item in resourcesSidebar[3].items.slice(1, -1)" :key="item.link" :href="item.link" :title="item.text" :desc="item.desc"/>
<OverviewLink v-for="item in resourcesSidebar[2].items.slice(1, -1)" :key="item.link" :href="item.link" :title="item.text" :desc="item.desc"/>
</OverviewLinkGrid>
## Use your preferred design tool
@@ -18,10 +18,10 @@ Tags help people find icons by concept, synonym, context, or common wording.
Tags should always be lowercase.
:::: example
::: do <LucideIcon name="mail" :iconNode="mail" /> email
::: do <LucideIcon :iconNode="mail" /> email
Lowercase tags **match the style** used across the icon library.
:::
::: dont <LucideIcon name="mail" :iconNode="mail" /> Email
::: dont <LucideIcon :iconNode="mail" /> Email
Capitalized tags create **inconsistent metadata** without improving search.
:::
::::
@@ -31,10 +31,10 @@ Capitalized tags create **inconsistent metadata** without improving search.
Use one clear word when it is enough. Use multi-word tags when the phrase is clearer.
:::: example
::: do <LucideIcon name="search" :iconNode="search" /> search
::: do <LucideIcon :iconNode="search" /> search
This is **short, common, and easy to find**.
:::
::: dont <LucideIcon name="search" :iconNode="search" /> searching through files & folders
::: dont <LucideIcon :iconNode="search" /> searching through files & folders
This reads like a **use case**, not a tag.
:::
::::
@@ -44,10 +44,10 @@ This reads like a **use case**, not a tag.
Some ideas are only clear as a phrase. But keep those phrases short.
:::: example
::: do <LucideIcon name="droplet" :iconNode="droplet" /> blood type
::: do <LucideIcon :iconNode="droplet" /> blood type
The phrase is **clearer** than either word on its own.
:::
::: dont <LucideIcon name="droplet" :iconNode="droplet" /> blood type medical label
::: dont <LucideIcon :iconNode="droplet" /> blood type medical label
This combines **several search concepts** into one long tag.
:::
::::
@@ -57,10 +57,10 @@ This combines **several search concepts** into one long tag.
Tags can include words people are likely to search for, even if they are not in the icon name.
:::: example
::: do <LucideIcon name="mail" :iconNode="mail" /> email
::: do <LucideIcon :iconNode="mail" /> email
This helps users find `mail` icons using a **common synonym**.
:::
::: dont <LucideIcon name="mail" :iconNode="mail" /> electronic postal message delivery
::: dont <LucideIcon :iconNode="mail" /> electronic postal message delivery
This is unlikely search wording and **adds noise**.
:::
::::
@@ -70,10 +70,10 @@ This is unlikely search wording and **adds noise**.
The icon name is already searchable. Tags should add other ways to find it.
:::: example
::: do <LucideIcon name="mail-search" :iconNode="mailSearch" /> message filter
::: do <LucideIcon :iconNode="mailSearch" /> message filter
This adds a **related concept** for `mail-search` without duplicating the name.
:::
::: dont <LucideIcon name="mail-search" :iconNode="mailSearch" /> mail search
::: dont <LucideIcon :iconNode="mailSearch" /> mail search
This **repeats the icon name** and does not improve discovery.
:::
::::
@@ -83,10 +83,10 @@ This **repeats the icon name** and does not improve discovery.
Tags should describe the icon, not say that it is an icon.
:::: example
::: do <LucideIcon name="calendar" :iconNode="calendar" /> event
::: do <LucideIcon :iconNode="calendar" /> event
This points to a **specific idea** users might search for.
:::
::: dont <LucideIcon name="calendar" :iconNode="calendar" /> icon
::: dont <LucideIcon :iconNode="calendar" /> icon
**Every entry is an icon**, so this tag does not help anyone find the right one.
:::
::::
@@ -96,10 +96,10 @@ This points to a **specific idea** users might search for.
Do not add loose terms just to make an icon appear in more searches.
:::: example
::: do <LucideIcon name="hospital" :iconNode="hospital" /> emergency room
::: do <LucideIcon :iconNode="hospital" /> emergency room
This is **relevant** for an icon that marks emergency room locations.
:::
::: dont <LucideIcon name="hospital" :iconNode="hospital" /> doctor nurse pharmacy
::: dont <LucideIcon :iconNode="hospital" /> doctor nurse pharmacy
These terms may be **nearby concepts**, but they do not all describe the same icon.
:::
::::
@@ -109,10 +109,10 @@ These terms may be **nearby concepts**, but they do not all describe the same ic
Related icons can share family terms, but variant tags should describe what is different.
:::: example
::: do <LucideIcon name="battery-low" :iconNode="batteryLow" /> depleted
::: do <LucideIcon :iconNode="batteryLow" /> depleted
This distinguishes `battery-low` from **other battery icons**.
:::
::: dont <LucideIcon name="battery-low" :iconNode="batteryLow" /> charged
::: dont <LucideIcon :iconNode="batteryLow" /> charged
This describes `battery-full` better than `battery-low`.
:::
::::
@@ -122,10 +122,10 @@ This describes `battery-full` better than `battery-low`.
Check similar icons before adding new tags. Reusing existing terms keeps search predictable.
:::: example
::: do <LucideIcon name="type" :iconNode="type" /> typography
::: do <LucideIcon :iconNode="type" /> typography
This matches existing text-formatting icons and keeps **related icons** together in search.
:::
::: dont <LucideIcon name="type" :iconNode="type" /> fontography
::: dont <LucideIcon :iconNode="type" /> fontography
Inventing a new term makes the icon harder to find and less consistent with related metadata.
:::
::::
@@ -16,10 +16,10 @@ This guide shows how to write clear use cases for Lucide icons.
Describe what the interface tells the user. Do not write from the contributor's point of view.
:::: example
::: do <LucideIcon name="wifi-off" :iconNode="wifiOff" /> Indicating a device is offline or unreachable
::: do <LucideIcon :iconNode="wifiOff" /> Indicating a device is offline or unreachable
This describes the **role the icon plays in an interface**.
:::
::: dont <LucideIcon name="wifi-off" :iconNode="wifiOff" /> I need an icon for my offline device screen
::: dont <LucideIcon :iconNode="wifiOff" /> I need an icon for my offline device screen
This explains the **contributor's situation**, not the icon's purpose.
:::
::::
@@ -29,10 +29,10 @@ This explains the **contributor's situation**, not the icon's purpose.
A use case should explain what the icon means in context. Do not repeat the icon name or only describe the drawing.
:::: example
::: do <LucideIcon name="microchip" :iconNode="microchip" /> Representing processors, chips, or embedded hardware
::: do <LucideIcon :iconNode="microchip" /> Representing processors, chips, or embedded hardware
This explains `microchip` **without repeating the name**.
:::
::: dont <LucideIcon name="microchip" :iconNode="microchip" /> it's a microchip icon
::: dont <LucideIcon :iconNode="microchip" /> it's a microchip icon
This **duplicates the icon name** and does not explain where the icon would be used.
:::
::::
@@ -42,10 +42,10 @@ This **duplicates the icon name** and does not explain where the icon would be u
Some icons have broad meanings. Add context when it makes the use case clearer.
:::: example
::: do <LucideIcon name="heading-2" :iconNode="heading2" /> Applying a level-2 heading in text editors
::: do <LucideIcon :iconNode="heading2" /> Applying a level-2 heading in text editors
The phrase explains both the **action and the product area**.
:::
::: dont <LucideIcon name="heading-2" :iconNode="heading2" /> Applying a heading
::: dont <LucideIcon :iconNode="heading2" /> Applying a heading
This is less useful because it **omits the level and context**.
:::
::::
@@ -55,10 +55,10 @@ This is less useful because it **omits the level and context**.
Each entry should cover one clear idea. Split different meanings into separate entries.
:::: example
::: do <LucideIcon name="square-parking" :iconNode="squareParking" /> Marking parking locations on maps
::: do <LucideIcon :iconNode="squareParking" /> Marking parking locations on maps
This is **short, clear, and focused** on one interface function.
:::
::: dont <LucideIcon name="square-parking" :iconNode="squareParking" /> Marking parking, transport, maps, cars, garages, and places
::: dont <LucideIcon :iconNode="squareParking" /> Marking parking, transport, maps, cars, garages, and places
This reads like a **tag list** and **mixes several ideas**.
:::
::::
@@ -68,10 +68,10 @@ This reads like a **tag list** and **mixes several ideas**.
For related icons, describe what makes each variant different.
:::: example
::: do <LucideIcon name="battery-low" :iconNode="batteryLow" /> Indicating a low battery charge level
::: do <LucideIcon :iconNode="batteryLow" /> Indicating a low battery charge level
This is specific to `battery-low` and **sets it apart** from other battery icons.
:::
::: dont <LucideIcon name="battery-low" :iconNode="batteryLow" /> Representing battery status
::: dont <LucideIcon :iconNode="batteryLow" /> Representing battery status
This is **too generic** and could apply to **every battery variant**.
:::
::::
@@ -81,10 +81,10 @@ This is **too generic** and could apply to **every battery variant**.
Use cases should make sense after the pull request is merged.
:::: example
::: do <LucideIcon name="handshake" :iconNode="handshake" /> Signifying a deal, agreement, or partnership
::: do <LucideIcon :iconNode="handshake" /> Signifying a deal, agreement, or partnership
This keeps the **useful meaning** without depending on **outside context**.
:::
::: dont <LucideIcon name="handshake" :iconNode="handshake" /> Same as above in #1234
::: dont <LucideIcon :iconNode="handshake" /> Same as above in #1234
This **depends on a discussion** readers **may never see**.
:::
::::
@@ -94,10 +94,10 @@ This **depends on a discussion** readers **may never see**.
Use cases should usually be 4 to 12 words. Prefer a short phrase over a long explanation.
:::: example
::: do <LucideIcon name="search" :iconNode="search" /> Searching files by name or content
::: do <LucideIcon :iconNode="search" /> Searching files by name or content
This is **short enough** to scan and **specific enough** to understand.
:::
::: dont <LucideIcon name="search" :iconNode="search" /> This icon can be used when users want to search through all of their files and folders to find something
::: dont <LucideIcon :iconNode="search" /> This icon can be used when users want to search through all of their files and folders to find something
This is **too long** and reads like **product copy instead of metadata**.
:::
::::
@@ -107,10 +107,10 @@ This is **too long** and reads like **product copy instead of metadata**.
Use cases are metadata phrases, not full sentences.
:::: example
::: do <LucideIcon name="credit-card" :iconNode="creditCard" /> Confirming a successful payment
::: do <LucideIcon :iconNode="creditCard" /> Confirming a successful payment
This matches the **phrase style** used across icon metadata.
:::
::: dont <LucideIcon name="credit-card" :iconNode="creditCard" /> Confirming a successful payment.
::: dont <LucideIcon :iconNode="creditCard" /> Confirming a successful payment.
The period adds **unnecessary punctuation** and makes entries inconsistent.
:::
::::
@@ -120,10 +120,10 @@ The period adds **unnecessary punctuation** and makes entries inconsistent.
Use plain text only. Formatting belongs in documentation, not metadata values.
:::: example
::: do <LucideIcon name="triangle-alert" :iconNode="triangleAlert" /> Warning users about a destructive action
::: do <LucideIcon :iconNode="triangleAlert" /> Warning users about a destructive action
This works in search, generated pages, and other places that use metadata.
:::
::: dont <LucideIcon name="triangle-alert" :iconNode="triangleAlert" /> <span>**Warning** users about a destructive action ⚠️</span>
::: dont <LucideIcon :iconNode="triangleAlert" /> <span>**Warning** users about a destructive action ⚠️</span>
Markdown and emoji can **show up in generated UI** and make metadata **harder to reuse**.
:::
::::
@@ -133,10 +133,10 @@ Markdown and emoji can **show up in generated UI** and make metadata **harder to
Use cases should describe meaning, not how the SVG was made.
:::: example
::: do <LucideIcon name="crop" :iconNode="crop" /> Representing cropped or trimmed content
::: do <LucideIcon :iconNode="crop" /> Representing cropped or trimmed content
This explains the icon's **interface meaning**.
:::
::: dont <LucideIcon name="crop" :iconNode="crop" /> Showing a rectangle with two path cuts and adjusted Bezier handles
::: dont <LucideIcon :iconNode="crop" /> Showing a rectangle with two path cuts and adjusted Bezier handles
This describes **construction details** that do not help people find or understand the icon.
:::
::::
+22 -22
View File
@@ -82,19 +82,19 @@ Icon names **must** use American English, not local variants.
Icon names **must** describe what the icon shows, not how someone might use it.
:::: example
::: do <LucideIcon name="save" :iconNode="save" /> `floppy-disk`
::: do <LucideIcon :iconNode="save" /> `floppy-disk`
The icon **shows** a floppy disk.
:::
::: dont <LucideIcon name="save" :iconNode="save" /> `save`
::: dont <LucideIcon :iconNode="save" /> `save`
Save is a use case.
:::
::::
:::: example
::: do <LucideIcon name="ban" :iconNode="ban" /> `circle-slash`
::: do <LucideIcon :iconNode="ban" /> `circle-slash`
The icon **shows** a circle with a slash across it.
:::
::: dont <LucideIcon name="ban" :iconNode="ban" /> `ban`
::: dont <LucideIcon :iconNode="ban" /> `ban`
Ban is an action.
:::
::::
@@ -110,10 +110,10 @@ Icons that belong to the same group **must** use the `<group>-<variant>` naming
The group name comes first. The variant comes after it.
:::: example
::: do <span><LucideIcon name="badge-plus" :iconNode="badgePlus" /> + <LucideIcon name="badge-check" :iconNode="badgeCheck" /></span> <span>`badge-plus` & `badge-check`</span>
::: do <span><LucideIcon :iconNode="badgePlus" /> + <LucideIcon :iconNode="badgeCheck" /></span> <span>`badge-plus` & `badge-check`</span>
`badge` is the group.
:::
::: dont <span><LucideIcon name="badge-plus" :iconNode="badgePlus" /> + <LucideIcon name="badge-check" :iconNode="badgeCheck" /></span> <span>`plus-badge` & `check-badge`</span>
::: dont <span><LucideIcon :iconNode="badgePlus" /> + <LucideIcon :iconNode="badgeCheck" /></span> <span>`plus-badge` & `check-badge`</span>
`plus` and `check` are not the group.
:::
::::
@@ -123,10 +123,10 @@ The group name comes first. The variant comes after it.
Alternate versions of an icon **must** be named for what makes them visually different. Do **not** use numbers just to separate one version from another.
:::: example
::: do <LucideIcon name="send-horizontal" :iconNode="sendHorizontal" /> `send-horizontal`
::: do <LucideIcon :iconNode="sendHorizontal" /> `send-horizontal`
The icon depicts a horizontal "send" symbol.
:::
::: dont <LucideIcon name="send-horizontal" :iconNode="sendHorizontal" /> <span>`send-2` or `send-alt`</span>
::: dont <LucideIcon :iconNode="sendHorizontal" /> <span>`send-2` or `send-alt`</span>
"send number 2" and "alternative send" are not clear names.
:::
::::
@@ -136,19 +136,19 @@ The icon depicts a horizontal "send" symbol.
Icon names **must not** include numbers unless the icon shows the number.
:::: example
::: do <LucideIcon name="arrow-down-0-1" :iconNode="arrowDown01" /> `arrow-down-0-1`
::: do <LucideIcon :iconNode="arrowDown01" /> `arrow-down-0-1`
The arrow points from 0 to 1.
:::
::: dont <LucideIcon name="send-horizontal" :iconNode="sendHorizontal" /> `send-2`
::: dont <LucideIcon :iconNode="sendHorizontal" /> `send-2`
The icon does not show the number 2.
:::
::::
:::: example
::: do <LucideIcon name="clock-3" :iconNode="clock3" /> `clock-3`
::: do <LucideIcon :iconNode="clock3" /> `clock-3`
The hands point to 3 o'clock.
:::
::: dont <LucideIcon name="user-round" :iconNode="userRound" /> `user-3`
::: dont <LucideIcon :iconNode="userRound" /> `user-3`
The icon does not show the number 3.
:::
::::
@@ -162,10 +162,10 @@ When an icon shows multiple elements of different sizes, order their names from
For an icon containing a circle and a person:
:::: example
::: do <LucideIcon name="moon-star" :iconNode="moonStar" /> `moon-star`
::: do <LucideIcon :iconNode="moonStar" /> `moon-star`
The `moon` is larger than the `star`.
:::
::: dont <LucideIcon name="circle-user" :iconNode="circleUser" /> `person-circle`
::: dont <LucideIcon :iconNode="circleUser" /> `person-circle`
The `person` is **not** larger than the `circle`.
:::
::::
@@ -179,19 +179,19 @@ If elements overlap, name them from front to back.
If they do not overlap, name them in English reading order: top to bottom, then left to right.
:::: example
::: do <LucideIcon name="pencil-ruler" :iconNode="pencilRuler" /> `pencil-ruler`
::: do <LucideIcon :iconNode="pencilRuler" /> `pencil-ruler`
The `pencil` is **in front** of the `ruler`, so it comes first.
:::
::: do <LucideIcon name="ruler-dimension-line" :iconNode="rulerDimensionLine" /> `ruler-dimension-line`
::: do <LucideIcon :iconNode="rulerDimensionLine" /> `ruler-dimension-line`
The ruler is below the dimension line, but it is **larger**, so it comes first.
:::
::::
:::: example
::: do <LucideIcon name="sun-snow" :iconNode="sunSnow" /> `sun-snow`
::: do <LucideIcon :iconNode="sunSnow" /> `sun-snow`
The `sun` is **left of** the `snowflake`, so it comes first.
:::
::: dont <LucideIcon name="pencil-ruler-horizontal" :iconNode="pencilRulerHorizontal" /> `ruler-pencil`
::: dont <LucideIcon :iconNode="pencilRulerHorizontal" /> `ruler-pencil`
The `ruler` is **below** the `pencil`, so `pencil-ruler` is the correct name.
:::
::::
@@ -201,10 +201,10 @@ The `ruler` is **below** the `pencil`, so `pencil-ruler` is the correct name.
Modifiers **must** come after the element they describe: `<element>-<modifier>`.
:::: example
::: do <LucideIcon name="heart-crack" :iconNode="heartCrack" /> `heart-broken`
::: do <LucideIcon :iconNode="heartCrack" /> `heart-broken`
The icon shows a heart that is **cracked**.
:::
::: dont <LucideIcon name="bone-fracture" :iconNode="boneFracture" /> `broken-bone`
::: dont <LucideIcon :iconNode="boneFracture" /> `broken-bone`
The icon shows a bone that is **broken**, so name it `bone-broken`.
:::
::::
@@ -212,12 +212,12 @@ The icon shows a bone that is **broken**, so name it `bone-broken`.
When an icon has multiple modified elements, each modifier **must** follow the element it describes.
:::: example
::: do <LucideIcon name="circle-fading-arrow-up" :iconNode="circleFadingArrowUp" /> `circle-fading-arrow-up`
::: do <LucideIcon :iconNode="circleFadingArrowUp" /> `circle-fading-arrow-up`
The icon shows a **fading** circle with an arrow pointing **up** inside it.
`circle` comes first because it is larger than `arrow`. `fading` follows `circle` because it modifies the circle. `up` follows `arrow` because it modifies the arrow.
:::
::: dont <LucideIcon name="notepad-text-dashed" :iconNode="notepadTextDashed" /> `notepad-text-dashed`
::: dont <LucideIcon :iconNode="notepadTextDashed" /> `notepad-text-dashed`
This icon shows a dashed notepad with text inside, so name it `notepad-dashed-text`.
`notepad` comes first because it is larger than `text`. `dashed` follows `notepad` because it modifies the notepad. `text` follows both because `dashed` does not modify `text`.
+95
View File
@@ -0,0 +1,95 @@
---
description: Rules Lucide icons must follow.
---
# Icon design specification
This page lists the rules Lucide icons must follow.
For examples and guidance, see the [Lucide design language](./design-principles).
## Requirement levels
These terms show how strictly each rule applies:
- **Must** and **must not** mark required rules.
- **Should** and **should not** mark rules that can flex when needed to make a better icon.
Any exception should be intentional and fit the [Lucide design language](./design-principles).
## Canvas
1. Icons **must** use a 24 × 24-pixel canvas.
2. The canvas **must** be square.
3. Icon strokes **must** remain at least 1 pixel from the edge of the canvas.
## Strokes
1. Strokes **must** be 2 pixels wide.
2. Strokes **must** use round line joins.
3. Open paths **must** use round line caps.
4. Strokes **must** be centered on their paths.
## Corners
1. Sharp corners **should** be rounded unless the geometry of the icon requires otherwise.
2. Elements at least 8 pixels wide or tall **should** use a 2-pixel corner radius for 90° corners.
3. Elements smaller than 8 pixels **should** use a 1-pixel corner radius for 90° corners.
4. Diagonal lines meeting at a 90° angle **should** use a radius that preserves pixel-grid alignment. This radius is typically approximately 2.41 pixels.
5. Acute corners **should** use an appropriate amount of rounding based on their geometry.
6. Corners where multiple lines meet **should** remain sharp when rounding would cause the icon to render inconsistently at different sizes.
## Spacing
1. Distinct elements **must** have at least 2 pixels of visual separation.
2. Gaps between distinct elements **must not** be smaller than 2 pixels.
3. Inner gaps **should** be at least 2 pixels wide.
4. Spacing **should** remain visually consistent where elements connect or intersect.
5. Elements **should not** terminate with an abrupt cut where another element visually continues or intersects them.
## Visual weight
1. Icons **should** have a visual weight similar to the `circle` and `square` icons.
2. Icons **should not** appear substantially larger, smaller, heavier, or lighter than comparable Lucide icons.
## Alignment and balance
1. Icons **should** be visually centered within the canvas.
2. Asymmetrical icons **may** be moved slightly off center so they look visually centered.
3. Symmetrical icons **should** be geometrically centered.
## Visual density
1. Icons **should** have a level of detail similar to other Lucide icons.
2. Details **should** be simplified when they cause an icon to appear substantially denser than comparable icons.
3. Details that are not necessary for recognition **should** be omitted.
## Curves
1. Continuous curves **should** have smooth curvature.
2. Curves **should not** contain unintended or abrupt changes in curvature.
3. Arcs and quadratic Bézier curves **should** be preferred where they can accurately represent the intended geometry.
4. Cubic Bézier curves **may** be used where necessary.
5. Control points of adjoining cubic Bézier curves **should** be aligned where required to maintain continuous curvature.
6. Curves **should not** contain unnecessary control points.
## Pixel alignment
1. Coordinates **should** align to the pixel grid where possible.
2. Centers of arcs and other geometric elements **should** align to the pixel grid where possible.
3. Off-grid geometry **may** be used when required for visual balance, recognizable geometry, or smooth curvature.
4. Pixel alignment **should not** take precedence over the visual quality of the icon.
## Shared geometry
1. Variants of an existing icon **should** preserve the geometry, placement, and orientation of the base icon.
2. Elements that already exist in other Lucide icons **should** reuse established geometry where applicable.
3. Related icons **should** use consistent representations of shared elements.
4. Common modifiers and add-ons **should** use consistent geometry, size, and placement across related icons.
5. Existing geometry **may** be modified when necessary to satisfy other Lucide design language rules.
## Priority of requirements
When two non-required rules conflict, choose visual clarity and consistency with the Lucide design language.
Rules marked **must** or **must not** can only be broken when the project defines an explicit exception.
+237
View File
@@ -0,0 +1,237 @@
---
title: Accessibility
description: Learn how to make your icons accessible to all users, including those with disabilities.
---
# Accessibility in depth
Icons are pictures that show what something means without using words. They can be very helpful
because they can quickly give information.
However, not everyone can understand them easily. When using icons it is very important to consider
the following aspects of accessibility.
::: info
By default, we hide icons from screen readers using `aria-hidden="true"`.
You can make them accessible yourself by following the guidelines below.
:::
## Provide visible labels
Icons are a helpful tool to improve perception, but they aren't a replacement for text.
In most cases, it is probably a good idea to also provide a textual representation of your icon's
function.
<!--@include: ../../docs/images/a11y/visible-labels.svg -->
## Contrast
Ensure there's enough contrast between the icon and its background so that it's visible to people
with low vision or color vision deficiencies.
We recommend
following [WCAG 2.1 SC 1.4.3](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html).
<!--@include: ../../docs/images/a11y/contrast.svg -->
## Use of color
Avoid relying solely on color to convey meaning in icons, as some users may have color blindness.
Instead, use additional visual cues like shape, shading or text.
<!--@include: ../../docs/images/a11y/use-of-color.svg -->
## Interactivity
Ensure that interactive icons are accessible via keyboard navigation and provide clear feedback when
activated.
<!--@include: ../../docs/images/a11y/interactivity.svg -->
In most cases this is easily done by wrapping them in icon buttons.
## Minimum target size
Small targets can be difficult to click or touch, if your icon is interactive, we recommend that it
should have a minimum target size of 44×44 pixels.
<!--@include: ../../docs/images/a11y/target-size.svg -->
In practice, this doesn't necessarily mean that the icon itself should be this large, only its
interactive wrapper element.
## Meaningfulness
Icons should represent concepts or actions in a universally understandable way. Avoid using abstract
or ambiguous, or culture-specific symbols that might confuse some users.
<!--@include: ../../docs/images/a11y/meaningfulness.svg -->
## Consistency
Maintain consistency in icon design and usage across your interface to help users learn and
understand their meanings more easily.
<!--@include: ../../docs/images/a11y/consistency.svg -->
## Text Alternatives
You may have to provide text labels or alternative text descriptions for icons, especially for
screen readers used by people with visual impairments.
However: descriptions should only be provided to standalone icons that aren't purely decorative, as
providing accessible names to non-functional elements only increases clutter when using screen
readers.
### On standalone icons
Icons are usually very unlikely to stand on their own with no semantically meaningful wrapper
element. In most cases they will be part of a badge, button (including icon buttons), navigation
item or other interactive UI element.
::: warning
In case some of your icons stand alone, and they serve a non-decorative function, make sure to
provide the appropriate accessible label for them.
:::
<!--@include: ../../docs/images/a11y/alttext-standalone.svg -->
In general try to avoid using functional icons with no interactivity, we recommend that:
1) you either add a visible description next to them, or
2) place them in badges, labels or on buttons, and at least add a tooltip to them.
In any such case, it is preferred that the accessible name be provided for these interactive
elements (badges, buttons, nav items etc.) only, _not_ the icons themselves.
### On buttons
Do not provide an accessible label to icons when used on a button, as this label will be read out by
screen readers, leading to nonsensical text.
<!--@include: ../../docs/images/a11y/alttext-buttons.svg -->
::: details Code examples
```tsx
// Don't do this
<button>
<Plus aria-label="Plus icon"/>
Add document
</button>
// Do this, just leave it
<button>
<Plus/>
Add document
</button>
```
:::
### On icon buttons
Icon buttons are buttons that do not contain any visible text apart from the icon itself (think of
the close button of a dialog for example).
As previously stated, you should provide your accessible label on the icon button itself, not the
contained icon.
<!--@include: ../../docs/images/a11y/alttext-iconbuttons.svg -->
::: details Code examples
```tsx
// Don't do this
<button class="btn-icon">
<House/>
</button>
// Don't do this either
<button class="btn-icon">
<House aria-label="Home icon"/>
</button>
// This works but might not be the best solution, see below
<button aria-label="Go to home" class="btn-icon">
<House/>
</button>
// Do this instead
<button class="btn-icon">
<House/>
<span class="visually-hidden">Go to home</span>
</button>
```
:::
## A note on `aria-label`
Although you could provide accessible labels to your elements via the `aria-label` attribute, we
generally recommend avoiding this and instead suggest that you use your chosen CSS framework's "
visually hidden" utility whenever possible. You can
[read more about why `aria-label` might not be the best solution](https://gomakethings.com/revisting-aria-label-versus-a-visually-hidden-class/).
### Example - Radix UI
Use [Radix UI's built-in accessible icon utility component](https://www.radix-ui.com/primitives/docs/utilities/accessible-icon).
```tsx
import { ArrowRightIcon } from 'lucide-react';
import { AccessibleIcon } from '@radix-ui/react-accessible-icon';
<AccessibleIcon label="Next item">
<ArrowRightIcon />
</AccessibleIcon>
```
### Example - Bootstrap
```html
<div>
<i data-lucide="phone" aria-hidden="true"></i>
<span class="visually-hidden">Phone number</span>
</div>
```
### Example - Tailwind CSS
```html
<div>
<i data-lucide="phone" aria-hidden="true"></i>
<span class="sr-only">Phone number</span>
</div>
```
If you're not sure, you may consider learning more
about [how to hide content.](https://www.a11yproject.com/posts/how-to-hide-content/)
## Further resources
We also recommend checking out the following resources about accessibility:
- [Web Content Accessibility Guidelines (WCAG) 2.1](https://www.w3.org/TR/WCAG21/)
- [Web Accessibility Initiative (WAI)](https://www.w3.org/WAI/)
- [Learn accessibility on web.dev](https://web.dev/learn/accessibility)
- [Inclusive Components](https://inclusive-components.design/)
- [A11yTalks](https://www.a11ytalks.com/)
- [A11y automation tracker](https://a11y-automation.dev/)
- [The A11Y Project](https://www.a11yproject.com/)
<style>
svg.a11y-example {
max-width: calc(100% + 48px);
margin: 0 -24px;
}
@media (min-width: 480px) {
svg.a11y-example {
margin: 0;
max-width: 100%;
}
}
</style>
+1 -1
View File
@@ -17,7 +17,7 @@ Most of the time, icons are used purely for decoration or visual reinforcement.
For a broader explanation of this, and other best practices on how to use icons accessibly in your application, please refer to our detailed guide on accessibility:
<OverviewLink href="/how-to/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
<OverviewLink href="/guide/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
Only if an icon **conveys essential meaning on its own** should it be made accessible. The sections below explain how to do that in Angular.
+46 -54
View File
@@ -2,7 +2,6 @@
title: Combining icons - Angular
description: Learn how to combine multiple icons into a single icon nested SVG elements in your Angular application.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackAngular.vue'
</script>
@@ -15,32 +14,28 @@ This is useful for if you want to be creative and make your own custom icons by
::: sandpack {template=angular showTabs=false editorHeight=400 editorWidthPercentage=60 dependencies="@lucide/angular"}
```ts /src/app/app.component.ts [active]
import { Component, ViewEncapsulation } from '@angular/core';
import { LucideScan, LucideUser } from '@lucide/angular';
import { Component, ViewEncapsulation } from "@angular/core";
import { LucideScan, LucideUser } from "@lucide/angular";
@Component({
selector: 'app',
imports: [LucideScan, LucideUser],
template: ` <svg
lucideScan
[size]="48"
[nonScalingStroke]="true"
>
<svg
lucideUser
[size]="12"
x="6"
y="6"
[strokeWidth]="4"
[nonScalingStroke]="true"
/>
</svg>`,
template: `
<svg lucideScan [size]="48">
<svg lucideUser
[size]="12"
x="6"
y="6"
[strokeWidth]="4"
[absoluteStrokeWidth]="true"
/>
</svg>`,
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None,
})
export class App {}
export class App {
}
```
:::
This is valid SVG and all SVG properties are supported on the icons.
@@ -58,29 +53,28 @@ You can also use SVG elements to create your own icons.
For example, you can add a notification badge to an icon by using the `circle` SVG element.
::: sandpack {template=angular showTabs=false editorHeight=400 editorWidthPercentage=60 dependencies="@lucide/angular"}
```ts /src/app/app.component.ts [active]
import { Component, ViewEncapsulation, signal } from '@angular/core';
import { LucideMail } from '@lucide/angular';
import { Component, ViewEncapsulation, signal } from "@angular/core";
import { LucideMail } from "@lucide/angular";
@Component({
selector: 'app',
imports: [LucideMail],
template: ` <svg
lucideMail
[size]="48"
>
@if (hasUnreadMessages()) {
<circle
r="3"
cx="21"
cy="5"
stroke="none"
fill="#F56565"
/>
}
</svg>`,
template: `
<svg lucideMail [size]="48">
@if (hasUnreadMessages()) {
<circle
r="3"
cx="21"
cy="5"
stroke="none"
fill="#F56565"
/>
}
</svg>`,
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None,
})
@@ -88,40 +82,38 @@ export class App {
protected readonly hasUnreadMessages = signal<boolean>(true);
}
```
:::
### Example with text element
You can also use the `text` SVG element to add text to your icon.
::: sandpack {template=angular showTabs=false editorHeight=400 editorWidthPercentage=60 dependencies="@lucide/angular"}
```ts /src/app/app.component.ts [active]
import { Component, ViewEncapsulation } from '@angular/core';
import { LucideFile } from '@lucide/angular';
import { Component, ViewEncapsulation } from "@angular/core";
import { LucideFile } from "@lucide/angular";
@Component({
selector: 'app',
imports: [LucideFile],
template: ` <svg
lucideFile
[size]="48"
>
<text
x="7.5"
y="19"
font-size="8"
font-family="Verdana,sans-serif"
stroke-width="1"
>
JS
</text>
</svg>`,
template: `
<svg lucideFile [size]="48">
<text
x="7.5"
y="19"
font-size="8"
font-family="Verdana,sans-serif"
stroke-width="1"
>
JS
</text>
</svg>`,
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None,
})
export class App {}
export class App {
}
```
:::
+32 -31
View File
@@ -2,7 +2,6 @@
title: Global Styling - Angular
description: Learn how to style all icons globally in your Angular application using CSS or the provideLucideConfig provider.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackAngular.vue'
</script>
@@ -30,9 +29,9 @@ import { provideLucideConfig } from '@lucide/angular';
export const appConfig: ApplicationConfig = {
providers: [
provideLucideConfig({
strokeWidth: 1.5,
strokeWidth: 1.5
}),
],
]
};
```
@@ -66,7 +65,7 @@ All Lucide icons include the `lucide` class. You can use this class in your styl
```
```ts /src/app/app.component.ts
import { Component, ViewEncapsulation } from '@angular/core';
import { Component, ViewEncapsulation } from "@angular/core";
import {
LucideCakeSlice,
LucideCandy,
@@ -77,7 +76,7 @@ import {
LucideSandwich,
LucideWine,
LucideDessert,
} from '@lucide/angular';
} from "@lucide/angular";
@Component({
selector: 'app',
@@ -93,27 +92,28 @@ import {
LucideDessert,
],
template: `<div class="grid">
<svg lucideCakeSlice />
<svg lucideCandy />
<svg lucideApple />
<svg lucideCookie />
<svg lucideMartini />
<svg lucideIceCream2 />
<svg lucideSandwich />
<svg lucideWine />
<svg lucideDessert />
</div>`,
<svg lucideCakeSlice />
<svg lucideCandy />
<svg lucideApple />
<svg lucideCookie />
<svg lucideMartini />
<svg lucideIceCream2 />
<svg lucideSandwich />
<svg lucideWine />
<svg lucideDessert />
</div>`,
styleUrls: ['./app.component.css', './icon.css'],
encapsulation: ViewEncapsulation.None,
})
export class App {}
export class App {
}
```
:::
### Non-scaling strokes
### Absolute stroke width
To keep the stroke width constant regardless of icon size, apply `vector-effect: non-scaling-stroke` to the icon's children. See [non-scaling strokes](../basics/stroke-width.md#non-scaling-strokes) for more details.
To keep the stroke width constant regardless of icon size, apply `vector-effect: non-scaling-stroke` to the icon's children. See [absolute-stroke-width](../basics/stroke-width.md#absolute-stroke-width) for more details.
::: sandpack {template=angular editorHeight=300 dependencies="@lucide/angular"}
@@ -137,7 +137,7 @@ To keep the stroke width constant regardless of icon size, apply `vector-effect:
```
```ts /src/app/app.component.ts
import { Component, ViewEncapsulation } from '@angular/core';
import { Component, ViewEncapsulation } from "@angular/core";
import {
LucideTentTree,
LucideCaravan,
@@ -148,7 +148,7 @@ import {
LucideMap,
LucideCloudMoon,
LucideSparkles,
} from '@lucide/angular';
} from "@lucide/angular";
@Component({
selector: 'app',
@@ -164,20 +164,21 @@ import {
LucideSparkles,
],
template: `<div class="grid">
<svg lucideTentTree />
<svg lucideCaravan />
<svg lucideFlameKindling />
<svg lucideMountainSnow />
<svg lucideTrees />
<svg lucideAxe />
<svg lucideMap />
<svg lucideCloudMoon />
<svg lucideSparkles />
</div>`,
<svg lucideTentTree />
<svg lucideCaravan />
<svg lucideFlameKindling />
<svg lucideMountainSnow />
<svg lucideTrees />
<svg lucideAxe />
<svg lucideMap />
<svg lucideCloudMoon />
<svg lucideSparkles />
</div>`,
styleUrls: ['./app.component.css', './icon.css'],
encapsulation: ViewEncapsulation.None,
})
export class App {}
export class App {
}
```
:::
+19 -23
View File
@@ -1,8 +1,7 @@
---
title: Stroke width - Angular
description: Learn how to adjust the stroke width of icons in your Angular application using the `strokeWidth` input or adjust the strokeWidth appearance using the `nonScalingStroke` input.
description: Learn how to adjust the stroke width of icons in your Angular application using the `strokeWidth` input or adjust the strokeWidth appearance using the `absoluteStrokeWidth` input.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackAngular.vue'
</script>
@@ -19,58 +18,55 @@ The `strokeWidth` can be adjusted to create a different look of the icons.
::: sandpack {template=angular showTabs=false editorHeight=400 editorWidthPercentage=60 dependencies="@lucide/angular"}
```ts /src/app/app.component.ts [active]
import { Component, ViewEncapsulation } from '@angular/core';
import { LucideFolderLock } from '@lucide/angular';
import { Component, ViewEncapsulation } from "@angular/core";
import { LucideFolderLock } from "@lucide/angular";
@Component({
selector: 'app',
imports: [LucideFolderLock],
template: `<svg
lucideFolderLock
[strokeWidth]="1"
/>`,
template: `<svg lucideFolderLock [strokeWidth]="1" />`,
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None,
})
export class App {}
export class App {
}
```
:::
## Non-scaling strokes
## Absolute stroke width
When binding the `size` input, the icon's stroke width will be relative to its size, this is the default SVG behavior. The `nonScalingStroke` input is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
When binding the `size` input, the icon's stroke width will be relative to its size, this is the default SVG behavior. The `absoluteStrokeWidth` input is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
This means that when `nonScalingStroke` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
This means that when `absoluteStrokeWidth` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
### Adjusting stroke width with `nonScalingStroke` input
### Adjusting stroke width with `absoluteStrokeWidth` input
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
::: sandpack {template=angular showTabs=false editorHeight=400 editorWidthPercentage=60 dependencies="@lucide/angular"}
```ts /src/app/app.component.ts [active]
import { Component, ViewEncapsulation } from '@angular/core';
import { LucideRollerCoaster } from '@lucide/angular';
import { Component, ViewEncapsulation } from "@angular/core";
import { LucideRollerCoaster } from "@lucide/angular";
@Component({
selector: 'app',
imports: [LucideRollerCoaster],
template: `
<svg
<svg
lucideRollerCoaster
[size]="96"
[nonScalingStroke]="true"
[absoluteStrokeWidth]="true"
></svg>
`,
`,
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None,
})
export class App {}
export class App {
}
```
:::
+10 -17
View File
@@ -2,7 +2,6 @@
title: Getting started - Angular
description: This guide will help you get started with Lucide in your Angular project.
---
<script setup>
import OverviewLink from '../../.vitepress/theme/components/base/OverviewLink.vue'
import OverviewLinkGrid from '../../.vitepress/theme/components/base/OverviewLinkGrid.vue'
@@ -57,7 +56,7 @@ import { LucideFileText } from '@lucide/angular';
template: '<svg lucideFileText></svg>',
imports: [LucideFileText],
})
export class App {}
export class App { }
```
### Dynamic icon component
@@ -75,7 +74,7 @@ import { LucideDynamicIcon, LucideCircleCheck, LucideCircleX } from '@lucide/ang
})
export class App {
protected readonly model = signal<boolean>(true);
protected readonly icon = computed(() => (this.model() ? LucideCircleCheck : LucideCircleX));
protected readonly icon = computed(() => this.model() ? LucideCircleCheck : LucideCircleX);
}
```
@@ -83,24 +82,18 @@ export class App {
To customize the appearance of an icon, you can use the following inputs:
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `strokeWidth` | _number_ | 2 |
| `nonScalingStroke` | _boolean_ | false |
| `title` | _string_ | null |
| name | type | default |
| ----------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `strokeWidth` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
| `title` | *string* | null |
Because icons render as SVG elements, all standard SVG attributes can also be applied. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
```html
<svg
lucideHouse
[size]="48"
color="red"
[strokeWidth]="1"
title="Home"
></svg>
<svg lucideHouse [size]="48" color="red" [strokeWidth]="1" title="Home"></svg>
```
For more examples and details on how to use these inputs, continue the guide:
+1 -1
View File
@@ -17,7 +17,7 @@ Most of the time, icons are used purely for decoration or visual reinforcement.
For a broader explanation of this, and other best practices on how to use icons accessibly in your application, please refer to our detailed guide on accessibility:
<OverviewLink href="/how-to/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
<OverviewLink href="/guide/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
Only if an icon **conveys essential meaning on its own** should it be made accessible. The sections below explain how to do that in Astro.
+2 -2
View File
@@ -27,9 +27,9 @@ Every icon has a class attribute applied called `lucide`. This class name can be
}
```
### Non-scaling strokes
### Absolute stroke width
For global non-scaling stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [non-scaling strokes](../basics/stroke-width.md#non-scaling-strokes) for more info.
For global absolute stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [absolute-stroke-width](../basics/stroke-width.md#absolute-stroke-width) for more info.
```css
.lucide {
+3 -10
View File
@@ -18,19 +18,13 @@ interface LucideProps extends SVGAttributes<SVGSVGElement> {
color?: string;
size?: number | string;
'stroke-width'?: number | string;
nonScalingStroke?: boolean;
/**
* @deprecated
*/
absoluteStrokeWidth?: boolean;
[key: string]: any; // Any other SVG attributes
}
```
### Using `IconProps`
<!-- Rename this to LucideProps -->
You can use the `IconProps` interface to type props for your custom icon components.
```astro
@@ -56,7 +50,7 @@ Type for individual icon components, this is use full when you want to type a va
import type { Component } from 'astro/types';
import type { IconProps } from '@lucide/astro';
type LucideIcon = Component<IconProps>;
type LucideIcon = Component<IconProps>
```
### Using `LucideIcon`
@@ -109,13 +103,12 @@ Not commonly used directly in application code. But can be useful for advanced u
```ts
type IconNode = [
elementName: 'circle' | 'ellipse' | 'g' | 'line' | 'path' | 'polygon' | 'polyline' | 'rect',
attrs: HTMLAttributes<'svg'>,
elementName: 'circle' | 'ellipse'| 'g' | 'line' | 'path' | 'polygon' | 'polyline' | 'rect',
attrs: HTMLAttributes<'svg'>
][];
```
### Using `IconNode`
You can use the `IconNode` type when you need to work with the raw SVG structure of an icon.
```astro [CustomIcon.astro]
+8 -8
View File
@@ -1,6 +1,6 @@
---
title: Stroke width - Astro
description: Learn how to customize the stroke width of Lucide icons in your Astro applications using the strokeWidth and nonScalingStroke props.
description: Learn how to customize the stroke width of Lucide icons in your Astro applications using the strokeWidth and absoluteStrokeWidth props.
---
# Stroke width
@@ -20,19 +20,19 @@ import FolderLock from '@lucide/astro/icons/folder-lock';
<FolderLock strokeWidth={1} />
```
## Non-scaling strokes
## Absolute stroke width
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `nonScalingStroke` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `absoluteStrokeWidth` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
This means that when `nonScalingStroke` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
This means that when `absoluteStrokeWidth` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
### Adjusting stroke width with `nonScalingStroke` prop
### Adjusting stroke width with `absoluteStrokeWidth` prop
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
```astro
---
@@ -41,6 +41,6 @@ import RollerCoaster from '@lucide/astro/icons/roller-coaster';
<RollerCoaster
size={96}
nonScalingStroke
absoluteStrokeWidth
/>
```
+7 -7
View File
@@ -54,13 +54,13 @@ import { Camera } from '@lucide/astro';
To customize the appearance of an icon, you can use the following props:
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `stroke-width` | _number_ | 2 |
| `nonScalingStroke` | _boolean_ | false |
| `default-class` | _string_ | lucide-icon |
| name | type | default |
| ----------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `stroke-width` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
| `default-class` | *string* | lucide-icon |
Because icons render as SVG elements, all standard SVG attributes can also be applied as props. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
+1 -1
View File
@@ -26,7 +26,7 @@ In addition to design, code is also important. Assets like icons can significant
Icons are pictures that show what something means without using words. They can be very helpful because they can quickly give information.
However, not everyone can understand them easily. Read more about [how to use Lucide in an accessible way](../how-to/accessibility.md).
However, not everyone can understand them easily. Read more about [how to use Lucide in an accessible way](./accessibility.md).
## Official Packages
+1 -1
View File
@@ -16,7 +16,7 @@ Most of the time, icons are used purely for decoration or visual reinforcement.
For a broader explanation of this, and other best practices on how to use icons accessibly in your application, please refer to our detailed guide on accessibility:
<OverviewLink href="/how-to/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
<OverviewLink href="/guide/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
Only if an icon **conveys essential meaning on its own** should it be made accessible. The sections below explain how to do that in your app.
+14 -16
View File
@@ -1,8 +1,7 @@
---
title: Stroke width - Lucide
description: Learn how to customize the stroke width of Lucide icons in your Vanilla JavaScript applications using the strokeWidth and nonScalingStroke attributes.
description: Learn how to customize the stroke width of Lucide icons in your Vanilla JavaScript applications using the strokeWidth and absoluteStrokeWidth attributes.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/Sandpack.vue'
</script>
@@ -19,13 +18,10 @@ The `strokeWidth` can be adjusted to create a different look of the icons.
::: sandpack {template=vanilla showTabs=false editorHeight=250 editorWidthPercentage=70 dependencies="lucide"}
```html /index.html [active]
<!doctype html>
<!DOCTYPE html>
<html>
<body>
<i
data-lucide="folder-lock"
stroke-width="1"
></i>
<i data-lucide="folder-lock" stroke-width="1"></i>
<script src="index.js"></script>
</body>
@@ -33,32 +29,34 @@ The `strokeWidth` can be adjusted to create a different look of the icons.
```
```js /index.js
import './styles.css';
import "./styles.css";
import { createIcons, FolderLock } from 'lucide/dist/cjs/lucide';
createIcons({
icons: {
FolderLock,
},
}
});
```
:::
<!-- ## Non-scaling strokes
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `nonScalingStroke` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
<!-- ## Absolute stroke width
This means that when `nonScalingStroke` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `absoluteStrokeWidth` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
This means that when `absoluteStrokeWidth` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
[Non-scaling stroke comparison](../../../images/non-scaling-stroke-compare.svg)
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
### Adjusting stroke width with `nonScalingStroke` prop
### Adjusting stroke width with `absoluteStrokeWidth` prop
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
::: sandpack {template=vanilla showTabs=false editorHeight=250 editorWidthPercentage=70 dependencies="lucide"}
@@ -66,7 +64,7 @@ Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
<!DOCTYPE html>
<html>
<body>
<i data-lucide="roller-coaster" stroke-width="96" non-scaling-stroke="true"></i>
<i data-lucide="roller-coaster" stroke-width="96" absolute-stroke-width="true"></i>
<script src="index.js"></script>
</body>
+286
View File
@@ -0,0 +1,286 @@
# `@lucide/angular`
::: warning
This documentation is for `@lucide/angular`.
To learn about our legacy package for Angular, please refer to [`lucide-angular`](https://v0.lucide.dev/guide/packages/lucide-angular).
:::
A standalone, signal-based, zoneless implementation of Lucide icons for Angular.
**What you can accomplish:**
- Use icons as standalone Angular components with full dependency injection support
- Configure icons globally through modern Angular providers
- Integrate with Angular's reactive forms and data binding
- Build scalable applications with tree-shaken icons and lazy loading support
## Prerequisites
This package requires Angular 17+ and uses standalone components, signals, and zoneless change detection.
## Installation
::: code-group
```sh [pnpm]
pnpm add @lucide/angular
```
```sh [yarn]
yarn add @lucide/angular
```
```sh [npm]
npm install @lucide/angular
```
```sh [bun]
bun add @lucide/angular
```
:::
## How to use
### Standalone icons
Every icon can be imported as a ready-to-use standalone component:
```html
<svg lucideFileText></svg>
```
```ts{2,7}
import { Component } from '@angular/core';
import { LucideFileText } from '@lucide/angular';
@Component({
selector: 'app-foobar',
templateUrl: './foobar.html',
imports: [LucideFileText],
})
export class Foobar { }
```
::: tip
Standalone icon components use the selector `svg[lucide{PascalCaseIconName}]`.
This ensures minimal bloating of the DOM and the ability to directly manipulate all attributes of the resulting SVG element.
:::
### Dynamic icon component
You may also use the dynamic `LucideIcon` component to dynamically render icons.
#### With tree-shaken imports
You may pass imported icons directly to the component:
```html{3}
@for (item of items) {
<a navbarItem [routerLink]="item.routerLink">
<svg [lucideIcon]="item.icon"></svg>
{{ item.title }}
</a>
}
```
```ts{2,8,14,19}
import { Component } from '@angular/core';
import { LucideIcon, LucideHouse, LucideUsersRound } from '@lucide/angular';
import { NavbarItem, NavbarItemModel } from './navbar-item';
@Component({
selector: 'app-navbar',
templateUrl: './navbar.html',
imports: [LucideIcon, NavbarItem],
})
export class Navbar {
readonly items: NavbarItemModel[] = [
{
title: 'Home',
icon: LucideHouse,
routerLink: [''],
},
{
title: 'Users',
icon: LucideUsersRound,
routerLink: ['admin/users'],
},
];
}
```
#### With icons provided via dependency injection
Alternatively, the component also accepts string inputs.
To use icons this way, first, you have to provide icons via `provideLucideIcons`:
:::code-group
```ts{7-10} [app.config.ts]
import { ApplicationConfig } from '@angular/core';
import { provideLucideIcons, LucideCircleCheck, LucideCircleX } from '@lucide/angular';
export const appConfig: ApplicationConfig = {
providers: [
// ...
provideLucideIcons(
LucideCircleCheck,
LucideCircleX,
),
]
};
```
```html [foobar.html]
<svg lucideIcon="circle-check"></svg>
```
```ts{7} [foobar.ts]
import { Component } from '@angular/core';
import { LucideIcon } from '@lucide/angular';
@Component({
selector: 'app-foobar',
templateUrl: './template-url',
imports: [LucideIcon],
})
export class Foobar { }
```
:::
::: tip
For optimal bundle size, provide icons at the highest appropriate level in your application.
Providing all icons at the root level may increase your initial bundle size, while providing them at feature module level enables better code splitting.
:::
::: warning
While you may provide your icons at any level of the dependency injection tree, be aware that [Angular's DI system is hierarchical](https://angular.dev/guide/di/defining-dependency-providers#injector-hierarchy-in-angular): `LucideIcon` will only have access to the icons provided closest to it in the tree.
:::
## Accessible labels
You can use the `title` input property to set the [accessible name element](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/title) on the SVG:
```html
<svg lucideIcon="house" title="Go to dashboard"></svg>
```
This will result in the following output:
```html{2}
<svg class="lucide lucide-house" ...>
<title>Go to dashboard</title>
<!-- SVG paths -->
</svg>
```
## Props
You can pass additional props to adjust the icon appearance.
| name | type | default |
|-----------------------|-----------|--------------|
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `strokeWidth` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
```html
<svg lucideHouse size="48" color="red" strokeWidth="1"></svg>
```
## Global configuration
You can use `provideLucideConfig` to configure the default property values as defined above:
```ts{2,7-9}
import { ApplicationConfig } from '@angular/core';
import { provideLucideConfig } from '@lucide/angular';
export const appConfig: ApplicationConfig = {
providers: [
// ...
provideLucideConfig({
strokeWidth: 1.5
}),
]
};
```
## Styling via CSS
Icons can also be styled by using custom CSS classes:
```html
<svg lucideHousePlus class="my-icon"></svg>
```
```css
svg.my-icon {
width: 12px;
height: 12px;
stroke-width: 3;
}
```
## With Lucide lab or custom icons
[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library.
While they aren't provided as standalone components, they can be still be passed to the `LucideIcon` component the same way as official icons:
```html
<!-- Directly as LucideIconData: -->
<svg [lucideIcon]="CoconutIcon"></svg>
<!-- As a provided icon by name: -->
<svg lucideIcon="coconut"></svg>
```
```ts{2,6-7,11-12}
import { provideLucideIcons } from '@lucide/angular';
import { coconut } from '@lucide/lab';
@Component({
templateUrl: './foobar.html',
// For using by name via provider:
providers: [provideLucideIcons({ coconut })],
imports: [LucideIcon]
})
export class Foobar {
// For passing directly as LucideIconData:
readonly CoconutIcon = coconut;
}
```
## Troubleshooting
### The icon is not being displayed
If using per-icon-components:
1. Ensure that the icon component is being imported, if using per-icon-components
2. Check that the icon name matches exactly (case-sensitive)
If using the dynamic component:
1. Ensure the icon is provided via `provideLucideIcons()` if using string names
2. Verify the icon is imported from `@lucide/angular` and not the legacy package
### TypeScript errors?
Make sure you're importing from `@lucide/angular` and not `lucide-angular`.
### Icons render with wrong defaults
Ensure `provideLucideConfig()` is used at the right level.
## Migration guide
Migrating from `lucide-angular`? Read our [comprehensive migration guide](https://github.com/lucide-icons/lucide/blob/main/packages/angular/MIGRATION.md).
@@ -2,7 +2,8 @@
`@lucide/icons` is a helper library that exports Lucide **icon data** in a tree-shakable format, also providing utilities for dynamic importing icons.
It intentionally ships **no real rendering logic or components** — but you can use this package to build third-party integrations for frameworks we don't (yet) support.
It intentionally ships **no real rendering logic or components** — other packages (for example [`@lucide/angular`](http://npmjs.com/package/@lucide/angular)) can consume this data to render icons in their respective
frameworks. You can also use this package to build third-party integrations for frameworks we don't (yet) support.
## Installation
@@ -34,11 +35,14 @@ Each icon is described by the following interface:
export type LucideIconData = {
name: string;
node: LucideIconNode[];
} & ({ size: number } | { width: number; height: number });
} & (
| { size: number }
| { width: number; height: number; }
);
```
| name | type | description |
| ---------------------------- | ------------------ | ------------------------------------------------------------------ |
|------------------------------|--------------------|--------------------------------------------------------------------|
| `name` | `string` | The name of the icon. |
| `node` | `LucideIconNode[]` | SVG child nodes as `[tagName, attributes]` tuples. |
| `size` or `width` & `height` | `number` | The dimensions of the icon (`size` is shorthand for square icons). |
@@ -61,16 +65,16 @@ All builders accept the same `params` object (`LucideBuildParams`) to customize
The following parameters are supported (names reflect the current implementation):
| param | type | effect |
| ------------------ | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `color` | `string` | Sets `stroke` (defaults to `currentColor`). |
| `size` | `number` | Sets both `width` and `height` (defaults to 24). |
| `width` | `number` | Sets `width` only. |
| `height` | `number` | Sets `height` only. |
| `strokeWidth` | `number` | Sets `stroke-width` (defaults to 2). |
| `nonScalingStroke` | `boolean` | Adds [`vector-effect="non-scaling-stroke"`](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/vector-effect) to child elements. |
| `className` | `string` | Appended to the generated `class` attribute. |
| `attributes` | `Record<string, string>` | Add or override any generated SVG attributes (including `class`, `viewBox`, and so on). |
| param | type | effect |
|-----------------------|--------------------------|------------------------------------------------------------------------------------|
| `color` | `string` | Sets `stroke` (defaults to `currentColor`). |
| `size` | `number` | Sets both `width` and `height` (defaults to 24). |
| `width` | `number` | Sets `width` only. |
| `height` | `number` | Sets `height` only. |
| `strokeWidth` | `number` | Sets `stroke-width` (defaults to 2). |
| `absoluteStrokeWidth` | `boolean` | Adds [`vector-effect="non-scaling-stroke"`](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/vector-effect) to child elements. |
| `className` | `string` | Appended to the generated `class` attribute. |
| `attributes` | `Record<string, string>` | Add or override any generated SVG attributes (including `class`, `viewBox`, etc.). |
::: info
SVG attributes generated by the builders include a default Lucide setup (`xmlns`, `viewBox`, `fill="none"`, `stroke="currentColor"`, `stroke-width="2"`, `stroke-linecap="round"`, `stroke-linejoin="round"`), plus a class string of the form: `lucide lucide-{iconName}`.
@@ -123,7 +127,6 @@ document.body.appendChild(el);
Creates a base64-encoded SVG data URI from a Lucide icon object.
This helper works in both browsers and Node.js:
- In browsers it uses `btoa` (with proper UTF-8 handling)
- In Node.js it falls back to `Buffer`
@@ -135,18 +138,15 @@ const uri = buildLucideDataUri(House, { size: 24 });
```
The returned value can be used directly in places such as:
- `<img src="...">`
- CSS `background-image`
- Canvas drawing
- Inline data URLs in HTML or SVG
::: tip Environment notes
The SVG is encoded as UTF-8 before base64 conversion to ensure correct handling of non-ASCII characters.
No runtime configuration is required. The function automatically selects the appropriate encoding strategy.
If neither `btoa` nor `Buffer` is available, an error is thrown.
- The SVG is encoded as UTF-8 before base64 conversion to ensure correct handling of non-ASCII characters.
- No runtime configuration is required — the function automatically selects the appropriate encoding strategy.
- If neither `btoa` nor `Buffer` is available, an error is thrown.
:::
## Dynamic imports
@@ -156,7 +156,6 @@ Dynamic imports are useful when you only know the icon name at runtime (for exam
::: tip
Validate `iconName` before indexing the map (and provide a fallback icon) to avoid runtime errors.
:::
## Dynamic imports
Dynamic imports are useful when the icon name is only known at runtime (for example, icon names stored in a CMS or database). For purely static usage, prefer direct imports for maximum tree-shaking.
+210
View File
@@ -0,0 +1,210 @@
# Lucide Astro
Astro components for Lucide icons that work perfectly with Astro's island architecture and multi-framework support. Each icon is an Astro component that renders as an inline SVG, providing excellent performance for static sites and server-side rendering scenarios.
**What you can accomplish:**
- Use icons as Astro components with zero JavaScript runtime overhead
- Build fast, static websites with optimized SVG icons
- Integrate seamlessly with Astro's component islands and partial hydration
- Create multi-framework applications where icons work across different UI libraries
- Optimize performance with direct icon imports and build-time rendering
## Installation
::: code-group
```sh [pnpm]
pnpm add @lucide/astro
```
```sh [yarn]
yarn add @lucide/astro
```
```sh [npm]
npm install @lucide/astro
```
```sh [bun]
bun add @lucide/astro
```
:::
## How to use
Lucide is built with ES Modules, so it's completely tree-shakable.
Each icon can be imported as an Astro component, which renders an inline SVG element. This way, only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
### Example
Default usage:
```astro
---
import { Skull } from '@lucide/astro';
---
<Skull />
```
Additional props can be passed to adjust the icon:
```astro
---
import { Camera } from '@lucide/astro';
---
<Camera color="#ff3e98" />
```
For faster builds and load times, you can import icons directly from the `@lucide/astro/icons` directory:
```astro
---
import CircleAlert from '@lucide/astro/icons/circle-alert';
---
<CircleAlert color="#ff3e98" />
```
## Props
| name | type | default |
| --------------------- | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `stroke-width` | _number_ | 2 |
| `absoluteStrokeWidth` | _boolean_ | false |
### Applying props
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
```astro
---
import { Phone } from '@lucide/astro';
---
<Phone fill="#333" />
```
This results a filled phone icon.
## Types
The package includes type definitions for all icons. This is useful if you want to dynamically render icons.
### Example
```astro
---
import { House, Library, Cog, type Icon as IconType } from '@lucide/astro';
type MenuItem = {
name: string;
href: string;
icon: typeof IconType;
};
const menuItems: MenuItem[] = [
{
name: 'Home',
href: '/',
icon: House,
},
{
name: 'Blog',
href: '/blog',
icon: Library,
},
{
name: 'Projects',
href: '/projects',
icon: Cog,
},
];
---
{
menuItems.map((item) => (
<a href={item.href}>
<item.icon />
<span>{item.name}</span>
</a>
))
}
```
## With Lucide Lab or custom icons
[Lucide Lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library.
They can be used by using the `Icon` component.
All props of the regular Lucide icons can be passed to adjust the icon appearance.
### Using the `Icon` component
This creates a single icon based on the iconNode passed and renders a Lucide icon component.
```astro
---
import { Icon } from '@lucide/astro';
import { burger, sausage } from '@lucide/lab';
---
<Icon iconNode={burger} />
<Icon iconNode={sausage} color="red"/>
```
## One generic icon component
It is possible to create one generic icon component to load icons, but it is not recommended.
::: danger
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application. This may be passable if you're doing SSG and SSR in server environments. However if you're doing SSR in serverless environments, it could negatively affect your app's performance, as a bigger bundle size will translate to an increase in cold starts.
:::
### Icon Component Example
```astro
---
import { icons, type IconProps } from '@lucide/astro';
interface Props extends IconProps {
name: keyof typeof icons;
}
const { name, ...restProps } = Astro.props;
const Icon = icons[name];
---
<Icon {...restProps} />
```
### Using the Icon Component
```astro
---
import LucideIcon from './LucideIcon.astro';
---
<LucideIcon name="Menu" />
```
## Accessibility
By default, we hide icons from screen readers using `aria-hidden="true"`.
You can add accessibility attributes using aria-labels.
```jsx
---
import { Check } from '@lucide/astro';
---
<Check aria-label="Task completed" />
```
For best practices on accessibility, please see our [accessibility guide](../accessibility.md).
+149
View File
@@ -0,0 +1,149 @@
---
title: Lucide Preact
---
# Lucide Preact
Preact components for Lucide icons that provide React-like development experience with a smaller footprint. Each icon is a lightweight Preact component that renders as an inline SVG, perfect for applications that need React compatibility with minimal bundle size.
**What you can accomplish:**
- Use icons as Preact components with React-like syntax and patterns
- Build lightweight applications with Preact's smaller runtime
- Create fast, responsive interfaces with minimal JavaScript overhead
- Maintain React compatibility while reducing bundle size
- Integrate with existing Preact applications and component libraries
## Installation
::: code-group
```sh [pnpm]
pnpm add lucide-preact
```
```sh [yarn]
yarn add lucide-preact
```
```sh [npm]
npm install lucide-preact
```
```sh [bun]
bun add lucide-preact
```
:::
## How to use
Lucide is built with ES Modules, so it's completely tree-shakable.
Each icon can be imported as a Preact component, which renders an inline SVG element. This way, only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
### Example
Additional props can be passed to adjust the icon:
```jsx
import { Camera } from 'lucide-preact';
// Usage
const App = () => {
return <Camera color="red" size={48} />;
};
export default App;
```
## Props
| name | type | default |
| --------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `strokeWidth` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
### Applying props
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
```jsx
// Usage
const App = () => {
return <Camera fill="red" stroke-linejoin="bevel" />;
};
```
> SVG attributes in Preact aren't transformed, so if you want to change for example the `stroke-linejoin` you need to pass it in kebabcase. Basically how the SVG spec want you to write it. See this topic in the [Preact documentation](https://preactjs.com/guide/v10/differences-to-react/#svg-inside-jsx).
## With Lucide Lab or custom icons
[Lucide Lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library.
They can be used by using the `Icon` component.
All props like regular Lucide icons can be passed to adjust the icon appearance.
### Using the `Icon` component
This creates a single icon based on the iconNode passed and renders a Lucide icon component.
```jsx
import { Icon } from 'lucide-preact';
import { coconut } from '@lucide/lab';
const App = () => (
<Icon iconNode={coconut} />
);
```
## One generic icon component
It is possible to create one generic icon component to load icons, but it is not recommended.
::: danger
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important when using bundlers like `Webpack`, `Rollup`, or `Vite`.
:::
### Icon Component Example
```jsx
import { icons } from 'lucide-preact';
const Icon = ({ name, color, size }) => {
const LucideIcon = icons[name];
return <LucideIcon color={color} size={size} />;
};
export default Icon;
```
#### Using the Icon Component
```jsx
import Icon from './Icon';
const App = () => {
return <Icon name="house" />;
};
export default App;
```
## Accessibility
By default, we hide icons from screen readers using `aria-hidden="true"`.
You can add accessibility attributes using aria-labels.
```jsx
import { Check } from 'lucide-preact';
const App = () => {
return <Check aria-label="Task completed" />;
};
```
For best practices on accessibility, please see our [accessibility guide](../accessibility.md).
+133
View File
@@ -0,0 +1,133 @@
# Lucide React Native
React Native components for Lucide icons that work seamlessly across iOS and Android platforms. Built on top of react-native-svg, each icon renders as a native SVG component, providing consistent visual appearance and performance across mobile devices.
**What you can accomplish:**
- Use icons as React Native components with platform-consistent rendering
- Build cross-platform mobile apps with scalable vector icons
- Create responsive interfaces that adapt to different screen densities
- Integrate with React Native's styling system and animation libraries
- Maintain consistent icon appearance across iOS and Android platforms
## Installation
First, ensure that you have `react-native-svg` (version between 12 and 15) installed. Then, install the package:
::: code-group
```sh [pnpm]
pnpm add lucide-react-native
```
```sh [yarn]
yarn add lucide-react-native
```
```sh [npm]
npm install lucide-react-native
```
```sh [bun]
bun add lucide-react-native
```
:::
## How to use
Each icon can be imported as a React component.
### Example
Additional props can be passed to adjust the icon:
```jsx
import { Camera } from 'lucide-react-native';
// Usage
const App = () => {
return <Camera color="red" size={48} />;
};
export default App;
```
## Props
| name | type | default |
| --------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `strokeWidth` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
### Applying props
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements.
```jsx
// Usage
const App = () => {
return <Camera fill="red" />;
};
```
## With Lucide Lab or custom icons
[Lucide Lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library.
They can be used by using the `Icon` component.
All props like regular Lucide icons can be passed to adjust the icon appearance.
### Using the `Icon` component
This creates a single icon based on the iconNode passed and renders a Lucide icon component.
```jsx
import { Icon } from 'lucide-react-native';
import { coconut } from '@lucide/lab';
const App = () => (
<Icon iconNode={coconut} />
);
```
## One generic icon component
It is possible to create one generic icon component to load icons, but it is not recommended.
::: warning
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important to keep in mind when using bundlers like `Webpack`, `Rollup`, or `Vite`.
:::
### Icon Component Example
```tsx
import * as icons from 'lucide-react-native/icons';
interface IconProps {
name: keyof typeof icons;
color?: string;
size?: number;
}
const Icon = ({ name, color, size }: IconProps) => {
const LucideIcon = icons[name];
return <LucideIcon color={color} size={size} />;
};
export default Icon;
```
#### Using the Icon Component
```tsx
import Icon from './Icon';
const App = () => {
return <Icon name="House" />;
};
export default App;
```
+162
View File
@@ -0,0 +1,162 @@
# Lucide Solid
SolidJS components for Lucide icons that leverage Solid's fine-grained reactivity system. Each icon is a reactive Solid component that renders as an inline SVG, providing exceptional performance through Solid's compile-time optimizations and reactive primitives.
**What you can accomplish:**
- Use icons as SolidJS components with fine-grained reactivity
- Create highly performant interfaces with Solid's reactive system
- Build dynamic icon components that respond to signals and stores
- Integrate seamlessly with Solid's JSX and component patterns
- Optimize performance with direct icon imports and minimal runtime overhead
## Installation
::: code-group
```sh [pnpm]
pnpm add lucide-solid
```
```sh [yarn]
yarn add lucide-solid
```
```sh [npm]
npm install lucide-solid
```
```sh [bun]
bun add lucide-solid
```
:::
## How to use
Lucide is built with ES Modules, so it's completely tree-shakable.
Each icon can be imported as a Solid component, which renders an inline SVG element. This way, only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
### Example
Additional props can be passed to adjust the icon:
```jsx
import { Camera } from 'lucide-solid';
// Usage
const App = () => {
return <Camera color="red" size={48} />;
};
export default App;
```
Vite loading/performing issues with the dev server can be resolved by import icons directly from the `lucide-solid/icons` directory:
```jsx
import Camera from 'lucide-solid/icons/camera';
// Usage
const App = () => {
return <Camera color="red" size={48} />;
};
export default App;
```
## Props
| name | type | default |
| --------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `strokeWidth` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
### Applying props
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
```jsx
// Usage
const App = () => {
return <Camera fill="red" stroke-linejoin="bevel" />;
};
```
## With Lucide Lab or custom icons
[Lucide Lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library.
They can be used by using the `Icon` component.
All props like the regular Lucide icons can be passed to adjust the icon appearance.
### Using the `Icon` component
This creates a single icon based on the iconNode passed and renders a Lucide icon component.
```jsx
import { Icon } from 'lucide-solid';
import { sausage } from '@lucide/lab';
const App = () => (
<Icon iconNode={sausage} color="red"/>
);
```
## One generic icon component
It is possible to create one generic icon component to load icons. It's not recommended.
::: danger
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important to keep in mind when using bundlers like `Webpack`, `Rollup`, or `Vite`.
:::
### Icon Component Example
```tsx
import { icons, type LucideProps } from 'lucide-solid';
import { splitProps } from 'solid-js';
import { Dynamic } from 'solid-js/web';
interface IconProps extends LucideProps {
name: keyof typeof icons;
}
const Icon = (props: IconProps) => {
const [local, others] = splitProps(props, ["name"]);
return <Dynamic component={icons[local.name]} {...others} />
};
export default Icon;
```
#### Using the Icon Component
```tsx
import Icon from './Icon';
const App = () => {
return <Icon name="home" />;
};
export default App;
```
## Accessibility
By default, we hide icons from screen readers using `aria-hidden="true"`.
You can add accessibility attributes using aria-labels.
```jsx
import { Check } from 'lucide-solid';
const App = () => {
return <Check aria-label="Task completed" />;
};
```
For best practices on accessibility, please see our [accessibility guide](../accessibility.md).
+265
View File
@@ -0,0 +1,265 @@
# Lucide Static
Static assets and utilities for Lucide icons that work without JavaScript frameworks. This package provides multiple formats including individual SVG files, SVG sprites, icon fonts, and Node.js utilities for server-side rendering and static site generation.
**What you can accomplish:**
- Use individual SVG files as images or CSS background images
- Implement icon fonts for CSS-based icon systems
- Create SVG sprites for efficient icon loading in static sites
- Import SVG strings in Node.js applications and server-side rendering
- Build static websites and applications without JavaScript framework dependencies
This package includes the following implementations of Lucide icons:
- Individual SVG files
- SVG sprite
- Icon font files
- A JavaScript library exporting SVG strings
## Who is this for?
`lucide-static` is suitable for _very specific use cases_ where you want to use Lucide icons without relying on a JavaScript framework or component system. It's ideal for:
- Projects that use icon fonts with plain CSS or utility-first frameworks
- Embedding raw SVG files or sprites directly in HTML
- Using SVGs as CSS background images
- Importing SVG strings into Node.js (CommonJS) environments
::: danger
### Not recommended for production {#production-warning}
SVG sprites and icon fonts include **all icons**, which can significantly increase your app's bundle size and load time.
For production environments, we recommend using a bundler with tree-shaking support to include only the icons you actually use. Consider using one of the framework-specific [packages](../../packages.md).
:::
## Installation
::: code-group
```sh [pnpm]
pnpm add lucide-static
```
```sh [yarn]
yarn add lucide-static
```
```sh [npm]
npm install lucide-static
```
```sh [bun]
bun add lucide-static
```
:::
## SVG Files
You can use standalone SVG files or SVG sprites in several ways.
Check out our [codesandbox example](https://codesandbox.io/s/using-the-svg-sprite-lz1kk).
### SVG file as image
#### In HTML:
::: code-group
```html [Webpack]
<!-- SVG file for a single icon -->
<img src="~lucide-static/icons/house.svg" />
```
```html [CDN]
<!-- SVG file for a single icon -->
<img src="https://unpkg.com/lucide-static@latest/icons/house.svg" />
```
:::
#### In CSS:
::: code-group
```css [Webpack]
.house-icon {
background-image: url(~lucide-static/icons/house.svg);
}
```
```css [CDN]
.house-icon {
background-image: url(https://unpkg.com/lucide-static@latest/icons/house.svg);
}
```
:::
Make sure you have the correct Webpack loader configured, such as [`url-loader`](https://v4.webpack.js.org/loaders/url-loader/).
### SVG file as string
To import an SVG as a string (e.g., for templating):
::: code-group
```js [Webpack]
import arrowRightIcon from 'lucide-static/icons/arrow-right';
```
```js [Vite]
import arrowRightIcon from 'lucide-static/icons/arrow-right.svg?raw';
```
:::
You'll need an SVG loader like [`svg-inline-loader`](https://v4.webpack.js.org/loaders/svg-inline-loader/).
### Using the SVG sprite
:::danger
[Not intended for production use.](#production-warning)
:::
You may also need an additional SVG loader to handle this.
#### Basic sprite usage (not production-optimized):
```html
<img src="lucide-static/sprite.svg#house" />
```
#### Inline usage:
```html
<svg
width="24"
height="24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<use href="#alert-triangle" />
</svg>
<!-- sprite SVG -->
<svg>...</svg>
```
#### Inline with CSS helper class
If you'd prefer, you can use CSS to hold your base SVG properties:
```css
.lucide-icon {
width: 24px;
height: 24px;
stroke: currentColor;
fill: none;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
}
```
...and update the SVG as follows:
```xml
<svg
xmlns="http://www.w3.org/2000/svg"
class="lucide-icon"
>
<use href="#triangle-alert" />
</svg>
<!-- sprite SVG -->
<svg>...</svg>
```
## Icon font
:::danger
[Not intended for production use.](#production-warning)
:::
Lucide icons are also available as a web font. To use them, you first need to include the corresponding stylesheet:
::: code-group
```css [Vite]
@import 'lucide-static/font/lucide.css';
```
```css [Webpack]
@import ('~lucide-static/font/lucide.css');
```
```html [CDN]
<link rel="stylesheet" href="https://unpkg.com/lucide-static@latest/font/lucide.css" />
```
```html [Static asset]
<link rel="stylesheet" href="/your/path/to/lucide.css" />
```
:::
Once included, use the format `icon-{kebab-case-name}`. You can copy icon names from the [Lucide Icons page](https://lucide.dev/icons).
```html
<div class="icon-house"></div>
```
If you're not using a package manager, you can download the font files directly from the [latest release](https://github.com/lucide-icons/lucide/releases/latest).
## Node.js
You can also import Lucide icons in Node.js projects:
::: code-group
```js [ESM]
import {MessageSquare} from 'lucide-static';
```
```js [CommonJs]
const {MessageSquare} = require('lucide-static');
```
:::
> Note: Each icon name is in PascalCase.
#### Express app example in Node.js
```js
import express from 'express';
import {MessageSquare} from 'lucide-static';
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>Lucide Icons</h1>
<p>This is a Lucide icon ${MessageSquare}</p>
</body>
</html>
`);
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
```
+349
View File
@@ -0,0 +1,349 @@
# Lucide Svelte
Svelte components for Lucide icons that work seamlessly with both Svelte 4 and Svelte 5. Each icon is a reactive Svelte component that renders as an inline SVG, providing excellent performance and integration with Svelte's reactive system and modern features.
**What you can accomplish:**
- Use icons as Svelte components with full reactivity and TypeScript support
- Bind icon properties to reactive variables and stores
- Create dynamic icon systems that respond to application state
- Build type-safe interfaces with comprehensive TypeScript definitions
- Optimize bundle sizes with direct icon imports and tree-shaking
## Installation
::: code-group
```sh [pnpm]
pnpm add @lucide/svelte
```
```sh [yarn]
yarn add @lucide/svelte
```
```sh [npm]
npm install @lucide/svelte
```
```sh [bun]
bun add @lucide/svelte
```
:::
> `@lucide/svelte` is only for Svelte 5, for Svelte 4 use the `lucide-svelte` package.
## How to use
Lucide is built with ES Modules, so it's completely tree-shakable.
Each icon can be imported as a Svelte component, which renders an inline SVG element. This way, only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
### Example
Default usage:
```svelte
<script>
import { Skull } from '@lucide/svelte';
</script>
<Skull />
```
Additional props can be passed to adjust the icon:
```svelte
<script>
import { Camera } from '@lucide/svelte';
</script>
<Camera color="#ff3e98" />
```
For faster builds and load times, you can import icons directly from the `@lucide/svelte/icons` directory:
```svelte
<script>
import CircleAlert from '@lucide/svelte/icons/circle-alert';
</script>
<CircleAlert color="#ff3e98" />
```
## Props
| name | type | default |
| --------------------- | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `strokeWidth` | _number_ | 2 |
| `absoluteStrokeWidth` | _boolean_ | false |
### Applying props
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
```svelte
<script>
import { Phone } from '@lucide/svelte';
</script>
<Phone fill="#333" />
```
This results a filled phone icon.
## Types
The package includes type definitions for all icons. This is useful if you want to dynamically load icons with the `svelte:component` directive whether you are using TypeScript or JSDoc.
### TypeScript Example
::: code-group
```svelte [Svelte 5]
<script lang="ts">
import { Home, Library, Cog, type Icon as IconType } from '@lucide/svelte';
type MenuItem = {
name: string;
href: string;
icon: typeof IconType;
};
const menuItems: MenuItem[] = [
{
name: 'Home',
href: '/',
icon: Home
},
{
name: 'Blog',
href: '/blog',
icon: Library
},
{
name: 'Projects',
href: '/projects',
icon: Cog
}
];
</script>
{#each menuItems as item}
{@const Icon = item.icon}
<a href={item.href}>
<Icon />
<span>{item.name}</span>
</a>
{/each}
```
```svelte [Svelte 4]
<script lang="ts">
import { Home, Library, Cog, type Icon } from '@lucide/svelte';
import type { ComponentType } from 'svelte';
type MenuItem = {
name: string;
href: string;
icon: ComponentType<Icon>;
};
const menuItems: MenuItem[] = [
{
name: 'Home',
href: '/',
icon: Home
},
{
name: 'Blog',
href: '/blog',
icon: Library
},
{
name: 'Projects',
href: '/projects',
icon: Cog
}
];
</script>
{#each menuItems as item}
{@const Icon = item.icon}
<a href={item.href}>
<Icon />
<span>{item.name}</span>
</a>
{/each}
```
:::
### JSDoc Example
::: code-group
```svelte [Svelte 5]
<script>
import { Home, Library, Cog } from '@lucide/svelte';
/**
* @typedef {Object} MenuItem
* @property {string} name
* @property {string} href
* @property {typeof import('@lucide/svelte').Icon} icon
*/
/** @type {MenuItem[]} */
const menuItems = [
{
name: 'Home',
href: '/',
icon: Home
},
{
name: 'Blog',
href: '/blog',
icon: Library
},
{
name: 'Projects',
href: '/projects',
icon: Cog
}
];
</script>
{#each menuItems as item}
{@const Icon = item.icon}
<a href={item.href}>
<Icon />
<span>{item.name}</span>
</a>
{/each}
```
```svelte [Svelte 4]
<script>
import { Home, Library, Cog } from '@lucide/svelte';
/**
* @typedef {Object} MenuItem
* @property {string} name
* @property {string} href
* @property {import('svelte').ComponentType<import('@lucide/svelte').Icon>} icon
*/
/** @type {MenuItem[]} */
const menuItems = [
{
name: 'Home',
href: '/',
icon: Home,
},
{
name: 'Blog',
href: '/blog',
icon: Library,
},
{
name: 'Projects',
href: '/projects',
icon: Cog,
}
];
</script>
{#each menuItems as item}
{@const Icon = item.icon}
<a href={item.href}>
<Icon />
<span>{item.name}</span>
</a>
{/each}
```
:::
For more details about typing the `svelte:component` directive, see the [Svelte documentation](https://svelte.dev/docs/typescript#types-componenttype).
## With Lucide Lab or custom icons
[Lucide Lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library.
They can be used by using the `Icon` component.
All props like the regular Lucide icons can be passed to adjust the icon appearance.
### Using the `Icon` component
This creates a single icon based on the iconNode passed and renders a Lucide icon component.
```svelte
<script>
import { Icon } from '@lucide/svelte';
import { pear, sausage } from '@lucide/lab';
</script>
<Icon iconNode={pear} />
<Icon iconNode={sausage} color="red"/>
```
## One generic icon component
It is possible to create one generic icon component to load icons, but it is not recommended.
::: danger
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important when using bundlers like `Webpack`, `Rollup`, or `Vite`.
:::
### Icon Component Example
::: code-group
```svelte [Svelte 5]
<script>
import * as icons from '@lucide/svelte';
let { name, ...props } = $props();
const Icon = icons[name];
</script>
<Icon {...props} />
```
```svelte [Svelte 4]
<script>
import * as icons from '@lucide/svelte';
export let name;
</script>
<svelte:component this={icons[name]} {...$$props} />
```
:::
#### Using the Icon Component
```svelte
<script>
import LucideIcon from './LucideIcon';
</script>
<LucideIcon name="Menu" />
```
## Accessibility
By default, we hide icons from screen readers using `aria-hidden="true"`.
You can add accessibility attributes using aria-labels.
```svelte
<script>
import { Check } from '@lucide/svelte';
</script>
<Check aria-label="Task completed" />
```
For best practices on accessibility, please see our [accessibility guide](../accessibility.md).
+171
View File
@@ -0,0 +1,171 @@
# Lucide Vue
Vue 2 components for Lucide icons that integrate with Vue's Options API and template system. Each icon is a Vue component that renders as an inline SVG, providing familiar Vue development patterns for legacy applications still using Vue 2.
**What you can accomplish:**
- Use icons as Vue 2 components with Options API integration
- Maintain legacy Vue 2 applications with modern icon components
- Integrate with Vue 2's template system and component lifecycle
- Build applications using Vue 2's familiar syntax and patterns
- Bridge the gap while planning migration to Vue 3
## Installation
::: code-group
```sh [pnpm]
pnpm add @lucide/vue
```
```sh [yarn]
yarn add @lucide/vue
```
```sh [npm]
npm install @lucide/vue
```
```sh [bun]
bun add @lucide/vue
```
:::
## How to use
Lucide is built with ES Modules, so it's completely tree-shakable.
Each icon can be imported as a Vue component, which renders an inline SVG Element. This way only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
### Example
You can pass additional props to adjust the icon.
```vue
<script setup>
import { Camera } from '@lucide/vue';
</script>
<template>
<Camera
color="red"
:size="32"
/>
</template>
```
## Props
| name | type | default |
| ----------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `stroke-width` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
| `default-class` | *string* | lucide-icon |
### Applying props
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
```vue
<template>
<Camera fill="red" />
</template>
```
## With Lucide Lab or custom icons
[Lucide Lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library.
They can be used by using the `Icon` component.
All props like regular Lucide icons can be passed to adjust the icon appearance.
### Using the `Icon` component
This creates a single icon based on the iconNode passed and renders a Lucide icon component.
```vue
<script setup>
import { Icon } from '@lucide/vue';
import { baseball } from '@lucide/lab';
</script>
<template>
<Icon :iconNode="baseball" />
</template>
```
## One generic icon component
It is possible to create one generic icon component to load icons, but it is not recommended.
::: danger
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important when using bundlers like `Webpack`, `Rollup`, or `Vite`.
:::
### Icon Component Example
```vue
<script setup>
import { computed } from 'vue';
import * as icons from "@lucide/vue";
const props = defineProps({
name: {
type: String,
required: true
},
size: Number,
color: String,
strokeWidth: Number,
defaultClass: String
})
const icon = computed(() => icons[props.name]);
</script>
<template>
<component
:is="icon"
:size="size"
:color="color"
:stroke-width="strokeWidth" :default-class="defaultClass"
/>
</template>
```
### Using the Icon Component
All other props listed above also work on the `Icon` Component.
```vue
<template>
<div id="app">
<Icon name="Airplay" />
</div>
</template>
```
## Accessibility
By default, we hide icons from screen readers using `aria-hidden="true"`.
You can add accessibility attributes using aria-labels.
```vue
<script setup>
import { Check } from '@lucide/vue';
</script>
<template>
<Check
color="red"
:size="32"
aria-label="Task completed"
/>
</template>
```
For best practices on accessibility, please see our [accessibility guide](../accessibility.md).
+1 -1
View File
@@ -17,7 +17,7 @@ Most of the time, icons are used purely for decoration or visual reinforcement.
For a broader explanation of this, and other best practices on how to use icons accessibly in your application, please refer to our detailed guide on accessibility:
<OverviewLink href="/how-to/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
<OverviewLink href="/guide/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
Only if an icon **conveys essential meaning on its own** should it be made accessible. The sections below explain how to do that in Preact.
+11 -15
View File
@@ -2,7 +2,6 @@
title: Combining icons - Preact
description: Learn how to combine multiple icons into a single icon nested SVG elements in your Preact application.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackPreact.vue'
</script>
@@ -15,21 +14,18 @@ This is useful if you want to create custom icons by combining existing ones.
::: sandpack {showTabs=false editorHeight=400 editorWidthPercentage=60 dependencies="lucide-preact"}
```jsx App.js [active]
import { Scan, User } from 'lucide-preact';
import { h } from 'preact';
import { Scan, User } from "lucide-preact";
import { h } from "preact";
function App() {
return (
<div className="app">
<Scan
size={48}
nonScalingStroke
>
<Scan size={48}>
<User
size={12}
x={6}
y={6}
nonScalingStroke
absoluteStrokeWidth
/>
</Scan>
</div>
@@ -37,8 +33,8 @@ function App() {
}
export default App;
```
```
:::
This is valid, since [SVGs can be nested](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/svg#nested_svg_element), and all SVG properties are supported on the icons.
@@ -59,8 +55,8 @@ For example, you can add a notification badge to an icon by using the `circle` S
::: sandpack {showTabs=false editorHeight=580 editorWidthPercentage=60 dependencies="lucide-preact"}
```jsx App.js [active]
import { Mail } from 'lucide-preact';
import { h } from 'preact';
import { Mail } from "lucide-preact";
import { h } from "preact";
function App() {
const hasUnreadMessages = true;
@@ -83,8 +79,8 @@ function App() {
}
export default App;
```
```
:::
### Example with text element
@@ -94,8 +90,8 @@ You can also use the `text` SVG element to add text to your icon.
::: sandpack {showTabs=false editorHeight=400 editorWidthPercentage=60 dependencies="lucide-preact"}
```jsx App.js [active]
import { File } from 'lucide-preact';
import { h } from 'preact';
import { File } from "lucide-preact";
import { h } from "preact";
function App() {
return (
@@ -116,6 +112,6 @@ function App() {
}
export default App;
```
```
:::
+10 -10
View File
@@ -2,7 +2,6 @@
title: Global Styling - Preact
description: Learn how to style all Lucide icons globally in your Preact application using CSS or the Lucide context provider.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackPreact.vue'
</script>
@@ -35,8 +34,8 @@ const App = () => (
This will apply the `color`, `size` and `strokeWidth` props to all icons that are children of the `LucideProvider`.
## Style by using CSS
## Style by using CSS
Styling icons is easy to accomplish using CSS.
Every icon has a class attribute applied called `lucide`. This class name can be used in the CSS file to target all icons that are being used within the app.
@@ -75,9 +74,9 @@ import {
Sandwich,
Wine,
Dessert,
} from 'lucide-preact';
import { h } from 'preact';
import './icon.css';
} from "lucide-preact";
import { h } from "preact";
import "./icon.css";
function App() {
return (
@@ -100,9 +99,10 @@ export default App;
:::
### Non-scaling strokes
For global non-scaling stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [non-scaling strokes](../basics/stroke-width.md#non-scaling-strokes) for more info.
### Absolute stroke width
For global absolute stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [absolute-stroke-width](../basics/stroke-width.md#absolute-stroke-width) for more info.
::: sandpack {editorHeight=480 editorWidthPercentage=60 dependencies="lucide-preact"}
@@ -136,9 +136,9 @@ import {
Map,
CloudMoon,
Sparkles,
} from 'lucide-preact';
import { h } from 'preact';
import './icon.css';
} from "lucide-preact";
import { h } from "preact";
import "./icon.css";
function App() {
return (
+1 -12
View File
@@ -2,7 +2,6 @@
title: Typescript - Preact
description: Learn about the different types exported by the `lucide-preact` package and how to use them in your Preact application.
---
# TypeScript
List of exported types from the `lucide-preact` package.
@@ -17,17 +16,12 @@ interface LucideProps {
size?: number | string;
color?: string;
strokeWidth?: number;
nonScalingStroke?: boolean;
/**
* @deprecated
*/
absoluteStrokeWidth?: boolean;
[key: string]: any; // Any other SVG attributes
}
```
### Using `LucideProps`
You can use the `LucideProps` interface to type your custom icon components or when you need to work with icon props.
```tsx
@@ -82,7 +76,6 @@ type IconNode = [elementName: string, attrs: Record<string, string | number>][];
```
### Using `IconNode`
You can use the `IconNode` type when you need to work with the raw SVG structure of an icon.
```tsx
@@ -96,11 +89,7 @@ const customIcon: IconNode = [
const MyCustomIcon = () => {
return (
<Icon
iconNode={customIcon}
size={24}
color="blue"
/>
<Icon iconNode={customIcon} size={24} color="blue" />
);
};
+12 -15
View File
@@ -1,8 +1,7 @@
---
title: Stroke width - Preact
description: Learn how to adjust the stroke width of icons in your Preact application using the `strokeWidth` prop or adjust the strokeWidth appearance using the `nonScalingStroke` prop.
description: Learn how to adjust the stroke width of icons in your Preact application using the `strokeWidth` prop or adjust the strokeWidth appearance using the `absoluteStrokeWidth` prop.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackPreact.vue'
</script>
@@ -19,8 +18,8 @@ The `strokeWidth` can be adjusted to create a different look of the icons.
::: sandpack {showTabs=false editorHeight=320 editorWidthPercentage=60 dependencies="lucide-preact"}
```jsx App.js [active]
import { h } from 'preact';
import { FolderLock } from 'lucide-preact';
import { h } from "preact";
import { FolderLock } from "lucide-preact";
function App() {
return (
@@ -32,35 +31,34 @@ function App() {
export default App;
```
:::
## Non-scaling strokes
## Absolute stroke width
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `nonScalingStroke` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `absoluteStrokeWidth` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
This means that when `nonScalingStroke` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
This means that when `absoluteStrokeWidth` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
### Adjusting stroke width with `nonScalingStroke` prop
### Adjusting stroke width with `absoluteStrokeWidth` prop
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
::: sandpack {showTabs=false editorHeight=340 editorWidthPercentage=60 dependencies="lucide-preact"}
```jsx App.js [active]
import { h } from 'preact';
import { RollerCoaster } from 'lucide-preact';
import { h } from "preact";
import { RollerCoaster } from "lucide-preact";
function App() {
return (
<div className="app">
<RollerCoaster
size={96}
nonScalingStroke
absoluteStrokeWidth={true}
/>
</div>
);
@@ -68,5 +66,4 @@ function App() {
export default App;
```
:::
+7 -14
View File
@@ -2,7 +2,6 @@
title: Getting started - Preact
description: This guide will help you get started with Lucide in your Preact project.
---
<script setup lang="ts">
import OverviewLink from '../../.vitepress/theme/components/base/OverviewLink.vue'
import OverviewLinkGrid from '../../.vitepress/theme/components/base/OverviewLinkGrid.vue'
@@ -57,25 +56,19 @@ export default App;
To customize the appearance of an icon, you can use the following props:
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `strokeWidth` | _number_ | 2 |
| `nonScalingStroke` | _boolean_ | false |
| name | type | default |
| --------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `strokeWidth` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
Because icons render as SVG elements, all standard SVG attributes can also be applied as props. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
```jsx
// Usage
const App = () => {
return (
<Camera
size={48}
color="red"
strokeWidth={1}
/>
);
return <Camera size={48} color="red" strokeWidth={1} />;
};
```
@@ -16,12 +16,12 @@ import { Scan, User} from "lucide-react-native";
const App = () => {
return (
<View style={styles.container}>
<Scan size={48} nonScalingStroke>
<Scan size={48}>
<User
size={12}
x={6}
y={6}
nonScalingStroke
absoluteStrokeWidth
/>
</Scan>
</View>
+1 -12
View File
@@ -2,7 +2,6 @@
title: Typescript - React Native
description: Learn about the different types exported by the `lucide-react-native` package and how to use them in your React Native application.
---
# TypeScript Support
List of exported types from the `lucide-react-native` package.
@@ -17,17 +16,12 @@ interface LucideProps {
size?: number | string;
color?: string;
strokeWidth?: number;
nonScalingStroke?: boolean;
/**
* @deprecated
*/
absoluteStrokeWidth?: boolean;
[key: string]: any; // Any other SVG props, supported by react-native-svg
}
```
### Using `LucideProps`
You can use the `LucideProps` interface to type your custom icon components or when you need to work with icon props.
```tsx
@@ -81,7 +75,6 @@ type IconNode = [elementName: string, attrs: Record<string, string | number>][];
```
### Using `IconNode`
You can use the `IconNode` type when you need to work with the raw SVG structure of an icon.
```tsx
@@ -95,11 +88,7 @@ const customIcon: IconNode = [
const MyCustomIcon = () => {
return (
<Icon
iconNode={customIcon}
size={24}
color="blue"
/>
<Icon iconNode={customIcon} size={24} color="blue" />
);
};
+9 -10
View File
@@ -1,8 +1,7 @@
---
title: Stroke width - React Native
description: Learn how to adjust the stroke width of icons in your React Native application using the `strokeWidth` prop or adjust the strokeWidth appearance using the `nonScalingStroke` prop.
description: Learn how to adjust the stroke width of icons in your React Native application using the `strokeWidth` prop or adjust the strokeWidth appearance using the `absoluteStrokeWidth` prop.
---
# Stroke width
All icons are designed with SVG elements using strokes.
@@ -30,19 +29,19 @@ const App = () => {
export default App;
```
## Non-scaling strokes
## Absolute stroke width
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `nonScalingStroke` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `absoluteStrokeWidth` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
This means that when `nonScalingStroke` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
This means that when `absoluteStrokeWidth` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
### Adjusting stroke width with `nonScalingStroke` prop
### Adjusting stroke width with `absoluteStrokeWidth` prop
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
```SnackPlayer name=State&ext=js&dependencies=react-native-svg,lucide-react-native
import React, {useState, useEffect} from 'react';
@@ -56,7 +55,7 @@ const App = () => {
<View style={style}>
<RollerCoaster
size={96}
nonScalingStroke
absoluteStrokeWidth={true}
/>
</View>
);
@@ -68,7 +67,7 @@ export default App;
<!-- <Sandpack
template="react"
:theme="sandpackTheme"
:files="nonScalingStroke"
:files="absoluteStrokeWidth"
:customSetup='{
dependencies: {
"lucide-react": "latest"
+7 -14
View File
@@ -2,7 +2,6 @@
title: Getting started - React Native
description: This guide will help you get started with Lucide in your React Native project.
---
<script setup>
import OverviewLink from '../../.vitepress/theme/components/base/OverviewLink.vue'
import OverviewLinkGrid from '../../.vitepress/theme/components/base/OverviewLinkGrid.vue'
@@ -59,25 +58,19 @@ export default App;
To customize the appearance of an icon, you can use the following props:
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `strokeWidth` | _number_ | 2 |
| `nonScalingStroke` | _boolean_ | false |
| name | type | default |
| --------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `strokeWidth` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
Because icons render as SVG elements, all standard SVG attributes can also be applied as props. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
```jsx
// Usage
const App = () => {
return (
<Camera
size={48}
color="red"
strokeWidth={1}
/>
);
return <Camera size={48} color="red" strokeWidth={1} />;
};
```
+1 -1
View File
@@ -16,7 +16,7 @@ Most of the time, icons are used purely for decoration or visual reinforcement.
For a broader explanation of this, and other best practices on how to use icons accessibly in your application, please refer to our detailed guide on accessibility:
<OverviewLink href="/how-to/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
<OverviewLink href="/guide/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
Only if an icon **conveys essential meaning on its own** should it be made accessible. The sections below explain how to do that in React.
+2 -2
View File
@@ -19,12 +19,12 @@ import { Scan, User } from "lucide-react";
function App() {
return (
<div className="app">
<Scan size={48} nonScalingStroke>
<Scan size={48}>
<User
size={12}
x={6}
y={6}
nonScalingStroke
absoluteStrokeWidth
/>
</Scan>
</div>
+2 -2
View File
@@ -99,9 +99,9 @@ export default App;
:::
### Non-scaling strokes
### Absolute stroke width
For global non-scaling stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [non-scaling strokes](../basics/stroke-width.md#non-scaling-strokes) for more info.
For global absolute stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [absolute-stroke-width](../basics/stroke-width.md#absolute-stroke-width) for more info.
::: sandpack {template=react editorHeight=300 dependencies="lucide-react"}
-4
View File
@@ -16,10 +16,6 @@ interface LucideProps {
size?: number | string;
color?: string;
strokeWidth?: number;
nonScalingStroke?: boolean;
/**
* @deprecated
*/
absoluteStrokeWidth?: boolean;
[key: string]: any; // Any other SVG attributes
}
+8 -8
View File
@@ -1,6 +1,6 @@
---
title: Stroke width - React
description: Learn how to adjust the stroke width of icons in your React application using the `strokeWidth` prop or adjust the strokeWidth appearance using the `nonScalingStroke` prop.
description: Learn how to adjust the stroke width of icons in your React application using the `strokeWidth` prop or adjust the strokeWidth appearance using the `absoluteStrokeWidth` prop.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/Sandpack.vue'
@@ -33,19 +33,19 @@ export default App;
:::
## Non-scaling strokes
## Absolute stroke width
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `nonScalingStroke` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `absoluteStrokeWidth` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
This means that when `nonScalingStroke` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
This means that when `absoluteStrokeWidth` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
### Adjusting stroke width with `nonScalingStroke` prop
### Adjusting stroke width with `absoluteStrokeWidth` prop
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
::: sandpack {template=react showTabs=false editorHeight=320 editorWidthPercentage=60 dependencies="lucide-react"}
@@ -57,7 +57,7 @@ function App() {
<div className="app">
<RollerCoaster
size={96}
nonScalingStroke
absoluteStrokeWidth={true}
/>
</div>
);
+6 -6
View File
@@ -54,12 +54,12 @@ export default App;
To customize the appearance of an icon, you can use the following props:
| name | type | default |
|--------------------| --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `strokeWidth` | *number* | 2 |
| `nonScalingStroke` | *boolean* | false |
| name | type | default |
| --------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `strokeWidth` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
Because icons render as SVG elements, all standard SVG attributes can also be applied as props. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
+1 -1
View File
@@ -16,7 +16,7 @@ Most of the time, icons are used purely for decoration or visual reinforcement.
For a broader explanation of this, and other best practices on how to use icons accessibly in your application, please refer to our detailed guide on accessibility:
<OverviewLink href="/how-to/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
<OverviewLink href="/guide/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
Only if an icon **conveys essential meaning on its own** should it be made accessible. The sections below explain how to do that in Solid.
+2 -6
View File
@@ -2,7 +2,6 @@
title: Combining icons - Solid
description: Learn how to combine multiple icons into a single icon nested SVG elements in your Solid application.
---
<!-- Not working yet -->
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/Sandpack.vue'
@@ -22,15 +21,12 @@ import User from 'lucide-solid/icons/user';
function App() {
return (
<div class="app">
<Scan
size={48}
nonScalingStroke
>
<Scan size={48}>
<User
size={12}
x={6}
y={6}
nonScalingStroke
absoluteStrokeWidth
/>
</Scan>
</div>
+6 -7
View File
@@ -2,7 +2,6 @@
title: Global Styling - Solid
description: Learn how to style all Lucide icons globally in your Solid application using CSS or the Lucide context provider.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/Sandpack.vue'
</script>
@@ -37,8 +36,8 @@ const App = () => (
This will apply the `color`, `size` and `strokeWidth` props to all icons that are children of the `LucideProvider`.
## Style by using CSS
## Style by using CSS
Styling icons is easy to accomplish using CSS.
Every icon has a class attribute applied called `lucide`. This class name can be used in the CSS file to target all icons that are being used within the app.
@@ -76,7 +75,7 @@ import IceCream2 from 'lucide-solid/icons/ice-cream-2';
import Sandwich from 'lucide-solid/icons/sandwich';
import Wine from 'lucide-solid/icons/wine';
import Dessert from 'lucide-solid/icons/dessert';
import './icon.css';
import "./icon.css";
function App() {
return (
@@ -96,12 +95,11 @@ function App() {
export default App;
```
:::
### Non-scaling strokes
### Absolute stroke width
For global non-scaling stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [non-scaling strokes](../basics/stroke-width.md#non-scaling-strokes) for more info.
For global absolute stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [absolute-stroke-width](../basics/stroke-width.md#absolute-stroke-width) for more info.
::: sandpack {template=vite-solid editorHeight=300 editorWidthPercentage=60 dependencies="lucide-solid"}
@@ -122,6 +120,7 @@ For global non-scaling stroke width styling the `vector-effect: non-scaling-stro
grid-template-rows: 1fr 1fr 1fr;
gap: 6px;
}
```
```tsx App.tsx
@@ -134,7 +133,7 @@ import Axe from 'lucide-solid/icons/axe';
import Map from 'lucide-solid/icons/map';
import CloudMoon from 'lucide-solid/icons/cloud-moon';
import Sparkles from 'lucide-solid/icons/sparkles';
import './icon.css';
import "./icon.css";
function App() {
return (
+1 -12
View File
@@ -2,7 +2,6 @@
title: Typescript - Solid
description: Learn about the different types exported by the `lucide-solid` package and how to use them in your Solid application.
---
# TypeScript Support
List of exported types from the `lucide-solid` package.
@@ -17,17 +16,12 @@ interface LucideProps extends SVGAttributes {
size?: number | string;
color?: string;
strokeWidth?: number;
nonScalingStroke?: boolean;
/**
* @deprecated
*/
absoluteStrokeWidth?: boolean;
[key: string]: any; // Any other SVG attributes
}
```
### Using `LucideProps`
You can use the `LucideProps` interface to type your custom icon components or when you need to work with icon props.
```tsx
@@ -82,7 +76,6 @@ type IconNode = [elementName: string, attrs: Record<string, string | number>][];
```
### Using `IconNode`
You can use the `IconNode` type when you need to work with the raw SVG structure of an icon.
```tsx
@@ -96,11 +89,7 @@ const customIcon: IconNode = [
const MyCustomIcon = () => {
return (
<Icon
iconNode={customIcon}
size={24}
color="blue"
/>
<Icon iconNode={customIcon} size={24} color="blue" />
);
};
+8 -11
View File
@@ -1,8 +1,7 @@
---
title: Stroke width - Solid
description: Learn how to adjust the stroke width of icons in your Solid application using the `strokeWidth` prop or adjust the strokeWidth appearance using the `nonScalingStroke` prop.
description: Learn how to adjust the stroke width of icons in your Solid application using the `strokeWidth` prop or adjust the strokeWidth appearance using the `absoluteStrokeWidth` prop.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/Sandpack.vue'
</script>
@@ -31,22 +30,21 @@ function App() {
export default App;
```
:::
## Non-scaling strokes
## Absolute stroke width
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `nonScalingStroke` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `absoluteStrokeWidth` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
This means that when `nonScalingStroke` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
This means that when `absoluteStrokeWidth` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
### Adjusting stroke width with `nonScalingStroke` prop
### Adjusting stroke width with `absoluteStrokeWidth` prop
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
::: sandpack {template=vite-solid showTabs=false editorHeight=320 editorWidthPercentage=60 dependencies="lucide-solid"}
@@ -58,7 +56,7 @@ function App() {
<div class="app">
<RollerCoaster
size={96}
nonScalingStroke
absoluteStrokeWidth={true}
/>
</div>
);
@@ -66,5 +64,4 @@ function App() {
export default App;
```
:::
+7 -13
View File
@@ -57,25 +57,19 @@ export default App;
To customize the appearance of an icon, you can use the following props:
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `strokeWidth` | _number_ | 2 |
| `nonScalingStroke` | _boolean_ | false |
| name | type | default |
| --------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `strokeWidth` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
Because icons render as SVG elements, all standard SVG attributes can also be applied as props. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
```jsx
// Usage
const App = () => {
return (
<Camera
size={48}
color="red"
strokeWidth={1}
/>
);
return <Camera size={48} color="red" strokeWidth={1} />;
};
```
+1 -1
View File
@@ -17,7 +17,7 @@ Most of the time, icons are used purely for decoration or visual reinforcement.
For a broader explanation of this, and other best practices on how to use icons accessibly in your application, please refer to our detailed guide on accessibility:
<OverviewLink href="/how-to/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
<OverviewLink href="/guide/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
Only if an icon **conveys essential meaning on its own** should it be made accessible. The sections below explain how to do that in Svelte.
@@ -2,7 +2,6 @@
title: Combining icons - Svelte
description: Learn how to combine multiple icons into a single icon nested SVG elements in your Svelte application.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackSvelte.vue';
</script>
@@ -21,12 +20,12 @@ import User from '@lucide/svelte/icons/user';
</script>
<div class="app">
<Scan size="48" nonScalingStroke>
<Scan size="48">
<User
size="12"
x="6"
y="6"
nonScalingStroke
absoluteStrokeWidth
/>
</Scan>
</div>
+2 -5
View File
@@ -2,7 +2,6 @@
title: Global Styling - Svelte
description: Learn how to style all Lucide icons globally in your Svelte application using CSS or the Lucide context provider.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackSvelte.vue';
</script>
@@ -90,12 +89,11 @@ import "./icon.css";
<Dessert />
</div>
```
:::
### Non-scaling strokes
### Absolute stroke width
For global non-scaling stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [non-scaling strokes](../basics/stroke-width.md#non-scaling-strokes) for more info.
For global absolute stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [absolute-stroke-width](../basics/stroke-width.md#absolute-stroke-width) for more info.
::: sandpack {template=vite-svelte editorHeight=420 editorWidthPercentage=55}
@@ -145,5 +143,4 @@ import "./icon.css";
<Sparkles />
</div>
```
:::
+3 -15
View File
@@ -2,7 +2,6 @@
title: Typescript - Svelte
description: Learn about the different types exported by the `@lucide/svelte` package and how to use them in your Svelte application.
---
# TypeScript Support
List of exported types from the `@lucide/svelte` package.
@@ -18,10 +17,6 @@ interface LucideProps extends SVGAttributes<SVGSVGElement> {
color?: string;
size?: number | string;
strokeWidth?: number | string;
nonScalingStroke?: boolean;
/**
* @deprecated
*/
absoluteStrokeWidth?: boolean;
children?: Snippet;
[key: string]: any; // Any other SVG attributes
@@ -29,11 +24,9 @@ interface LucideProps extends SVGAttributes<SVGSVGElement> {
```
### Using `LucideProps`
You can use the `LucideProps` interface to type props for your custom icon components.
::: code-group
```svelte [IconWrapper.svelte]
<script lang="ts">
import { Camera, type LucideProps } from '@lucide/svelte';
@@ -47,7 +40,6 @@ let props: LucideProps = $props();
</div>
</template>
```
:::
## `LucideIcon`
@@ -57,7 +49,7 @@ Type for individual icon components, this is use full when you want to type a va
```ts
import type { Component } from 'svelte';
type LucideIcon = Component<LucideProps>;
type LucideIcon = Component<LucideProps>
```
### Using `LucideIcon`
@@ -143,7 +135,6 @@ You can use the `LucideIcon` type when you need to work with icon components dir
{/each}
```
:::
## `IconNode`
@@ -153,17 +144,15 @@ Not commonly used directly in application code. But can be useful for advanced u
```ts
type IconNode = [
elementName: 'circle' | 'ellipse' | 'g' | 'line' | 'path' | 'polygon' | 'polyline' | 'rect',
attrs: SVGAttributes<SVGSVGElement>,
elementName: 'circle' | 'ellipse'| 'g' | 'line' | 'path' | 'polygon' | 'polyline' | 'rect',
attrs: SVGAttributes<SVGSVGElement>
][];
```
### Using `IconNode`
You can use the `IconNode` type when you need to work with the raw SVG structure of an icon.
::: code-group
```svelte [CustomIcon.svelte]
<script lang="ts">
import { type IconNode, Icon } from '@lucide/svelte';
@@ -177,5 +166,4 @@ const customIcon: IconNode = [
<Icon iconNode={customIcon} size="24" color="blue" />
```
:::
+8 -10
View File
@@ -1,8 +1,7 @@
---
title: Stroke width - Svelte
description: Learn how to adjust the stroke width of icons in your Svelte application using the `strokeWidth` prop or adjust the strokeWidth appearance using the `nonScalingStroke` prop.
description: Learn how to adjust the stroke width of icons in your Svelte application using the `strokeWidth` prop or adjust the strokeWidth appearance using the `absoluteStrokeWidth` prop.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackSvelte.vue'
</script>
@@ -25,22 +24,21 @@ import FolderLock from "@lucide/svelte/icons/folder-lock";
<FolderLock strokeWidth={1} />
```
:::
## Non-scaling strokes
## Absolute stroke width
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `nonScalingStroke` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `absoluteStrokeWidth` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
This means that when `nonScalingStroke` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
This means that when `absoluteStrokeWidth` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
### Adjusting stroke width with `nonScalingStroke` prop
### Adjusting stroke width with `absoluteStrokeWidth` prop
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
::: sandpack {template=vite-svelte editorHeight=240 editorWidthPercentage=60}
@@ -51,7 +49,7 @@ import RollerCoaster from "@lucide/svelte/icons/roller-coaster";
<RollerCoaster
size={96}
nonScalingStroke
absoluteStrokeWidth
/>
```
+7 -8
View File
@@ -2,7 +2,6 @@
title: Getting started - Svelte
description: This guide will help you get started with Lucide in your Svelte project.
---
<script setup>
import OverviewLink from '../../.vitepress/theme/components/base/OverviewLink.vue'
import OverviewLinkGrid from '../../.vitepress/theme/components/base/OverviewLinkGrid.vue'
@@ -54,13 +53,13 @@ Each icon can be imported as a Svelte component, which renders an inline SVG ele
To customize the appearance of an icon, you can use the following props:
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `stroke-width` | _number_ | 2 |
| `nonScalingStroke` | _boolean_ | false |
| `default-class` | _string_ | lucide-icon |
| name | type | default |
| ----------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `stroke-width` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
| `default-class` | *string* | lucide-icon |
Because icons render as SVG elements, all standard SVG attributes can also be applied as props. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
+1 -1
View File
@@ -63,7 +63,7 @@ Also, a `llms.txt` is now available for LLMs to use.
We have improved the accessibility of our icons by setting `aria-hidden` to `true` by default. This change ensures that screen readers will ignore icons that are purely decorative, improving the overall accessibility of your applications. If you need to make an icon accessible, you can provide an appropriate `aria-label` or add a `title` attribute to the icon element.
See our [accessibility in-depth guide](/how-to/accessibility) for more details and best practices on making your icons accessible.
See our [accessibility in-depth guide](/guide/accessibility) for more details and best practices on making your icons accessible.
## Removed UMD build, only ESM and CJS now
+1 -1
View File
@@ -17,7 +17,7 @@ Most of the time, icons are used purely for decoration or visual reinforcement.
For a broader explanation of this, and other best practices on how to use icons accessibly in your application, please refer to our detailed guide on accessibility:
<OverviewLink href="/how-to/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
<OverviewLink href="/guide/accessibility" title="Accessible Icons" desc="Best practices for accessible icons in your application."/>
Only if an icon **conveys essential meaning on its own** should it be made accessible. The sections below explain how to do that in Vue.
+8 -9
View File
@@ -2,7 +2,6 @@
title: Combining icons - Vue
description: Learn how to combine multiple icons into a single icon nested SVG elements in your Vue application.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackVue.vue'
</script>
@@ -16,24 +15,22 @@ This is useful if you want to create custom icons by combining existing ones.
```vue src/App.vue [active]
<script setup>
import { Scan, User } from '@lucide/vue';
import { Scan, User } from "@lucide/vue";
</script>
<template>
<div class="app">
<Scan
:size="48"
nonScalingStroke
>
<Scan :size="48">
<User
:size="12"
x="6"
y="6"
nonScalingStroke
absoluteStrokeWidth
/>
</Scan>
</div>
</template>
```
:::
@@ -57,7 +54,7 @@ For example, you can add a notification badge to an icon by using the `circle` S
```vue src/App.vue [active]
<script setup>
import { Mail } from '@lucide/vue';
import { Mail } from "@lucide/vue";
const hasUnreadMessages = true;
</script>
@@ -76,6 +73,7 @@ const hasUnreadMessages = true;
</Mail>
</div>
</template>
```
:::
@@ -88,7 +86,7 @@ You can also use the `text` SVG element to add text to your icon.
```vue src/App.vue [active]
<script setup>
import { File } from '@lucide/vue';
import { File } from "@lucide/vue";
</script>
<template>
@@ -106,6 +104,7 @@ import { File } from '@lucide/vue';
</File>
</div>
</template>
```
:::
+7 -9
View File
@@ -2,7 +2,6 @@
title: Global Styling - Vue
description: Learn how to style all Lucide icons globally in your Vue application using CSS or the Lucide context provider.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackVue.vue'
</script>
@@ -75,9 +74,9 @@ import {
Sandwich,
Wine,
Dessert,
} from '@lucide/vue';
} from "@lucide/vue";
import './icon.css';
import "./icon.css";
</script>
<template>
@@ -94,12 +93,11 @@ import './icon.css';
</div>
</template>
```
:::
### Non-scaling strokes
### Absolute stroke width
For global non-scaling stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [non-scaling strokes](../basics/stroke-width.md#non-scaling-strokes) for more info.
For global absolute stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [absolute-stroke-width](../basics/stroke-width.md#absolute-stroke-width) for more info.
::: sandpack {template=vue editorHeight=300 editorWidthPercentage=55 dependencies="@lucide/vue"}
@@ -134,9 +132,9 @@ import {
Map,
CloudMoon,
Sparkles,
} from '@lucide/vue';
} from "@lucide/vue";
import './icon.css';
import "./icon.css";
</script>
<template>
@@ -152,6 +150,6 @@ import './icon.css';
<Sparkles />
</div>
</template>
```
```
:::
+2 -22
View File
@@ -2,7 +2,6 @@
title: Typescript - Vue
description: Learn about the different types exported by the `@lucide/vue` package and how to use them in your Vue application.
---
# TypeScript Support
List of exported types from the `@lucide/vue` package.
@@ -17,21 +16,15 @@ interface LucideProps {
size?: number | string;
color?: string;
strokeWidth?: number;
nonScalingStroke?: boolean;
/**
* @deprecated
*/
absoluteStrokeWidth?: boolean;
[key: string]: any; // Any other SVG attributes
}
```
### Using `LucideProps`
You can use the `LucideProps` interface to type props for your custom icon components.
::: code-group
```vue [IconWrapper.vue]
<script lang="ts" setup>
import { type LucideProps } from '@lucide/vue';
@@ -46,7 +39,6 @@ defineProps<LucideProps>();
</div>
</template>
```
:::
## `LucideIcon`
@@ -62,7 +54,6 @@ type LucideIcon = React.FC<LucideProps>;
You can use the `LucideIcon` type when you need to work with icon components directly.
::: code-group
```vue [IconButton.vue]
<script lang="ts" setup>
import { type LucideProps } from '@lucide/vue';
@@ -76,14 +67,10 @@ defineProps<{
<template>
<button :aria-label="label">
<component
:is="icon"
:size="16"
/>
<component :is="icon" :size="16" />
</button>
</template>
```
:::
## `IconNode`
@@ -96,11 +83,9 @@ type IconNode = [elementName: string, attrs: Record<string, string | number>][];
```
### Using `IconNode`
You can use the `IconNode` type when you need to work with the raw SVG structure of an icon.
::: code-group
```vue [CustomIcon.vue]
<script lang="ts" setup>
import { type IconNode, Icon } from '@lucide/vue';
@@ -113,12 +98,7 @@ const customIcon: IconNode = [
</script>
<template>
<Icon
:iconNode="customIcon"
size="24"
color="blue"
/>
<Icon :iconNode="customIcon" size="24" color="blue" />
</template>
```
:::
+11 -13
View File
@@ -1,8 +1,7 @@
---
title: Stroke width - Vue
description: Learn how to adjust the stroke width of icons in your Vue application using the `strokeWidth` prop or adjust the strokeWidth appearance using the `nonScalingStroke` prop.
description: Learn how to adjust the stroke width of icons in your Vue application using the `strokeWidth` prop or adjust the strokeWidth appearance using the `absoluteStrokeWidth` prop.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackVue.vue'
</script>
@@ -20,43 +19,42 @@ The `strokeWidth` can be adjusted to create a different look of the icons.
```vue src/App.vue [active]
<script setup>
import { FolderLock } from '@lucide/vue';
import { FolderLock } from "@lucide/vue";
</script>
<template>
<FolderLock :strokeWidth="1" />
</template>
```
:::
## Non-scaling strokes
## Absolute stroke width
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `nonScalingStroke` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `absoluteStrokeWidth` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
This means that when `nonScalingStroke` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
This means that when `absoluteStrokeWidth` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
### Adjusting stroke width with `nonScalingStroke` prop
### Adjusting stroke width with `absoluteStrokeWidth` prop
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
::: sandpack {template=vue showTabs=false editorHeight=320 editorWidthPercentage=60 dependencies="@lucide/vue"}
```vue src/App.vue [active]
<script setup>
import { RollerCoaster } from '@lucide/vue';
import { RollerCoaster } from "@lucide/vue";
</script>
<template>
<RollerCoaster
:size="96"
nonScalingStroke
absoluteStrokeWidth
/>
</template>
```
```
:::
+8 -13
View File
@@ -2,7 +2,6 @@
title: Getting started - Vue
description: This guide will help you get started with Lucide in your Vue project.
---
<script setup>
import OverviewLink from '../../.vitepress/theme/components/base/OverviewLink.vue'
import OverviewLinkGrid from '../../.vitepress/theme/components/base/OverviewLinkGrid.vue'
@@ -56,13 +55,13 @@ import { Camera } from '@lucide/vue';
To customize the appearance of an icon, you can use the following props:
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `stroke-width` | _number_ | 2 |
| `nonScalingStroke` | _boolean_ | false |
| `default-class` | _string_ | lucide-icon |
| name | type | default |
| ----------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `stroke-width` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
| `default-class` | *string* | lucide-icon |
### Applying props
@@ -70,11 +69,7 @@ Because icons render as SVG elements, all standard SVG attributes can also be ap
```vue
<template>
<Camera
:size="48"
color="red"
:stroke-width="1"
/>
<Camera :size="48" color="red" :stroke-width="1" />
</template>
```
-271
View File
@@ -1,271 +0,0 @@
---
title: Accessibility
description: Learn how to make your icons accessible to all users, including those with disabilities.
---
<script setup>
import {
menu,
pawPrint,
shirt,
umbrella,
userRoundCog,
} from '~/.vitepress/data/iconNodes';
import LucideIcon from '~/.vitepress/theme/components/base/LucideIcon.vue';
</script>
# Accessibility in depth
Icons are pictures that convey meaning without using words.
They can help people scan an interface, recognize actions, and understand status quickly.
Not everyone understands icons easily. Use the following accessibility rules when you add icons to an interface.
::: tip
Lucide icons are hidden from screen readers by default with `aria-hidden="true"`.
Add accessible labels when icons carry meaning or act as controls.
:::
## Provide visible labels
Icons can improve scanning, but they aren't a replacement for text.
Text helps people understand actions and navigation more reliably than icons alone.
:::: example
::: do <span aria-hidden="true">On this page <LucideIcon name="menu" :iconNode="menu" /></span>
Provide a written description of your interactive elements.
:::
::: dont <LucideIcon name="menu" :iconNode="menu" />
Don't rely on icons alone to communicate what elements do.
:::
::::
## Provide enough contrast
Use enough contrast between an icon and its background. Low contrast makes icons harder to see for people with low vision or color vision deficiencies.
Follow [WCAG 2.1 SC 1.4.3](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html) when contrast requirements apply.
:::: example
::: do ../images/a11y/contrast_do.svg?raw=true
Use a contrast ratio of at least 4.5:1.
:::
::: dont ../images/a11y/contrast_dont.svg?raw=true
Don't use low contrast.
:::
::::
## Do not rely on color alone
Use non-color cues like shape, shading, or text to mark state, status, and validity. Color can support meaning, but it must not be the only cue.
:::: example
::: do ../images/a11y/state_do.svg?raw=true
Mark state with non-color visual cues too.
:::
::: dont ../images/a11y/state_dont.svg?raw=true
Don't mark state only with color.
:::
::::
## Make interactive icons focusable
Wrap interactive icons in semantic elements. Icons that perform actions need keyboard access and clear feedback when activated.
:::: example
::: do ../images/a11y/interactive_icons_do.svg?raw=true
Wrap interactive icons in semantic elements, such as buttons, so they are focusable.
:::
::: dont ../images/a11y/interactive_icons_dont.svg?raw=true
Don't leave interactive icons unable to be focused.
:::
::::
## Use a large enough target size
Use a large enough target size for interactive icon controls. Small targets can be difficult to click or tap.
:::: example
::: do ../images/a11y/target_size_do.svg?raw=true
Keep the target size at a minimum of 44 by 44 pixels.
:::
::: dont ../images/a11y/target_size_dont.svg?raw=true
Don't make the target size smaller than 44 by 44 pixels.
:::
::::
The icon itself does not need to be 44 by 44 pixels. The interactive wrapper needs to meet the target size.
## Choose universal symbols when possible
Choose icons that are widely recognized for your use case. Avoid icons that only make sense to a narrow audience.
:::: example
::: do <span aria-hidden="true"><LucideIcon name="shirt" :iconNode="shirt" /> Clothing</span>
Pick icons that are universal symbols for your use case.
:::
::: dont <span aria-hidden="true"><LucideIcon name="umbrella" :iconNode="umbrella" /> Clothing</span>
Don't pick icons that are not universally recognizable for your use case.
:::
::::
## Avoid cultural or linguistic shortcuts
Choose icons with a clear connection to the concept. Puns, idioms, and culture-specific references can be difficult to understand or translate.
:::: example
::: do <span aria-hidden="true"><LucideIcon name="user-round-cog" :iconNode="userRoundCog" /> Role bearers</span>
Pick icons with a clear connection to the concept you want to represent.
:::
::: dont <span aria-hidden="true"><LucideIcon name="paw-print" :iconNode="pawPrint" /> Role bearers</span>
Don't pick icons based on puns or other cultural or linguistic cues.
:::
::::
## Use different icons for different meanings
Use different icons for different meanings. Reusing one icon for unrelated concepts makes the interface harder to learn.
:::: example
::: do ../images/a11y/distinct_use_case_do.svg?raw=true
Use different icons for distinct purposes or meanings.
:::
::: dont ../images/a11y/distinct_use_case_dont.svg?raw=true
Don't use the same icon for multiple distinct purposes or meanings, especially in the same context.
:::
::::
## Use the same icon for the same meaning
Use the same icon for the same meaning. Consistent icon use helps people recognize familiar actions across an interface.
:::: example
::: do ../images/a11y/same_use_case_do.svg?raw=true
Use the same icon for the same purpose or function.
:::
::: dont ../images/a11y/same_use_case_dont.svg?raw=true
Don't use different icons for the same purpose or function.
:::
::::
## Hide decorative icons from assistive technology
Keep decorative icons hidden from screen readers. Decorative icons repeat nearby text or add visual styling without adding meaning.
:::: example
::: do ../images/a11y/decorative_icons_do.svg?raw=true
Omit `aria-label` on decorative icons.
:::
::: dont ../images/a11y/decorative_icons_dont.svg?raw=true
Don't provide accessible labels to decorative icons.
:::
::::
## Label functional standalone icons carefully
Avoid standalone functional icons when possible. If an icon carries meaning without nearby text or an interactive wrapper, give that icon an accessible label.
:::: example
::: do ../images/a11y/functional_icons_do.svg?raw=true
Provide an accessible label for functional icons, but avoid standalone functional icons when possible.
:::
::: dont ../images/a11y/functional_icons_dont.svg?raw=true
Don't provide an accessible label for purely decorative icons.
:::
::::
In many cases, add visible text, place the icon inside a badge or button, or add a tooltip to the meaningful wrapper instead.
## Label icon buttons on the button
Give icon buttons an accessible name. Put the name on the button or in visually hidden text inside the button, not on the icon.
:::: example
::: do ../images/a11y/icon_button_do.svg?raw=true
Provide the accessible label for icon buttons themselves.
:::
::: dont ../images/a11y/icon_button_dont.svg?raw=true
Don't provide the accessible label for icons on icon buttons.
:::
::::
::: details Code examples
```tsx
// Don't do this
<button className="btn-icon">
<House />
</button>
// Don't do this either
<button className="btn-icon">
<House aria-label="Home icon" />
</button>
// This works, but visually hidden text is usually more reliable
<button aria-label="Go to home" className="btn-icon">
<House />
</button>
// Prefer this
<button className="btn-icon">
<House />
<span className="visually-hidden">Go to home</span>
</button>
```
:::
## A note on `aria-label`
You can provide accessible labels with `aria-label`, but visually hidden text is often more reliable.
Read [why `aria-label` might not be the best solution](https://gomakethings.com/revisting-aria-label-versus-a-visually-hidden-class/) for more context.
### Radix UI
Use [Radix UI's built-in accessible icon utility component](https://www.radix-ui.com/primitives/docs/utilities/accessible-icon).
```tsx
import { ArrowRightIcon } from 'lucide-react';
import { AccessibleIcon } from '@radix-ui/react-accessible-icon';
<AccessibleIcon label="Next item">
<ArrowRightIcon />
</AccessibleIcon>;
```
### Bootstrap
```html
<div>
<i data-lucide="phone" aria-hidden="true"></i>
<span class="visually-hidden">Phone number</span>
</div>
```
### Tailwind CSS
```html
<div>
<i data-lucide="phone" aria-hidden="true"></i>
<span class="sr-only">Phone number</span>
</div>
```
If you are not sure which hiding technique to use, read [how to hide content](https://www.a11yproject.com/posts/how-to-hide-content/).
## Further resources
Use these accessibility resources:
- [Web Content Accessibility Guidelines (WCAG) 2.1](https://www.w3.org/TR/WCAG21/)
- [Web Accessibility Initiative (WAI)](https://www.w3.org/WAI/)
- [Learn accessibility on web.dev](https://web.dev/learn/accessibility)
- [Inclusive Components](https://inclusive-components.design/)
- [A11yTalks](https://www.a11ytalks.com/)
- [A11y automation tracker](https://a11y-automation.dev/)
- [The A11Y Project](https://www.a11yproject.com/)
-190
View File
@@ -1,190 +0,0 @@
---
title: How to pick the right icon
description: Learn when to use icons, when to avoid them, and how to choose icons that make interfaces easier to understand.
---
<script setup>
import {
badgeCheck,
badgeX,
check,
download,
folderSearch,
globe,
house,
imageOff,
layoutList,
mail,
menu,
plus,
search,
settings,
smartphone,
sparkles,
trash,
x,
} from '~/.vitepress/data/iconNodes';
const customCheck = [['path', {d: 'M19.05 5.253c.26.1.42.352.63.571.159.166.547.536.672.69.088.11.158.28.257.397-.075.202-.212.133-.453.038q-.315.238-.625.485l-.208-.159c-.14-.016-.045.182-.058.253-.135.685-1.145 1.03-1.61 1.376-.101.074-.32.424-.474.382-.04-.012-.133-.101-.154-.09q-.151.298-.293.598c-.446.156-.638.591-.906.928-.728.913-1.366 1.874-2.074 2.787-.138.178-.225.463-.403.606-.074.059-.265-.029-.208.158l-.14-.092c-.005.125.06.254.004.357a2.2 2.2 0 0 1-.259.37c-.034.031-.111-.041-.135-.006-.04.062-.007.272-.064.356-.052.076-.237.135-.262.203-.091.247-.092.572-.282.774-.052.054-.217.06-.228.081-.018.043.084.127.081.162-.014.178-.278.295-.367.42-.29.41-.527.885-.818 1.293-.076.107-.166.248-.264.392l-.613 1.273-1.16-1.208c-.135-.19-.27-.393-.326-.558-.02-.061.103-.138.07-.178-.035-.044-.13-.008-.152-.024-.158-.11-.489-.358-.524-.553-.006-.037.064-.128.052-.144-.007-.007-.08.026-.107.007-.232-.164-.33-.343-.49-.56-.312-.415-.828-.734-1.167-1.143-.074-.09.013-.309 0-.318-.031-.02-.147.077-.225.058-.26-.062-.407-.385-.632-.459-.112-.037-.343.032-.452.008-.087-.02-.208-.189-.285-.139-.045.031-.141.164-.173.168-.03.002-.007-.097-.028-.117-.088-.08-.091-.16-.165-.245-.112-.133-.569-.21-.304-.827l.008-.019c.053-.117.15-.228.215-.358.066-.13.444-.992.535-1.009.132-.017.256.314.309.331.037.012.12-.042.172-.03.165.034.205.13.449.005q-.019.203-.044.403c.093-.009.1.188.142.204.034.014.105-.055.14-.038.038.02.034.143.106.173.117.05.282-.14.364-.121.085.02.103.205.237.195l.081-.042.093-.167c.059.01-.002.126.034.157.043.036.14-.042.17-.018.024.02-.004.122.03.143.051.03.131-.088.172-.088.02 0 .246.089.257.097.08.061-.04.214.009.279.134.177.404.211.592.307a.44.44 0 0 1 .187.201c-.443.26-.494.747-.035.114-.006.148.19.048.233.14.026.059-.021.165.04.224.11.104.448.016.077.427.192.062.147.31.55.03.054.014-.083.296-.079.36.007.062.15.423.182.473.034.05.095.134.16.146.081.013.498-.275.116.19.12.07.138.118.162.255.003.025-.063.082-.055.092.017.02.095.014.13.046.06.052-.057.202.158.02l.102.016c-.002-.055-.01-.114-.017-.165-.004-.02-.062-.059-.07-.087-.017-.07.128-.127-.067-.248l.239-.002q-.025-.079-.048-.158l-.181-.116c.244.073.228-.075.308-.09.017-.001.1.05.141.036.049-.017.066-.096.117-.119l-.245-.226c-.003-.103.256.03.303-.001a1 1 0 0 0 .081-.167c0-.088-.217-.207-.058-.354.029-.025.117-.005.14-.032.038-.048-.023-.306-.164-.417.226.063.258-.149.345-.163.026-.003.146.072.202.045.045-.022.013-.179.06-.214.05-.036.159.012.181-.004.02-.015-.046-.089-.027-.117.062-.086.244-.078.294-.144.07-.097-.105-.346-.152-.502.03-.01.095.003.11-.018.193-.262.448-.534.69-.766.112-.107.648-.183.066-.485-.06-.11.38-.267.428-.323.047-.057-.01-.173.024-.22.101-.142.244-.19.295-.42.013-.06-.058-.193-.037-.218.028-.029.157.02.196-.015.09-.084.2-.288.292-.364.017-.014.112.054.16.053.185-.001.26-.11-.042-.33.261.017.204-.216.288-.332.177-.246.607-.597.673-.896.04-.19-.083-.303.191-.382.061-.018.131-.027.204-.048.174-.05.491.067.31-.278.19-.053.24-.199.553-.058l-.127-.196.04-.048.167.144c.12-.089.053-.437.148-.523.16-.145.649-.427.864-.481.114-.03.018-.153.273.051l.01-.097q-.05-.096-.102-.19c.103-.09.297-.11.398-.194.18-.152.34-.528.605-.572.067-.012.215.057.26.02.065-.054-.063-.258.02-.326.142-.118.59-.1.715-.218.038-.035.005-.123.029-.151.099-.122.203-.187.24-.383m-9.145 12.15c-.111.13.148.094.324-.011zm-1.57-2.539c.012-.033-.085-.048-.137-.005-.199.168.085.152.138.005m3.356-1.475q.068.022.133.045l.018-.033q-.093-.06-.186-.124z', fill: 'currentColor', stroke: 'none'}]];
const customMail = [['path', {fill:"currentColor", stroke: 'none', 'fill-rule': "evenodd", d: "M22 20H2V7.003l10 6.546 10-6.546z M22 5.905 12 11.45 2 5.905V4h20z"}]];
import LucideIcon from '~/.vitepress/theme/components/base/LucideIcon.vue';
</script>
# How to pick the right icon
Icons can make an interface easier to scan. They work best when people already understand the symbol or when the icon appears with a clear text label.
Use text instead of an icon when the meaning is complex, abstract, or easy to misunderstand.
## Match the interface style
Use icons with the same visual language in the same interface. Mixed styles can make related controls look unrelated.
:::: example
::: do <span class="g-4"><LucideIcon name="house" :iconNode="house" size="48" /> <LucideIcon name="plus" :iconNode="plus" size="48" /> <LucideIcon name="check" :iconNode="check" size="48" /> <LucideIcon name="mail" :iconNode="mail" size="48" /></span>
Use one icon style for related controls.
:::
::: dont <span class="g-4"><LucideIcon name="house" :iconNode="house" strokeWidth="1" size="48" /> <LucideIcon name="plus" :iconNode="plus" strokeWidth="3" size="48" /> <LucideIcon name="check" :iconNode="customCheck" size="48" /> <LucideIcon name="mail" :iconNode="customMail" size="48" /></span>
Don't mix unrelated icon styles in the same interface.
:::
::::
## Use familiar icons for familiar actions
Icons work well for common actions and destinations that people already recognize from other interfaces.
:::: example
::: do <span class="g-4"><LucideIcon name="search" :iconNode="search" size="48" /> <LucideIcon name="house" :iconNode="house" size="48" /> <LucideIcon name="settings" :iconNode="settings" size="48" /> <LucideIcon name="x" :iconNode="x" size="48" /></span>
Use icons for common actions with widely understood symbols.
:::
::: dont <span>"strategy", "optimize", "synergy", "innovation"</span>
Don't use icons alone for abstract concepts with no common symbol.
:::
::::
## Use icons as visual anchors
Icons can help people scan lists, menus, cards, and repeated controls. The icon needs to support the text, not compete with it.
:::: example
::: do ../images/how-to/visual_anchor_do.svg?raw=true
Use icons to make associated options easier to scan.
:::
::: dont ../images/how-to/visual_anchor_dont.svg?raw=true
Don't add icons to every line when they only create visual clutter.
:::
::::
## Use icons in compact interfaces
Icons can help in tight spaces, such as mobile navigation, toolbars, tables, and compact controls. Keep labels when the icon is not obvious.
:::: example
::: do ../images/how-to/compact_interfaces_labels_do.svg?raw=true
Keep labels in all layout variants when space allows.
:::
::: caution ../images/how-to/compact_interfaces_labels_dont.svg?raw=true
Use icon-only controls only when a visible label does not fit.
In these cases, make sure that the label is accessible via hover, focus, or tap.
:::
::::
:::: example
::: do ../images/how-to/compact_interfaces_do.svg?raw=true
Keep text labels next to icons in compact layouts, even when space is sparse.
:::
::: dont ../images/how-to/compact_interfaces_dont.svg?raw=true
Don't remove labels in compact layouts when the meaning without them is unclear.
:::
::::
:::: example
::: caution ../images/how-to/compact_interfaces_caution_1.svg?raw=true
Use icon-only controls only when the icon represents a widely understood action.
:::
::: caution ../images/how-to/compact_interfaces_caution_2.svg?raw=true
Use icon-only controls only when the label is available on hover, focus, or tap.
:::
::::
## Choose the clearest symbol
Use a familiar symbol when one exists. Novel symbols make people stop and interpret the interface.
:::: example
::: do <span><LucideIcon name="trash" :iconNode="trash" /> `trash`<br>for deleting an image</span>
Use a familiar symbol for a familiar action.
:::
::: dont <span><LucideIcon name="image-off" :iconNode="imageOff" /> `image-off`<br>for deleting an image</span>
Don't make people learn a new symbol for a common action.
:::
::::
## Match the context, not every detail
Choose the icon that makes the action clearest in context. A more specific icon is better only when the extra detail helps people understand the action.
:::: example
::: do ../images/how-to/appropriate_context_do.svg?raw=true
Use clear action icons when the surrounding interface already provides the object context.
:::
::: dont ../images/how-to/appropriate_context_dont.svg?raw=true
Don't add object details when the context already makes the object clear.
:::
::::
## Keep icon meaning consistent
Use the same icon for the same meaning, and use different icons for different meanings.
:::: example
::: do ../images/how-to/consistent_icon_meaning_do.svg?raw=true
Use different icons for distinct purposes or meanings.
:::
::: dont ../images/how-to/consistent_icon_meaning_dont.svg?raw=true
Don't use the same icon for multiple distinct purposes or meanings.
:::
::::
:::: example
::: do ../images/how-to/consistent_icon_function_do.svg?raw=true
Use the same icon for the same purpose or function.
:::
::: dont ../images/how-to/consistent_icon_function_dont.svg?raw=true
Don't use different icons for the same purpose or function.
:::
::::
## Do not iconize repeated status decoration
Avoid adding an icon to every repeated status marker when color, weight, text, or layout already communicates the state. Repeated status icons can turn useful list structure into visual noise.
:::: example
::: do ../images/how-to/repeated_status_do.svg?raw=true
Use the lightest cue that makes the status clear.
:::
::: dont ../images/how-to/repeated_status_dont.svg?raw=true
Don't add repeated status icons when they only restate what the list already shows.
:::
::::
## Do not replace built-in control cues
Do not add icons to controls that already show people how they work. Native controls are easier to recognize when they behave and look familiar.
:::: example
::: do ../images/how-to/native_ui_elements_do.svg?raw=true
Use the built-in visual cue when the control already communicates its behavior.
:::
::: dont ../images/how-to/native_ui_elements_dont.svg?raw=true
Don't replace native controls with similarly themed interactive icons.
:::
::::
<style>
.g-4 {
display: flex;
flex-direction: row;
gap: 1rem;
}
</style>
-29
View File
@@ -1,29 +0,0 @@
---
title: How to use Lucide icons
description: Learn how to use icons in an accessible, user-friendly way
---
<script setup>
import OverviewLink from '../.vitepress/theme/components/base/OverviewLink.vue';
import OverviewLinkGrid from '../.vitepress/theme/components/base/OverviewLinkGrid.vue';
import { resourcesSidebar } from '../.vitepress/sidebar/resources.ts';
</script>
# How to use Lucide icons
Icons can make an interface easier to scan, but they only help when their meaning is clear. These guides explain how to choose icons that support the interface, when to pair icons with text, and when the best icon to use is no icon at all.
Use the accessibility guide to make icons readable, understandable, and usable with assistive technology. Use the icon guide to decide when icons belong in an interface and how to pick symbols people are likely to recognize.
## What this guide covers
<OverviewLinkGrid>
<OverviewLink v-for="item in resourcesSidebar[2].items.slice(1)" :key="item.link" :href="item.link" :title="item.text" :desc="item.desc"/>
</OverviewLinkGrid>
## Further resources
- [The no-bullshit guide to icon design and usage](https://erik-engheim.medium.com/the-no-bullshit-guide-to-icon-design-and-usage-40948878dbbb) by Erik Engheim
- [On icons](https://ia.net/topics/on-icons/) by iA
- [How to use icons in UI and UX design](https://blog.thenounproject.com/how-to-use-icons-in-ui-and-ux-design-best-practices/) by The Noun Project
- [UX Myth: Icons enhance usability](https://uxmyths.com/post/715009009/myth-icons-enhance-usability) by UX Myths
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 40 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 59 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 244 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 209 KiB

+20
View File
@@ -0,0 +1,20 @@
<svg width="480" height="328" viewBox="0 0 480 328" fill="none" class="a11y-example">
<title>In short: use a contrast ratio of at least 4.5:1</title>
<rect width="480" height="152" rx="8" style="fill: var(--vp-code-block-bg)" />
<rect x="183.5" y="24" width="113" height="56" rx="28" fill="#712CF8"/>
<path d="M227.5 46L216.5 57L211.5 52" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M257.893 51.7273C257.893 53.2614 257.616 54.5871 257.062 55.7045C256.509 56.822 255.749 57.6837 254.783 58.2898C253.817 58.8958 252.714 59.1989 251.473 59.1989C250.232 59.1989 249.129 58.8958 248.163 58.2898C247.197 57.6837 246.438 56.822 245.884 55.7045C245.33 54.5871 245.053 53.2614 245.053 51.7273C245.053 50.1932 245.33 48.8674 245.884 47.75C246.438 46.6326 247.197 45.7708 248.163 45.1648C249.129 44.5587 250.232 44.2557 251.473 44.2557C252.714 44.2557 253.817 44.5587 254.783 45.1648C255.749 45.7708 256.509 46.6326 257.062 47.75C257.616 48.8674 257.893 50.1932 257.893 51.7273ZM256.189 51.7273C256.189 50.4678 255.978 49.4048 255.557 48.5384C255.14 47.6719 254.574 47.0161 253.859 46.571C253.149 46.1259 252.354 45.9034 251.473 45.9034C250.592 45.9034 249.795 46.1259 249.08 46.571C248.369 47.0161 247.804 47.6719 247.382 48.5384C246.965 49.4048 246.757 50.4678 246.757 51.7273C246.757 52.9867 246.965 54.0497 247.382 54.9162C247.804 55.7827 248.369 56.4384 249.08 56.8835C249.795 57.3286 250.592 57.5511 251.473 57.5511C252.354 57.5511 253.149 57.3286 253.859 56.8835C254.574 56.4384 255.14 55.7827 255.557 54.9162C255.978 54.0497 256.189 52.9867 256.189 51.7273ZM260.855 59V44.4545H262.616V51.6705H262.787L269.321 44.4545H271.622L265.514 51.017L271.622 59H269.491L264.435 52.2386L262.616 54.2841V59H260.855Z" fill="black"/>
<path d="M42 110L30 122" style="stroke: var(--vp-a11y-danger)" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M30 110L42 122" style="stroke: var(--vp-a11y-danger)" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<text x="58" y="122" style="fill: var(--vp-a11y-danger)" font-size="18" font-weight="800">
<tspan>Don't use low contrast.</tspan>
</text>
<rect y="176" width="480" height="152" rx="8" style="fill: var(--vp-code-block-bg)" />
<rect x="183.5" y="200" width="113" height="56" rx="28" fill="#712CF8"/>
<path d="M227.5 222L216.5 233L211.5 228" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M257.893 227.727C257.893 229.261 257.616 230.587 257.062 231.705C256.509 232.822 255.749 233.684 254.783 234.29C253.817 234.896 252.714 235.199 251.473 235.199C250.232 235.199 249.129 234.896 248.163 234.29C247.197 233.684 246.438 232.822 245.884 231.705C245.33 230.587 245.053 229.261 245.053 227.727C245.053 226.193 245.33 224.867 245.884 223.75C246.438 222.633 247.197 221.771 248.163 221.165C249.129 220.559 250.232 220.256 251.473 220.256C252.714 220.256 253.817 220.559 254.783 221.165C255.749 221.771 256.509 222.633 257.062 223.75C257.616 224.867 257.893 226.193 257.893 227.727ZM256.189 227.727C256.189 226.468 255.978 225.405 255.557 224.538C255.14 223.672 254.574 223.016 253.859 222.571C253.149 222.126 252.354 221.903 251.473 221.903C250.592 221.903 249.795 222.126 249.08 222.571C248.369 223.016 247.804 223.672 247.382 224.538C246.965 225.405 246.757 226.468 246.757 227.727C246.757 228.987 246.965 230.05 247.382 230.916C247.804 231.783 248.369 232.438 249.08 232.884C249.795 233.329 250.592 233.551 251.473 233.551C252.354 233.551 253.149 233.329 253.859 232.884C254.574 232.438 255.14 231.783 255.557 230.916C255.978 230.05 256.189 228.987 256.189 227.727ZM260.855 235V220.455H262.616V227.67H262.787L269.321 220.455H271.622L265.514 227.017L271.622 235H269.491L264.435 228.239L262.616 230.284V235H260.855Z" fill="white"/>
<path d="M44 286L33 297L28 292" style="stroke: var(--vp-c-success-2)" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<text x="58" y="299" style="fill: var(--vp-a11y-success)" font-size="18" font-weight="800">
Do use a contrast ratio of at least 4.5:1.
</text>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

-5
View File
@@ -1,5 +0,0 @@
<svg width="320" height="200" viewBox="0 0 320 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="104" y="72" width="113" height="56" rx="28" fill="#712CF8"/>
<path d="M148 94L137 105L132 100" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M178.393 99.7273C178.393 101.261 178.116 102.587 177.562 103.705C177.009 104.822 176.249 105.684 175.283 106.29C174.317 106.896 173.214 107.199 171.973 107.199C170.732 107.199 169.629 106.896 168.663 106.29C167.697 105.684 166.938 104.822 166.384 103.705C165.83 102.587 165.553 101.261 165.553 99.7273C165.553 98.1932 165.83 96.8674 166.384 95.75C166.938 94.6326 167.697 93.7708 168.663 93.1648C169.629 92.5587 170.732 92.2557 171.973 92.2557C173.214 92.2557 174.317 92.5587 175.283 93.1648C176.249 93.7708 177.009 94.6326 177.562 95.75C178.116 96.8674 178.393 98.1932 178.393 99.7273ZM176.689 99.7273C176.689 98.4678 176.478 97.4048 176.057 96.5384C175.64 95.6719 175.074 95.0161 174.359 94.571C173.649 94.1259 172.854 93.9034 171.973 93.9034C171.092 93.9034 170.295 94.1259 169.58 94.571C168.869 95.0161 168.304 95.6719 167.882 96.5384C167.465 97.4048 167.257 98.4678 167.257 99.7273C167.257 100.987 167.465 102.05 167.882 102.916C168.304 103.783 168.869 104.438 169.58 104.884C170.295 105.329 171.092 105.551 171.973 105.551C172.854 105.551 173.649 105.329 174.359 104.884C175.074 104.438 175.64 103.783 176.057 102.916C176.478 102.05 176.689 100.987 176.689 99.7273ZM181.355 107V92.4545H183.116V99.6705H183.287L189.821 92.4545H192.122L186.014 99.017L192.122 107H189.991L184.935 100.239L183.116 102.284V107H181.355Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

-5
View File
@@ -1,5 +0,0 @@
<svg width="320" height="200" viewBox="0 0 320 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="104" y="72" width="113" height="56" rx="28" fill="#712CF8"/>
<path d="M148 94L137 105L132 100" stroke="#0D1016" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M178.393 99.7273C178.393 101.261 178.116 102.587 177.562 103.705C177.009 104.822 176.249 105.684 175.283 106.29C174.317 106.896 173.214 107.199 171.973 107.199C170.732 107.199 169.629 106.896 168.663 106.29C167.697 105.684 166.938 104.822 166.384 103.705C165.83 102.587 165.553 101.261 165.553 99.7273C165.553 98.1932 165.83 96.8674 166.384 95.75C166.938 94.6326 167.697 93.7708 168.663 93.1648C169.629 92.5587 170.732 92.2557 171.973 92.2557C173.214 92.2557 174.317 92.5587 175.283 93.1648C176.249 93.7708 177.009 94.6326 177.562 95.75C178.116 96.8674 178.393 98.1932 178.393 99.7273ZM176.689 99.7273C176.689 98.4678 176.478 97.4048 176.057 96.5384C175.64 95.6719 175.074 95.0161 174.359 94.571C173.649 94.1259 172.854 93.9034 171.973 93.9034C171.092 93.9034 170.295 94.1259 169.58 94.571C168.869 95.0161 168.304 95.6719 167.882 96.5384C167.465 97.4048 167.257 98.4678 167.257 99.7273C167.257 100.987 167.465 102.05 167.882 102.916C168.304 103.783 168.869 104.438 169.58 104.884C170.295 105.329 171.092 105.551 171.973 105.551C172.854 105.551 173.649 105.329 174.359 104.884C175.074 104.438 175.64 103.783 176.057 102.916C176.478 102.05 176.689 100.987 176.689 99.7273ZM181.355 107V92.4545H183.116V99.6705H183.287L189.821 92.4545H192.122L186.014 99.017L192.122 107H189.991L184.935 100.239L183.116 102.284V107H181.355Z" fill="#0D1016"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

Some files were not shown because too many files have changed in this diff Show More