Compare commits

...
Author SHA1 Message Date
8970c2c4f9 feat(lab): add check-x icon (#4737)
* feat(icons): add check-x icon (#4130)

* Move check x to lab

* fix(lab): add missing use-cases array to lab/check-x.json

* Add use cases for notifications in check-x.json

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: ishanbagra18 <your-email@example.com>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-09-10 09:01:13 +02:00
Karsa 26993aba5a fix(icons): improve legibility of credit card icons (#4831) 2026-09-10 08:45:29 +02:00
Karsa a53bd66a03 fix(icons): arcified flip icons & renamed them (#4833) 2026-09-09 23:05:32 +02:00
Karsa 3bcf71f7cf fix(icons): changed satellite-dish icon (#4813)
* Updated icons/satellite-dish.svg

* Updated icons/satellite-dish.json
2026-09-09 14:20:16 +02:00
Karsa 9e5f0607cd feat(docs): fixed fuse js search (move single phrase search to matching all words) (#4825) 2026-09-09 14:19:48 +02:00
Karsa 75955ec47b fix(docs): replace missing LucideIcon icon names in guides (#4827) 2026-09-09 08:20:42 +02:00
Karsa 58fd3ccd59 fix(icons): changed door-open (#4826)
Made the top right corner have 2px corner radius
2026-09-08 23:06:29 +02:00
Karsa 22e6094bb5 feat(packages/icons): fixed @lucide/icons rollup config (#4824) 2026-09-08 19:49:41 +02:00
Karsa ba95e4c988 feat(icons): delegate carton/carton-off from lab (#4818) 2026-09-08 14:01:03 +02:00
Karsa e8db514793 Update id-card-lanyard.svg (#4819) 2026-09-08 13:58:33 +02:00
Karsa ab000be04f fix(icons): changed id-card icon (#4820) 2026-09-08 13:55:03 +02:00
Karsaandgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> a537cb6eb3 feat(icons): added tic-tac-toe icon (#4772)
* Added icons/tic-tac-toe.svg

* Added icons/tic-tac-toe.json

* Update icons/tic-tac-toe.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-07 14:50:22 +02:00
Karsa 3859eb20fa feat(icons): added user-group icons (#4782)
* feat(icons): added user-group icons

* feat(icons): added more metadata to user-group icons
2026-09-07 12:05:31 +02:00
Jakob Guddas 2bfb9bb1ba fix(icons): changed table-2 icon (#4810)
* Updated icons/table-2.svg

* Updated icons/table-2.json
2026-09-06 22:26:48 +02:00
Copilotericfenniscopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
94e4cb9d9d chore(dependencies): Update dependencies (#4806)
* chore(deps): upgrade dependencies across workspace and unify shared versions

Co-authored-by: ericfennis <11825403+ericfennis@users.noreply.github.com>

* chore(deps): finish workspace dependency upgrade and align versions

* fix: keep vitest on 4.1.10, drop deprecated baseUrl, reformat with prettier

* fix(lucide-react): drop inert outDir so TS 6 rootDir check passes

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ericfennis <11825403+ericfennis@users.noreply.github.com>
2026-09-04 17:34:58 +02:00
Karsa 0196353e5c fix(icons): changed computer icon (#4607)
* Updated icons/computer.svg

* Updated icons/computer.json

* Updated icons/computer.svg

* Update computer.svg

* Update computer.json

* Update computer.svg
2026-09-04 16:42:57 +02:00
KarsaandEric Fennis 99d25bdee2 feat(packages): extract icon build logic into @lucide/shared (#4409)
* feat(packages): extract build logic to @lucide/shared, still wip

* feat(): unify icon build logic some more, add nonScalingStroke option, marking absoluteStrokeWidth as deprecated

* feat(): unify icon build logic some more, add nonScalingStroke option, marking absoluteStrokeWidth as deprecated

* feat(packages): extract build logic to @lucide/shared, still wip

* feat(): unify icon build logic some more, add nonScalingStroke option, marking absoluteStrokeWidth as deprecated

* feat(): unify icon build logic some more, add nonScalingStroke option, marking absoluteStrokeWidth as deprecated

* chore(icons): revert git hook changes made to icons

* fix(packages/astro,react-native,vue): fix iconNode type
fix(packages/vue): fix hasA11yProp

* fix(packages/solid): make component reactive & add unit tests for checking prop changes

* test(packages/vue): add reactivity tests to @lucide/vue

* fix(packages): replace cpy-cli, accidentally removed during main merge

* docs(packages): upgrade react documentation with nonScalingStroke

* fix(tests): update snapshots for lucide-react

* feat(docs): upgraded package guides with nonScalingStroke, dropping absoluteStrokeWidth

* fix(vue,react-native): fix linting issues

* fix(icons): add proper fallback for icon width in calculatedStrokeWidth

* fix(packages/svelte): add globalProps.class to icons

* fix(packages/shared): wrap width, height & size in isDefined

* Update types.ts

* fix(packages/svelte): do not pass propsClass to mergeClasses

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2026-09-04 16:38:01 +02:00
Eric FennisCopilot Autofix powered by AIcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
07a2c792ef chore(lucide-react): Add Lucide React integration tests (#4804)
* Add Lucide React integration tests

* Apply batched suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Remove redundant icon comparison test

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* test(lucide-react): fix browser locator markup assertions

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-09-04 16:26:02 +02:00
Swastik Sharmagithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Eric FennisKarsa
93a1d72465 feat(icons): added dome icons (#4261)
* feat(icons): add dome and dome-2 icon

* Update icons/dome.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update icons/dome-2.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore(icons): updare contributors for dome icons

* refactor(icons): remove dome-2 and keep the best design as dome

* chore(icons): update categories for dome icon

* feat(icons/dome): replaced design with compliant and linted version

* Update dome.json

* Update dome.json

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-09-04 15:07:48 +02:00
Ricardo GonzalezCopilot Autofix powered by AIgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Karsa
83ba4986c8 feat(icons): added equal-approximately-not icon (#4802)
* feat(icons): added `equal-approximately-not` icon (closes #4800).

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Update icons/equal-approximately-not.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update icons/equal-approximately-not.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update icons/equal-approximately-not.json

Co-authored-by: Karsa <contact@karsa.org>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-09-04 15:06:43 +02:00
Karsa 65271a11e7 feat(icons): added circle-dashed-check icon (#4796)
* Added icons/circle-dashed-check.svg

* Added icons/circle-dashed-check.json
2026-09-04 15:04:53 +02:00
90567c4ce0 feat(icons): added trash-off icon (#4788)
* feat(icons): added `trash-2-off` icon

Fixes #4750

Signed-off-by: Liang Xu <lx3133584@users.noreply.github.com>

* fix(icons): update trash-2-off design and align metadata with trash-2

- Update SVG paths to eliminate gap and overlap violations
- Add full list of contributors from trash/trash-2
- Sync tags and categories with trash-2 and provide use-cases
- Clean up unrelated angular cache files

Signed-off-by: Liang Xu <lx3133584@users.noreply.github.com>

* refactor(icons): rename to trash-off, align use-cases and revert unrelated files

- Rename trash-2-off to trash-off
- Align use-cases with contributor guide recommendations
- Revert unintended changes to packages/angular cache files

Signed-off-by: Liang Xu <lx3133584@users.noreply.github.com>

---------

Signed-off-by: Liang Xu <lx3133584@users.noreply.github.com>
Co-authored-by: Liang Xu <lx3133584@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-09-04 14:38:21 +02:00
Samuel AlakeKarsagithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Karsa
4dc5b7ebae feat(icons): add gap-horizontal and gap-vertical (#4544)
* feat(icons): add gap-horizontal and gap-vertical

Adds two icons for the gap between items in a layout: facing brackets
with the gap itself marked between them.

The brackets are the container edges and the dot marks the space, which
is what distinguishes these from the align-* family — those show the
items and a guideline, these show only the space. Rails span 2-22,
matching align-horizontal-space-between's M3 2v20.

The dot uses the "M12 12h.01" zero-length path, the same idiom dice-*,
badge-percent and ~130 other icons use for a 2px dot.

* feat(icons): add gap-horizontal and gap-vertical

Adds two icons for the gap between items in a layout: two facing brackets
with a dashed line marking the space between them.

Redesigned from the earlier dot version per review on #4544. This uses
the square-centerline-dashed-horizontal / -vertical construction with the
bracket ends flipped inward, so the brackets read as the two item edges
and the dashed line as the gap. Avoids the small-circle dot that the
earlier version relied on.

Co-Authored-By: Karsa <17746067+karsa-mistmere@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: Karsa <17746067+karsa-mistmere@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-04 14:05:55 +02:00
KarsaandJakob Guddas a87bc9b15b fix(icons): deprecated swiss franc icons (#4799)
* fix(icons): deprecated swiss franc icons & refined icon deprecation reasons

* Update tools/build-icons/utils/deprecationReasonTemplate.ts

Co-authored-by: Jakob Guddas <github@jguddas.de>

* fix(icons): replace icon.obsolete => icon.use-case

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
2026-09-04 14:04:24 +02:00
Karsa f96d09cf3a fix(site): fix HomeHeroIconsCard.data.ts (trash-2 no longer exists) (#4805) 2026-09-04 13:52:41 +02:00
713b1fcd25 feat(docs): added better contribution guide (#4746)
* Add metadata information

* improve contribution

* feat(docs): added new contribution guide

* feat(docs): minor linting fix

* feat(docs): update dead link

* feat(docs): change layout, some stylistic change, et cetera

* feat(docs): alter metadata example layout

* feat(docs): update titles, split use case & tag guide

* feat(docs): finetune some design guide images & make

* feat(docs): finetune some design guide images & add icons to use case guide

* feat(docs): added ux writing instructions & proofread markdowns to match these guidelines

* feat(docs): updated design language / specification descriptions to better distinguish what is what

* feat(docs): updated design language / specification descriptions to better distinguish what is what

* feat(docs): changed some languages again

* fix(icons): add design principle do/dont about diagonal lines

* fix(icons): decrease blurriness of ideal pixel perfection pixel preview

* fix(icons): remove color from pixel perfection previews

* fix(icons): remove color from pixel perfection previews

* fix(icons): reword symmerical icon rule

* fix(icons): fix calendar design in density rule image

* fix(icons): slightly adjust centered stroke rule text

* Rename 'useCases' property to 'use-cases'

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Update allowed SVG elements in code conventions

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-09-04 12:24:52 +02:00
Karsa bca7e75a81 feat(icons): changed leaf icon (#4801) 2026-09-04 12:07:34 +02:00
Jakob Guddas 7f30808e30 Updated icons/trash.svg (#3141) 2026-09-04 12:06:01 +02:00
Eric Fennis 6f56b8f1f6 Create automatic release flow for lucide lab (#4792) 2026-09-04 10:18:54 +02:00
Karsa b1a94838ac Update bottle-toothbrush-comb.svg (#4756) 2026-09-03 17:30:23 +02:00
Eric Fennis ecccc7b963 Add label for lab icons (#4793) 2026-09-03 17:18:14 +02:00
3ccaafa69b feat(icons): added square-alert Icon (#3687)
* Add square alert icon

Introduces a new 'square-alert' icon with associated metadata and SVG file. The icon represents alert or warning notifications within a square shape.

* Reorder elements in square-alert.svg

Moved the <rect> element before the <path> elements to adjust the SVG structure. No visual changes to the icon.

* Add newline at end of square-alert.json

linting fix

* changed path to line

* Add missing contributors to square-alert.json

* Update square-alert.json

* docs(square-alert): add use cases

* refactor(icons): rename square-alert to square-exclamation-point

* fix: review comments

* Update icons/square-exclamation-point.json

* Update square-exclamation-point.json

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-09-03 16:35:59 +02:00
Jay ♠️andKarsa a744a40e23 feat(icons): add can-soda icon (#4718)
* feat(icons): add `can-soda` icon

* Update icons/can-soda.svg

Co-authored-by: Karsa <contact@karsa.org>

* fix(icons): fix my own gap issues 😅

---------

Co-authored-by: Karsa <contact@karsa.org>
2026-09-03 16:34:01 +02:00
Eric FennisandKarsa 20cc4c12b6 chore(copilot-reviews): Improve use-cases description. (#4558)
* Add metadata information

* Adjust the property name

* Remove this section

---------

Co-authored-by: Karsa <contact@karsa.org>
2026-09-03 15:19:40 +02:00
Karsa f1d4838196 feat(icons): added virus/virus-off icon (#4765)
* Added icons/virus.svg

* Added icons/virus.json

* feat(icons): added metadata to virus & virus-off
2026-09-03 11:31:06 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> bdb3684959 chore(deps): bump the vue-deps group with 2 updates (#4771)
Bumps the vue-deps group with 2 updates: [@vue/test-utils](https://github.com/vuejs/test-utils) and [vue](https://github.com/vuejs/core).


Updates `@vue/test-utils` from 2.4.11 to 2.5.0
- [Release notes](https://github.com/vuejs/test-utils/releases)
- [Commits](https://github.com/vuejs/test-utils/compare/v2.4.11...v2.5.0)

Updates `vue` from 3.5.41 to 3.5.42
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/compare/v3.5.41...v3.5.42)

---
updated-dependencies:
- dependency-name: "@vue/test-utils"
  dependency-version: 2.5.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: vue-deps
- dependency-name: vue
  dependency-version: 3.5.42
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: vue-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-03 11:29:53 +02:00
Karsa 85b455c323 feat(icons): fixed germ & germ-off (#4789)
* Update germ.svg

* Update germ-off.svg
2026-09-03 11:23:06 +02:00
Benjamin Haubegithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Eric Fennis
d72697aeab feat(icons): added 'engine' icon (#4598)
* Add icons/engine

* fix(icons): changed 'engine' icon

* Apply suggestions from code review

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update engine.svg

* Add contributor 'jamiemlaw' to engine.json

* Apply suggestion from @github-actions[bot]

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-03 11:22:41 +02:00
431af7618e feat(icons): added credit-card-reader icon (#4616)
* Added icons/credit-card-reader.svg

* Added icons/credit-card-reader.json

* Updated icons/credit-card-reader.json

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Updated icons/credit-card-reader.svg

* Updated icons/credit-card-reader.json

* Update credit-card-reader.json

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-09-03 11:03:06 +02:00
Jakob Guddasgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Karsa
7a3df42d5a feat(icons): added door-stairwell icon & updated door-* icons (#3554)
* Added icons/stairwell.svg

* Added icons/stairwell.json

* Update icons/stairwell.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Updated icons/stairwell.svg

* Updated icons/stairwell.json

* Update icons/stairwell.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Updated icons/door-closed.svg

* Updated icons/door-open.svg

* Update door-closed-locked.svg

* Update door-closed.svg

* Update door-open.svg

* Update and rename stairwell.svg to door-stairwell.svg

* Update and rename stairwell.json to door-stairwell.json

* Update door-stairwell.json

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-09-03 10:58:41 +02:00
6022cf9878 feat(icons): Add new icons germ and germ-off (#4056)
* add new icons  and

* Fix SVG path data for virus-off icon

* renamed virus to germ, implemented feedback

* Refactor SVG paths for consistency and clarity

* Update germ.json

* Update germ-off.json

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
Co-authored-by: Karsa <contact@karsa.org>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2026-09-03 10:52:29 +02:00
Xouguigithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>KarsaEric Fennis
d771617ede feat(icons): added lighthouse icon (#4507)
* feat: add lighthouse icon

* use case

* Update icons/lighthouse.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update icons/lighthouse.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update icons/lighthouse.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* icon change

* updated use cases to match guide

* Update lighthouse.json

* Update lighthouse.svg

* Update lighthouse.svg

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2026-09-03 10:48:39 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> c711d5990c chore(deps): bump softprops/action-gh-release (#4781)
Bumps the github-actions group with 1 update: [softprops/action-gh-release](https://github.com/softprops/action-gh-release).


Updates `softprops/action-gh-release` from 3.0.2 to 3.0.3
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/3d0d9888cb7fd7b750713d6e236d1fcb99157228...efb35369e0ad2afab669f228072c1b0d510eae64)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 3.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-03 10:39:38 +02:00
Ethan Hazel dce50dd0c9 fix(docs): updated artboard name on illustrator template (#4724) 2026-09-01 17:01:16 +02:00
32703fc21a feat(icons): added shopping-cart-plus & shopping-cart-minus icons (#4248)
* Added icons/shopping-cart-plus.svg

* Added icons/shopping-cart-plus.json

* feat(icons): add shopping-cart variants

Updated the base shopping-cart icon and added the plus and minus variants to satisfy the request in issue #1746. All icons have been redesigned to stay consistent with each other, adhering to the official Lucide contribution guidelines.

Closes #1746
Base icon design is related to PR #2909

* fix(icons): update shopping-cart variants

* feat(metadata): simplify search tags for shopping-cart variants

* Update shopping-cart.json

* Update shopping-cart-minus.svg

* Update shopping-cart-plus.svg

* Update shopping-cart-plus.json

* Update shopping-cart-minus.json

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
Co-authored-by: Karsa <contact@karsa.org>
2026-09-01 16:44:59 +02:00
Jakob Guddasgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Copilot Autofix powered by AIKarsaEric Fennis
5c7c083e56 feat(icons): added shrimp-off icon (#3613)
* Added icons/shrimp-off.svg

* Added icons/shrimp-off.json

* Update icons/shrimp-off.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Updated icons/shrimp.svg

* Updated icons/shrimp-off.svg

* Apply suggestion from @jguddas

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Update shrimp-off.json

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Update icons/shrimp-off.json

Co-authored-by: Karsa <contact@karsa.org>

* Update shrimp.json

* Update shrimp-off.json

* Update shrimp-off.json

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2026-09-01 16:39:50 +02:00
c646eea633 feat(icons): added bridge icon (#3949)
* Added icons/bridge.svg

* Added icons/bridge.json

* Replace icon design with jamiemlaw's design from issue #3364

* Add jamiemlaw as a contributor and tags to bridge.json

* Apply suggestion from @karsa-mistmere

Co-authored-by: Karsa <contact@karsa.org>

* Add empty use-cases array to bridge.json

* Update bridge.json

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-09-01 15:39:43 +02:00
LouisandKarsa 066f42db8b feat(icons): added can icon (#4767)
* can icon

* cleaned using lucide studio

* added use cases and tags

* Update can.svg

* Update can.json

---------

Co-authored-by: Karsa <contact@karsa.org>
2026-09-01 15:35:33 +02:00
eaace8a81b feat(icons): Add mail-pen icon (#4399)
* Add mail pen icon

* Update icons/mail-pen.svg

Co-authored-by: Karsa <contact@karsa.org>

* Update mail-pen.svg

* Update mail-pen.json

Added contributors from mail & missing metadata

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-09-01 15:33:18 +02:00
2119ad0eb1 feat(icons): add whistle icon (#3006)
* added icons/whistle.svg

* updated icons/whistle.svg

* updated whistle-icon

* Fix indentation

* Update whistle icon from karsa

* Update whistle.json

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Update whistle.json

---------

Co-authored-by: timmy471 <timilehin.ayantunji@etranzact.com>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-09-01 15:33:00 +02:00
Karsa c5a83d26ff fix(icons): added RWD metadata to monitor, tablet & smartphone icons (#4775) 2026-09-01 09:09:51 +02:00
eb3c04d059 feat(icons): Add polygon icon (#3007)
* Add icons/polygon.svg

* Applied code from jguddas

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* extended metadata in polygon.json

* Rename polygon.json to vector-polygon.json

* Rename polygon.svg to vector-polygon.svg

* Update icons/vector-polygon.svg

* Update vector-square.svg

---------

Co-authored-by: timmy471 <timilehin.ayantunji@etranzact.com>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-08-31 09:15:36 +02:00
Amenitigithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Karsa
796dad298f feat(icons): added credit-card-plus icon (#4441)
* Added icons/credit-card-plus.svg

* Added icons/credit-card-plus.json

* Update icons/credit-card-plus.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update credit-card-plus.svg

updated + sub as used in other icons

* Update credit-card-plus.svg

* Update credit-card-plus.json

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-08-29 09:13:34 +02:00
Amenitigithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Karsa
3f4a337c5d feat(icons): added credit-card-minus icon (#4440)
* Added icons/credit-card-minus.svg

* Added icons/credit-card-minus.json

* Update icons/credit-card-minus.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update credit-card-minus.json

* Update credit-card-minus.json

Changed contributors based on credit-card

* Update credit-card-minus.svg

Updated to use "-" based of other icons using minus sign.

* Update credit-card-minus.svg

* Update credit-card-minus.json

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-08-29 09:13:23 +02:00
Karsa 47ad47f321 feat(icons): added credit-card-x & credit-card-check icon (#4763)
* Added icons/credit-card-x.svg

* Added icons/credit-card-x.json

* Added icons/credit-card-check.svg

* Added icons/credit-card-check.json

* Update credit-card-x.json

* Update credit-card-check.json
2026-08-29 09:13:22 +02:00
Karsa c967b3225c fix(icons): changed piano icon (#4766)
* Updated icons/piano.svg

* Updated icons/piano.json

* Update piano.json
2026-08-28 22:23:07 +02:00
Ali Yasir Naçgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Jakob GuddasKarsa
0516a35c56 feat(icons): added message-circle-dashed-check icon (#3678)
* Added icons/message-circle-tick-dashed.svg

* Added icons/message-circle-tick-dashed.json

* Update icons/message-circle-tick-dashed.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* renamed file names

* Update message-circle-dashed-check.svg

* Update message-circle-dashed-check.svg

replaces paths to use the exact same ones as in `message-circle-dashed`

* Update message-circle-dashed-check.json

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jakob Guddas <github@jguddas.de>
Co-authored-by: Karsa <contact@karsa.org>
2026-08-28 15:01:56 +02:00
KarsaandEric Fennis 48fb4d0079 fix(icons): unify check, cross and plus sizes across icons (#3875)
* fix(icons): unify check, cross and plus sizes across icons

* fix(icons): fix minor gap issues

* fix(icons): shrink x in git-merge-conflict

* fix(icons): adjust x to be aligned with matching plus in book-x, grid-2x2-x and user-round-x

* fix(icons): update checkmark in message-circle-check.svg

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2026-08-28 15:01:54 +02:00
Jakob Guddasgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Karsa
672d891a6b fix(icons): changed asterisk icon (#3906)
* Updated icons/asterisk.svg

* Updated icons/asterisk.json

* Updated icons/asterisk.svg

* Update icons/asterisk.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Updated icons/asterisk.svg

* Updated icons/asterisk.json

* Update asterisk.json

* Refactor SVG paths in asterisk icon

* Update paths in asterisk.svg for new design

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-08-28 14:22:36 +02:00
Jakob Guddas d8a7841d33 fix(icons): changed square-split-vertical icon (#3939)
* Updated icons/square-split-horizontal.svg

* Updated icons/square-split-horizontal.json

* Updated icons/square-split-vertical.svg

* Updated icons/square-split-vertical.json
2026-08-28 14:22:08 +02:00
716ae6d4e9 fix(icons): rotate key icon (#3111)
* Updated icons/key.svg

* Updated icons/key.json

* Update icons/key.svg

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Add space before close key.svg

* Updated icons/key.svg

* Updated icons/key.json

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-08-28 14:17:48 +02:00
Jakob Guddas cd6ee554c8 fix(icons): rotate blend icon (#3105)
* Updated icons/blend.svg

* Updated icons/blend.json

* Updated icons/blend.json
2026-08-28 14:17:15 +02:00
Jakob Guddas be0956479b fix(icons): changed panda icon (#3187)
* Updated icons/panda.svg

* Updated icons/panda.json

* Updated icons/panda.svg
2026-08-28 12:36:34 +02:00
Jakob GuddasandKarsa 9f3692dee3 chore(tags): added music disc related tags to circle-dot (#3909)
* Updated icons/circle-dot.svg

* Updated icons/circle-dot.json

---------

Co-authored-by: Karsa <contact@karsa.org>
2026-08-28 12:25:29 +02:00
Jakob Guddasdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Eric Fennis
af82050077 fix(icons): changed beef icon (#3457)
* ci: Improve build speeds (#2778)

* Revert sync to async functions

* Replace more sync fs functions

* Format files

* Fix build svelte package

* build(deps): bump esbuild from 0.19.12 to 0.25.0 (#2791)

Bumps [esbuild](https://github.com/evanw/esbuild) from 0.19.12 to 0.25.0.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG-2024.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.19.12...v0.25.0)

---
updated-dependencies:
- dependency-name: esbuild
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps-dev): bump vite from 5.1.8 to 5.4.12 (#2786)

Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.1.8 to 5.4.12.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.12/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.12/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps-dev): bump vite from 5.4.12 to 5.4.13 (#2798)

Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.12 to 5.4.13.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.13/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.13/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix: Add await to checkIconsAndCategories script

* fix(lucide-react): Revert exports property package.json, fixing edge worker environments. (#2814)

* Revert exports prop

* Adjust export

* Adjust export path

* Add to gitignore

* Adjust build process

* Update .gitignore and add dynamicIconImports module

* Formatting

* refactor: Optimize readAllMetadata function to use Promise.all for concurrent metadata reading

* refactor(scripts): Formatting in readAllMetadata

* Updated icons/beef.svg

* Updated icons/beef.svg

* Updated icons/beef.json

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-28 12:21:38 +02:00
50de1605e1 feat(icons): add playing-card, playing-cards, and playing-cards-fan (#4258)
* Added icons `playing-card`, `playing-cards`, `playing-cards-2`

* updated playing card icons according to @karsa-mistmere

* updated playing card icons according to @karsa-mistmere

* added `playing-cards-fan` icon from @karsa-mistmere

* fix(metadata): add missing use-cases for playing card icons

* Update playing-card.json

* Update playing-cards-fan.json

* Update playing-cards.json

* Update playing-cards.svg

* Update playing-cards-fan.svg

* Update playing-card.svg

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-08-28 11:29:51 +02:00
TFJandKarsa 56b50bba8a docs(icon-description): added old and empty tags/use case for ghost (#4762)
* chore: added old and empty tags/use case for ghost

* chore: added dead use-case

Co-authored-by: Karsa <contact@karsa.org>

* chore: applied tags

Co-authored-by: Karsa <contact@karsa.org>

---------

Co-authored-by: Karsa <contact@karsa.org>
2026-08-28 10:47:13 +02:00
bd4cdc5f39 fix(icons): changed shopping-cart icon (#2909)
* Updated icons/shopping-cart.svg

* Updated icons/shopping-cart.json

* Updated icons/shopping-cart.svg

* Update icons/shopping-cart.svg

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-08-28 09:16:41 +02:00
Jakob GuddasandKarsa fb617bfd6e fix(icons): changed swords icon (#4707)
* Updated icons/swords.svg

* Updated icons/swords.json

* Update swords.json

* Updated icons/swords.svg

* Updated icons/swords.json

* Update swords.json

* Update sword.svg

* Update sword.json

* Update swords.json

---------

Co-authored-by: Karsa <contact@karsa.org>
2026-08-28 09:11:17 +02:00
Karsa 50eacd724a feat(icons): make face-angry yet more angry (#4708) 2026-08-28 09:09:18 +02:00
Benjamin HaubeandKarsa 06e26d6ff1 feat(icons): added 'robot-vacuum' icon (#4599)
* add icons/robot-vacuum

* fix(icons): changed 'robot-vacuum' icon

* Update robot-vacuum.json

* Update robot-vacuum.svg

---------

Co-authored-by: Karsa <contact@karsa.org>
2026-08-28 09:07:35 +02:00
517 changed files with 22305 additions and 10229 deletions
+65 -1
View File
@@ -15,6 +15,70 @@ The `tags` property is an array of strings that describe the icon and can be use
Validate the tags against the `icon.schema.json` to ensure they are correctly formatted and adhere to the defined structure.
Provide tag suggestions based on the name of the icon and the use cases provided in the PR description. Use the existing tags in the repository as a reference for consistency and to avoid duplicates. Don't suggest words like: 'icon' and preferably use single words. Tags should always be in lowercase, and may also contain spaces (e.g. `magnifying glass`). The name of icon should not be included in the tags, as it is already specified.
# Categories
## Categories
The `categories` property is an array of strings that specify the categories to which the icon belongs, such as "devices", "interface", "media", etc. See the `categories` property in the `icon.schema.json` for more details on the allowed values. The categories should be chosen based on the use cases provided in the PR description and the existing categories in the repository. The categories should be relevant to the icon and should help users find the icon when searching for specific types of icons. The name of icon should not be included in the categories, as it is already specified. Suggest categories based on the name of the icon and the use cases provided in the PR description. Use the existing categories in the repository as a reference for consistency and to avoid duplicates. Categories should always be in lowercase and should not contain spaces.
## Use Cases
The `use-cases` property is an array of strings that describe the specific scenarios in which the icon would be used. Each use case should be concise and clearly convey the context in which the icon is applicable. Use the existing use cases in the repository as a reference for consistency and to avoid duplicates.
### Writing icon use-cases
A use-case tells a reader **where and why an icon would be used in a real interface**. Each entry should let someone who has never seen the icon understand what it's for.
### Format
- Write each use-case as a short phrase, not a sentence. Start with a present participle verb: *Representing…*, *Indicating…*, *Marking…*, *Showing…*, *Confirming…*, *Toggling…*, *Categorizing…*, *Searching…*.
- Keep it to roughly 4–12 words. One clear idea per entry.
- No trailing period. No leading bullet, number, or dash (the surrounding format supplies that).
- Give each icon 1–4 use-cases, ordered most-common first. Prefer fewer strong entries over many weak or repetitive ones.
### Voice
- Write from the interface's perspective, describing the function: "Indicating a low battery charge level" — not the requester's story ("I need an icon that shows…").
- Name the concrete context where useful: *in smart home apps*, *in navigation apps*, *in text editors*, *on maps*. Context is what makes a use-case self-explanatory.
- Be neutral and factual. No first person, no marketing adjectives ("perfect for", "ideal", "beautiful"), no emoji.
### What to exclude
- **The requester's personal narrative.** "I'm building a SvelteKit UI and need…" → drop the framing, keep the function.
- **References to other issues, PRs, or icons by ID.** No "As provided in #1865", "complementary to git-branch-plus", "same as above", "see #2055".
- **Design/implementation chatter.** Bezier offsets, grid alignment, path cuts, "the icon works perfectly" — none of that is a use-case.
- **Restating the icon's name.** For `microchip`, "microchip" is not a use-case; describe what it represents ("Representing processors, chips, or embedded hardware").
- **Links, image tags, emoji, and markdown artifacts.**
- **Meta-commentary.** "Self-explanatory", "lots and lots of use cases", "obvious :)".
### Cross-contamination
When a request covers several icons at once, assign each use-case only to the icon it actually describes. A bullet prefixed with another icon's name belongs to that icon, not this one. Don't let `briefcase-medical`'s meanings leak into `briefcase-business`.
### Variants
Related icons should get **variant-specific** wording, not one shared blurb. `battery-low` → "Indicating a low battery charge level"; `battery-full` → "…full…". `square-arrow-right-enter` → sign in / join; `-exit` → sign out / export. Resist copying the same line across a family.
### Deriving from source material
When mining descriptions, comments, or linked issues:
- Prefer the **stated purpose** over the backstory. Extract the function, discard the anecdote.
- If a source lists genuinely distinct uses, keep them as separate entries; if it repeats one idea five ways, collapse to one.
- Merge an intro line with its bullets ("To represent:" + "pottery" → "Representing pottery").
- If the only signal is noise (a name restatement, a link, "thanks!"), leave the icon without a use-case rather than inventing one.
- Never fabricate a use-case that isn't supported by the icon's meaning or the source.
## Examples
Good:
- `ambulance` → "Directing users to nearby emergency services in navigation apps"
- `calendar-sync` → "Representing recurring events, promotions, or limited-time offers"
- `globe-x` → "Indicating a device or application is offline or unreachable"
- `heading-2` → "Applying a level-2 heading in text editors"
Poor → fixed:
- ~~"I need a firewall icon :-)"~~ → "Representing firewalls and firewall rules on cybersecurity platforms"
- ~~"As above"~~ → "Signifying a deal, agreement, or partnership"
- ~~"microchip"~~ → "Representing processors, chips, or embedded hardware"
- ~~"Same use cases as the other currency symbols, except Turkish lira"~~ → "Displaying prices or amounts in Turkish lira"
@@ -0,0 +1,587 @@
---
applyTo: "docs/*.md"
---
# UX writing guidelines
Follow these guidelines when writing or editing Lucide documentation, especially Markdown files.
Write for people who are trying to understand a concept, follow a specification, or complete a task. Prioritize clarity, precision, and scannability over personality or decorative prose.
## Be direct and concise
State the important information first. Remove words that do not add meaning.
Prefer short sentences and paragraphs, but do not sacrifice precision just to make text shorter.
**Do:**
> Icons must use a 24 × 24 pixel canvas.
**Don't:**
> When creating a new icon, you should make sure that the canvas you're working with has dimensions of 24 × 24 pixels.
Avoid unnecessary introductions such as:
- "It's important to note that…"
- "Keep in mind that…"
- "As you can see…"
- "In order to…"
- "It should be noted that…"
State the information directly instead.
## Put the rule before the explanation
When documenting a requirement or recommendation, state it before explaining why it exists.
**Do:**
> Keep at least 1 pixel of space between unrelated elements. This prevents shapes from visually merging at small sizes.
**Don't:**
> Because shapes can visually merge at small sizes, it's important to make sure that unrelated elements have enough space between them.
This makes documentation easier to scan and makes normative requirements easier to identify.
## Explain the reason when it adds value
Explain *why* a rule exists when the reasoning helps contributors apply it to situations that are not explicitly documented.
Do not merely restate the rule.
**Do:**
> Avoid simulated fills. They don't scale consistently with the rest of the icon set.
**Don't:**
> Avoid simulated fills because simulated fills should not be used.
Reasoning is particularly useful for design rules where contributors may need to evaluate unusual cases.
## Use scannable structure
Assume readers will scan the page before reading it in detail.
Use:
- descriptive headings
- short paragraphs
- lists for sets of related items
- examples for rules that benefit from demonstration
- **bold** for important terms or short emphasis
- code formatting for filenames, properties, commands, values, and identifiers
Avoid long uninterrupted blocks of text.
Headings should communicate the subject or rule without requiring the surrounding text for context.
**Do:**
> ## Keep 1 pixel of safe space
**Don't:**
> ## Spacing
## Use sentence case
Use sentence case for:
- page titles
- headings
- table headings
- labels
- example captions
Capitalize proper nouns and branded terms normally.
**Do:**
> ## Use consistent corner radii
**Don't:**
> ## Use Consistent Corner Radii
## Address the reader directly
Use **you** and **your** when referring to something the reader does.
**Do:**
> If your icon contains overlapping shapes, simplify the hidden geometry.
Avoid referring to the reader as "the user," "the contributor," or other third-person terms when direct language is more natural.
However, prefer an imperative when the subject is obvious.
**Prefer:**
> Keep related elements visually grouped.
**Over:**
> You should keep related elements visually grouped.
## Use "we" only when it means the Lucide project or maintainers
First-person plural is acceptable when describing an intentional project decision, convention, or policy.
**Do:**
> We use `kebab-case` for icon names.
> We generally avoid adding brand logos to Lucide.
Do not use "we" merely to make documentation conversational.
**Prefer:**
> Icons use a 2 pixel stroke.
**Over:**
> We use a 2 pixel stroke for our icons.
## Use normative language consistently
Use specific language to communicate how strictly a rule applies.
- **must** — required; violating this is not acceptable
- **must not** — prohibited
- **should** — recommended; exceptions may be appropriate
- **should not** — discouraged; exceptions may be appropriate
- **can** — possible or permitted
- **may** — optional or dependent on context
Do not use **should** when something is actually required.
**Do:**
> Icons must use a 24 × 24 pixel canvas.
**Don't:**
> Icons should use a 24 × 24 pixel canvas.
Avoid vague substitutes such as "ideally," "normally," or "preferably" when a more precise normative term applies.
## Prefer active voice
Use active voice unless passive voice makes the subject clearer or avoids unnecessary repetition.
**Do:**
> Align nodes to the pixel grid.
**Don't:**
> Nodes should be aligned to the pixel grid.
Passive voice is acceptable when the actor is irrelevant.
> Deprecated icons are removed in major releases.
## Use positive instructions when possible
Tell readers what to do rather than only what not to do.
**Do:**
> Use a single continuous path when the elements form one continuous shape.
**Less useful:**
> Don't split continuous shapes into unnecessary paths.
Use negative instructions when the prohibition itself is important.
> Don't use simulated fills.
## Be precise about consequences
When explaining why something should or should not be done, describe the actual consequence rather than using vague warnings.
**Do:**
> Keep unrelated elements at least 2 pixels apart. Smaller gaps can disappear when the icon is rendered at small sizes.
**Don't:**
> Be careful when placing elements too close together.
Avoid language that exaggerates consequences or attempts to influence a contributor's decision emotionally.
## Prefer concrete language
Use specific terms instead of vague references.
**Do:**
> The two endpoints must remain inside the 1 pixel safe zone.
**Don't:**
> These should stay within the appropriate area.
Avoid ambiguous references such as:
- this
- that
- it
- things
- stuff
- appropriate
- proper
- correct
when the intended subject can be named directly.
## Introduce terminology before relying on it
Define Lucide-specific or technical terms when readers may not already know them.
Once defined, use the same term consistently.
**Do:**
> The **safe zone** is the 1 pixel area between the icon artwork and the canvas boundary.
Do not alternate between different terms for the same concept unless the distinction is intentional.
For example, don't alternate between "safe zone," "padding," and "margin" if they refer to the same rule.
## Use abbreviations sparingly
Spell out uncommon abbreviations on first use.
> Scalable Vector Graphics (SVG)
Common technical abbreviations such as HTML, CSS, SVG, API, and URL do not need to be expanded when the intended audience can reasonably be expected to know them.
Avoid Latin abbreviations such as:
- e.g.
- i.e.
- etc.
Prefer:
- for example
- that is
- and so on
## Use examples deliberately
Use examples when they clarify how to apply a rule.
Keep examples focused on the rule being demonstrated. Avoid introducing unrelated differences that make the comparison harder to understand.
When contrasting examples, use **Do** and **Don't** consistently.
**Do:**
> Use one path for a continuous outline.
**Don't:**
> Split a continuous outline into several overlapping paths.
The explanatory text should describe the principle, not merely narrate what is visible in the example.
## Use links descriptively
Link text should describe the destination or concept.
**Do:**
> See the [Icon Design Specification](./specification) for exact dimensions and spacing requirements.
**Don't:**
> For more information, [click here](./specification).
Avoid generic link text such as:
- click here
- here
- this page
- learn more
when a descriptive label is possible.
## Avoid unnecessary repetition
Do not repeat information already established by a heading, example, or immediately preceding sentence.
**Prefer:**
> ## Keep 1 pixel of safe space
>
> Keep all artwork within the 22 × 22 pixel live area.
**Over:**
> ## Keep 1 pixel of safe space
>
> When designing an icon, you should keep 1 pixel of safe space around the icon.
Cross-reference another section instead of duplicating detailed rules that already have a canonical explanation.
## Use contractions in prose
Use natural contractions such as:
- don't
- can't
- isn't
- it's
- you'll
They make explanatory prose less formal and easier to scan.
Use uncontracted forms when deliberate emphasis is useful.
> Do not change existing icon geometry solely to reduce the number of SVG nodes.
Normative statements using **must not** should not be contracted.
## Use the serial comma
Use the serial (Oxford) comma in lists of three or more items.
**Do:**
> Check the icon's size, stroke width, and spacing.
**Don't:**
> Check the icon's size, stroke width and spacing.
## Use punctuation normally in prose
Use periods for complete sentences.
Periods may be omitted from:
- headings
- short labels
- short list items that are not complete sentences
- captions consisting only of a short phrase
Be consistent within a list.
If list items are complete sentences, end them with periods. If they are fragments, generally omit periods.
## Skip colons in headings
Do not end headings with colons.
**Do:**
> ## Naming conventions
**Don't:**
> ## Naming conventions:
Use a colon normally when introducing a list or explanation in body text.
## Use exclamation points sparingly
Avoid exclamation points in technical documentation unless the context genuinely calls for excitement or celebration.
**Prefer:**
> Your first icon is ready.
**Over:**
> Your first icon is ready!
Do not use exclamation points to make instructions sound friendlier.
## Use ellipses only when they have meaning
Use an ellipsis (`…`) to represent omitted content or an intentionally incomplete statement.
Do not use ellipses decoratively or to make prose sound conversational.
When documenting literal UI text, preserve the punctuation used by the interface.
## Use parentheses for definitions and compact clarification
Use parentheses when they make a definition, abbreviation, or short clarification easier to understand.
> Scalable Vector Graphics (SVG)
Avoid using parentheses for long side notes. Rewrite important information as part of the sentence or as a separate sentence.
## Prefer "and" over ampersands
Use **and** in normal prose.
**Do:**
> Naming and metadata
**Avoid:**
> Naming & metadata
Use an ampersand only when it is part of an official name, literal UI text, code, or another established term.
## Avoid em dashes
Prefer commas, periods, colons, or parentheses when they produce a simpler sentence.
**Prefer:**
> This rule has one exception: existing legacy icons.
**Avoid:**
> This rule has one exception — existing legacy icons.
Use an en dash (`–`) without surrounding spaces for ranges.
> 1–3 pixels
> A–Z
Do not substitute a hyphen for an en dash in prose ranges unless required by a technical syntax.
## Use hyphens correctly
Hyphenate compound modifiers when necessary for clarity.
> 24 × 24 pixel canvas
> 2-pixel-wide gap
> pixel-aligned element
Do not hyphenate a phrase when it functions as a verb.
> Sign off on the design.
> Complete the sign-off.
Do not add hyphens mechanically when the meaning is already clear.
## Use code formatting consistently
Use backticks for literal technical values and identifiers, including:
- filenames and paths
- commands
- package names
- properties and attributes
- icon names
- code values
- SVG elements and attributes
**Do:**
> Add `camera-off` as an alias.
> Set `stroke-width` to `2`.
> Edit `icons/camera.svg`.
Do not use code formatting merely for emphasis.
## Use bold for semantic emphasis
Use **bold** sparingly to highlight a term or distinction that helps readers scan the page.
Do not bold entire sentences or paragraphs.
Prefer bold over italics for general emphasis.
Use *italics* only when conventional, such as when referring to a term as a term or when a specific distinction benefits from it.
## Don't use all caps for emphasis
Do not use blocks of uppercase text for emphasis.
**Don't:**
> NEVER place nodes outside the canvas.
**Do:**
> **Never** place nodes outside the canvas.
Preserve capitalization when documenting literal identifiers or established technical terms.
## Keep lists parallel
Items in the same list should use the same grammatical structure.
**Do:**
- Use a 24 × 24 pixel canvas
- Keep 1 pixel of safe space
- Use a 2 pixel stroke
- Align nodes to the pixel grid
**Don't:**
- Use a 24 × 24 pixel canvas
- Safe space should be 1 pixel
- A 2 pixel stroke
- Nodes are aligned to the pixel grid
Parallel structure makes rules easier to scan and compare.
## Avoid unnecessary filler and enthusiasm
Lucide documentation should sound helpful and confident, not promotional.
Avoid filler such as:
- "Simply…"
- "Just…"
- "Obviously…"
- "Of course…"
- "Easy…"
- "Luckily…"
- "Don't worry…"
These words can be inaccurate or dismissive when the task is not simple for the reader.
Also avoid marketing language such as:
- "powerful"
- "seamless"
- "effortless"
- "amazing"
- "best-in-class"
unless the word communicates a specific, verifiable distinction.
## Prefer timeless documentation
Avoid wording tied unnecessarily to the current state of development.
**Prefer:**
> Lucide supports custom icon aliases.
**Avoid:**
> Lucide now supports custom icon aliases.
Use time-sensitive language only when the timing itself matters, such as migration notes, deprecations, or release documentation.
## Preserve established Lucide terminology
When editing existing documentation, preserve established Lucide terminology and naming conventions unless there is a clear reason to change them.
Do not invent synonyms merely to avoid repetition. Consistency is more important than stylistic variety in technical documentation.
When terminology differs between the Lucide codebase, API, UI, and documentation, prefer the term used by the relevant canonical specification.
+5
View File
@@ -30,6 +30,11 @@
- any-glob-to-any-file:
- 'icons/*.svg'
🔬 Lab icon:
- changed-files:
- any-glob-to-any-file:
- 'lab/*.svg'
# For changes in the lucide package
🧳 lucide package:
- changed-files:
+1 -1
View File
@@ -102,7 +102,7 @@ jobs:
echo '${{ steps.change-log.outputs.CHANGE_LOG }}'
- name: Create Release
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
with:
tag_name: ${{ steps.new-version.outputs.NEW_VERSION }}
name: Version ${{ steps.new-version.outputs.NEW_VERSION }}
+1
View File
@@ -3,6 +3,7 @@ name: Lucide Lab checks
on:
pull_request:
paths:
- lab/**
- packages/lab/**
- packages/shared/**
- tools/build-icons/**
+22
View File
@@ -7,10 +7,13 @@ on:
pull_request:
paths:
- packages/lucide-react/**
- integrations/lucide-react/**
- packages/shared/**
- tools/build-icons/**
- tools/rollup-plugins/**
- scripts/generateNextJSAliases.mjs
- package.json
- pnpm-workspace.yaml
- pnpm-lock.yaml
permissions:
@@ -48,3 +51,22 @@ jobs:
- name: Test
run: pnpm --filter lucide-react test
integration:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
cache: 'pnpm'
node-version-file: 'package.json'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Install Chromium
run: pnpm --filter @lucide/integration-react-vite exec playwright install --with-deps chromium
- name: Run integration checks
run: pnpm test:integrations:react
+146
View File
@@ -0,0 +1,146 @@
name: Release @lucide/lab
on:
push:
branches:
- main
paths:
- lab/**/*.svg
workflow_dispatch:
inputs:
release-type:
description: Release type
required: true
default: 'minor'
type: choice
options:
- patch
- minor
- major
permissions: {}
jobs:
create-release:
if: github.repository == 'lucide-icons/lucide'
runs-on: ubuntu-latest
permissions:
contents: write # Required to create the release and tag
outputs:
VERSION: ${{ steps.new-version.outputs.NEW_VERSION }}
SHOULD_RELEASE: ${{ steps.release-notes.outputs.SHOULD_RELEASE }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # Required to diff the lab icons against the previous tag
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
cache: 'pnpm'
node-version-file: 'package.json'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Get latest tag
id: latest-tag
run: |
LATEST_TAG=$(git tag --list '@lucide/lab@*' --sort=-v:refname | head -n 1)
if [ -z "$LATEST_TAG" ]; then
echo "::error::No @lucide/lab@* tag found to release from."
exit 1
fi
echo "Latest tag: $LATEST_TAG"
echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_OUTPUT
- name: Create new version
id: new-version
run: |
NEW_VERSION=$(pnpm semver "${LATEST_TAG#@lucide/lab@}" -i "$RELEASE_TYPE")
echo "New version: $NEW_VERSION"
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT
env:
LATEST_TAG: ${{ steps.latest-tag.outputs.LATEST_TAG }}
RELEASE_TYPE: ${{ inputs.release-type || 'minor' }}
- name: Generate release notes
id: release-notes
run: |
NEW_TAG="@lucide/lab@$NEW_VERSION"
ADDED=$(git diff --name-only --diff-filter=A "$LATEST_TAG" HEAD -- 'lab/*.svg' \
| xargs -r -n1 basename | sed 's/\.svg$//' | sort)
REMOVED=$(git diff --name-only --diff-filter=D "$LATEST_TAG" HEAD -- 'lab/*.svg' \
| xargs -r -n1 basename | sed 's/\.svg$//' | sort)
if [ -z "$ADDED" ] && [ "$EVENT_NAME" != 'workflow_dispatch' ]; then
echo "::notice::No icons were added to ./lab since $LATEST_TAG, skipping release."
echo "SHOULD_RELEASE=false" >> $GITHUB_OUTPUT
exit 0
fi
{
if [ -n "$ADDED" ]; then
printf '## New icons\n\n'
printf '%s\n' "$ADDED" | sed 's|.*|- `&`|'
printf '\n'
fi
if [ -n "$REMOVED" ]; then
printf '## Removed icons\n\nThese graduated to the core icon set.\n\n'
printf '%s\n' "$REMOVED" | sed 's|.*|- `&`|'
printf '\n'
fi
printf '**Full changelog**: https://github.com/lucide-icons/lucide/compare/%s...%s\n' "$LATEST_TAG" "$NEW_TAG"
} > lab-release-notes.md
cat lab-release-notes.md
echo "SHOULD_RELEASE=true" >> $GITHUB_OUTPUT
env:
LATEST_TAG: ${{ steps.latest-tag.outputs.LATEST_TAG }}
NEW_VERSION: ${{ steps.new-version.outputs.NEW_VERSION }}
EVENT_NAME: ${{ github.event_name }}
- name: Create Release
if: steps.release-notes.outputs.SHOULD_RELEASE == 'true'
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
with:
tag_name: '@lucide/lab@${{ steps.new-version.outputs.NEW_VERSION }}'
name: '@lucide/lab@${{ steps.new-version.outputs.NEW_VERSION }}'
body_path: lab-release-notes.md
make_latest: 'false' # Never displace the core icon release as "Latest"
publish:
if: github.repository == 'lucide-icons/lucide' && needs.create-release.outputs.SHOULD_RELEASE == 'true'
runs-on: ubuntu-latest
needs: create-release
permissions:
id-token: write # Required for OIDC (npm provenance)
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
cache: 'pnpm'
node-version-file: 'package.json'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Set new version
run: pnpm version ${{ needs.create-release.outputs.VERSION }} --filter @lucide/lab --fail-if-no-match --no-git-tag-version
- name: Build
run: pnpm --filter @lucide/lab build
- name: Publish
run: pnpm --filter @lucide/lab publish --access public --no-git-checks --ignore-scripts --tag latest
env:
NPM_CONFIG_PROVENANCE: true
+1 -1
View File
@@ -169,7 +169,7 @@ jobs:
zip -r lucide-icons-${{ needs.prepare.outputs.VERSION }}.zip icons
- name: Release zip and fonts
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
with:
tag_name: ${{ needs.prepare.outputs.VERSION }}
+9 -1
View File
@@ -3,9 +3,10 @@
.next
.obsidian
.now
.idea
.cache
.env
node_modules
.pnpm-store
dist
build
sandbox
@@ -13,6 +14,10 @@ stash
coverage
stats
*.log
*.tsbuildinfo
integrations/**/.react-router
integrations/**/.vitest-attachments
integrations/**/__screenshots__
outlined
lucide-font
packages/**/src/icons/*.js
@@ -23,6 +28,9 @@ packages/**/src/aliases.ts
!packages/**/src/aliases/index.ts
packages/**/src/utils/*.ts
!packages/shared/src/utils/*.ts
!packages/shared/src/build/
!packages/shared/src/build/*.ts
packages/shared/src/build/types.d.ts
packages/**/src/dynamicIconImports.ts
packages/**/DynamicIcon.d.ts
packages/**/dynamicIconImports.js
-3
View File
@@ -1,5 +1,2 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm lint-staged
pnpm checkIcons
+7
View File
@@ -19,6 +19,13 @@ packages/lucide-static/icon-nodes.json
packages/lucide-static/font
packages/svelte/.svelte-kit
# integration test artifacts and generated routes
integrations/**/.react-router
integrations/**/next-env.d.ts
integrations/**/routeTree.gen.ts
integrations/**/.vitest-attachments
integrations/**/__screenshots__
# lucide-svelte
packages/svelte/src/icons/*.svelte
packages/svelte/.svelte-kit
+3 -1
View File
@@ -4,6 +4,7 @@ import { groupIconMdPlugin, groupIconVitePlugin } from 'vitepress-plugin-group-i
import sidebar from './sidebar';
import snackPlayer from './markdown/snackPlayer';
import sandpackPlugin from './markdown/sandpack';
import examplePlugin from './markdown/example';
import { readFile } from 'node:fs/promises';
import { resourcesSidebar } from './sidebar/resources';
import llmstxt from 'vitepress-plugin-llms';
@@ -31,6 +32,7 @@ export default defineConfig({
config(md) {
md.use(groupIconMdPlugin);
md.use(snackPlayer);
md.use(examplePlugin);
md.use(sandpackPlugin, {
defaultFiles: {
'/styles.css': {
@@ -96,7 +98,7 @@ export default defineConfig({
text: 'Resources',
items: [
...resourcesSidebar[0].items,
{ text: 'Design icons', link: '/contribute/icon-design-guide' },
{ text: 'Contributing icons', link: '/contribute/icons/' },
],
},
{ text: 'Packages', link: '/packages' },
@@ -119,8 +119,7 @@ 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,8 +2,7 @@ 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({
+204
View File
@@ -0,0 +1,204 @@
import { readFileSync } from 'node:fs';
import { dirname, isAbsolute, resolve } from 'node:path';
import type MarkdownIt from 'markdown-it';
import type { RenderRule } from 'markdown-it/lib/renderer.mjs';
import container from 'markdown-it-container';
type ContainerArgs = [typeof container, string, { render: RenderRule }];
const parseInfo = (info: string, marker: string) => info.trim().slice(marker.length).trim();
const stripWrappingQuotes = (value: string) => {
const quote = value[0];
if ((quote === '"' || quote === "'") && value.at(-1) === quote) {
return value.slice(1, -1);
}
return value;
};
const isRawSvgUrl = (url: string) => {
const [filePath, query = ''] = url.split('?');
const params = new URLSearchParams(query);
return filePath.endsWith('.svg') && params.get('raw') === 'true';
};
const isImageUrl = (value: string) => {
const [filePath] = value.split('?');
return /\.(avif|gif|jpe?g|png|svg|webp)$/i.test(filePath);
};
const resolveMarkdownPath = (env: Record<string, unknown>) =>
(env.path as string | undefined) ??
(env.file as string | undefined) ??
(env.realPath as string | undefined);
const renderImage = (
url: string,
env: Record<string, unknown>,
escapeAttr: (value: string) => string,
) => {
if (!isRawSvgUrl(url)) {
return `<img class="example-guidance__image" src="${escapeAttr(url)}" alt="" loading="lazy">`;
}
const [filePath] = url.split('?');
const markdownPath = resolveMarkdownPath(env);
const resolvedPath = isAbsolute(filePath)
? resolve(process.cwd(), `.${filePath}`)
: resolve(markdownPath ? dirname(markdownPath) : process.cwd(), filePath);
const svg = readFileSync(resolvedPath, 'utf8');
const replacedSvg = svg
.replaceAll(/(#000(000)?|black)/g, 'currentColor')
.replaceAll(' stroke="#D8D8D9"', 'style="stroke: currentColor; stroke-opacity: .25;"');
return `<div class="example-guidance__image example-guidance__image--raw">${replacedSvg}</div>`;
};
const renderPreview = (
value: string,
env: Record<string, unknown>,
escapeHtml: (value: string) => string,
renderInline: (value: string) => string,
) => {
if (isImageUrl(value)) {
return renderImage(value, env, escapeHtml);
}
return `<div class="example-guidance__text">${renderInline(value)}</div>`;
};
const hasTopLevelContent = (tokens: Parameters<RenderRule>[0], index: number) => {
let guidanceDepth = 0;
for (let i = index + 1; i < tokens.length; i += 1) {
const token = tokens[i];
if (token.type === 'container_example_close') {
return false;
}
if (token.type === 'container_do_open' || token.type === 'container_dont_open') {
guidanceDepth += 1;
continue;
}
if (token.type === 'container_do_close' || token.type === 'container_dont_close') {
guidanceDepth -= 1;
continue;
}
if (guidanceDepth === 0) {
return true;
}
}
return false;
};
const hasGuidance = (tokens: Parameters<RenderRule>[0], index: number) => {
for (let i = index + 1; i < tokens.length; i += 1) {
const token = tokens[i];
if (token.type === 'container_example_close') {
return false;
}
if (token.type === 'container_do_open' || token.type === 'container_dont_open') {
return true;
}
}
return false;
};
const isFirstGuidance = (tokens: Parameters<RenderRule>[0], index: number) => {
for (let i = index - 1; i >= 0; i -= 1) {
const token = tokens[i];
if (token.type === 'container_example_open') {
return true;
}
if (token.type === 'container_do_open' || token.type === 'container_dont_open') {
return false;
}
}
return true;
};
const getExampleOpenIndex = (tokens: Parameters<RenderRule>[0], index: number) => {
for (let i = index; i >= 0; i -= 1) {
if (tokens[i].type === 'container_example_open') {
return i;
}
}
return index;
};
export default function examplePlugin(md: MarkdownIt) {
const escapeHtml = md.utils.escapeHtml;
const createExampleContainer = (): ContainerArgs => [
container,
'example',
{
render(tokens, idx) {
const token = tokens[idx];
if (token.nesting === 1) {
const hasContent = hasTopLevelContent(tokens, idx);
const guidanceOnlyClass = hasContent ? '' : ' example-block--guidance-only';
const contentOpen = hasContent ? '<div class="example-block__content">\n' : '';
return `<section class="example-block${guidanceOnlyClass}">\n${contentOpen}`;
}
const exampleOpenIndex = getExampleOpenIndex(tokens, idx);
const contentClose =
hasTopLevelContent(tokens, exampleOpenIndex) && !hasGuidance(tokens, exampleOpenIndex)
? '</div>\n'
: '';
return `${contentClose}</section>\n`;
},
},
];
const createGuidanceContainer = (type: 'do' | 'dont'): ContainerArgs => [
container,
type,
{
render(tokens, idx, _options, env) {
const token = tokens[idx];
if (token.nesting === 1) {
const exampleOpenIndex = getExampleOpenIndex(tokens, idx);
const preview = stripWrappingQuotes(parseInfo(token.info, type));
const media = renderPreview(preview, env, escapeHtml, md.renderInline.bind(md));
const contentClose =
hasTopLevelContent(tokens, exampleOpenIndex) && isFirstGuidance(tokens, idx)
? '</div>\n'
: '';
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`;
}
return '</figcaption></figure>\n';
},
},
];
md.use(...createExampleContainer());
md.use(...createGuidanceContainer('do'));
md.use(...createGuidanceContainer('dont'));
}
+64 -14
View File
@@ -11,41 +11,91 @@ export const resourcesSidebar = [
link: '/community',
},
{
text: 'Code of Conduct',
text: 'Code of conduct',
link: '/code-of-conduct',
},
{
text: 'Brand logo statement',
link: '/brand-logo-statement',
},
],
},
{
text: 'Contribute',
items: [
{
text: 'Contributing',
link: '/contribute',
text: 'Contribution guide',
link: '/contribute/',
},
],
},
{
text: 'Designing icons',
text: 'Contributing icons',
items: [
{
text: 'Icon Design Principles',
link: '/contribute/icon-design-guide',
text: 'Getting started',
link: '/contribute/icons/',
},
{
text: 'Designing in Illustrator',
link: '/contribute/illustrator-guide',
text: 'Design language',
link: '/contribute/icons/design-principles',
desc: 'Learn the visual principles that shape Lucide icons with side-by-side examples.',
},
{
text: 'Designing in Inkscape',
link: '/contribute/inkscape-guide',
text: 'Design specification',
link: '/contribute/icons/specification',
desc: 'Review the technical requirements every Lucide icon must meet.',
},
{
text: 'Designing in Figma',
link: '/contribute/figma-guide',
text: 'Naming conventions',
link: '/contribute/icons/naming-conventions',
desc: 'Learn how to choose clear, consistent, and predictable names for Lucide icons.',
},
{
text: 'Designing in Affinity Designer',
link: '/contribute/affinity-designer-guide',
text: 'Metadata conventions',
link: '/contribute/icons/metadata-conventions',
desc: 'Learn how to write use cases, tags, categories, aliases, and other icon metadata.',
items: [
{
text: 'Use case guide',
link: '/contribute/icons/metadata-conventions/use-case-guide',
desc: '',
},
{
text: 'Tag guide',
link: '/contribute/icons/metadata-conventions/tag-guide',
desc: '',
},
],
},
{
text: 'SVG conventions',
link: '/contribute/icons/code-conventions',
desc: 'Learn how to structure and write Lucide SVG files.',
},
{
text: 'Design software guides',
collapsed: false,
desc: 'Learn how to design and export Lucide icons with common vector tools.',
items: [
{
text: 'Adobe Illustrator',
link: '/contribute/icons/illustrator-guide',
desc: '',
},
{
text: 'Inkscape',
link: '/contribute/icons/inkscape-guide',
},
{
text: 'Figma',
link: '/contribute/icons/figma-guide',
},
{
text: 'Affinity Designer',
link: '/contribute/icons/affinity-designer-guide',
},
],
},
],
},
@@ -53,7 +53,7 @@ const pickIcons = [
'terminal',
'thermometer',
'thumbs-up',
'trash-2',
'trash',
'umbrella',
'watch',
'sparkles',
@@ -122,7 +122,7 @@ const categoriesList = computed(() => {
});
const searchPlaceholder = useSearchPlaceholder(searchQuery, searchResults);
const isSearchMetadataLoading = computed(
() => searchQuery.value.length > 0 && (tags.value == null || categoriesMap.value == null),
() => searchQuery.value.length > 0 && !isFetchingTags && !isFetchingCategories,
);
const { list, containerProps, wrapperProps, scrollTo } = useVirtualList(categoriesList, {
@@ -88,9 +88,13 @@ 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,
@@ -115,7 +119,7 @@ const searchResults = useSearch(searchQueryDebounced, mappedIcons, [
const searchPlaceholder = useSearchPlaceholder(searchQuery, searchResults);
const isSearchMetadataLoading = computed(
() => searchQuery.value.length > 0 && (tags.value == null || categories.value == null),
() => searchQuery.value.length > 0 && !isFetchingTags && !isFetchingCategories,
);
const chunkedIcons = computed(() => {
@@ -32,7 +32,8 @@
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%),
@@ -56,7 +57,8 @@
.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,6 +9,7 @@ const useSearch = <T>(
const index = shallowRef(
new Fuse(collection.value, {
threshold: 0.2,
useExtendedSearch: true,
keys,
}),
);
@@ -17,7 +18,9 @@ const useSearch = <T>(
index.value.setCollection(collection.value);
if (query.value) {
return index.value.search(query.value).map((result) => result.item);
return index.value
.search({ $and: query.value.split(' ').filter((t) => !!t) })
.map((result) => result.item);
}
return collection.value;
+137
View File
@@ -183,3 +183,140 @@ html {
background: transparent;
border: none;
}
.custom-block.success {
border-color: transparent;
color: var(--vp-c-text-1);
background-color: var(--vp-c-success-soft);
}
/* Example guidance blocks */
.example-block {
margin: 32px 0;
}
.example-block__title {
margin: 0 0 12px;
font-size: 20px;
line-height: 1.4;
}
.example-block > :first-child {
margin-top: 0;
}
.example-block > :last-child {
margin-bottom: 0;
}
.example-block__content > :first-child {
margin-top: 0;
}
.example-block__content > :last-child {
margin-bottom: 0;
}
.example-guidance__image {
display: block;
width: 100%;
height: auto;
background-color: var(--vp-c-bg-soft);
border-bottom: 4px solid var(--vp-c-divider);
border-top-left-radius: 16px;
border-top-right-radius: 16px;
overflow: hidden;
}
.example-guidance__image--raw svg {
display: block;
width: 100%;
height: auto;
}
.example-guidance__text {
display: flex;
flex-direction: column;
gap: 8px;
align-items: center;
justify-content: center;
min-height: 160px;
padding: 24px;
background-color: var(--vp-c-bg-alt);
border-bottom: 1px solid var(--vp-c-divider);
border-top-left-radius: 16px;
border-top-right-radius: 16px;
color: var(--vp-c-text-1);
font-size: 20px;
line-height: 1.4;
text-align: center;
text-wrap: balance;
}
.example-guidance__text svg.lucide {
flex-shrink: 0;
display: inline-block;
vertical-align: -6px;
}
.example-guidance__caption {
color: var(--vp-c-text-1);
}
.example-guidance__caption > p {
margin: 0;
padding: 0 16px 16px;
}
.example-guidance__label {
display: flex;
gap: 8px;
padding: 12px;
margin: 0 0 16px;
background-color: var(--example-guidance-label-bg);
color: var(--vp-c-neutral-inverse);
border-bottom-left-radius: 16px;
border-bottom-right-radius: 16px;
}
.example-guidance--do {
--example-guidance-label-bg: var(--vp-c-success-1);
}
.example-guidance--dont {
--example-guidance-label-bg: var(--vp-c-danger-1);
}
@media (min-width: 640px) {
.example-block {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 24px;
}
.example-block__content {
grid-column: 1 / -1;
}
.example-guidance {
margin: 0;
}
}
@media (min-width: 960px) {
.example-block {
grid-template-columns: minmax(0, 0.9fr) repeat(2, minmax(0, 1fr));
}
.example-block--guidance-only {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.example-block__content {
grid-column: 1;
}
.example-guidance {
grid-column: auto;
grid-row: auto;
}
}
@@ -29,7 +29,7 @@ export default function useSearchPlaceholder(
}
}
state.value = {
isNoResults: query in BRAND_STOPWORDS && searchResults.length === 0 && query !== '',
isNoResults: query !== '' && searchResults.length === 0,
isBrand: query in BRAND_STOPWORDS,
query: BRAND_STOPWORDS[query] ?? query,
};
+1 -1
View File
@@ -29,7 +29,7 @@ Contribution in form of code or new icons is always welcome, but you can also he
### Design New Icons
If you have design skills, consider contributing new icons to the Lucide library. Check out our [icon design guide](/contribute/icon-design-guide.md) for tips and guidelines on creating icons that fit the Lucide style.
If you have design skills, consider contributing new icons to the Lucide library. Check out our [icon design guide](/contribute/icons/design-principles.md) for tips and guidelines on creating icons that fit the Lucide style.
### Contribute Code
@@ -1,18 +0,0 @@
---
title: Affinity Designer Template Guide
---
# Affinity Designer Template Guide
This guide describes how to use the Affinity Designer template for Lucide.
## General Workflow
>Attention: By default, Affinity Designer sets the unit for stroke to points. Make sure that it is set to pixel. To do this, open `Preferences > User Interface`. Under `Decimal Places for Unit Types`, uncheck `Show Lines in points`.
1. Download and open the [Affinity Designer template](https://github.com/lucide-icons/lucide/blob/main/docs/public/templates/affinity_designer.aftemplate).
2. Follow the [Icon Design Principles](icon-design-guide.md) while you use the template (to ensure integrity with the Lucide icon pack).
3. Export the file as SVG (`File > Export`). Make sure that _Rastering_ is set to _Nothing_, _Export text as curves_ is checked (hopefully, you won't need this), _Use hex colors_ is checked, and _Flatten transforms_ is checked.
![SVG export options in Affinity Designer](../images/affinity-designer-export-options.png?raw=true)
4. Optimize the exported SVG file further with [SVGOMG](https://jakearchibald.github.io/svgomg/) or [`svgo`](https://github.com/svg/svgo) (using `svgo --multipass exported_icon.svg`).
-51
View File
@@ -1,51 +0,0 @@
---
title: Figma Template Guide
---
# Figma Template Guide
This guide shows the steps to setup Figma for creating icons that conform to the Featherity design guidelines.
## Setting Up The Frame
When you create a new document in Figma, the document. Each individual icon you want to create, has to be created in a separate frame.
To do this, create a frame of 24x24 pixels.
1. Click the frame button (or press `F`)
2. Draw a 24x24 frame (or edit it afterwards from the design window)
In this newly created frame, you will create your icon. If you want, you can change the name of your frame to the name of the icon you are going to create. Then it will be exported as `FRAME-NAME.svg`.
## Create Your icon
To design your icon in the style of Feather Icons, you need to adjust a few settings in Figma.
Draw in your new frame with the pen tool. You can open it with the window at the top, or with the shortcut `P`. Once you click in your frame, you can adjust the settings for the pen tool in the design-window on the right.
Set the following:
1. Vector
1. Corner radius: 2px
2. Stroke
1. Stroke width: 2px
2. Stroke alignment: center
![Figma Stroke Options](../images/figma-stroke-options.png)
## Export Or Copy Your Icon
Once you have completed your icon, you can export it.
1. Select the frame
2. Open the *Export* tab on the right
3. Set the file type as SVG
4. Press export
Or you can also copy its source as SVG.
1. Select the frame
2. Right click it
3. Click on *Copy/Paste as*
4. Click on *Copy as SVG*
That's it. You just made your first icon. Congratulations!
## Figma Tips
1. The [Icon Design Guidelines](icon-design-guide.md) dictate that you keep 2px spacing between detached elements. In Figma, you can easily check this with: `⌥` Option (MacOS) or `Alt` (Windows).
-199
View File
@@ -1,199 +0,0 @@
---
description: Guidelines and best practices for designing icons for the Lucide icon library.
---
# Icon Design Guide
Guidelines and best practices for designing icons for the Lucide icon library.
## Icon Design Principles
Here are rules that should be followed to keep quality and consistency when making icons for Lucide.
### 1. Icons must be designed on a **24 by 24 pixels** canvas.
![24px-24px](../images/24px-24px.svg?raw=true "24px-24px")
### 2. Icons must have at least **1 pixel padding** within the canvas.
![1px-padding](../images/1px-padding.svg?raw=true "1px-padding")
### 3. Icons must have a **stroke width of 2 pixels**.
![2px-stroke](../images/2px-stroke.svg?raw=true "2px-stroke")
### 4. Icons must use **round joins**.
![round-joints](../images/round-joints.svg?raw=true "round-joints")
### 5. Icons must use **round caps**.
![round-caps](../images/round-caps.svg?raw=true "round-caps")
### 6. Icons must use **centered strokes**.
![centered-strokes](../images/centered-strokes.svg?raw=true "centered-strokes")
### 7. Shapes (such as rectangles) must have a **border radius of**
#### A. **2 pixels** if they are at least 8 pixels in size
![2px-border-radius](../images/2px-border-radius.svg?raw=true "2px-border-radius")
#### B. **1 pixel** if they are smaller than 8 pixels in size
![1px-border-radius](../images/1px-border-radius.svg?raw=true "1px-border-radius")
### 8. Distinct elements must have **2 pixels of spacing between each other**
![2px-element-spacing](../images/2px-element-spacing.svg?raw=true '2px-element-spacing')
![2px-element-spacing-connected](../images/2px-element-spacing-connected.svg?raw=true '2px-element-spacing-connected')
![2px-element-spacing-abrupt-cut](../images/2px-element-spacing-abrupt-cut.svg?raw=true '2px-element-spacing-abrupt-cut')
### 9. Icons should have a similar optical volume to `circle` and `square`.
![optical-volume-ideal](../images/optical-volume-ideal.svg?raw=true "optical-volume-ideal")
![optical-volume-low](../images/optical-volume-low.svg?raw=true "optical-volume-low")
![optical-volume-high](../images/optical-volume-high.svg?raw=true "optical-volume-high")
**Tip:** place your icon next to the circle or square icon and blur them both; your icon should not feel much darker than the base shape.
### 10. Icons should be visually centered by their center of gravity.
![visually-centered](../images/visually-centered.svg?raw=true "visually-centered")
![visually-centered-bad](../images/visually-centered-bad.svg?raw=true "visually-centered-bad")
**Tip:** place your icon both above/below and next to the square or circle icon and check if it feels off center. Symmetrical icons should always be aligned to the center.
### 11. Icons should have similar visual density and level of detail.
![density-ideal](../images/density-ideal.svg?raw=true "density-ideal")
![density-high](../images/density-high.svg?raw=true "density-high")
**Tip:** try to make abstractions to dense elements. Blur your icon, and when blurred it should not feel overly dark.
### 12. Continuous curves should join smoothly.
![curvature-smooth](../images/curvature-smooth.svg?raw=true "curvature-smooth")
![curvature-uneven](../images/curvature-uneven.svg?raw=true "curvature-uneven")
**Tip:** make sure to use arcs or quadratic curves. When using cubic curves control points should have mirrored angles for smooth curves.
### 13. Icons should aim to be pixel perfect so that they will be sharp on low DPI displays.
![pixel-perfection-ideal](../images/pixel-perfection-ideal.svg?raw=true "pixel-perfection-ideal")
![pixel-perfection-bad](../images/pixel-perfection-bad.svg?raw=true "pixel-perfection-bad")
**Tip:** whenever possible align elements and arc centers to the grid.
### 14. Icons should share common shapes
You should try to create consistent groups and variants, reuse and try to create uniformity.
Consistency inside groups and variants has a lower priority than the rules above.
**Example:** All `-off` icons should look the same unless it for example violates the optical volume rule.
**Tip:** Try to not move the base shape to enable better use in a toggle context.
## Naming conventions
1. Icon names use lower kebab case.\
For example: `arrow-up` instead of `Arrow Up`.
2. Icon names use International English names, as opposed to local variants.\
For example: `color` instead of `colour`.
3. Icons should be named for what they depict rather than their use case or what they represent.\
For example: `floppy-disk` instead of `save` and `circle-slash` rather than `ban`.
4. Icons that are part of a group are named `<group>-<variant>`.\
For example: `badge-plus` is based on `badge`.
5. Icon names for alternate icons should represent what makes the alternate unique instead of being numbered.\
For example: `send-horizontal` instead of `send-2`.
6. Names containing numerals are not allowed, unless the number itself is represented in the icon.\
For example: `arrow-down-0-to-1` contains both numerals.
7. Icons depicting multiple elements (e.g. a person and a circle) of different sizes must list these elements in decreasing order of size.\
For example: if the circle is bigger, it should be `circle-person`, if the person is bigger, it should be `person-circle`.
8. Icons depicting multiple elements of roughly equal sizes (e.g. a `ruler` and a `pencil`) must list these elements front to back in case one element is in front of the other, otherwise in English reading order (top to bottom, left to right).\
For example: if the `pencil` is either in front of, above or left of `ruler`, it should be `pencil-ruler`, otherwise, it should be `ruler-pencil`.
9. Icons depicting some sort of variation of an element must use the `[element]-[modifier]` naming scheme, with modifiers being applied to each element respectively.\
For example: a dashed circle must be named `circle-dashed`, not `dashed-circle`, and in coordination with the previous guidelines, a dashed circle containing a broken heart would be named `circle-dashed-heart-broken`, due to the heart being smaller than the circle.
## Code Conventions
Before an icon is added to the library, we like to have readable and optimized SVG code.
### Global Attributes
For each icon these attributes are applied, corresponding to the above rules.
```xml
<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"
>
<!-- SVGElements -->
</svg>
```
### Minify paths
The code of paths can sometimes get quite large. To reduce file size we like to minify the code.
We recommend to use [Lucide Studio](https://studio.lucide.dev/?utm_source=lucide.dev&utm_medium=design-guide) to tidy paths to 3 points of precision.
### Allowed elements
SVG files may only contain simple path and shape elements, which may not have any attributes other than sizing and spacing.\
In practice only the following elements and attributes are allowed:
* `<path d>`
* `<line x1 x2>`
* `<polygon points>`
* `<polyline points>`
* `<circle cx cy r>`
* `<ellipse cx cy rx ry>`
* `<rect x y width height rx>`
This also means that no transforms, filters, fills or explicit strokes are allowed.
Never use [`<use>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use). While it may sometimes seem like a good way to optimize file size, there's no way to ensure that the referenced element IDs will be unique once the SVGs are embedded in HTML documents.
## JSON metadata descriptor
Each icon added must also come with a matching JSON file listing tags and categories for the icon.
Please use the following template:
```json
{
"$schema": "../icon.schema.json",
"contributors": [
"github-username",
"another-github-username"
],
"tags": [
"foo",
"bar"
],
"categories": [
"devices"
]
}
```
@@ -0,0 +1,19 @@
---
description: Learn how to use the Affinity Designer template for Lucide.
---
# Affinity Designer template guide
This guide explains how to use the Affinity Designer template for Lucide.
## Workflow
> Affinity Designer uses points for strokes by default. Change strokes to pixels before drawing. Open `Preferences > User Interface`, then under `Decimal Places for Unit Types`, uncheck `Show Lines in points`.
1. Download and open the [Affinity Designer template](https://github.com/lucide-icons/lucide/blob/main/docs/public/templates/affinity_designer.aftemplate).
2. Follow the [design language](design-principles.md) while designing your icon.
3. Export the file as SVG with `File > Export`. Set rasterization to _Nothing_, check _Export text as curves_, check _Use hex colors_, and check _Flatten transforms_.
![SVG export options in Affinity Designer](../../images/affinity-designer-export-options.png?raw=true)
4. Optimize the exported SVG with [Lucide Studio](https://studio.lucide.dev/).
+91
View File
@@ -0,0 +1,91 @@
---
description: Learn about allowed SVG elements and attributes, optimization, and other code conventions.
---
# SVG conventions
Before you add an icon to Lucide, make sure its SVG is readable and optimized.
## Global attributes
Each icon uses these root SVG attributes:
```xml
<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"
>
<!-- SVGElements -->
</svg>
```
## Minify paths
Path data can get large. Minify it to keep SVG files small.
Use [Lucide Studio](https://studio.lucide.dev/?utm_source=lucide.dev&utm_medium=design-guide) to tidy paths to 3 decimal places.
## Allowed elements
SVG files may only contain simple path and shape elements. These elements may only use sizing and position attributes.
Only these elements and attributes are allowed:
- `<path d>`
- `<line x1 y1 x2 y2>`
- `<polygon points>`
- `<polyline points>`
- `<circle cx cy r>`
- `<ellipse cx cy rx ry>`
- `<rect x y width height rx>`
Do not use transforms, filters, fills, or explicit stroke colors.
Never use [`<use>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use). It can reduce file size, but referenced IDs may conflict when SVGs are embedded in HTML.
## Metadata file
Each icon must also have a matching JSON file with contributors, use cases, tags, and categories.
See [metadata conventions](./metadata-conventions/) for details.
## Validation
Before submitting SVG changes, format and validate the icon files:
```sh
pnpm run lint:icons
```
You can automatically format SVG files with Prettier:
```sh
pnpm run lint:icons-fix
```
To check icon names, categories, metadata, and SVG structure together, run:
```sh
pnpm run lint:icons:all
```
## Checklist
Before opening a pull request, confirm that:
- The SVG uses the standard `24 × 24` viewBox.
- The SVG uses `fill="none"` and `stroke="currentColor"`.
- Stroke width, line caps, and line joins match the Lucide defaults.
- Paths are tidy and use appropriate numeric precision.
- The SVG uses only allowed elements and attributes.
- The SVG does not use transforms, filters, fills, explicit strokes, or `<use>`.
- The icon has a matching JSON metadata file.
- `pnpm run lint:icons` passes.
- `pnpm run lint:json:icons` passes.
+368
View File
@@ -0,0 +1,368 @@
---
description: Learn the visual principles that make Lucide icons consistent and recognizable.
---
# Lucide design language
Lucide is a consistent icon set, not a collection of unrelated icons. Every icon should feel like it belongs with the rest of the library.
This guide explains the visual rules behind Lucide icons and how to use them when designing new icons.
For the full rule list, see the [icon design specification](./specification)
## 1. Use a 24 × 24-pixel canvas
Icons **must** be designed on a 24 × 24-pixel canvas.
:::: example
::: do ../../images/24px-24px.svg?raw=true
Use a **24 × 24 pixel** canvas.
:::
::: dont ../../images/24px-24px-violation.svg?raw=true
Don't use a canvas that is larger, smaller, or not square.
:::
::::
## 2. Keep a 1-pixel safe zone
Icons **must** have at least 1 pixel of padding between their strokes and the edge of the canvas.
:::: example
::: do ../../images/1px-padding.svg?raw=true
Keep at least **1 pixel of padding** around the icon.
:::
::: dont ../../images/1px-padding-violation.svg?raw=true
Don't place strokes at the edge of the canvas. They may get clipped.
:::
::::
## 3. Use 2-pixel strokes
Strokes **must** be 2 pixels wide.
:::: example
::: do ../../images/2px-stroke.svg?raw=true
Use a **2-pixel stroke width**.
:::
::: dont ../../images/2px-stroke-violation.svg?raw=true
Don't use **thicker or thinner** strokes, or **mix stroke widths**.
:::
::::
## 4. Use round line joins
Strokes **must** use round line joins.
:::: example
::: do ../../images/round-joints.svg?raw=true
Use **round line joins**.
:::
::: dont ../../images/round-joints-violation.svg?raw=true
Don't use **miter or bevel** line joins.
:::
::::
::: tip
Round joins do not replace corner rounding. Most sharp corners still need a radius.
:::
## 5. Use round line caps
Open paths **must** use round line caps.
:::: example
::: do ../../images/round-caps.svg?raw=true
Use **round line caps** on open paths.
:::
::: dont ../../images/round-caps-violation.svg?raw=true
Don't use **butt or square** line caps.
:::
::::
## 6. Use centered strokes
Strokes **must** be centered on their paths.
:::: example
::: do ../../images/centered-strokes.svg?raw=true
Keep strokes **centered** on their paths.
:::
::: dont ../../images/centered-strokes-violation.svg?raw=true
Don't use **inside or outside** strokes. They change how line joins appear, creating sharp inner corners.
:::
::::
## 7. Use consistent corner radii
Almost every sharp corner **should** be rounded.
:::: example
::: do ../../images/border-radius-correct.svg?raw=true
Use **rounded corners**.
:::
::: dont ../../images/border-radius-violation.svg?raw=true
Don't use **sharp 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.
:::
::: do ../../images/1px-border-radius.svg?raw=true
Use a **1-pixel corner radius** for shapes smaller than 8 pixels.
:::
::::
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.
:::
::: 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.
:::
::::
Avoid rounding corners **where multiple lines meet**.
:::: example
::: do ../../images/border-radius-line-join.svg?raw=true
Keep corners sharp where multiple lines meet so the icon scales well.
:::
::: dont ../../images/border-radius-line-join-violation.svg?raw=true
Don't round corners where more than two lines meet. This can make the icon scale poorly.
:::
::::
## 8. Keep at least 2 pixels between elements
Distinct elements **must** have at least 2 pixels of visual spacing between them.
:::: example
::: do ../../images/2px-element-spacing.svg?raw=true
Keep **2 pixels of spacing** between distinct elements.
:::
::: dont ../../images/1px-element-spacing.svg?raw=true
Don't use gaps smaller than **2 pixels** between distinct elements.
:::
::::
This also applies inside shapes. Most inner gaps **should** be at least 2 pixels wide.
:::: example
::: do ../../images/2px-inner-spacing.svg?raw=true
Keep at least **2 pixels of spacing** inside shapes.
:::
::: dont ../../images/1px-inner-spacing.svg?raw=true
Don't use inner gaps smaller than **2 pixels**.
:::
::::
You can test this by placing a **2-pixel-wide circle** inside your shape.
:::: example
::: do ../../images/2px-inner-gap.svg?raw=true
If a 2-pixel-wide circle fits **without overlapping**, the gap is **wide enough**.
:::
::: dont ../../images/1px-inner-gap.svg?raw=true
If the circle **overlaps** the shape, the gap should be **wider**.
:::
::::
The 2 pixel spacing also applies when elements visually connect or intersect.
:::: example
::: dont ../../images/2px-element-spacing-connected.svg?raw=true
Don't connect elements without keeping **2 pixels of spacing**.
:::
::: dont ../../images/2px-element-spacing-abrupt-cut.svg?raw=true
Don't use **abrupt cuts** where one element meets another.
:::
::::
## 9. Aim for consistent visual weight
Icons should have a similar visual weight when viewed alongside each other.
:::: example
::: do ../../images/visual-weight-consistent.svg?raw=true
Match the visual weight of `circle` and `square`.
:::
::: dont ../../images/visual-weight-uneven.svg?raw=true
The first icon is **too large**. The last one is **too small**.
:::
::::
::: tip
The amount and placement of strokes affect how heavy an icon looks. An icon with many close strokes can look heavier than a simpler icon, even with the same stroke width.
Place your icon next to `circle` or `square`, then blur both icons. Your icon should not look much lighter or darker than the reference icon.
:::
## 10. Balance icons visually
Icons should look centered and balanced within the canvas.
:::: example
::: do ../../images/visually-centered-do.svg?raw=true
Keep your icons visually centered.
:::
::: dont ../../images/visually-centered-dont.svg?raw=true
This icon feels shifted toward the top left.
:::
::::
:::: example
::: do ../../images/visually-centered-symmetrical-do.svg?raw=true
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.
:::
::::
::: tip
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
Lucide icons should have a similar level of detail.
:::: example
::: do ../../images/density-optimal.svg?raw=true
Simplify complex subjects, but keep the features that make them recognizable.
:::
::: dont ../../images/density-too-dense.svg?raw=true
Don't add extra details that make the design feel crowded.
:::
::::
::: tip
Dense areas and close strokes can make an icon look heavier than nearby icons.
View the icon at its intended size and blur it. Areas that turn dark may have too much detail.
:::
## 12. Use smooth, simple curves
Curves should be smooth and as simple as the shape allows.
:::: example
::: do ../../images/curvature-smooth.svg?raw=true
Prefer **simple arcs** and **quadratic curves** where possible.
:::
::: dont ../../images/curvature-uneven.svg?raw=true
Don't use **uneven or unnecessarily complex** curves.
:::
::::
::: tip
When you need cubic Bézier curves, align their control points to avoid visible bumps.
Avoid extra control points. They make shapes harder to edit and can create small flaws.
:::
## 13. Design for the pixel grid
Lucide icons should look sharp at small sizes, including on low-density displays.
:::: example
::: do ../../images/pixel-perfection-ideal.svg?raw=true
Align coordinates, arc centers, and other geometric elements to the pixel grid when possible.
:::
::: dont ../../images/pixel-perfection-bad.svg?raw=true
Don't place geometry off the pixel grid without a visual reason.
:::
::::
:::: example
::: do ../../images/pixel-perfection-subelement-do.svg?raw=true
Also **align subelements** to the pixel grid.
:::
::: dont ../../images/pixel-perfection-subelement-dont.svg?raw=true
Don't place subelements off-grid. They may become blurry on low-density displays.
:::
::::
:::: example
::: do ../../images/pixel-perfection-diagonals-do.svg?raw=true
In general try to **align every diagonal line** to the pixel grid.
:::
::: dont ../../images/pixel-perfection-diagonals-dont.svg?raw=true
Avoid placing diagonal lines off-grid. They will appear blurry and optically wider on low-density displays.
:::
::::
::: tip
Pixel alignment should support the icon. Do not let it harm shape recognition, smooth curves, or visual balance.
:::
## 14. Reuse established shapes
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
Reuse existing base icons **exactly as they appear**.
:::
::: dont ../../images/established-shapes-base-dont.svg?raw=true
Don't change the **geometry, placement, or orientation** of base shapes.
:::
::::
Related icons should share shapes and visual patterns when possible.
:::: example
::: do ../../images/established-shapes-sub-do.svg?raw=true
Reuse elements from existing icons **without change**.
:::
::: dont ../../images/established-shapes-sub-dont.svg?raw=true
Don't redesign **existing elements**.
:::
::::
Common modifiers and elements should look consistent across the library.
:::: example
::: do ../../images/established-shapes-consistency-do.svg?raw=true
Keep add-ons consistent in **placement and size**.
:::
::: dont ../../images/established-shapes-consistency-dont.svg?raw=true
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.
Consistency with an existing icon should not override clarity, balance, or readability. Adjust the shape when needed.
:::
## Summary
When designing a Lucide icon:
1. **Use a 24 × 24 pixel canvas** with at least **1 pixel of safe zone**.
2. **Use 2 pixel centered strokes** with **round caps and joins**.
3. **Round sharp corners** using consistent radii appropriate for their size and geometry.
4. **Keep at least 2 pixels of spacing** between distinct elements and, where possible, inside shapes.
5. **Match the visual weight** of `circle` and `square`.
6. **Center icons visually**, accounting for visual weight.
7. **Keep visual density low** and remove unnecessary detail.
8. **Use smooth, simple curves** without unnecessary control points.
9. **Align geometry to the pixel grid** where possible.
10. **Reuse established shapes** from existing Lucide icons.
When these guidelines conflict, prioritize **clarity, visual balance, and consistency** with the rest of Lucide.
+60
View File
@@ -0,0 +1,60 @@
---
description: Learn how to create Lucide icons in Figma.
---
# Figma template guide
This guide shows how to set up Figma for Lucide icons.
## Set up the frame
Create each icon in its own frame.
Use a `24 × 24` pixel frame.
1. Click the frame button, or press `F`.
2. Draw a `24 × 24` frame, or set the size in the right sidebar.
Design the icon inside this frame. Name the frame after the icon so Figma exports it as `frame-name.svg`.
## Create your icon
Set up the stroke before drawing.
Draw in the frame with the pen tool. Open it from the toolbar or press `P`. After you start drawing, adjust the vector settings in the right sidebar.
Set the following:
1. Vector
1. Corner radius: 2px
2. Stroke
1. Stroke width: 2px
2. Stroke alignment: center
![Figma stroke options](../../images/figma-stroke-options.png)
## Export or copy your icon
When your icon is ready, export it.
1. Select the frame.
2. Open the _Export_ section in the right sidebar.
3. Set the file type to SVG.
4. Click _Export_.
You can also copy the SVG source.
1. Select the frame.
2. Right-click it.
3. Choose _Copy/Paste as_.
4. Choose _Copy as SVG_.
You now have an SVG to prepare for contribution.
## Optimize your icon
You can optimize the exported SVG with [Lucide Studio](https://studio.lucide.dev/).
## Check spacing in Figma
The [design language](design-principles.md) requires at least 2 pixels of spacing between separate elements. In Figma, hold `Option` on macOS or `Alt` on Windows to check spacing.
@@ -0,0 +1,27 @@
---
description: Learn how to use the Adobe Illustrator template for Lucide.
---
# Adobe Illustrator template guide
This guide explains how to use the Adobe Illustrator template for Lucide.
> Templates can fall out of date. Check the [design language](design-principles.md) before you start.
## Workflow
The Illustrator template follows the [design language](design-principles.md).
1. Download and open the [Illustrator template](https://github.com/lucide-icons/lucide/blob/main/docs/public/templates/illustrator_template.ai).
2. Remove the content from the example logo layer (`Draw`) and start drawing.
3. Check that your icon follows the [design language](design-principles.md).
4. Before export, remove unnecessary layers, especially `Padding` and `Grid`.
5. Export the file with `Export > Export As...`, then save it as SVG. Use these SVG options:
![SVG export options in Illustrator](../../images/illustrator-svg-options.png?raw=true 'SVG export options in Illustrator')
6. Optimize your SVG with [Lucide Studio](https://studio.lucide.dev/)
+35
View File
@@ -0,0 +1,35 @@
---
description: Guidelines and instructions for contributing icons to Lucide
---
<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>
# Designing icons for Lucide
Every icon should feel like it belongs with the rest of Lucide.
This guide explains how to design and prepare icons for Lucide.
## What this guide covers
<OverviewLinkGrid>
<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
You can design Lucide icons with any vector editor that can export SVG.
Use these step-by-step guides for common tools:
<OverviewLinkGrid>
<OverviewLink v-for="item in resourcesSidebar[2].items.at(-1).items" :key="item.link" :href="item.link" :title="item.text" :desc="item.desc"/>
</OverviewLinkGrid>
These guides explain how to set up your document, follow the Lucide rules, and export a usable SVG.
Regardless of which tool you use, the same design and SVG requirements apply.
+42
View File
@@ -0,0 +1,42 @@
---
description: Learn how to create Lucide icons in Inkscape.
---
# Inkscape setup guide
This guide shows how to set up Inkscape for Lucide icons.
## Set up the canvas
Inkscape creates new documents with a default canvas size. Change it to `24 × 24` pixels:
1. Open the Document Properties dialog with `File > Document Properties`.
2. On the _Page Size_ tab, under _Custom Size_, set units to `px` and set width and height to `24`.
![Setting page size](../../images/page-size.png?raw=true 'Setting page size')
3. On the _Grid_ tab, select `Rectangular Grid` and click _New Grid_.
![Setting grid properties](../../images/grid-1.png?raw=true 'Setting grid properties')
4. Set grid units to `px`, then set `Spacing X` and `Spacing Y` to `1`.
![Setting grid properties](../../images/grid-2.png?raw=true 'Setting grid properties')
5. Close the Document Properties dialog.
6. To center the canvas in the viewport, select `View > Zoom > Drawing`.
## Set up paths
1. Create a path or shape.
2. With the path selected, press `Ctrl+Shift+F` to open the Stroke and Fill panel.
![Stroke style properties](../../images/strokes.png?raw=true 'Setting grid properties')
3. On the _Stroke Style_ tab:
- Set stroke width to `2px`.
- Select the rounded join type.
- Select the rounded cap type.
4. For rectangles, select the rectangle and set `Rx` and `Ry` to `2px` in the toolbar.
![Rectangle radius properties](../../images/corner-radius.png?raw=true 'Rectangle radius properties')
## Save a file
1. When you are ready, click _Save As_ and choose _Optimized SVG_ as the file type.
![Save as](../../images/save-as.png?raw=true 'Save as')
## Optimize your icon
As a final step, optimize your SVG with [Lucide Studio](https://studio.lucide.dev/).
@@ -0,0 +1,169 @@
---
description: Learn how to write clear and consistent metadata for Lucide icons.
---
<script setup>
import OverviewLink from '../../../.vitepress/theme/components/base/OverviewLink.vue';
import OverviewLinkGrid from '../../../.vitepress/theme/components/base/OverviewLinkGrid.vue';
</script>
# Metadata conventions
Every Lucide icon has a matching JSON metadata file. Metadata credits contributors, groups icons, improves search, and explains where an icon is useful.
Use this guide when you add a new icon or review existing metadata.
## Metadata file location
Each icon metadata file must live next to its SVG file in the `icons` directory.
The JSON file must use the same base name as the SVG file:
- `home.svg` -> `home.json`
- `arrow-up.svg` -> `arrow-up.json`
- `square-parking.svg` -> `square-parking.json`
All icon metadata files must pass `icon.schema.json`.
## Required fields
Every icon metadata file must include:
- `$schema`
- `contributors`
- `use-cases`
- `tags`
- `categories`
A minimal metadata file looks like this:
```json
{
"$schema": "../icon.schema.json",
"contributors": ["github-username", "another-github-username"],
"use-cases": ["Representing example items in an interface"],
"tags": ["foo", "bar"],
"categories": ["devices"]
}
```
## Contributors
The `contributors` field lists GitHub usernames for people who created or meaningfully changed the icon.
### Contributor rules
1. If you create a new icon based on existing ones, add all contributors from all base icons.
2. Add a username when someone made a significant change to the icon design.
3. Do not add people for minor review comments, metadata-only edits, or unrelated discussion.
## Use cases
The `use-cases` field explains where and why someone would use the icon in an interface.
Use cases should be short phrases, not full sentences. Start with an `-ing` verb, such as:
- Representing [concept]
- Indicating [state]
- Marking [item]
- Showing [information]
- Toggling [setting]
### Use case rules
- Keep each use case focused on one idea
- Keep entries concise and specific
- Write from the interface's perspective
- Describe real usage, not the icon name or appearance
- Add context when it clarifies meaning
- Do not end with punctuation
- Do not add Markdown or emoji
- Do not add implementation details or pull request references
<OverviewLinkGrid>
<OverviewLink href="./use-case-guide.md" title="Use case guide" desc="Learn the best practices for writing use cases"/>
</OverviewLinkGrid>
## Tags
The `tags` field is a list of search terms for the icon.
Tags should describe concepts, synonyms, related terms, and common contexts.
Check existing tags before adding new ones. This keeps search consistent and avoids duplicates.
### Tag rules
- Use lowercase tags.
- Prefer single words where possible.
- Multi-word tags are allowed when they are clearer, such as `magnifying glass`.
- Do not include the icon name as a tag.
- Do not add generic tags like `icon`.
- Do not add unrelated concepts just to increase search coverage.
For example, `mail-search` can use tags like `email`, `message`, `letter`, `find`, and `filter`, but not `mail`, `search` or `mail search`.
<OverviewLinkGrid>
<OverviewLink href="./tag-guide.md" title="Tag guide" desc="Learn the best practices for writing tags"/>
</OverviewLinkGrid>
## Categories
The `categories` field groups icons by broad use.
Categories must come from the allowed category list in `icon.schema.json`.
Choose categories based on what the icon represents and where people use it. Check similar icons first.
### Category rules
- Use only categories allowed by `icon.schema.json`.
- Use lowercase category names.
- Do not invent new categories in icon metadata.
- Choose relevant categories only.
## Variants and related icons
Related icons should have related metadata, but do not copy use cases blindly.
Write metadata for the specific variant:
- `battery-low` -> `Indicating a low battery charge level`
- `battery-full` -> `Indicating a full battery charge level`
- `square-arrow-right-enter` -> sign in, enter, or join contexts
- `square-arrow-right-exit` -> sign out, exit, or export contexts
When a request covers several icons, assign each use case only to the icon it describes. Do not copy metadata to icons it does not describe.
## Aliases
Some icons can include an optional `aliases` field for alternate names.
Only add aliases when an icon has been renamed from a non-compliant name.
## Validation
Before submitting metadata changes, validate the icon JSON files:
```sh
pnpm run lint:json:icons
```
You can also format changed files with Prettier:
```sh
pnpm exec prettier "icons/*.json" --check
```
## Checklist
Before opening a pull request, confirm that:
- The JSON file name matches the SVG file name.
- The file includes all required fields.
- Contributors are GitHub usernames.
- Use cases describe real interface usage.
- Tags are lowercase and useful for search.
- Categories are allowed by `icon.schema.json`.
- Metadata is specific to the icon and its variants.
- `pnpm run lint:json:icons` passes.
@@ -0,0 +1,131 @@
---
description: Learn the best practices for writing tags for Lucide icons.
---
<script setup>
import { batteryLow, calendar, droplet, hospital, mail, mailSearch, search, type } from '~/.vitepress/data/iconNodes';
import LucideIcon from '~/.vitepress/theme/components/base/LucideIcon.vue';
</script>
# Tag guide
This guide shows how to write useful search tags for Lucide icons.
Tags help people find icons by concept, synonym, context, or common wording.
## Use lowercase tags
Tags should always be lowercase.
:::: example
::: do <LucideIcon name="mail" :iconNode="mail" /> email
Lowercase tags **match the style** used across the icon library.
:::
::: dont <LucideIcon name="mail" :iconNode="mail" /> Email
Capitalized tags create **inconsistent metadata** without improving search.
:::
::::
## Prefer short tags
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
This is **short, common, and easy to find**.
:::
::: dont <LucideIcon name="search" :iconNode="search" /> searching through files & folders
This reads like a **use case**, not a tag.
:::
::::
## Use multi-word tags when needed
Some ideas are only clear as a phrase. But keep those phrases short.
:::: example
::: do <LucideIcon name="droplet" :iconNode="droplet" /> blood type
The phrase is **clearer** than either word on its own.
:::
::: dont <LucideIcon name="droplet" :iconNode="droplet" /> blood type medical label
This combines **several search concepts** into one long tag.
:::
::::
## Add synonyms and common wording
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
This helps users find `mail` icons using a **common synonym**.
:::
::: dont <LucideIcon name="mail" :iconNode="mail" /> electronic postal message delivery
This is unlikely search wording and **adds noise**.
:::
::::
## Do not repeat the icon name
The icon name is already searchable. Tags should add other ways to find it.
:::: example
::: do <LucideIcon name="mail-search" :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
This **repeats the icon name** and does not improve discovery.
:::
::::
## Avoid generic tags
Tags should describe the icon, not say that it is an icon.
:::: example
::: do <LucideIcon name="calendar" :iconNode="calendar" /> event
This points to a **specific idea** users might search for.
:::
::: dont <LucideIcon name="calendar" :iconNode="calendar" /> icon
**Every entry is an icon**, so this tag does not help anyone find the right one.
:::
::::
## Keep tags relevant
Do not add loose terms just to make an icon appear in more searches.
:::: example
::: do <LucideIcon name="hospital" :iconNode="hospital" /> emergency room
This is **relevant** for an icon that marks emergency room locations.
:::
::: dont <LucideIcon name="hospital" :iconNode="hospital" /> doctor nurse pharmacy
These terms may be **nearby concepts**, but they do not all describe the same icon.
:::
::::
## Match the specific variant
Related icons can share family terms, but variant tags should describe what is different.
:::: example
::: do <LucideIcon name="battery-low" :iconNode="batteryLow" /> depleted
This distinguishes `battery-low` from **other battery icons**.
:::
::: dont <LucideIcon name="battery-low" :iconNode="batteryLow" /> charged
This describes `battery-full` better than `battery-low`.
:::
::::
## Use existing tags as a reference
Check similar icons before adding new tags. Reusing existing terms keeps search predictable.
:::: example
::: do <LucideIcon name="type" :iconNode="type" /> typography
This matches existing text-formatting icons and keeps **related icons** together in search.
:::
::: dont <LucideIcon name="type" :iconNode="type" /> fontography
Inventing a new term makes the icon harder to find and less consistent with related metadata.
:::
::::
@@ -0,0 +1,142 @@
---
description: Learn the best practices for writing use cases for Lucide icons.
---
<script setup>
import { batteryLow, creditCard, crop, handshake, heading2, microchip, search, squareParking, triangleAlert, wifiOff } from '~/.vitepress/data/iconNodes';
import LucideIcon from '~/.vitepress/theme/components/base/LucideIcon.vue';
</script>
# Use case guide
This guide shows how to write clear use cases for Lucide icons.
## Write from the interface's perspective
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
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
This explains the **contributor's situation**, not the icon's purpose.
:::
::::
## Describe real usage, not the icon name
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
This explains `microchip` **without repeating the name**.
:::
::: dont <LucideIcon name="microchip" :iconNode="microchip" /> it's a microchip icon
This **duplicates the icon name** and does not explain where the icon would be used.
:::
::::
## Add context when it clarifies meaning
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
The phrase explains both the **action and the product area**.
:::
::: dont <LucideIcon name="heading-2" :iconNode="heading2" /> Applying a heading
This is less useful because it **omits the level and context**.
:::
::::
## Keep each use case focused
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
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
This reads like a **tag list** and **mixes several ideas**.
:::
::::
## Write variant-specific use cases
For related icons, describe what makes each variant different.
:::: example
::: do <LucideIcon name="battery-low" :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
This is **too generic** and could apply to **every battery variant**.
:::
::::
## Avoid pull request references
Use cases should make sense after the pull request is merged.
:::: example
::: do <LucideIcon name="handshake" :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
This **depends on a discussion** readers **may never see**.
:::
::::
## Keep entries concise
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
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
This is **too long** and reads like **product copy instead of metadata**.
:::
::::
## Do not end with punctuation
Use cases are metadata phrases, not full sentences.
:::: example
::: do <LucideIcon name="credit-card" :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.
The period adds **unnecessary punctuation** and makes entries inconsistent.
:::
::::
## Avoid markdown and emoji
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
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>
Markdown and emoji can **show up in generated UI** and make metadata **harder to reuse**.
:::
::::
## Avoid implementation details
Use cases should describe meaning, not how the SVG was made.
:::: example
::: do <LucideIcon name="crop" :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
This describes **construction details** that do not help people find or understand the icon.
:::
::::
+238
View File
@@ -0,0 +1,238 @@
---
description: Learn how to choose clear and consistent names for Lucide icons.
---
<script setup>
import {
arrowDown01,
badgeCheck,
badgePlus,
ban,
boneFracture,
circleDashed,
circleFadingArrowUp,
circleUser,
clock3,
heartCrack,
moonStar,
notepadTextDashed,
pencilRuler,
rulerDimensionLine,
save,
sendHorizontal,
squareDashed,
sunSnow,
userRound,
} from '~/.vitepress/data/iconNodes';
import LucideIcon from '~/.vitepress/theme/components/base/LucideIcon.vue';
const pencilRulerHorizontal = [
["path",{"d":"M10 16v-3","key":"1sz6hv"}],
["path",{"d":"M14 16v-3","key":"1rh0ni"}],
["path",{"d":"M16 2.999v5.98","key":"q5wnuh"}],
["path",{"d":"M18 16v-3","key":"gc63g1"}],
["path",{"d":"M19.005 2.994A3 3 0 0122 5.984a3 3 0 01-2.986 2.99l-11.777.017a2 2 0 01-.943-.25l-4.03-2.274a.5.5 0 010-.934l4.03-2.274a2 2 0 01.944-.247z","key":"1bk0ej"}],
["path",{"d":"M6 16v-3","key":"h6yyjy"}],
["rect",{"x":"2","y":"13","width":"20","height":"8","rx":"2","key":"ct2kk9"}]
];
const pencilRulerVertical = [
["path",{"d":"M16 10h-3","key":"4p2xpj"}],
["path",{"d":"M16 14h-3","key":"1xsqil"}],
["path",{"d":"M16 18h-3","key":"12gup7"}],
["path",{"d":"M16 6h-3","key":"1o5sfa"}],
["path",{"d":"M2.995 19.005a1 1 0 105.98.01L8.99 7.236a2 2 0 00-.25-.943l-2.274-4.03a.5.5 0 00-.934 0L3.26 6.294a2 2 0 00-.248.944z","key":"rw57er"}],
["path",{"d":"M3 16h5.979","key":"kkz6vb"}],
["rect",{"x":"13","y":"2","width":"8","height":"20","rx":"2","key":"qzgro9"}]
];
</script>
# Naming conventions
Learn how to choose clear, consistent names for Lucide icons.
This page covers word order, modifiers, variants, related icons, and other rules that keep icon names predictable.
Use this when naming a new icon or reviewing a proposed name.
## 1. Use lowercase kebab-case
Icon names **must** use lowercase kebab-case.
:::: example
::: do `arrow-up-0-1`
Use lowercase kebab-case.
:::
::: dont `Arrow Up 0-1` or `arrowUp01`
Avoid other naming schemes.
:::
::::
## 2. Use American English
Icon names **must** use American English, not local variants.
:::: example
::: do <span>`color`, `maximize`, `center`</span>
:::
::: dont <span>`colour`, `maximise`, `centre`</span>
:::
::::
## 3. Name icons for what they depict
Icon names **must** describe what the icon shows, not how someone might use it.
:::: example
::: do <LucideIcon name="save" :iconNode="save" /> `floppy-disk`
The icon **shows** a floppy disk.
:::
::: dont <LucideIcon name="save" :iconNode="save" /> `save`
Save is a use case.
:::
::::
:::: example
::: do <LucideIcon name="ban" :iconNode="ban" /> `circle-slash`
The icon **shows** a circle with a slash across it.
:::
::: dont <LucideIcon name="ban" :iconNode="ban" /> `ban`
Ban is an action.
:::
::::
::: tip
An icon can mean different things in different products. Naming icons by appearance keeps names clear and independent from use cases.
:::
## 4. Name related icons consistently
Icons that belong to the same group **must** use the `<group>-<variant>` naming scheme.
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>
`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>
`plus` and `check` are not the group.
:::
::::
## 5. Describe alternate icons
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`
The icon depicts a horizontal "send" symbol.
:::
::: dont <LucideIcon name="send-horizontal" :iconNode="sendHorizontal" /> <span>`send-2` or `send-alt`</span>
"send number 2" and "alternative send" are not clear names.
:::
::::
## 6. Only use numerals when depicted
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`
The arrow points from 0 to 1.
:::
::: dont <LucideIcon name="send-horizontal" :iconNode="sendHorizontal" /> `send-2`
The icon does not show the number 2.
:::
::::
:::: example
::: do <LucideIcon name="clock-3" :iconNode="clock3" /> `clock-3`
The hands point to 3 o'clock.
:::
::: dont <LucideIcon name="user-round" :iconNode="userRound" /> `user-3`
The icon does not show the number 3.
:::
::::
Do not use numbers to separate similar icons.
## 7. Order elements by size
When an icon shows multiple elements of different sizes, order their names from largest to smallest.
For an icon containing a circle and a person:
:::: example
::: do <LucideIcon name="moon-star" :iconNode="moonStar" /> `moon-star`
The `moon` is larger than the `star`.
:::
::: dont <LucideIcon name="circle-user" :iconNode="circleUser" /> `person-circle`
The `person` is **not** larger than the `circle`.
:::
::::
## 8. Order equally sized elements by position
When an icon depicts multiple elements of roughly equal size, their names **must** be ordered according to their visual position.
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`
The `pencil` is **in front** of the `ruler`, so it comes first.
:::
::: do <LucideIcon name="ruler-dimension-line" :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`
The `sun` is **left of** the `snowflake`, so it comes first.
:::
::: dont <LucideIcon name="pencil-ruler-horizontal" :iconNode="pencilRulerHorizontal" /> `ruler-pencil`
The `ruler` is **below** the `pencil`, so `pencil-ruler` is the correct name.
:::
::::
## 9. Place modifiers after the element they describe
Modifiers **must** come after the element they describe: `<element>-<modifier>`.
:::: example
::: do <LucideIcon name="heart-crack" :iconNode="heartCrack" /> `heart-broken`
The icon shows a heart that is **cracked**.
:::
::: dont <LucideIcon name="bone-fracture" :iconNode="boneFracture" /> `broken-bone`
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`
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`
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`.
:::
::::
## Summary
When naming an icon:
1. **Describe what you see**, not what the icon could mean.
2. **Use American English** and **lowercase kebab-case**.
3. **Keep related icons together** with `<group>-<variant>`.
4. **Describe what makes an alternate unique** instead of numbering it.
5. **Only use numerals when they are depicted** in the icon.
6. **Order elements from largest to smallest**.
7. If elements are roughly the same size, order them **front to back**, or otherwise in **English reading order**.
8. **Place modifiers after the element they describe**: `<element>-<modifier>`.
+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.
-31
View File
@@ -1,31 +0,0 @@
---
title: Illustrator Template Guide
---
# Illustrator Template Guide
This Guide explains how to properly use the Adobe Illustrator Template for Lucide.
>Attention: Even though it is unlikely the template can be outdated or not 100% correct. Please check the Icon Design Guide before you start working with the template to ensure integrity with the Lucide icon pack.
## General Workflow
The Illustrator template is created following guidelines from the [Icon Design Guide](icon-design-guide.md).
**Workflow:**
1. Download and open the [Illustrator template](https://github.com/lucide-icons/lucide/blob/main/docs/public/templates/illustrator_template.ai).
2. You can now remove the content from the example logo layer ("Draw") and start creating.
3. Verify that you follow the [Icon Design Guidelines](icon-design-guide.md).
4. Before you export the file as an SVG make sure to check that you followed the guidelines and remove all unnecessary layers (especially "Padding" and "Grid").
5. Export the file with the export menu under: `Export > Export As..` then save the file as SVG. Select the following options in the SVG Options dialog:
![SVG export options in Illustrator](../images/illustrator-svg-options.png?raw=true "Setting Page Size")
After that, double check that the [code conventions and SVG global attributes](icon-design-guide.md#code-conventions) are correct.
7. Minify paths with [SVGOMG](https://jakearchibald.github.io/svgomg/).
-41
View File
@@ -1,41 +0,0 @@
---
title: Icon Design Guide
---
# Inkscape Setup Guide
This guide shows the steps to setup Inkscape for creating icons that conform to the Lucide design
guidelines.
## Setting up The Canvas
When opening a new document, Inkscape will create a canvas of a default size. To change the size to 24x24:
1. Open the Document Properties dialog (File -> Document Properties).
2. On the “Page Size” tab, under “Custom Size” set the Units to `px` and set both Height and Width to 24.
![Setting Page Size](../images/page-size.png?raw=true "Setting Page Size")
3. On the “Grid” tab, select `Rectangular Grid` and click “New Grid”.
![Setting Grid Properties](../images/grid-1.png?raw=true "Setting Grid Properties")
4. Set the Grid Units to `px` and set Spacing X and Spacing Y both to 1.
![Setting Grid Properties](../images/grid-2.png?raw=true "Setting Grid Properties")
5. Close the Document Properties dialog.
6. To center the canvas in the viewport, select View -> Zoom -> Drawing.
## Setting up The Paths
1. Create a path or shape.
2. With the path selected, open the Stroke and Fill panel by pressing `Ctrl+Shift+F` on your keyboard.
![Stroke Style Properties](../images/strokes.png?raw=true "Setting Grid Properties")
3. On the “Stroke Style” tab:
* Set Stroke Width to `2px`.
* Select the rounded join type.
* Select the rounded cap type.
4. If the shape is a rectangle, select the rectangle and in the top of the screen below the menu bar, set `Rx` and `Ry` to `2px`.
![Rectangle Radius Properties](../images/corner-radius.png?raw=true "Rectangle Radius Properties")
## Saving A File
1. When ready to save the file, click Save As and select “Optimized SVG” as the file type.
![Save As](../images/save-as.png?raw=true "Save as")
2. After clicking Save, to conform with the other icons in the package, set Pretty Printing to use spaces and set the indentation depth to 2.
![Optimize](../images/optimize-settings.png?raw=true "Optimize")
+54 -46
View File
@@ -2,6 +2,7 @@
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>
@@ -14,28 +15,32 @@ 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">
<svg lucideUser
[size]="12"
x="6"
y="6"
[strokeWidth]="4"
[absoluteStrokeWidth]="true"
/>
</svg>`,
template: ` <svg
lucideScan
[size]="48"
[nonScalingStroke]="true"
>
<svg
lucideUser
[size]="12"
x="6"
y="6"
[strokeWidth]="4"
[nonScalingStroke]="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.
@@ -53,28 +58,29 @@ 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,
})
@@ -82,38 +88,40 @@ 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 {}
```
:::
+31 -32
View File
@@ -2,6 +2,7 @@
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>
@@ -29,9 +30,9 @@ import { provideLucideConfig } from '@lucide/angular';
export const appConfig: ApplicationConfig = {
providers: [
provideLucideConfig({
strokeWidth: 1.5
strokeWidth: 1.5,
}),
]
],
};
```
@@ -65,7 +66,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,
@@ -76,7 +77,7 @@ import {
LucideSandwich,
LucideWine,
LucideDessert,
} from "@lucide/angular";
} from '@lucide/angular';
@Component({
selector: 'app',
@@ -92,28 +93,27 @@ 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 {}
```
:::
### Absolute stroke width
### Non-scaling strokes
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.
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.
::: 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,21 +164,20 @@ 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 {}
```
:::
@@ -13,7 +13,7 @@ import Sandpack from '~/.vitepress/theme/components/editors/SandpackAngular.vue'
While they aren't provided as standalone components, they can be still be passed to the `LucideIcon` component the same way as official icons:
::: info Limitation
Only custom icons that follow Lucide's [code conventions](../../../contribute/icon-design-guide.md#code-conventions) are supported.
Only custom icons that follow Lucide's [code conventions](../../../contribute/icons/code-conventions.md#code-conventions) are supported.
:::
### Directly as LucideIconData
+23 -19
View File
@@ -1,7 +1,8 @@
---
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 `absoluteStrokeWidth` 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 `nonScalingStroke` input.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackAngular.vue'
</script>
@@ -18,55 +19,58 @@ 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 {}
```
:::
## Absolute stroke width
## Non-scaling strokes
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.
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.
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.
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.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
### Adjusting stroke width with `absoluteStrokeWidth` input
### Adjusting stroke width with `nonScalingStroke` input
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
::: 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"
[absoluteStrokeWidth]="true"
[nonScalingStroke]="true"
></svg>
`,
`,
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None,
})
export class App {
}
export class App {}
```
:::
+17 -10
View File
@@ -2,6 +2,7 @@
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'
@@ -56,7 +57,7 @@ import { LucideFileText } from '@lucide/angular';
template: '<svg lucideFileText></svg>',
imports: [LucideFileText],
})
export class App { }
export class App {}
```
### Dynamic icon component
@@ -74,7 +75,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));
}
```
@@ -82,18 +83,24 @@ 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 |
| `absoluteStrokeWidth` | *boolean* | false |
| `title` | *string* | null |
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `strokeWidth` | _number_ | 2 |
| `nonScalingStroke` | _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:
+2 -2
View File
@@ -27,9 +27,9 @@ Every icon has a class attribute applied called `lucide`. This class name can be
}
```
### Absolute stroke width
### Non-scaling strokes
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.
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.
```css
.lucide {
+10 -3
View File
@@ -18,13 +18,19 @@ 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
@@ -50,7 +56,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`
@@ -103,12 +109,13 @@ 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 absoluteStrokeWidth props.
description: Learn how to customize the stroke width of Lucide icons in your Astro applications using the strokeWidth and nonScalingStroke props.
---
# Stroke width
@@ -20,19 +20,19 @@ import FolderLock from '@lucide/astro/icons/folder-lock';
<FolderLock strokeWidth={1} />
```
## Absolute stroke width
## 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 `absoluteStrokeWidth` 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 `nonScalingStroke` 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.
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.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
### Adjusting stroke width with `absoluteStrokeWidth` prop
### Adjusting stroke width with `nonScalingStroke` prop
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
```astro
---
@@ -41,6 +41,6 @@ import RollerCoaster from '@lucide/astro/icons/roller-coaster';
<RollerCoaster
size={96}
absoluteStrokeWidth
nonScalingStroke
/>
```
+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 |
| `absoluteStrokeWidth` | *boolean* | false |
| `default-class` | *string* | lucide-icon |
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `stroke-width` | _number_ | 2 |
| `nonScalingStroke` | _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).
@@ -2,8 +2,7 @@
`@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** — 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.
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.
## Installation
@@ -35,14 +34,11 @@ 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). |
@@ -65,16 +61,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). |
| `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.). |
| 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). |
::: 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}`.
@@ -127,6 +123,7 @@ 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`
@@ -138,15 +135,18 @@ 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,6 +156,7 @@ 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.
+16 -14
View File
@@ -1,7 +1,8 @@
---
title: Stroke width - Lucide
description: Learn how to customize the stroke width of Lucide icons in your Vanilla JavaScript applications using the strokeWidth and absoluteStrokeWidth attributes.
description: Learn how to customize the stroke width of Lucide icons in your Vanilla JavaScript applications using the strokeWidth and nonScalingStroke attributes.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/Sandpack.vue'
</script>
@@ -18,10 +19,13 @@ 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>
@@ -29,34 +33,32 @@ 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
<!-- ## 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 `absoluteStrokeWidth` 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 `nonScalingStroke` 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.
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
[Non-scaling stroke comparison](../../../images/non-scaling-stroke-compare.svg)
### Adjusting stroke width with `absoluteStrokeWidth` prop
### Adjusting stroke width with `nonScalingStroke` prop
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
::: sandpack {template=vanilla showTabs=false editorHeight=250 editorWidthPercentage=70 dependencies="lucide"}
@@ -64,7 +66,7 @@ Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
<!DOCTYPE html>
<html>
<body>
<i data-lucide="roller-coaster" stroke-width="96" absolute-stroke-width="true"></i>
<i data-lucide="roller-coaster" stroke-width="96" non-scaling-stroke="true"></i>
<script src="index.js"></script>
</body>
-286
View File
@@ -1,286 +0,0 @@
# `@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).
-210
View File
@@ -1,210 +0,0 @@
# 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
@@ -1,149 +0,0 @@
---
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
@@ -1,133 +0,0 @@
# 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
@@ -1,162 +0,0 @@
# 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
@@ -1,265 +0,0 @@
# 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
@@ -1,349 +0,0 @@
# 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
@@ -1,171 +0,0 @@
# 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).
+15 -11
View File
@@ -2,6 +2,7 @@
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>
@@ -14,18 +15,21 @@ 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}>
<Scan
size={48}
nonScalingStroke
>
<User
size={12}
x={6}
y={6}
absoluteStrokeWidth
nonScalingStroke
/>
</Scan>
</div>
@@ -33,8 +37,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.
@@ -55,8 +59,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;
@@ -79,8 +83,8 @@ function App() {
}
export default App;
```
:::
### Example with text element
@@ -90,8 +94,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 (
@@ -112,6 +116,6 @@ function App() {
}
export default App;
```
:::
+10 -10
View File
@@ -2,6 +2,7 @@
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>
@@ -34,8 +35,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
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.
@@ -74,9 +75,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 (
@@ -99,10 +100,9 @@ export default App;
:::
### Non-scaling strokes
### 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.
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.
::: 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 (
+12 -1
View File
@@ -2,6 +2,7 @@
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.
@@ -16,12 +17,17 @@ 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
@@ -76,6 +82,7 @@ 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
@@ -89,7 +96,11 @@ const customIcon: IconNode = [
const MyCustomIcon = () => {
return (
<Icon iconNode={customIcon} size={24} color="blue" />
<Icon
iconNode={customIcon}
size={24}
color="blue"
/>
);
};
+15 -12
View File
@@ -1,7 +1,8 @@
---
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 `absoluteStrokeWidth` 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 `nonScalingStroke` prop.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackPreact.vue'
</script>
@@ -18,8 +19,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 (
@@ -31,34 +32,35 @@ function App() {
export default App;
```
:::
## Absolute stroke width
## 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 `absoluteStrokeWidth` 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 `nonScalingStroke` 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.
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.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
### Adjusting stroke width with `absoluteStrokeWidth` prop
### Adjusting stroke width with `nonScalingStroke` prop
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
::: 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}
absoluteStrokeWidth={true}
nonScalingStroke
/>
</div>
);
@@ -66,4 +68,5 @@ function App() {
export default App;
```
:::
+14 -7
View File
@@ -2,6 +2,7 @@
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'
@@ -56,19 +57,25 @@ 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 |
| `absoluteStrokeWidth` | *boolean* | false |
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `strokeWidth` | _number_ | 2 |
| `nonScalingStroke` | _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}>
<Scan size={48} nonScalingStroke>
<User
size={12}
x={6}
y={6}
absoluteStrokeWidth
nonScalingStroke
/>
</Scan>
</View>
+12 -1
View File
@@ -2,6 +2,7 @@
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.
@@ -16,12 +17,17 @@ 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
@@ -75,6 +81,7 @@ 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
@@ -88,7 +95,11 @@ const customIcon: IconNode = [
const MyCustomIcon = () => {
return (
<Icon iconNode={customIcon} size={24} color="blue" />
<Icon
iconNode={customIcon}
size={24}
color="blue"
/>
);
};
+10 -9
View File
@@ -1,7 +1,8 @@
---
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 `absoluteStrokeWidth` 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 `nonScalingStroke` prop.
---
# Stroke width
All icons are designed with SVG elements using strokes.
@@ -29,19 +30,19 @@ const App = () => {
export default App;
```
## Absolute stroke width
## 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 `absoluteStrokeWidth` 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 `nonScalingStroke` 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.
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.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
### Adjusting stroke width with `absoluteStrokeWidth` prop
### Adjusting stroke width with `nonScalingStroke` prop
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
```SnackPlayer name=State&ext=js&dependencies=react-native-svg,lucide-react-native
import React, {useState, useEffect} from 'react';
@@ -55,7 +56,7 @@ const App = () => {
<View style={style}>
<RollerCoaster
size={96}
absoluteStrokeWidth={true}
nonScalingStroke
/>
</View>
);
@@ -67,7 +68,7 @@ export default App;
<!-- <Sandpack
template="react"
:theme="sandpackTheme"
:files="absoluteStrokeWidth"
:files="nonScalingStroke"
:customSetup='{
dependencies: {
"lucide-react": "latest"
+14 -7
View File
@@ -2,6 +2,7 @@
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'
@@ -58,19 +59,25 @@ 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 |
| `absoluteStrokeWidth` | *boolean* | false |
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `strokeWidth` | _number_ | 2 |
| `nonScalingStroke` | _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}
/>
);
};
```
+2 -2
View File
@@ -19,12 +19,12 @@ import { Scan, User } from "lucide-react";
function App() {
return (
<div className="app">
<Scan size={48}>
<Scan size={48} nonScalingStroke>
<User
size={12}
x={6}
y={6}
absoluteStrokeWidth
nonScalingStroke
/>
</Scan>
</div>
+2 -2
View File
@@ -99,9 +99,9 @@ export default App;
:::
### Absolute stroke width
### Non-scaling strokes
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.
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.
::: sandpack {template=react editorHeight=300 dependencies="lucide-react"}
+4
View File
@@ -16,6 +16,10 @@ 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 `absoluteStrokeWidth` 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 `nonScalingStroke` prop.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/Sandpack.vue'
@@ -33,19 +33,19 @@ export default App;
:::
## Absolute stroke width
## 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 `absoluteStrokeWidth` 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 `nonScalingStroke` 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.
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.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
### Adjusting stroke width with `absoluteStrokeWidth` prop
### Adjusting stroke width with `nonScalingStroke` prop
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
::: sandpack {template=react showTabs=false editorHeight=320 editorWidthPercentage=60 dependencies="lucide-react"}
@@ -57,7 +57,7 @@ function App() {
<div className="app">
<RollerCoaster
size={96}
absoluteStrokeWidth={true}
nonScalingStroke
/>
</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 |
| `absoluteStrokeWidth` | *boolean* | false |
| name | type | default |
|--------------------| --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `strokeWidth` | *number* | 2 |
| `nonScalingStroke` | *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).
+6 -2
View File
@@ -2,6 +2,7 @@
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'
@@ -21,12 +22,15 @@ import User from 'lucide-solid/icons/user';
function App() {
return (
<div class="app">
<Scan size={48}>
<Scan
size={48}
nonScalingStroke
>
<User
size={12}
x={6}
y={6}
absoluteStrokeWidth
nonScalingStroke
/>
</Scan>
</div>
+7 -6
View File
@@ -2,6 +2,7 @@
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>
@@ -36,8 +37,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
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,7 +76,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 (
@@ -95,11 +96,12 @@ function App() {
export default App;
```
:::
### Absolute stroke width
### Non-scaling strokes
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.
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.
::: sandpack {template=vite-solid editorHeight=300 editorWidthPercentage=60 dependencies="lucide-solid"}
@@ -120,7 +122,6 @@ For global absolute stroke width styling the `vector-effect: non-scaling-stroke`
grid-template-rows: 1fr 1fr 1fr;
gap: 6px;
}
```
```tsx App.tsx
@@ -133,7 +134,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 (
+12 -1
View File
@@ -2,6 +2,7 @@
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.
@@ -16,12 +17,17 @@ 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
@@ -76,6 +82,7 @@ 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
@@ -89,7 +96,11 @@ const customIcon: IconNode = [
const MyCustomIcon = () => {
return (
<Icon iconNode={customIcon} size={24} color="blue" />
<Icon
iconNode={customIcon}
size={24}
color="blue"
/>
);
};
+11 -8
View File
@@ -1,7 +1,8 @@
---
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 `absoluteStrokeWidth` 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 `nonScalingStroke` prop.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/Sandpack.vue'
</script>
@@ -30,21 +31,22 @@ function App() {
export default App;
```
:::
## Absolute stroke width
## 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 `absoluteStrokeWidth` 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 `nonScalingStroke` 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.
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.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
### Adjusting stroke width with `absoluteStrokeWidth` prop
### Adjusting stroke width with `nonScalingStroke` prop
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
::: sandpack {template=vite-solid showTabs=false editorHeight=320 editorWidthPercentage=60 dependencies="lucide-solid"}
@@ -56,7 +58,7 @@ function App() {
<div class="app">
<RollerCoaster
size={96}
absoluteStrokeWidth={true}
nonScalingStroke
/>
</div>
);
@@ -64,4 +66,5 @@ function App() {
export default App;
```
:::
+13 -7
View File
@@ -57,19 +57,25 @@ 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 |
| `absoluteStrokeWidth` | *boolean* | false |
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `strokeWidth` | _number_ | 2 |
| `nonScalingStroke` | _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}
/>
);
};
```
@@ -2,6 +2,7 @@
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>
@@ -20,12 +21,12 @@ import User from '@lucide/svelte/icons/user';
</script>
<div class="app">
<Scan size="48">
<Scan size="48" nonScalingStroke>
<User
size="12"
x="6"
y="6"
absoluteStrokeWidth
nonScalingStroke
/>
</Scan>
</div>
+5 -2
View File
@@ -2,6 +2,7 @@
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>
@@ -89,11 +90,12 @@ import "./icon.css";
<Dessert />
</div>
```
:::
### Absolute stroke width
### Non-scaling strokes
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.
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.
::: sandpack {template=vite-svelte editorHeight=420 editorWidthPercentage=55}
@@ -143,4 +145,5 @@ import "./icon.css";
<Sparkles />
</div>
```
:::
+15 -3
View File
@@ -2,6 +2,7 @@
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.
@@ -17,6 +18,10 @@ 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
@@ -24,9 +29,11 @@ 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';
@@ -40,6 +47,7 @@ let props: LucideProps = $props();
</div>
</template>
```
:::
## `LucideIcon`
@@ -49,7 +57,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`
@@ -135,6 +143,7 @@ You can use the `LucideIcon` type when you need to work with icon components dir
{/each}
```
:::
## `IconNode`
@@ -144,15 +153,17 @@ 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';
@@ -166,4 +177,5 @@ const customIcon: IconNode = [
<Icon iconNode={customIcon} size="24" color="blue" />
```
:::
+10 -8
View File
@@ -1,7 +1,8 @@
---
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 `absoluteStrokeWidth` 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 `nonScalingStroke` prop.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackSvelte.vue'
</script>
@@ -24,21 +25,22 @@ import FolderLock from "@lucide/svelte/icons/folder-lock";
<FolderLock strokeWidth={1} />
```
:::
## Absolute stroke width
## 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 `absoluteStrokeWidth` 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 `nonScalingStroke` 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.
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.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
### Adjusting stroke width with `absoluteStrokeWidth` prop
### Adjusting stroke width with `nonScalingStroke` prop
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
::: sandpack {template=vite-svelte editorHeight=240 editorWidthPercentage=60}
@@ -49,7 +51,7 @@ import RollerCoaster from "@lucide/svelte/icons/roller-coaster";
<RollerCoaster
size={96}
absoluteStrokeWidth
nonScalingStroke
/>
```
+8 -7
View File
@@ -2,6 +2,7 @@
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'
@@ -53,13 +54,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 |
| `absoluteStrokeWidth` | *boolean* | false |
| `default-class` | *string* | lucide-icon |
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `stroke-width` | _number_ | 2 |
| `nonScalingStroke` | _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).
+9 -8
View File
@@ -2,6 +2,7 @@
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>
@@ -15,22 +16,24 @@ 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">
<Scan
:size="48"
nonScalingStroke
>
<User
:size="12"
x="6"
y="6"
absoluteStrokeWidth
nonScalingStroke
/>
</Scan>
</div>
</template>
```
:::
@@ -54,7 +57,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>
@@ -73,7 +76,6 @@ const hasUnreadMessages = true;
</Mail>
</div>
</template>
```
:::
@@ -86,7 +88,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>
@@ -104,7 +106,6 @@ import { File } from "@lucide/vue";
</File>
</div>
</template>
```
:::
+9 -7
View File
@@ -2,6 +2,7 @@
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>
@@ -74,9 +75,9 @@ import {
Sandwich,
Wine,
Dessert,
} from "@lucide/vue";
} from '@lucide/vue';
import "./icon.css";
import './icon.css';
</script>
<template>
@@ -93,11 +94,12 @@ import "./icon.css";
</div>
</template>
```
:::
### Absolute stroke width
### Non-scaling strokes
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.
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.
::: sandpack {template=vue editorHeight=300 editorWidthPercentage=55 dependencies="@lucide/vue"}
@@ -132,9 +134,9 @@ import {
Map,
CloudMoon,
Sparkles,
} from "@lucide/vue";
} from '@lucide/vue';
import "./icon.css";
import './icon.css';
</script>
<template>
@@ -150,6 +152,6 @@ import "./icon.css";
<Sparkles />
</div>
</template>
```
:::
+22 -2
View File
@@ -2,6 +2,7 @@
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.
@@ -16,15 +17,21 @@ 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';
@@ -39,6 +46,7 @@ defineProps<LucideProps>();
</div>
</template>
```
:::
## `LucideIcon`
@@ -54,6 +62,7 @@ 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';
@@ -67,10 +76,14 @@ defineProps<{
<template>
<button :aria-label="label">
<component :is="icon" :size="16" />
<component
:is="icon"
:size="16"
/>
</button>
</template>
```
:::
## `IconNode`
@@ -83,9 +96,11 @@ 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';
@@ -98,7 +113,12 @@ const customIcon: IconNode = [
</script>
<template>
<Icon :iconNode="customIcon" size="24" color="blue" />
<Icon
:iconNode="customIcon"
size="24"
color="blue"
/>
</template>
```
:::
+13 -11
View File
@@ -1,7 +1,8 @@
---
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 `absoluteStrokeWidth` 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 `nonScalingStroke` prop.
---
<script setup>
import Sandpack from '~/.vitepress/theme/components/editors/SandpackVue.vue'
</script>
@@ -19,42 +20,43 @@ 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>
```
:::
## Absolute stroke width
## 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 `absoluteStrokeWidth` 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 `nonScalingStroke` 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.
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.
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
![Absolute stroke width comparison](../../../images/absolute-stroke-width-compare.png?raw=true "Absolute stroke width comparison")
<!--@include: ../../../images/non-scaling-stroke-compare.svg -->
### Adjusting stroke width with `absoluteStrokeWidth` prop
### Adjusting stroke width with `nonScalingStroke` prop
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
Setting `nonScalingStroke` to `true` will make the stroke width non-scaling.
::: 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"
absoluteStrokeWidth
nonScalingStroke
/>
</template>
```
:::
+13 -8
View File
@@ -2,6 +2,7 @@
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'
@@ -55,13 +56,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 |
| `absoluteStrokeWidth` | *boolean* | false |
| `default-class` | *string* | lucide-icon |
| name | type | default |
| ------------------ | --------- | ------------ |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `stroke-width` | _number_ | 2 |
| `nonScalingStroke` | _boolean_ | false |
| `default-class` | _string_ | lucide-icon |
### Applying props
@@ -69,7 +70,11 @@ 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>
```
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

+69
View File
@@ -0,0 +1,69 @@
<svg width="240" height="240" viewBox="0 0 240 240" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1939_21540)">
<path d="M0 10H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M10 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 20H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M20 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 30H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M30 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 40H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M40 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 50H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M50 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 60H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M60 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 70H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M70 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 80H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M80 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 90H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M90 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 100H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M100 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 110H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M110 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 120H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M120 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 130H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M130 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 140H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M140 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 150H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M150 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 160H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M160 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 170H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M170 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 180H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M180 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 190H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M190 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 200H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M200 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 210H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M210 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 220H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M220 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 230H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M230 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
</g>
<path d="M200 80H100C88.9543 80 80 88.9543 80 100V200C80 211.046 88.9543 220 100 220H200C211.046 220 220 211.046 220 200V100C220 88.9543 211.046 80 200 80Z" stroke="black" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M160 50V40C160 29 151 20 140 20H40C29 20 20 29 20 40V140C20 151 29 160 40 160H50" stroke="black" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
<rect x="70" y="123" width="74" height="10" transform="rotate(90 70 123)" fill="url(#paint0_linear_1939_21540)"/>
<rect x="123" y="60" width="74" height="10" fill="url(#paint1_linear_1939_21540)"/>
<defs>
<linearGradient id="paint0_linear_1939_21540" x1="70" y1="127.25" x2="144" y2="127.25" gradientUnits="userSpaceOnUse">
<stop stop-color="#DD0031" stop-opacity="0"/>
<stop offset="0.499255" stop-color="#DD0031"/>
<stop offset="1" stop-color="#DD0031" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint1_linear_1939_21540" x1="123" y1="64.25" x2="197" y2="64.25" gradientUnits="userSpaceOnUse">
<stop stop-color="#DD0031" stop-opacity="0"/>
<stop offset="0.499255" stop-color="#DD0031"/>
<stop offset="1" stop-color="#DD0031" stop-opacity="0"/>
</linearGradient>
<clipPath id="clip0_1939_21540">
<rect width="240" height="240" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

+5
View File
@@ -0,0 +1,5 @@
<svg width="120" height="120" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 10H120M0 20H120M0 30H120M5 0V120M0 40H120M15 0V120M0 50H120M25 0V120M0 60H120M35 0V120M0 70H120M45 0V120M0 80H120M55 0V120M0 90H120M65 0V120M0 100H120M75 0V120M0 110H120M85 0V120M95 0V120M105 0V120M115 0V120" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M35 89.9999L84.9998 59.9999L35 29.9999V89.9999Z" stroke="black" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="52" cy="60" r="10" fill="#DD0031" fill-opacity="0.2" stroke="#DD0031" stroke-dasharray="1 1"/>
</svg>

After

Width:  |  Height:  |  Size: 613 B

+86
View File
@@ -0,0 +1,86 @@
<svg width="240" height="240" viewBox="0 0 240 240" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1940_23527)">
<path d="M0 10H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M10 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 20H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M20 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 30H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M30 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 40H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M40 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 50H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M50 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 60H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M60 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 70H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M70 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 80H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M80 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 90H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M90 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 100H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M100 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 110H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M110 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 120H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M120 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 130H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M130 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 140H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M140 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 150H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M150 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 160H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M160 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 170H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M170 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 180H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M180 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 190H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M190 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 200H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M200 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 210H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M210 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 220H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M220 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M0 230H240" stroke="#D8D8D9" stroke-width="0.5"/>
<path d="M230 0V240" stroke="#D8D8D9" stroke-width="0.5"/>
</g>
<path d="M79.9999 150V55C79.9999 46.7157 86.7157 40 94.9999 40C103.284 40 110 46.7157 110 55V105V35C110 26.7157 116.716 20 125 20C133.284 20 140 26.7157 140 35V100V55C140 46.7157 146.716 40 155 40C163.284 40 170 46.7157 170 55V110V75C170 66.7157 176.716 60 185 60C193.284 60 200 66.7157 200 75V154.75C200 190.786 170.786 220 134.75 220C112.5 220 91.1612 211.161 75.4282 195.428L37.4999 157.5C30.5964 150.596 30.5964 139.404 37.4999 132.5C44.4035 125.596 55.5964 125.596 62.4999 132.5L89.9999 160" stroke="black" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
<rect x="47.917" y="132.154" width="74" height="15.4386" transform="rotate(45 47.917 132.154)" fill="url(#paint0_linear_1940_23527)"/>
<rect x="190" y="66" width="74" height="10" transform="rotate(90 190 66)" fill="url(#paint1_linear_1940_23527)"/>
<rect x="160" y="49" width="74" height="10" transform="rotate(90 160 49)" fill="url(#paint2_linear_1940_23527)"/>
<rect x="130" y="36" width="74" height="10" transform="rotate(90 130 36)" fill="url(#paint3_linear_1940_23527)"/>
<rect x="100" y="49" width="74" height="10" transform="rotate(90 100 49)" fill="url(#paint4_linear_1940_23527)"/>
<defs>
<linearGradient id="paint0_linear_1940_23527" x1="47.917" y1="138.716" x2="121.917" y2="138.716" gradientUnits="userSpaceOnUse">
<stop stop-color="#DD0031" stop-opacity="0"/>
<stop offset="0.499255" stop-color="#DD0031"/>
<stop offset="1" stop-color="#DD0031" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint1_linear_1940_23527" x1="190" y1="70.25" x2="264" y2="70.25" gradientUnits="userSpaceOnUse">
<stop stop-color="#DD0031" stop-opacity="0"/>
<stop offset="0.499255" stop-color="#DD0031"/>
<stop offset="1" stop-color="#DD0031" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint2_linear_1940_23527" x1="160" y1="53.25" x2="234" y2="53.25" gradientUnits="userSpaceOnUse">
<stop stop-color="#DD0031" stop-opacity="0"/>
<stop offset="0.499255" stop-color="#DD0031"/>
<stop offset="1" stop-color="#DD0031" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint3_linear_1940_23527" x1="130" y1="40.25" x2="204" y2="40.25" gradientUnits="userSpaceOnUse">
<stop stop-color="#DD0031" stop-opacity="0"/>
<stop offset="0.499255" stop-color="#DD0031"/>
<stop offset="1" stop-color="#DD0031" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint4_linear_1940_23527" x1="100" y1="53.25" x2="174" y2="53.25" gradientUnits="userSpaceOnUse">
<stop stop-color="#DD0031" stop-opacity="0"/>
<stop offset="0.499255" stop-color="#DD0031"/>
<stop offset="1" stop-color="#DD0031" stop-opacity="0"/>
</linearGradient>
<clipPath id="clip0_1940_23527">
<rect width="240" height="240" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.4 KiB

+67
View File
@@ -0,0 +1,67 @@
<svg width="244" height="184" viewBox="0 0 244 184" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1946_25554)">
<path d="M62 37H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M67 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 42H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M72 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 47H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M77 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 52H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M82 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 57H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M87 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 62H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M92 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 67H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M97 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 72H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M102 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 77H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M107 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 82H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M112 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 87H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M117 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 92H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M122 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 97H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M127 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 102H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M132 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 107H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M137 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 112H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M142 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 117H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M147 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 122H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M152 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 127H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M157 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 132H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M162 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 137H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M167 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 142H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M172 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M62 147H182" stroke="#D8D8D9" stroke-width="0.25"/>
<path d="M177 32V152" stroke="#D8D8D9" stroke-width="0.25"/>
</g>
<mask id="mask0_1946_25554" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="42" y="12" width="160" height="160">
<path d="M202 172H42V12H202V172ZM62 32V152H182V32H62Z" fill="#D9D9D9"/>
</mask>
<g mask="url(#mask0_1946_25554)">
<path d="M67.025 109.508C71.455 109.519 75.2044 112.41 76.5079 116.403L121.576 136.912C121.704 136.97 121.842 137 121.982 137C122.121 137 122.258 136.97 122.385 136.913L167.39 116.438C168.677 112.446 172.406 109.544 176.83 109.509C182.353 109.465 186.865 113.907 186.909 119.43C186.932 122.436 186.082 125.384 184.46 127.916C182.845 130.436 180.535 132.435 177.808 133.67L177.808 133.671L130.657 155.123C130.653 155.124 130.648 155.126 130.644 155.128C127.923 156.362 124.97 157 121.982 157C118.994 157 116.041 156.362 113.32 155.128C113.316 155.126 113.311 155.125 113.306 155.123L66.0455 133.616C66.025 133.606 66.0048 133.597 65.9844 133.587C63.2939 132.341 61.0182 130.349 59.4263 127.85C57.8345 125.35 56.9928 122.447 57 119.484L57.004 119.226C57.1542 113.822 61.5884 109.495 67.025 109.508ZM176.83 82.0063C182.353 81.9627 186.865 86.4046 186.909 91.9272C186.932 94.9333 186.082 97.8822 184.46 100.414C182.845 102.934 180.535 104.933 177.808 106.168L130.657 127.621C130.653 127.623 130.648 127.625 130.644 127.626C127.923 128.86 124.97 129.498 121.982 129.498C118.994 129.498 116.041 128.86 113.32 127.626C113.316 127.624 113.311 127.622 113.306 127.62L66.0455 106.114C66.0251 106.104 66.0048 106.095 65.9844 106.085C63.2939 104.839 61.0182 102.847 59.4263 100.348C57.8345 97.8479 56.9927 94.9442 57 91.9814L57.004 91.7236C57.1541 86.3203 61.5884 81.9929 67.025 82.0063C71.4548 82.0174 75.2038 84.9075 76.5074 88.9009L121.576 109.41C121.704 109.468 121.842 109.498 121.982 109.498C122.121 109.498 122.258 109.468 122.385 109.411L167.39 88.936C168.677 84.944 172.406 82.0413 176.83 82.0063ZM121.955 47C121.814 47 121.675 47.0302 121.546 47.0889C121.544 47.09 121.541 47.0911 121.539 47.0923L83.3658 64.479L121.598 81.918L121.602 81.9194C121.73 81.978 121.869 82.0083 122.009 82.0083C122.15 82.0083 122.289 81.9781 122.418 81.9194L122.43 81.9141L160.642 64.5288L122.37 47.0923C122.367 47.0912 122.365 47.0899 122.363 47.0889C122.234 47.0302 122.095 47 121.955 47ZM187 64.5317C187 67.5358 186.127 70.4758 184.487 72.9937C182.868 75.48 180.568 77.4487 177.863 78.6665L130.712 100.118L130.711 100.118C127.979 101.363 125.012 102.008 122.009 102.008C119.002 102.008 116.03 101.362 113.295 100.113V100.112L66.1475 78.6079L66.148 78.6074C63.446 77.3893 61.1496 75.4222 59.5318 72.9385C57.8917 70.4206 57.0191 67.4806 57.0191 64.4766C57.0191 61.4725 57.8917 58.5325 59.5318 56.0146L59.6875 55.7803C61.2965 53.4056 63.5343 51.5227 66.1529 50.3433H66.1524L113.24 28.8955V28.895C115.976 27.6462 118.948 27 121.955 27C124.962 27 127.934 27.6462 130.669 28.895L130.669 28.8955L177.868 50.3984L177.867 50.3989C180.485 51.5783 182.723 53.4606 184.332 55.835L184.487 56.0698L184.639 56.3066C186.181 58.7712 187 61.6215 187 64.5317Z" fill="#DD0031" fill-opacity="0.2" stroke="#DD0031" stroke-width="0.5" stroke-dasharray="0.5 0.5"/>
</g>
<path d="M67 92.0063C66.9974 93.0583 67.2963 94.0891 67.8612 94.9762C68.4262 95.8634 69.2335 96.5698 70.1874 97.0117L117.448 118.518C118.873 119.164 120.418 119.498 121.982 119.498C123.546 119.498 125.091 119.164 126.516 118.518L173.667 97.0667C174.64 96.629 175.464 95.9176 176.04 95.019C176.615 94.1205 176.918 93.0737 176.909 92.0063M67 119.508C66.9974 120.56 67.2963 121.591 67.8612 122.478C68.4262 123.366 69.2335 124.072 70.1874 124.514L117.448 146.02C118.873 146.666 120.418 147 121.982 147C123.546 147 125.091 146.666 126.516 146.02L173.667 124.569C174.64 124.131 175.464 123.42 176.04 122.521C176.615 121.623 176.918 120.576 176.909 119.508M126.516 37.992C125.084 37.3383 123.528 37 121.955 37C120.381 37 118.825 37.3383 117.393 37.992L70.2972 59.4437C69.3221 59.8741 68.493 60.579 67.9109 61.4726C67.3289 62.3662 67.019 63.4099 67.019 64.4766C67.019 65.5433 67.3289 66.587 67.9109 67.4806C68.493 68.3742 69.3221 69.0791 70.2972 69.5095L117.448 91.0162C118.88 91.6699 120.436 92.0082 122.009 92.0082C123.583 92.0082 125.139 91.6699 126.571 91.0162L173.722 69.5645C174.697 69.1341 175.526 68.4292 176.108 67.5356C176.69 66.642 177 65.5983 177 64.5316C177 63.4649 176.69 62.4212 176.108 61.5276C175.526 60.634 174.697 59.9291 173.722 59.4987L126.516 37.992Z" stroke="black" stroke-width="10" stroke-linecap="round" stroke-linejoin="round"/>
<mask id="path-50-inside-1_1946_25554" fill="white">
<path d="M182 32V152H62V32H182ZM67 147H177V37H67V147Z"/>
</mask>
<path d="M182 32V152H62V32H182ZM67 147H177V37H67V147Z" fill="#DD0031" fill-opacity="0.5"/>
<path d="M182 32H183V31H182V32ZM182 152V153H183V152H182ZM62 152H61V153H62V152ZM62 32V31H61V32H62ZM67 147H66V148H67V147ZM177 147V148H178V147H177ZM177 37H178V36H177V37ZM67 37V36H66V37H67ZM182 32H181V152H182H183V32H182ZM182 152V151H62V152V153H182V152ZM62 152H63V32H62H61V152H62ZM62 32V33H182V32V31H62V32ZM67 147V148H177V147V146H67V147ZM177 147H178V37H177H176V147H177ZM177 37V36H67V37V38H177V37ZM67 37H66V147H67H68V37H67Z" fill="#DD0031" fill-opacity="0.25" mask="url(#path-50-inside-1_1946_25554)"/>
<defs>
<clipPath id="clip0_1946_25554">
<rect width="120" height="120" fill="white" transform="translate(62 32)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 8.0 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

+9
View File
@@ -0,0 +1,9 @@
<svg width="244" height="88" viewBox="0 0 244 88" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M45.8333 32H27.1667C25.6939 32 24.5 33.1939 24.5 34.6667V53.3333C24.5 54.8061 25.6939 56 27.1667 56H45.8333C47.3061 56 48.5 54.8061 48.5 53.3333V34.6667C48.5 33.1939 47.3061 32 45.8333 32Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M68.9545 34.7273L63.3295 55.625H61.054L66.679 34.7273H68.9545Z" fill="black"/>
<path d="M96.6111 40H90.3889C89.898 40 89.5 40.398 89.5 40.8889V47.1111C89.5 47.602 89.898 48 90.3889 48H96.6111C97.102 48 97.5 47.602 97.5 47.1111V40.8889C97.5 40.398 97.102 40 96.6111 40Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M125.955 34.7273L120.33 55.625H118.054L123.679 34.7273H125.955Z" fill="black"/>
<path d="M154.5 34H146.5C145.395 34 144.5 34.8954 144.5 36V52C144.5 53.1046 145.395 54 146.5 54H154.5C155.605 54 156.5 53.1046 156.5 52V36C156.5 34.8954 155.605 34 154.5 34Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M182.955 34.7273L177.33 55.625H175.054L180.679 34.7273H182.955Z" fill="black"/>
<path d="M215.5 38H199.5C198.395 38 197.5 38.8954 197.5 40V48C197.5 49.1046 198.395 50 199.5 50H215.5C216.605 50 217.5 49.1046 217.5 48V40C217.5 38.8954 216.605 38 215.5 38Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

+3 -73
View File
@@ -1,74 +1,4 @@
<svg width="480" height="480" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill="#3C3C43" d="M0 0h480v480H0z"/>
<g clip-path="url(#a)">
<rect x="120" y="120" width="240" height="240" rx="8" fill="#F5F5F5"/>
<path d="M120 130h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M130 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 140h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M140 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 150h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M150 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 160h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M160 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 170h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M170 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 180h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M180 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 190h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M190 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 200h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M200 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 210h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M210 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 220h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M220 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 230h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M230 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 240h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M240 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 250h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M250 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 260h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M260 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 270h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M270 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 280h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M280 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 290h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M290 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 300h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M300 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 310h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M310 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 320h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M320 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 330h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M330 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 340h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M340 120v240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M120 350h240" stroke="#D8D8D9" stroke-width=".5"/>
<path d="M350 120v240" stroke="#D8D8D9" stroke-width=".5"/>
</g>
<g id="embed-lucide-layers" stroke="#3C3C43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(120 120), scale(10)">
<path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z" />
<path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12" />
<path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17" />
</g>
<g opacity=".5" stroke="#fff" stroke-width="3">
<path d="M120 92v16"/>
<path d="M360 92v16"/>
<path d="M120 100h240"/>
</g>
<g opacity=".5" stroke="#fff" stroke-width="3">
<path d="M387.922 120h-16"/>
<path d="M387.922 360h-16"/>
<path d="M379.922 120v240"/>
</g>
<path d="M203.395 86v-3.435l8.025-7.43a30.442 30.442 0 0 0 1.718-1.784c.47-.528.825-1.046 1.068-1.552a3.851 3.851 0 0 0 .363-1.662c0-.66-.151-1.23-.451-1.707a2.964 2.964 0 0 0-1.233-1.112c-.521-.264-1.112-.396-1.773-.396-.69 0-1.291.14-1.805.419-.514.278-.91.678-1.189 1.2-.279.52-.418 1.14-.418 1.86h-4.525c0-1.475.334-2.756 1.002-3.842.668-1.086 1.603-1.927 2.807-2.521 1.204-.594 2.591-.892 4.161-.892 1.615 0 3.02.286 4.217.859 1.203.565 2.139 1.35 2.807 2.356.668 1.005 1.002 2.157 1.002 3.456 0 .852-.169 1.692-.507 2.521-.33.83-.921 1.75-1.772 2.764-.852 1.005-2.052 2.212-3.6 3.621L210 81.95v.154h9.468V86h-16.073Zm18.701-3.963v-3.754l9.412-14.828h3.237v5.196h-1.916l-5.933 9.39v.176h13.375v3.82h-18.175ZM232.917 86v-5.108l.088-1.662V63.454h4.47V86h-4.558Zm10.574 6.34V69.09h4.624v2.841h.209c.205-.455.503-.917.892-1.387.396-.477.91-.873 1.541-1.189.638-.323 1.431-.484 2.378-.484 1.232 0 2.37.323 3.412.969 1.042.638 1.875 1.603 2.499 2.895.624 1.284.936 2.895.936 4.832 0 1.887-.305 3.48-.914 4.778-.602 1.292-1.424 2.272-2.466 2.94-1.035.66-2.194.99-3.478.99-.911 0-1.685-.15-2.323-.451-.631-.301-1.149-.679-1.552-1.134a5.755 5.755 0 0 1-.925-1.398h-.143v9.049h-4.69Zm4.591-14.794c0 1.005.139 1.882.418 2.63.279.75.682 1.332 1.211 1.75.528.412 1.17.617 1.926.617.764 0 1.409-.209 1.938-.627.528-.426.928-1.013 1.2-1.761.279-.756.418-1.626.418-2.61 0-.976-.136-1.834-.407-2.576-.272-.74-.672-1.32-1.2-1.739-.529-.418-1.178-.627-1.949-.627-.763 0-1.409.202-1.937.605-.521.404-.921.976-1.2 1.717-.279.742-.418 1.615-.418 2.62Zm18.34-8.455 3.104 5.912 3.182-5.912h4.81l-4.898 8.455L277.651 86h-4.789l-3.336-5.846-3.28 5.846h-4.844l5.02-8.454-4.844-8.455h4.844Z" fill="#fff"/>
<path d="M392.239 251.5v-3.435l8.025-7.43a30.403 30.403 0 0 0 1.718-1.784c.469-.528.825-1.046 1.067-1.552a3.839 3.839 0 0 0 .364-1.662c0-.661-.151-1.23-.452-1.707a2.96 2.96 0 0 0-1.233-1.111c-.521-.265-1.111-.397-1.772-.397-.69 0-1.292.14-1.805.419-.514.278-.91.678-1.189 1.199-.279.522-.419 1.142-.419 1.861h-4.524c0-1.475.334-2.756 1.002-3.842.667-1.086 1.603-1.927 2.807-2.521 1.203-.594 2.59-.892 4.161-.892 1.615 0 3.02.287 4.216.859 1.204.565 2.14 1.35 2.807 2.356.668 1.005 1.002 2.157 1.002 3.456 0 .852-.169 1.692-.506 2.521-.33.83-.921 1.751-1.773 2.764-.851 1.005-2.051 2.212-3.599 3.621l-3.292 3.226v.154h9.467v3.897h-16.072Zm18.701-3.963v-3.754l9.412-14.828h3.237v5.196h-1.916l-5.934 9.39v.176h13.376v3.82H410.94Zm10.821 3.963v-5.108l.088-1.662v-15.775h4.47V251.5h-4.558Zm10.574 6.341v-23.25h4.623v2.84h.21c.205-.455.502-.917.891-1.387.397-.477.91-.873 1.541-1.189.639-.323 1.432-.484 2.378-.484 1.233 0 2.371.323 3.413.968 1.042.639 1.875 1.604 2.499 2.896.624 1.284.936 2.895.936 4.832 0 1.887-.305 3.479-.914 4.778-.602 1.292-1.424 2.272-2.466 2.939-1.035.661-2.194.991-3.479.991-.91 0-1.684-.15-2.323-.451-.631-.301-1.148-.679-1.552-1.134a5.736 5.736 0 0 1-.924-1.398h-.144v9.049h-4.689Zm4.59-14.796c0 1.006.14 1.883.419 2.631.279.749.682 1.333 1.211 1.751.528.411 1.17.616 1.926.616.763 0 1.409-.209 1.938-.627.528-.426.928-1.013 1.2-1.762.278-.755.418-1.625.418-2.609 0-.976-.136-1.834-.407-2.576-.272-.741-.672-1.321-1.2-1.739-.529-.418-1.178-.627-1.949-.627-.763 0-1.409.201-1.937.605-.521.404-.921.976-1.2 1.717-.279.742-.419 1.615-.419 2.62Zm18.341-8.454 3.104 5.911 3.181-5.911h4.811l-4.899 8.454 5.031 8.455h-4.788l-3.336-5.846-3.281 5.846h-4.843l5.02-8.455-4.844-8.454h4.844Z" fill="#fff"/>
<defs>
<clipPath id="a">
<rect x="120" y="120" width="240" height="240" rx="8" fill="#fff"/>
</clipPath>
</defs>
<svg width="244" height="88" viewBox="0 0 244 88" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M91 35H77C75.8954 35 75 35.8954 75 37V51C75 52.1046 75.8954 53 77 53H91C92.1046 53 93 52.1046 93 51V37C93 35.8954 92.1046 35 91 35Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M109.7 51V49.4091L114.622 44.3097C115.147 43.7557 115.581 43.2704 115.922 42.8537C116.267 42.4323 116.525 42.0322 116.696 41.6534C116.866 41.2746 116.951 40.8722 116.951 40.446C116.951 39.9631 116.838 39.5464 116.61 39.196C116.383 38.8409 116.073 38.5687 115.68 38.3793C115.287 38.1851 114.844 38.0881 114.352 38.0881C113.831 38.0881 113.377 38.1946 112.988 38.4077C112.6 38.6207 112.302 38.9214 112.093 39.3097C111.885 39.6979 111.781 40.1525 111.781 40.6733H109.686C109.686 39.7879 109.889 39.0137 110.297 38.3509C110.704 37.688 111.262 37.1742 111.973 36.8097C112.683 36.4403 113.49 36.2557 114.395 36.2557C115.308 36.2557 116.113 36.438 116.809 36.8026C117.51 37.1624 118.057 37.6548 118.45 38.2798C118.843 38.9001 119.039 39.6009 119.039 40.3821C119.039 40.9219 118.938 41.4498 118.734 41.9659C118.535 42.482 118.187 43.0573 117.69 43.6918C117.193 44.3215 116.502 45.0862 115.616 45.9858L112.725 49.0114V49.1179H119.274V51H109.7ZM121.348 48.1591V46.3835L127.633 36.4545H129.032V39.0682H128.145L123.649 46.1847V46.2983H132.264V48.1591H121.348ZM128.244 51V47.6193L128.258 46.8097V36.4545H130.339V51H128.244ZM143.411 48.5852L135.243 40.4176L136.586 39.0753L144.753 47.2429L143.411 48.5852ZM136.586 48.5852L135.243 47.2429L143.411 39.0753L144.753 40.4176L136.586 48.5852ZM148.059 51V49.4091L152.981 44.3097C153.507 43.7557 153.94 43.2704 154.281 42.8537C154.627 42.4323 154.885 42.0322 155.055 41.6534C155.225 41.2746 155.311 40.8722 155.311 40.446C155.311 39.9631 155.197 39.5464 154.97 39.196C154.743 38.8409 154.432 38.5687 154.039 38.3793C153.646 38.1851 153.204 38.0881 152.711 38.0881C152.19 38.0881 151.736 38.1946 151.348 38.4077C150.959 38.6207 150.661 38.9214 150.453 39.3097C150.244 39.6979 150.14 40.1525 150.14 40.6733H148.045C148.045 39.7879 148.249 39.0137 148.656 38.3509C149.063 37.688 149.622 37.1742 150.332 36.8097C151.042 36.4403 151.85 36.2557 152.754 36.2557C153.668 36.2557 154.473 36.438 155.169 36.8026C155.869 37.1624 156.416 37.6548 156.809 38.2798C157.202 38.9001 157.399 39.6009 157.399 40.3821C157.399 40.9219 157.297 41.4498 157.093 41.9659C156.895 42.482 156.547 43.0573 156.049 43.6918C155.552 44.3215 154.861 45.0862 153.975 45.9858L151.085 49.0114V49.1179H157.633V51H148.059ZM159.707 48.1591V46.3835L165.993 36.4545H167.392V39.0682H166.504L162.008 46.1847V46.2983H170.623V48.1591H159.707ZM166.603 51V47.6193L166.618 46.8097V36.4545H168.699V51H166.603Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

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