Compare commits

...

169 Commits

Author SHA1 Message Date
Eric Fennis
d1d57d3c85 Format code 2025-07-04 17:40:28 +02:00
Eric Fennis
701c2fb6b2 Delete lucide-vue 2024-01-23 18:24:03 +01:00
Eric Fennis
294ec9c727 Add simlinks 2024-01-23 17:46:05 +01:00
Eric Fennis
99c883e60a revert import change 2024-01-23 17:45:55 +01:00
Eric Fennis
9e68779d22 create new vue directory 2024-01-23 17:45:43 +01:00
Daniel Bayley
06372db723 Optimise/add missing calendar[-*] icons/improve metadata (#1377)
* Optimise `calendar`[`-*`] icons

* Add `calendar-plus` variant

* Add `calendar-minus` variant

* Add `calendar-slash` icon

* Improve `calendar`[`-*`] icons metadata

* Add `calendar-fold` icon

* Remove calendar-slash

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-22 20:02:19 +01:00
Eric Fennis
114fb08556 fix icon preview comment (#1823) 2024-01-21 19:45:21 +01:00
Eric Fennis
3bad7f6ced fix site, downgrade sandpack-vue3 2024-01-21 18:20:52 +01:00
Daniel Bayley
e450afe408 Add ticket-* icons/improve metadata (#1312)
* Add `ticket-x` (cancel/refund) icon

* Improve `ticket` metadata

* Add `ticket-slash` (marked/redeemed) icon

* Terminal Add `ticket-check` (purchased) icon

* Add `ticket-plus` (book) icon

* Add `ticket-minus` (remove from basket) icon

* Add `ticket-percent` (discount) icon

* Add `ticket-text` (T&Cs) icon

* Remove ticket text

* Fix duplicate item

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-21 18:04:03 +01:00
Daniel Bayley
6fcfc820ca Add text-search icon (#1807) 2024-01-21 17:22:12 +01:00
dependabot[bot]
55f264bea6 Bump vite from 5.0.10 to 5.0.12 (#1817)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.0.10 to 5.0.12.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.0.12/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.0.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>
2024-01-21 16:46:12 +01:00
Han Yeong-woo
675158df16 Cleanup tools (#1756)
* Use prettier own instead of eslint plugin

* Extend prettier config angular eslint

* Upgrade root prettier to 3

* Fix css syntax errors

* Change eslint ignore to prettier ignore

* Ignore formatting for outputs

* Fix lint-staged error when edited multiple files

* Bump pnpm version

* Remove unnecessary pnpm config

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-18 12:36:48 +01:00
Gustavo Bonfim
042393a931 docs(react-native): fix generic icon import (#1813) 2024-01-18 12:27:02 +01:00
Daniel Bayley
551635003c Optimise/add receipt[-*] icons (#1401)
* Optimise `receipt` icon

* Add `receipt-text` icon

* Improve `receipt` metadata

* Add `receipt-pound-sterling` icon

* Add `receipt-euro` icon

* Add `receipt-swiss-franc` icon

* Add `receipt-japanese-yen` icon

* Add `receipt-indian-rupee` icon

* Add `receipt-russian-ruble` icon

* Add `receipt-cent` icon

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-17 20:06:56 +01:00
Eric Fennis
5c7119f6d1 Export all types lucide-react-native (#1809) 2024-01-17 14:28:14 +01:00
Daniel Bayley
7bfdb2f54a Fix missing metadata (#1808)
* Fix missing metadata

From #1280.

* Fix more missing metadata

From #1378.
2024-01-17 12:13:47 +01:00
Eric Fennis
e3abcdbcc6 Remove v-memo 2024-01-17 11:17:09 +01:00
Daniel Bayley
62d350140e Add missing arrow-*-from-square/optimise external-link icon/s (#1383)
* Add `arrow-up-right-from-square` (share) icon

* Add `arrow-up-left-from-square` icon

* Add `arrow-down-left-from-square` icon

* Add `arrow-down-right-from-square` icon

* Optimise `external-link` icon

* Improve `external-link` metadata

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-16 16:44:44 +01:00
Daniel Bayley
ad90ee7582 Refine file/sticky-note[-*] icons/add file-dot (dotfile) icon (#1378)
* Refine `file`[`-*`] icons

* Refine `sticker` icon fold

* Refine `sticky-note` icon

* Improve `sticky-note` metadata

* Add `sticky-note-text` icon

* Add `file-dot` icon

* Update icons/file-badge-2.svg

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

* Add `file-sliders-big` (config) icon

* Add `file-sliders` (config) icon

* Improve `folder-dot` metadata

* Remove icons

* Remove sticky note text

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Jakob Guddas <github@jguddas.de>
2024-01-16 16:41:08 +01:00
Eric Fennis
b0e825cb57 Site improvements and update site dependencies (#1805)
* try to speed up build times

* Update deps

* Update site deps and fix search issue

* Small improvements

* fix imports

* Remove unused var
2024-01-16 16:22:09 +01:00
Karsa
d4cbe899fb Remove aliasesSupport flag from rollup.config.mjs (#1794)
* Remove aliasesSupport flag from rollup.config.mjs and add always add aliases

* Update rollup.config.mjs

* Update rollup.config.mjs

* Update rollup.config.mjs

* Update rollup.config.mjs

---------

Co-authored-by: Rigó József Karsa <karsa@sztaki.hu>
2024-01-16 16:21:57 +01:00
Daniel Bayley
be3ccc8ece Add/optimise swatch-book/aperture/blend/eclipse (dark/light) mode/paint-roller icons and improve palette/brush metadata (#1280)
* Add `swatch-book` icon

* Improve `palette`/`brush` icons metadata

* Update icons/swatch-book.svg

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

* Add `color-wheel` icon

* Improve `palette`/`swatch-book` icons metadata

* Update icons/color-wheel.svg

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

* Add `paint-roller` icon

* Improve metadata

* Add `contrast` alternate icon

* Add `eclipse` (dark/light mode toggle) icon

* Add `blend` icon

* Refine `color-wheel` icon

* Optimise `aperture` icon

* Add `aperture` variant

* Drop `color-wheel` icon

* Refine `paint-roller` icon

* Fix `aperture-2` optimisation

* Update icons/aperture.svg

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

* Fix `aperture` variant optimisation

* Rename `contrast-2` to `circle-line-vertical`

* Remove aperture-2 and circle-line-vertical

---------

Co-authored-by: Karsa <contact@karsa.org>
Co-authored-by: Jakob Guddas <github@jguddas.de>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-16 15:42:22 +01:00
Eric Fennis
e56b09d400 Add cache header site assets (#1801) 2024-01-13 15:32:18 +01:00
Eric Fennis
7e936c8803 Update stale action 2024-01-13 10:10:43 +01:00
ocavue
c9ffa4033f Add list-collapse icon (#1790)
* Add `list-collapse` icon

* Update icons/list-collapse.json

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

---------

Co-authored-by: Karsa <contact@karsa.org>
2024-01-10 10:12:13 +01:00
Karsa
32a6187d69 Fixes pen-square (#1784) 2024-01-09 15:42:14 +01:00
Staffan Mowitz
2bf20db4bf Update CONTRIBUTING.md (#1787)
Update link for creating a new icon request issue
2024-01-09 11:25:03 +01:00
Eric Fennis
4473df5ad5 Export all types from lucide-svelte (#1779)
* Export all types from lucide-svelte

* Export all types
2024-01-07 17:26:15 +01:00
Jakob Guddas
bc5efd7f0d feat(ci): added filename lint job (#1782) 2024-01-07 17:15:49 +01:00
Eric Fennis
05f209cb04 Fix icon preview comment workflow (#1775)
* Add helpers

* fix preview script

* refactor markup to javascript

* test

* Add escaping

* Try alternative escaping

* test comment markup

* update comment markup

* Revert comment markup step

* revert escaping

* Test with markup file instead of GITHUB_OUTPUT var
2024-01-07 15:59:33 +01:00
Eric Fennis
ef89510a47 Implement deprecated block comment (#1765)
* Implement deprecate comment lucide-react

* Add export template with comment

* Add block comment to Lucide Svelte

* Add blockcomment to lucide-angular

* Add block comment to lucide-static

* revert runtime change build:tags

* Fix failed tests

* Remove optional property in icon schema
2024-01-07 15:59:19 +01:00
Daniel Bayley
b72cea6399 Add notebook/pad[-*] icons & optimise/rename *-edit icons (#1363)
* Add `notebook` icon

* Add `notebook-tabs` (contacts variant) icon

* Add `notebook-text` icon

* Add `notepad-text` icon

* Add `notebook-pen` icon

* Optimise `file-edit` icon

* Rename `file-edit` to `file-pen`

* Optimise `clipboard-edit` icon

* Rename `clipboard-edit` to `clipboard-pen`

* Optimise `folder-edit` icon

* Rename `folder-edit` to `folder-pen`

* Optimise `file-signature` icon

* Rename `file-signature` to `file-pen-line`

* Optimise `clipboard-signature` icon

* Rename `clipboard-signature` to `clipboard-pen-line`

* Add `notepad-text-dashed` (draft/template) icon

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-07 00:16:44 +01:00
Tyrone Tudehope
d2152b3cdd Rename between-horizontal-* icons (#1781) 2024-01-07 00:13:25 +01:00
Jakob Guddas
ea43df6431 Manually optimized folder-sync (#1745)
* Update folder-sync.svg

* Update folder-sync.svg

* Update folder-sync.json

* Update folder-sync.svg

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-05 17:36:55 +01:00
Eric Fennis
4042a366e8 Merge branch 'main' of https://github.com/lucide-icons/lucide 2024-01-05 17:32:54 +01:00
Eric Fennis
5e0ba7e897 fix aliases property in asterisk-square 2024-01-05 17:32:51 +01:00
Daniel Bayley
6b4f575992 Add between-* icons (#1508)
* Add `between-horizontal` icon

* Add `between-vertical` icon

* Rename icons and end icons

* Fix lint issues

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-05 16:58:25 +01:00
Daniel Bayley
92784de9c5 Rename square-* icons appropriately (#1384)
* Rename `square-gantt` to `gantt-square`

* Rename `square-dot` to `dot-square`

* Rename `square-kanban` icons to `kanban-square`

* Rename `square-code` to `code-square`

* Rename `square-asterisk` to `asterisk-square`

* Rename `square-equal` to `equal-square`

* Rename `square-slash` to `slash-square`

* Cleanup merge conflicts

* Add alias back

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-05 16:20:41 +01:00
Daniel Bayley
314ee3b255 Add amenities icons (#1461)
* Add `washing-machine` icon

* Add `safe` icon

* Add `vault` icon

* Add `heater` icon

* Refine `vault` icon

* Refine `safe` icon

* Remove safe icon

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-05 12:47:57 +01:00
Eric Fennis
ee7add11bf fix: Run lint always 2024-01-05 11:50:36 +01:00
Daniel Bayley
001d0a51fb Add bolt (settings variant)/drill icons (#1340)
* Add `bolt` (settings variant) icon

* Add `screw` icon

* Add `screw-head` icon

* Add `drill` icon

* Improve tool icons metadata

* Revert "Add `screw-head` icon"

This reverts commit 15cc69ffea.

* Revert "Add `screw` icon"

This reverts commit bc764555d5.

* Simplify `drill` icon

* Update icons/drill.svg

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

---------

Co-authored-by: Karsa <contact@karsa.org>
2024-01-04 16:24:16 +01:00
Eric Fennis
fd4308e755 Add nitro prepare command docs site (#1774)
* Add nitro prepare command docs site

* Add prepare command to other vitepress commands
2024-01-03 11:39:54 +01:00
SHYAKA Davis
59893119b5 docs: Add Lucide-Svelte icon import instructions and type definitions (#1766)
* docs: Add Lucide-Svelte icon import instructions and type definitions

* Add Svelte docs link.

* apply feedback + recommended import manner

* Refactor menuItems type definition

---------

Co-authored-by: Davis SHYAKA <87414827+davis-shyaka@users.noreply.github.com>
2024-01-03 11:39:42 +01:00
Eric Fennis
faff6a8269 Update dependencies and general improvements in packages (#1773)
* update deps and vitest

* dedupe packages

* update package.json files

* Update to latest vite and vites

* Fix build

* Update lockfile
2024-01-03 11:38:06 +01:00
Han Yeong-woo
3fe74beeb0 Bump github actions (#1755) 2024-01-02 15:33:27 +01:00
Eugene Sviridov
f8aafd63b9 remove mentions of the site folder in doc and config files (#1769) 2024-01-02 15:14:34 +01:00
Daniel Bayley
f0422f415c Sort rows/columns icons (#1500)
* Optimise `rows` icon

* Optimise `columns` icon

* Improve metadata

* Improve metadata

* Add `rows-3` variant

* Rename `rows` to `rows-2`

* Rename `columns` to `columns-2`

* Add `columns-3` variant

* Add `panels-*` to `aliases`

Moved from #1156.

* Add `rows-4` variant

* Add `columns-4` variant

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-12-28 14:47:14 +01:00
Jakob Guddas
14a196d89c Renamed alarm-minus to alarm-clock-minus (#1629)
* Renamed alarm-minus to alarm-minus

* Renamed alarm-plus to alarm-clock-plus

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-12-28 14:41:26 +01:00
Jakob Guddas
87a89b30da Automatic optimisation of squirrel icon (#1764) 2023-12-28 14:31:26 +01:00
Jakob Guddas
3180910b23 Automatic optimisation of rabbit icon (#1763) 2023-12-28 14:30:52 +01:00
Jakob Guddas
46a4041cc7 improved SvgPreview radii highlighting (#1747)
* improved SvgPreview radii highlighting

* Update index.tsx

* Update index.tsx

* Update index.tsx

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-12-28 14:29:46 +01:00
Han Yeong-woo
e3166c65df Fix type error of preact createLucideIcon() (#1754)
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-12-28 14:28:15 +01:00
CokaKoala
d9d7e245a3 fix: Exports Icon type (#1762)
* fixed import path

* export Icon type
2023-12-28 14:26:15 +01:00
Karsa
e19a9cc43a Fixes package list item 404 navigation error (#1751)
Co-authored-by: Rigó József Karsa <karsa@sztaki.hu>
2023-12-26 12:06:09 +01:00
Daniel Bayley
5ecfd61397 Optimise/add remaining panel-*/consolidate layout icons (#1156)
* Optimise `layout` icon

* Optimise `panel-*` icons

…from #1156.

* Fix JSON

* Rename `layout` to `panels-top-left`

* Add `panel-bottom-narrow` (status bar) icon

* Add `panels-left-bottom` icon

* Add `panels-right-bottom` icon

* Add `panels-left-right-bottom` icon

* Add `panels-left-right` icon

* Add `panels-bottom-left-right` icon

* Add `panels-top-split` icon

* Improve metadata

* Rename `panel-top-inactive` to `panel-top-dashed`

* Rename `panel-bottom-inactive` to `panel-bottom-dashed`

* Rename `panel-left-inactive` to `panel-left-dashed`

* Rename `panel-right-inactive` to `panel-right-dashed`

* Add `panel-top-narrow` (menu bar) icon

* Refine/rename `panels-top-split` to `panels-top-narrow-split`

* Remove `panel-bottom-narrow` icon

* Remove `panel-top-narrow` icon

* Remove `panels-bottom-left-right` icon

* Remove `panels-left-right-bottom` icon

* Remove `panels-top-narrow-split` icon

* Remove `panels-left-right` icon

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-12-25 11:28:46 +01:00
Eric Fennis
5366782da0 Adding documentation about Global Styling (#1721)
* Add global styling docs

* Add global styling and filled icon docs

* Fix typos global-styling.md

* Update filled-icons.md
2023-12-24 13:29:05 +01:00
Jakob Guddas
262f9e8865 fix: made cp1 in preview absolute for smooth curves (#1739) 2023-12-24 13:28:53 +01:00
it-is-not
7af26002a0 add icons (#1222) 2023-12-24 12:53:44 +01:00
CokaKoala
e71a776acc Fixed export maps, types, and packaging for lucide-svelte (#1707)
* add extensions for `NodeNext` support

* fixed exports map and replaced the packaging system for `@sveltejs/pacakge`

* lockfile

* ignore generated `.svelte-kit` dir

* no longer needed

* fixed main export

* fixed IconNode and IconProps types

* have icon props extend svg attributes

* build script for prepending the license to each `dist` file

* Update packages/lucide-svelte/scripts/addLicense.mjs

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-12-24 12:45:57 +01:00
Jakob Guddas
0a69fb9e52 Fix gavel gap (#1744)
* Fix `gavel` gap

* Update gavel.json
2023-12-24 12:26:02 +01:00
Eric Fennis
3648e02992 Add cooking-pot icon (#1737)
Co-authored-by: Guillermo Angeles <guillermo.angeles@adoptaunabuelo.com>
2023-12-22 13:53:26 +01:00
Wojciech Maj
64504da1cd Add more tags (#1734) 2023-12-21 14:18:35 +01:00
Daniel Bayley
e166ba4e80 Add materials icons (#1407)
* Add `fence` icon

* Add `anvil` (metal) icon

* Add `brick-wall` icon

* Refine `anvil` icon

* Update icons/anvil.json

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

* Update icons/brick-wall.json

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

* Add `panel` icon

* Refine `brick-wall` icon

* Rename `panel` to `inspection-panel`

---------

Co-authored-by: Karsa <contact@karsa.org>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-12-20 09:08:50 +01:00
Wojciech Maj
1123214b13 Add support for react-native-svg ^14.0.0 (#1732)
Closes #1722
2023-12-19 22:59:59 +01:00
Eric Fennis
4140ba5612 bumping up packages (#1728) 2023-12-18 12:04:42 +01:00
Jakob Guddas
019f38281c chore: pull-request workflow refactor (#1729)
* chore: pull-request workflow refactor

* chore: pull-request workflow refactor

* chore: pull-request workflow refactor
2023-12-18 11:03:17 +01:00
Bhargav Shirin Nalamati
633595d1c1 Update README.md (#1653) 2023-12-16 16:34:28 +01:00
Daniel Bayley
df58c3ff2f Add fire/safety/security/amenities icons (#1392)
* Add `fire-extinguisher` icon

* Add `smoke-alarm` icon

* Improve fire related metadata

* Add `fire-alarm` icon

* Add `cctv` icon

* Add `cctv-off` icon

* Update icons/fire-alarm.json

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

* Update icons/fire-alarm.json

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

* Rename `fire-alarm` to `bell-alarm`

* Refine `cctv` icons

* Optimise `bell-alarm` icon

* Rename `bell-alarm` to `bell-electric`

* Rename `smoke-alarm` to `alarm-smoke`

* Refine `alarm-smoke` icon

* Refine `cctv` icons

* Update icons/alarm-smoke.svg

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

* Update icons/cctv.svg

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

* Update icons/fire-extinguisher.svg

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

* update pr workflow

* update pr workflow

* add env

* remove cctv off icons

---------

Co-authored-by: Karsa <contact@karsa.org>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-12-16 15:39:40 +01:00
Jakob Guddas
e7abba5273 feat: added renameIcon script (#1630)
* feat: added renameIcon script

* feat: added renameIcon script

* chore: converted renameIcon.sh to mjs

* refactor: cleanup

* Delete scripts/renameIcon.sh
2023-12-16 15:20:08 +01:00
Eric Fennis
2693da38d3 fix: update pr workflow 2023-12-15 16:31:19 +01:00
Jakob Guddas
ab59a1ec36 feat: added pointer-off icon (#1567) 2023-12-15 14:18:47 +01:00
Jakob Guddas
315c020279 Add squircle (#1293)
* Add `squircle`

* Create squircle.json

* Update squircle.svg

* Update icons/squircle.json

* Update squircle.json

* Update squircle.json

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-12-15 13:48:36 +01:00
James Vickery
494f7953c8 New icons: user-search and user-round-search (#1620)
* user-search and user-search-2 icons

* updated user-search icons

* Update icons/user-search.json

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

* Update icons/user-search-2.json

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

* Renamed user-search-2 to user-round-search.

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
Co-authored-by: Karsa <contact@karsa.org>
2023-12-15 12:21:07 +01:00
Eric Fennis
a5ea3a5368 Set fail-fast: false, release workflow 2023-12-15 12:20:22 +01:00
Daniel Bayley
6486f76c55 Fix missing contributors (#1706) 2023-12-15 11:09:52 +01:00
Eric Fennis
e32db96f1f update workflow 2023-12-13 22:44:08 +01:00
Eric Fennis
73f70c885a Update pull-request.yml 2023-12-13 22:28:05 +01:00
Daniel Bayley
14c7ea8e13 Refine/add message[-*] icons (#1208)
* Add `message-square-warning` icon

* Optimise `message-square-plus` icon

* Add `message-square-diff` (request changes) icon

* Refine `message-circle` icon

* Add `message-circle-question` icon

* Add `message-circle-warning` icon

* Add `message-square-x` icon

* Add `message-square-off` icon

* Add `message-circle-plus` icon

* Add `message-circle-x` icon

* Add `message-circle-off` icon

* Refine `message-circle` icons

* Fix `message-circle-question` mark

* Fix `message-square-diff` icon

* Add `message-square-share` icon

* Add `message-square-text` icon

* Refine `message-square-x` icon

* Add `message-square-code` icon

* Improve `message-*` icons metadata

* Add `message-square-more` icon

* Improve `more-horizontal` metadata

* Add `message-circle-more` icon

* Add `message-circle-dashed` icon

* Add `message-square-text-quote` icon

* Add `message-square-quote` icon

* Add `message-square-reply` icon

* Add `message-circle-code` icon

* Add `message-circle-reply` icon

* Add `message-circle-heart` icon

* Add `message-square-heart` icon

* Add `message-square-dot` (unread) icon

* Add `message-square-dot-big` (unread/notification) variant

* Remove message-square-text-quote and rename message-square-dot-big

* Added as contributor in meta data

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-12-13 21:14:49 +01:00
Eric Fennis
9fc7653dc1 Add carbon to site 2023-12-13 20:45:25 +01:00
Jakob Guddas
2b007e7962 Lessened $schema type strictness (#1718)
* Lessened $schema type strictness

* Lessened $schema type strictness
2023-12-11 15:53:52 +01:00
dependabot[bot]
bb1e470f3a Bump vite from 4.4.7 to 4.4.12 (#1714)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.4.7 to 4.4.12.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.4.12/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.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>
2023-12-08 10:55:14 +01:00
Eric Fennis
4a1e6bbfa5 Update site dependencies & small fixes (#1699)
* update styling

* Update vitepress
2023-11-28 21:02:23 +01:00
Gionata Mettifogo
e5ee997566 Update README.md (#1704)
The readme lists the url below with uppercase L
@import ('~lucide-static/font/Lucide.css');

but the file in node_modules/lucide-static/font has a lowercase L making it fail on certain loaders like the one used by Storybook on MacOS.

The fix is simply to use lowercase
2023-11-28 21:00:46 +01:00
Daniel Bayley
27c0a136cd Add music/piano/keyboard/guitar/pick/amp/drum/album/audio/waveform icons (#1124)
* Add `piano` icon

* Add `keyboard-music` icon

* Optimise `speaker` icon

* Refine `speaker` icon

* Improve metadata

* Add `guitar` icon

* Add `guitar-pick` icon

* Add `guitar-amp` icon

* Add `drum` icon

* Add `disc-album` icon

* Add `disc-album-remove` icon

* Add `disc-album` variant

* Add `file-music` icon

* Add `audio-waveform` icon

* Add `audio-lines` icon

* Refine `speaker` icon

* Remove icons

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-11-28 21:00:08 +01:00
Sukomal Dutta
84b3c46b65 remove extra space in svg class attribute (#1703)
* remove extra space in svg class attribute

* Update packages/lucide-react/src/createLucideIcon.ts

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

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
2023-11-28 20:59:37 +01:00
James Vickery
1a09e7fb39 Renamed user-*-2 to user-round-* (#1638)
* Renamed user-*-2 to user-round-*

* Added user-round icon optimizations as per Discord + renamed user*-(square|circle) to (square|circle)-user* also as per Discord

---------

Co-authored-by: Karsa <contact@karsa.org>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-11-24 13:59:28 +01:00
Eric Fennis
75e9724072 Make sure we apply all classes to the lucide icons (#1691)
* Make sure all classes are applied for all packages

* Add class test to angular component

* Adjust lucide-static tests

* update snapshot

* Fix types
2023-11-24 13:59:12 +01:00
Eric Fennis
fbaccc7d9f Fix lint errors svg files (#1698) 2023-11-24 11:22:05 +01:00
Zakher Masri
c24bc4d7ef Fixed Illustrator template link + fixed typo (#1664)
* Fixed Illustrator template link + fixed typo

* Added `pilcrow-left` icon

* Revert "Added `pilcrow-left` icon"

This reverts commit 6ccdf9c55e.
2023-11-24 11:08:57 +01:00
Otto Coster
5c8c8f4362 Support Angular 17 (#1696) 2023-11-24 11:07:49 +01:00
Daniel Bayley
ffd2a62941 Improve Adobe Illustrator template (#1689) 2023-11-24 09:19:02 +01:00
Eric Fennis
e77959e1a6 lucide-vue Deprecation warning (#1663)
* Add Vue deprecation warning

* Add deprecation warning docs page

* Fix typo

* Update warning text
2023-11-24 08:14:47 +01:00
Eric Fennis
149ee36e61 Improve license notice in packages (#1657)
* Improve license message

* Implement license notice in lucide-static

* Tighten package PR workflows

* Update lockfile
2023-11-17 11:12:31 +01:00
Karsa
88bf60b5d7 Update Angular logo on site (#1684) 2023-11-17 11:11:26 +01:00
Jakob Guddas
1e5df716a4 feat: added curve handles to svg preview (#1661) 2023-11-13 21:18:51 +01:00
Karsa
fc0ea760e5 Fixes #1665 (#1674)
Replace Do with Don't in Pixel perfection bad example.
2023-11-09 16:27:59 +01:00
Jakob Guddas
c85275899a Renamed alarm-check to alarm-clock-check (#1628) 2023-11-06 11:00:44 +01:00
Eric Fennis
288edde1ea Linting SVG files (#1642)
* eslint rules for SVGS

* apply options

* Add typescript eslinter

* Make eslint work with the codebase

* Format icons

* Test svg

* Add workflow

* Fix lint command

* Revert duplicated aliases

* Update .eslintrc.js

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

* Update .eslintrc.js

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

* Move linter to separate workflow

* Add pnpm install

* Revert icon changes

* Test eslint workflow

* turn of fail lint-contributors

* Revert theater

* process feedback

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
2023-11-06 11:00:04 +01:00
Karsa
207ff6c487 Adds ribbon (#1438)
* Adds ribbon

* Update icons/ribbon.svg

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

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Jakob Guddas <github@jguddas.de>
2023-11-03 08:49:20 +01:00
Sukomal Dutta
a1a9a4d839 fix export IconNode type (#1656)
* fix export IconNode type

* add Types exports
2023-11-01 15:53:17 +01:00
Karsa
c5804ad9a5 Refactored icon exports to use the new proposed icon node format. (#1641) 2023-10-31 21:03:39 +01:00
Jakob Guddas
c72fb4a28b feat: changed backdrop color for new icons in group to gray (#1640) 2023-10-31 21:03:17 +01:00
Jakob Guddas
da5ad547b5 feat: improved backdrop group name resolution (#1645) 2023-10-31 21:02:35 +01:00
Daniel Bayley
66cfe527b3 Optimise/add missing check[-*] icon/s (#1297)
* Optimise `check`[`-*`] icons

* Add missing `check-square` variant
2023-10-31 19:54:25 +01:00
Karsa
d1866225ba Fixes radiation center dot (#1655) 2023-10-31 07:13:25 +01:00
Jakob Guddas
372735999f fix: exclude renames from contributor generation (#1643)
* fix: exclude renames from contributor generation

* fix: exclude renames from contributor generation
2023-10-30 21:31:25 +01:00
Jakob Guddas
f3a33346dd Fixed gaps in cake icon (#1651)
* Fixed gaps in `cake` icon

* Update cake.json

* Update icons/cake.svg

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

---------

Co-authored-by: Karsa <contact@karsa.org>
2023-10-30 20:13:21 +01:00
Jakob Guddas
3373acf596 Rebuild tree-deciduous using arcs (#1647)
* Rebuild tree-deciduous using arcs

* Update icons/tree-deciduous.svg

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

---------

Co-authored-by: Karsa <contact@karsa.org>
2023-10-30 20:11:40 +01:00
Eric Fennis
73d5bfc318 Fix icon contributors 2023-10-29 21:09:08 +01:00
ayushrakesh
ddbc074aa3 Update README.md (#1652) 2023-10-29 18:47:00 +01:00
Jakob Guddas
8f4d6b1651 feat: added lint-contributors job (#1625)
* feat: added lint-contributors job

Signed-off-by: Jakob Guddas <github@jguddas.de>

* feat: improved lint-contributors job

Signed-off-by: Jakob Guddas <github@jguddas.de>

* feat: add comments to lint-contributors job

Signed-off-by: Jakob Guddas <github@jguddas.de>

---------

Signed-off-by: Jakob Guddas <github@jguddas.de>
2023-10-27 08:59:27 +02:00
Daniel Bayley
d8b08f8fda Add missing git icons (#995)
* Add `git-pull-request-create` icon

* Add `git-pull-request-create-arrow` variant

* Improve `git-*` icons metadata

* Optimise `git-pull-request-closed` icon

* Refine `git-fork` icon

…to match [`network`](https://lucide.dev/icons/network)

* Add `git-graph` icon

* Rename `git-commit` to `git-commit-horizontal`

* Add `git-commit-vertical` icon

* Add `git-pull-request-arrow` icon

* Add `git-compare-arrows` icon
2023-10-27 08:56:26 +02:00
Daniel Bayley
fddacb6260 Optimise/add power[-circle/-square] icons (#1353)
* Add `power-circle` icon

* Optimise `power` icon

* Improve `power` icon metadata

* Add `power-square` icon

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-10-23 21:35:57 +02:00
Sun Xiaoran
3d0c8691c9 fix: jsx type for icons in vue 3 (#1617) 2023-10-23 21:24:05 +02:00
Jakob Guddas
47998b05aa feat: added linting and formatting of icon and category json files (#1632) 2023-10-23 21:05:02 +02:00
Sukomal Dutta
9a9e051343 correct typo in icon size example (#1634) 2023-10-23 21:02:05 +02:00
Jakob Guddas
6c6c8448fa fix: duplicate Next.js aliases (#1631) 2023-10-22 13:06:07 +02:00
Eric Fennis
49445aad3a Showcase page for the website (#1604)
* add showcase items

* Add showcase cards

* Complete showcase list

* Add light/dark mode versions
2023-10-20 13:45:47 +02:00
Jakob Guddas
70656eb4f0 Optimized armchair icon (#1610) 2023-10-20 11:38:03 +02:00
Sukomal Dutta
930f862547 fix website jumping isuue (#1612)
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-10-20 11:36:53 +02:00
Eric Fennis
931b7f5376 Add pnpm action 2023-10-20 11:19:48 +02:00
Jakob Guddas
81e44bdc40 feat: improved folder cohesion (#1223)
* feat: improved folders

* fix: snapped node

* Update icons/folder-heart.svg

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

* Update folder-cog-2.svg

* Update folder-cog.svg

* feat: revert folder-symlink

* feat: revert folder-output

---------

Co-authored-by: Karsa <contact@karsa.org>
2023-10-20 09:27:48 +02:00
Parikshit Adhikari
e6e90944b9 typo fixed (#1621) 2023-10-19 17:17:06 +02:00
Eric Fennis
f6fd369bfe Github Actions cleanup - Use setup node for pnpm cache (#1616)
* Switch setup node for pnpm cache

* Test workflows

* Add pnpm setup back again
2023-10-18 09:50:18 +02:00
Eric Fennis
bbf183fe48 Fix lock file 2023-10-17 21:43:34 +02:00
Daniel Bayley
4f5642b872 Add book-* icons (#1352)
* Add `book-text` icon

* Add `book-open-text` icon

* Add `book-a` (dictionary) icon

* Improve `book`/`contact` icons metadata

* Add `book-check` (read) icon

* Add `book-type` (font book) icon

* Add `book-spine` icon

* Add `book-elastic` icon

* Add `book-user` (contacts) icon

* Add `book-address-user` (contacts variant) icon

* Add `book-address` (contacts variant) icon

* Add `book-heart` (diary/journal) icon

* Improve `book-*` icons metadata

* Add `book-image` icon

* Add `library-big` icon

* Improve metadata

* Rename `book-address`[`-*`] icons to `book-tabs`[`-*`]

* Improve metadata

* Add `notebook` icon

* Add `notebook-tabs` (contacts variant) icon

* Add `notebook-text` icon

* Add `notebook-elastic` icon

* Add `notebook-pencil` icon

* Add `notepad-text` (`notebook` variant) icon

* Add `notepad-lines` icon

* Refine `library-big` icon

Remove detail.

* Update icons/book-heart.json

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

* Refine `book-tabs` icon

* Remove `book-tabs-user` icon

* Improve `book` icons metadata

* Move `note`[`book`/`pad`] icons

* Add `book-volume` (audiobook) icon

* Add `book-headphones` (audiobook variant) icon

* Add `book-audio` variant icon

* Add `library-square` icon

* Add `book-open` variant

* Rename `book-template` to `book-dashed`

* Add `book-git-commit` icon

* Delete icons/book-elastic.json

* Delete icons/book-elastic.svg

* Delete icons/book-git-commit.json

* Delete icons/book-git-commit.svg

* Delete icons/book-open-2.json

* Delete icons/book-open-2.svg

* Delete icons/book-spine.json

* Delete icons/book-spine.svg

* Delete icons/book-tabs.json

* Delete icons/book-tabs.svg

* Delete icons/book-volume.json

* Delete icons/book-volume.svg

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-10-17 21:38:27 +02:00
Emma Alexia
1dce6a141a fix/docs: release tags don't work for newly-created/updated icons (#1589)
As per 3391b5b717, the format of new GitHub release tags is just the version number without the `v` prefix. As we can see on https://github.com/lucide-icons/lucide/releases?page=2, versions older than 0.266.0 use a `v` prefix. The current docs assume that all versions contain the `v` prefix; this PR fixes it so that the format of versions both from before and after this change are accounted for.
2023-10-17 21:30:26 +02:00
Eric Fennis
dbfce919fc Alias support for lucide package (#1592)
* Setup aliases for lucide

* Make aliases work for lucide package
2023-10-17 21:27:46 +02:00
Jakob Guddas
52adb78df8 Optimized globe (#1606) 2023-10-17 21:26:47 +02:00
Jan
c5cfbed28c add info about dynamic imports to nextjs docs (#1564)
* add info about dynamic imports to nextjs docs

* remove warning
2023-10-17 21:25:49 +02:00
Jakob Guddas
1e4fd13852 Optimized backpack icon (#1611) 2023-10-17 21:11:44 +02:00
Eric Fennis
0a0fd1cf6c Adds new font in lucide-static and speed up icon outlining (#1599)
* Apply new icon font build in release

* remove dockerfile
2023-10-16 22:03:57 +02:00
dependabot[bot]
487d03fc4d Bump undici from 5.24.0 to 5.26.3 (#1615)
Bumps [undici](https://github.com/nodejs/undici) from 5.24.0 to 5.26.3.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v5.24.0...v5.26.3)

---
updated-dependencies:
- dependency-name: undici
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-16 21:43:56 +02:00
Karsa
950160ad5a Fixes some over-optimisation done in #1573 (#1605) 2023-10-13 17:15:24 +02:00
Eric Fennis
b6f5898aee Remove lucide flutter form the main repo (#1593) 2023-10-13 14:33:45 +02:00
Sukomal Dutta
a9c1dca801 fix #1579 issue added debounced in search (#1600)
* add debounced in search

* updated iconsCategoryOverview

* fix site loading issue

* apply suggestion
2023-10-13 14:32:34 +02:00
Jakob Guddas
c05c7e333f feat: added umbrella-off icon (#1568)
* feat: added umbrella-off icon

* Update umbrella-off.svg

* Update umbrella-off.svg

* Update umbrella-off.svg

* Update icons/umbrella-off.json
2023-10-12 08:36:17 +02:00
Jakob Guddas
dff42fe326 fix: gh-icon improvements (#1595) 2023-10-11 13:21:42 +02:00
Daniel Bayley
c1f642e20f Add navigation icons (#1390)
* Add `signpost` icon

* Add `signpost-big` icon

* Improve `milestone` metadata

* Add `map-pinned` icon

* Add `waypoints` icon

* Add `route` (journey/planner) icon

* Add `route-off` (clear journey) icon

* Refine `map-pinned` icon

* Refine `map-pinned` icon
2023-10-10 08:38:37 +02:00
Jakob Guddas
cf9565b69c feat: added image-down icon (#1570) 2023-10-05 22:39:32 +02:00
Daniel Bayley
4cc4468d2f Add camping icons (#1409)
* Add `caravan` icon

* Improve `tent` metadata

* Rename `tent` to `tipi`

* Add `tent-tree` (camping) icon

* Add `flame-kindling` (campfire) icon

* Refine `tipi` icon

* Refine `tent-tree` icon

* Revert rename `tipi` to `tent`

* Refine `caravan` icon

* Refine `tent` icon

* Fix `flame-kindling` optimisation

* Update flame-kindling.svg

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-10-03 09:53:21 +02:00
Daniel Bayley
fd9ab8f17a Add barcode/scan icons/optimise/improve metadata (#1354)
* Add `barcode` icon

* Add `scan-barcode` icon

* Add `scan-text` icon

* Improve `scan` icons metadata

* Add `scan-eye` icon

* Add `scan-search` icon

* Optimise `scan-line` icon

* Add `fullscreen` icon

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-10-03 09:35:20 +02:00
Eric Fennis
c9101f0f39 Add Lucide basics guide on site (#1521)
* add sidebar topics

* Start with styling icons doc

* write some doc text

* add sandpack

* Add custom sandpack theme

* Adjust sandpack

* update sidebar

* Add example

* Add more examples

* updat lockfile

* update vitepress

* Fix sidebar

* Adjust theme with latest vitepress!

* Example updates!

* Finish last examples

* Remove markdown comments

* Update docs/guide/advanced/filled-icons.md

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

* Update docs/guide/basics/color.md

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

* Update docs/guide/basics/color.md

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

* Update docs/guide/basics/stroke-width.md

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

* Update docs/guide/basics/color.md

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

* Update docs/guide/basics/sizing.md

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

* Update docs/guide/basics/stroke-width.md

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

* Update docs/guide/basics/stroke-width.md

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

* Update docs/guide/basics/color.md

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

* Update docs/guide/basics/color.md

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

* Update docs/guide/basics/sizing.md

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

* Update docs/guide/basics/sizing.md

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

* Update docs/guide/basics/sizing.md

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

* Update docs/guide/basics/sizing.md

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

* Update docs/guide/basics/sizing.md

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

* Update docs/guide/basics/stroke-width.md

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

* Process feedback

* Add editor width percentage

* process feedback

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
2023-10-03 08:21:01 +02:00
Cd16d
614ef1a1d5 Lock icons (#1346)
* new lock/unlock icons

* Update icons/lock-2.svg

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

* Update icons/unlock-2.svg

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

* Update lock-2.svg

* Update unlock-2.svg

* Update unlock-2.svg

* Rename lock-2.json to lock-dot.json

* Rename lock-2.svg to lock-dot.svg

* Rename unlock-2.json to unlock-dot.json

* Rename unlock-2.svg to unlock-dot.svg

* Update icons/lock-dot.svg

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

* Update icons/unlock-dot.svg

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

* Update and rename lock-dot.json to lock-keyhole.json

* Rename lock-dot.svg to lock-keyhole.svg

* Update and rename unlock-dot.json to unlock-keyhole.json

* Rename unlock-dot.svg to unlock-keyhole.svg

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-10-02 20:25:05 +02:00
Jakob Guddas
1a441812ac feat: changed mouse-pointer-click (#1563)
* feat: changed `mouse-pointer-click`

* Update mouse-pointer-click.json
2023-10-02 19:40:22 +02:00
Daniel Bayley
4a33e90c65 Add geometry icons (#1142)
* Add `radius` icon

* Add `tangent` icon

* Refine `radius` icon

* Add `circumference` icon

* Add `tangent` icon

* Fix: rename `circumference` to `diameter`

* Add `cylinder` icon

* Add `cylinder-volume` icon

* Add `area` icon

* Refine `layers` icon

* Add `drafting-compass` icon

* Update icons/drafting-compass.svg

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

* Update icons/cylinder-volume.svg

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

* Update icons/diameter.svg

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

* Add `pyramid` icon

* Add `cone` icon

* Update icons/cone.svg

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

* Refine `cone` icon

* Improve geometry icons metadata

* Refine `layers` icon

* Add `layers` alternate icon

* Add `pentagon` icon

* Improve `layers` alternate icon metadata

* Add `torus` icon

* Refine `area` icon

* Improve metadata

* Add `layers-3` variant

* Add `plot` icon

* Refine `plot` icon

* Rename `plot` to `land-plot`

* Add `cuboid` (brick) icon

* Add `weight` icon

* Optimise `triangle` icon

* Update icons/weight.svg

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

* Update icons/weight.json

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

* Refine `pyramid` icon

* Optimise `tangent` icon

* Refine `cone` icon

* Refine `pyramid` icon

* Update icons/cone.svg

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

* Update icons/cuboid.svg

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

* Update icons/cylinder-volume.svg

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

* Update icons/land-plot.svg

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

* Update icons/diameter.svg

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

* Update icons/layers-2.svg

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

* Update icons/layers.svg

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

* Update icons/pyramid.svg

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

* Update icons/radius.svg

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

* Update icons/tangent.svg

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

* Update icons/triangle.svg

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

* Update icons/layers-3.svg

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

* Delete icons/area.json

* Delete icons/area.svg

* Delete icons/cylinder-volume.json

* Delete icons/cylinder-volume.svg

* Add comma database.json

---------

Co-authored-by: Karsa <contact@karsa.org>
Co-authored-by: Jakob Guddas <github@jguddas.de>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-10-02 19:29:54 +02:00
Jakob Guddas
062a64a078 feat: optimized uncategorized icons (#1573) 2023-09-25 20:16:25 +02:00
Eric Fennis
95a1ea7255 Merge branch 'main' of https://github.com/lucide-icons/lucide 2023-09-24 21:54:03 +02:00
Eric Fennis
a0a5bc8fc2 update digital ocean link website 2023-09-24 21:53:56 +02:00
Jakob Guddas
698eded89b Update gift.svg (#1571)
* Update gift.svg

* Update gift.json
2023-09-21 21:52:19 +02:00
Binyamin Aron Green
a70b713572 Fix solid package.json (#1558) (#1569)
- allow access to types file in "exports" field

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-09-20 15:24:23 +02:00
Jakob Guddas
34530ad805 feat: more tags for graduation-cap (#1562) 2023-09-19 16:34:24 +02:00
Jakob Guddas
f73aed151a chore: added "dropdown" to tags (#1565)
* Update chevron-down.json

* Update chevron-up.json
2023-09-19 16:33:13 +02:00
Maxim Coppieters
2bd7748562 Add theater/drama icons (#1474)
* Add theater/drama icons

Related to #1399

Co-Authored-By: Daniel Bayley <daniel.bayley@me.com>

* Remove alternate drama icon

* Improve tags

---------

Co-authored-by: Daniel Bayley <daniel.bayley@me.com>
2023-09-16 13:04:13 +02:00
Daniel Bayley
da8a6c5a1b Add missing bookmark-* icons (#1259)
* Add `bookmark-x` icon

* Add `bookmark-off` icon

* Remove `bookmark-off` icon

* Add `bookmark-slash` icon

* Swap `bookmark-slash` with `bookmark-check`
2023-09-16 12:57:53 +02:00
Eric Fennis
5736028dfa Update sponsor logos 2023-09-14 11:11:18 +02:00
Eric Fennis
45d2063340 Add digital ocean logo in readme 2023-09-14 10:42:02 +02:00
Erwann Lagouche
f71d3ffd1d Add speech icon (#1337)
* add speech icon

* center icon and apply global attributes

* fix: make paddings wider

* fix: smoothe angle on base of neck

* fix: add jguddas to contributors

* Update speech.svg

* Update speech.json

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-09-13 21:05:54 +02:00
Oliver Schmidt
b8c3a5fa0b Changed font creation process (#1413)
* Changed font creation process

* Class name prefix

Class name prefix added for backward compatibility.

* Container option in workflow removed

Removed the container option in github workflow lucide-font because it is not needed anymore, workflow was changed to nodejs only

* Fixed whitespaces in package.json

* Use releaseInformation instead of info.json

* Added workflow step

* Moved unicode numbers to convert function

* Added locale argument to sort function

* Delete pnpm-lock

* Updated versions, recreated pnpm-lock

* Updated dependencies

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-09-13 21:05:22 +02:00
Eric Fennis
a4076db69b fix: Allow slash icon with double release 2023-09-11 09:07:14 +02:00
Eric Fennis
55cb681461 Remove conflicting alias (#1555) 2023-09-09 08:29:41 +02:00
Eric Fennis
09d9bb747d Add bot-2 icon (#1544)
* Add bot-2 icon

* replace existing bot icon
2023-09-08 09:46:47 +02:00
Javi Aguilar
42f9cdceca Replace sun-moon icon (#1545)
* Add sun-moon-2 icon

* Update icons/sun-moon-2.svg

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

* CR remarks

* Update sun-moon.json

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
2023-09-06 10:21:01 +02:00
Eric Fennis
c652723b32 Generated aliases for Weird NextJS Case transformations (#1549)
* add script

* Create script to generate the aliases Nextjs

* Apply aliases to the icon meta files

* Make sure duplicated imports are not added

* add command to lint-staged
2023-09-06 09:26:02 +02:00
Jan
a44328d8be Adjust name from "data-lucide-name" to "data-lucide" in documentation & vitepress config adjusted (#1551)
* adjusted name

* adjusted vitepress config and README file

* use glob pattern

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-09-04 16:02:34 +02:00
Eric Fennis
376568239f adjust export order (#1548) 2023-09-02 21:49:11 +02:00
Jackson
92d05b5fca Improve clarity and readability of packages guides in docs (#1547) 2023-09-02 21:48:45 +02:00
Daniel Bayley
27b5b7eaad Add slash icon/improve [*-]slash metadata (#1241)
* Add `slash` icon

* Improve `slash` icons metadata
2023-09-02 15:46:42 +02:00
Daniel Bayley
4de1355e54 Refine film/clapperboard icons (#1506)
* Refine `film` icon

* Refine `clapperboard` icon

* Improve metadata
2023-09-02 15:45:06 +02:00
1073 changed files with 20014 additions and 10622 deletions

View File

@@ -4,3 +4,8 @@ coverage
lib lib
tests tests
node_modules node_modules
.eslintrc.js
docs/images
docs/guide/basics/examples
docs/guide/advanced/examples
packages/lucide-react/dynamicIconImports.js

View File

@@ -1,22 +1,18 @@
const DEFAULT_ATTRS = require('./scripts/render/default-attrs.json');
module.exports = { module.exports = {
root: true,
env: { env: {
browser: true, browser: true,
node: true, node: true,
}, },
extends: ['airbnb-base', 'prettier'], extends: ['airbnb-base', 'prettier'],
plugins: ['import', 'prettier'], plugins: ['import', '@html-eslint'],
rules: { rules: {
'no-console': 'off', 'no-console': 'off',
'no-param-reassign': 'off', 'no-param-reassign': 'off',
'no-shadow': 'off', 'no-shadow': 'off',
'no-use-before-define': 'off', 'no-use-before-define': 'off',
'prettier/prettier': [
'error',
{
singleQuote: true,
trailingComma: 'all',
},
],
'import/no-extraneous-dependencies': [ 'import/no-extraneous-dependencies': [
'error', 'error',
{ devDependencies: ['**/*.test.js', '**/*.spec.js', './scripts/**'] }, { devDependencies: ['**/*.test.js', '**/*.spec.js', './scripts/**'] },
@@ -33,8 +29,42 @@ module.exports = {
}, },
parserOptions: { parserOptions: {
tsconfigRootDir: __dirname, tsconfigRootDir: __dirname,
project: ['./site/tsconfig.json', './packages/*/tsconfig.json'], project: ['./docs/tsconfig.json', './packages/*/tsconfig.json'],
ecmaVersion: 'latest', ecmaVersion: 'latest',
sourceType: 'module', sourceType: 'module',
}, },
overrides: [
{
files: ['./icons/*.svg'],
parser: '@html-eslint/parser',
rules: {
'@html-eslint/require-doctype': 'off',
'@html-eslint/no-duplicate-attrs': 'error',
'@html-eslint/no-inline-styles': 'error',
'@html-eslint/require-attrs': [
'error',
...Object.entries(DEFAULT_ATTRS)
.map(([attr, value]) => ({ tag: 'svg', attr, value: String(value) }))
],
'@html-eslint/indent': ['error', 2],
"@html-eslint/no-multiple-empty-lines": ["error", { "max": 0 }],
'@html-eslint/no-extra-spacing-attrs': [
'error',
{
enforceBeforeSelfClose: true,
},
],
'@html-eslint/require-closing-tags': [
'error',
{
selfClosing: 'always',
allowSelfClosingCustom: true,
},
],
'@html-eslint/element-newline': 'error',
'@html-eslint/no-trailing-spaces': 'error',
'@html-eslint/quotes': 'error',
}
},
],
}; };

View File

@@ -9,16 +9,16 @@ inputs:
runs: runs:
using: "composite" using: "composite"
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: actions/setup-node@v4
with: with:
node-version: 16 node-version: 16
- uses: pnpm/action-setup@v2.0.1 - uses: pnpm/action-setup@v2
name: Install pnpm name: Install pnpm
id: pnpm-install id: pnpm-install
with: with:
version: 7 version: 8
run_install: false run_install: false
- name: Get pnpm store directory - name: Get pnpm store directory

View File

@@ -9,16 +9,16 @@ inputs:
runs: runs:
using: "composite" using: "composite"
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: actions/setup-node@v4
with: with:
node-version: 16 node-version: 16
- uses: pnpm/action-setup@v2.0.1 - uses: pnpm/action-setup@v2
name: Install pnpm name: Install pnpm
id: pnpm-install id: pnpm-install
with: with:
version: 7 version: 8
run_install: false run_install: false
- name: Get pnpm store directory - name: Get pnpm store directory

66
.github/labeler.yml vendored
View File

@@ -1,62 +1,92 @@
# For changed dependencies # For changed dependencies
📦 dependencies: 📦 dependencies:
- pnpm-lock.yaml - changed-files:
- any-glob-to-any-file:
- pnpm-lock.yaml
# For changes in documentation # For changes in documentation
📖 documentation: 📖 documentation:
- docs/*.md - changed-files:
- docs/**/*.md - any-glob-to-any-file:
- docs/*.md
- docs/**/*.md
# For changes in the site, but not markdown files # For changes in the site, but not markdown files
🌍 site: 🌍 site:
- 'docs/**' - changed-files:
- any-glob-to-any-file:
- 'docs/**'
# For changes in the metadata # For changes in the metadata
🫧 metadata: 🫧 metadata:
- 'icons/*.json' - changed-files:
- categories/* - any-glob-to-any-file:
- 'icons/*.json'
- categories/*
# For changes or added icons # For changes or added icons
🎨 icon: 🎨 icon:
- 'icons/*.svg' - changed-files:
- any-glob-to-any-file:
- 'icons/*.svg'
# For changes in the lucide package # For changes in the lucide package
🧳 lucide package: 🧳 lucide package:
- 'packages/lucide/*' - changed-files:
- any-glob-to-any-file:
- 'packages/lucide/*'
# For changes in the lucide React package # For changes in the lucide React package
⚛️ react package: ⚛️ react package:
- 'packages/lucide-react/*' - changed-files:
- any-glob-to-any-file:
- 'packages/lucide-react/*'
# For changes in the lucide React Native package # For changes in the lucide React Native package
⚛️ react native package: ⚛️ react native package:
- 'packages/lucide-react-native/*' - changed-files:
- any-glob-to-any-file:
- 'packages/lucide-react-native/*'
# For changes in the lucide vue packages # For changes in the lucide vue packages
💎 vue package: 💎 vue package:
- 'packages/lucide-vue/*' - changed-files:
- 'packages/lucide-vue-next/*' - any-glob-to-any-file:
- 'packages/lucide-vue/*'
- 'packages/lucide-vue-next/*'
# For changes in the lucide angular package # For changes in the lucide angular package
🅰️ angular package: 🅰️ angular package:
- 'packages/lucide-angular/*' - changed-files:
- any-glob-to-any-file:
- 'packages/lucide-angular/*'
# For changes in the lucide preact package # For changes in the lucide preact package
⚛️ preact package: ⚛️ preact package:
- 'packages/lucide-preact/*' - changed-files:
- any-glob-to-any-file:
- 'packages/lucide-preact/*'
# For changes in the lucide svelte package # For changes in the lucide svelte package
🧣 svelte package: 🧣 svelte package:
- 'packages/lucide-svelte/*' - changed-files:
- any-glob-to-any-file:
- 'packages/lucide-svelte/*'
# For changes in the lucide solid package # For changes in the lucide solid package
🪝 solid package: 🪝 solid package:
- 'packages/lucide-solid/*' - changed-files:
- any-glob-to-any-file:
- 'packages/lucide-solid/*'
# For changes in the lucide static package # For changes in the lucide static package
🪨 static package: 🪨 static package:
- 'packages/lucide-static/*' - changed-files:
- any-glob-to-any-file:
- 'packages/lucide-static/*'
# For changes in the lucide flutter package # For changes in the lucide flutter package
🏹 flutter package: 🏹 flutter package:
- 'packages/lucide-flutter/*' - changed-files:
- any-glob-to-any-file:
- 'packages/lucide-flutter/*'

View File

@@ -15,33 +15,17 @@ jobs:
VERSION: ${{ steps.new-version.outputs.NEW_VERSION }} VERSION: ${{ steps.new-version.outputs.NEW_VERSION }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install --frozen-lockfile
- name: Fetch tags - name: Fetch tags
run: git fetch --all --tags run: git fetch --all --tags
@@ -50,9 +34,6 @@ jobs:
id: latest-tag id: latest-tag
run: echo "LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_OUTPUT run: echo "LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_OUTPUT
- name: Install dependencies
run: pnpm install
- name: Check if we can patch - name: Check if we can patch
run: .github/workflows/version-up.sh --minor run: .github/workflows/version-up.sh --minor

View File

@@ -7,12 +7,11 @@ jobs:
stale: stale:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/stale@v3 - uses: actions/stale@v9
with: with:
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-pr-message: This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 5 days. stale-pr-message: This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 5 days.
close-pr-message: This PR was closed because it has been stalled for 5 days with no activity. close-pr-message: This PR was closed because it has been stalled for 5 days with no activity.
close-pr-label: 🧶 stale close-pr-label: 🧶 stale
days-before-stale: 30 days-before-stale: 30
days-before-close: 5 days-before-close: -1
days-before-pr-close: -1

View File

@@ -9,4 +9,4 @@ jobs:
pull-requests: write pull-requests: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/labeler@v4 - uses: actions/labeler@v5

25
.github/workflows/linting.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Linting
on:
pull_request:
branches:
- '**'
jobs:
linting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v4
with:
node-version: 18
cache: 'pnpm'
- name: Install Dependencies
run: pnpm install --frozen-lockfile
- name: Run Linter
run: pnpm lint

View File

@@ -11,33 +11,17 @@ jobs:
lucide-angular: lucide-angular:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install --frozen-lockfile
- name: Build - name: Build
run: pnpm --filter lucide-angular build run: pnpm --filter lucide-angular build

View File

@@ -10,47 +10,27 @@ on:
jobs: jobs:
lucide-font: lucide-font:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: ericfennis/lucide-font:latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3.4.1 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install --filter outline-svg run: pnpm install --frozen-lockfile
- name: Outline svg Icons - name: Outline svg Icons
run: pnpm build:outline-icons run: pnpm build:outline-icons
- name: Create directory - name: Create font in ./lucide-font
run: mkdir lucide-font run: pnpm build:font
- name: Build font
run: fontcustom compile "./outlined" -h -n "lucide" -o ./lucide-font -F
- name: "Upload to Artifacts" - name: "Upload to Artifacts"
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v3
with: with:
name: lucide-font name: lucide-font
path: lucide-font path: lucide-font

View File

@@ -5,39 +5,24 @@ on:
paths: paths:
- packages/lucide-preact/** - packages/lucide-preact/**
- tools/build-icons/** - tools/build-icons/**
- tools/rollup-plugins/**
- pnpm-lock.yaml - pnpm-lock.yaml
jobs: jobs:
lucide-preact: lucide-preact:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install --frozen-lockfile
- name: Build - name: Build
run: pnpm --filter lucide-preact build run: pnpm --filter lucide-preact build

View File

@@ -5,39 +5,24 @@ on:
paths: paths:
- packages/lucide-react-native/** - packages/lucide-react-native/**
- tools/build-icons/** - tools/build-icons/**
- tools/rollup-plugins/**
- pnpm-lock.yaml - pnpm-lock.yaml
jobs: jobs:
lucide-react-native: lucide-react-native:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install --frozen-lockfile
- name: Build - name: Build
run: pnpm --filter lucide-react-native build run: pnpm --filter lucide-react-native build

View File

@@ -5,39 +5,25 @@ on:
paths: paths:
- packages/lucide-react/** - packages/lucide-react/**
- tools/build-icons/** - tools/build-icons/**
- tools/rollup-plugins/**
- scripts/generateNextJSAliases.mjs
- pnpm-lock.yaml - pnpm-lock.yaml
jobs: jobs:
lucide-react: lucide-react:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install --frozen-lockfile
- name: Build - name: Build
run: pnpm --filter lucide-react build run: pnpm --filter lucide-react build

View File

@@ -5,39 +5,24 @@ on:
paths: paths:
- packages/lucide-solid/** - packages/lucide-solid/**
- tools/build-icons/** - tools/build-icons/**
- tools/rollup-plugins/**
- pnpm-lock.yaml - pnpm-lock.yaml
jobs: jobs:
lucide-solid: lucide-solid:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install --frozen-lockfile
- name: Build - name: Build
run: pnpm --filter lucide-solid build run: pnpm --filter lucide-solid build

View File

@@ -11,33 +11,17 @@ jobs:
lucide-static: lucide-static:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install --frozen-lockfile
- name: Build - name: Build
run: pnpm --filter lucide-static build run: pnpm --filter lucide-static build

View File

@@ -5,39 +5,24 @@ on:
paths: paths:
- packages/lucide-svelte/** - packages/lucide-svelte/**
- tools/build-icons/** - tools/build-icons/**
- tools/rollup-plugins/**
- pnpm-lock.yaml - pnpm-lock.yaml
jobs: jobs:
lucide-svelte: lucide-svelte:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install --frozen-lockfile
- name: Build - name: Build
run: pnpm --filter lucide-svelte build run: pnpm --filter lucide-svelte build

View File

@@ -5,39 +5,24 @@ on:
paths: paths:
- packages/lucide-vue-next/** - packages/lucide-vue-next/**
- tools/build-icons/** - tools/build-icons/**
- tools/rollup-plugins/**
- pnpm-lock.yaml - pnpm-lock.yaml
jobs: jobs:
lucide-vue-next: lucide-vue-next:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install --frozen-lockfile
- name: Build - name: Build
run: pnpm --filter lucide-vue-next build run: pnpm --filter lucide-vue-next build

View File

@@ -5,39 +5,24 @@ on:
paths: paths:
- packages/lucide-vue/** - packages/lucide-vue/**
- tools/build-icons/** - tools/build-icons/**
- tools/rollup-plugins/**
- pnpm-lock.yaml - pnpm-lock.yaml
jobs: jobs:
lucide-vue: lucide-vue:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install --frozen-lockfile
- name: Build - name: Build
run: pnpm --filter lucide-vue build run: pnpm --filter lucide-vue build

View File

@@ -5,39 +5,24 @@ on:
paths: paths:
- packages/lucide/** - packages/lucide/**
- tools/build-icons/** - tools/build-icons/**
- tools/rollup-plugins/**
- pnpm-lock.yaml - pnpm-lock.yaml
jobs: jobs:
lucide: lucide:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install --frozen-lockfile
- name: Build - name: Build
run: pnpm --filter lucide build run: pnpm --filter lucide build

View File

@@ -4,155 +4,106 @@ on:
pull_request_target: pull_request_target:
paths: paths:
- 'icons/*.svg' - 'icons/*.svg'
branches:
permissions: - main
pull-requests: write - fix-icon-preview
contents: write
jobs: jobs:
add-changed-icons-comment: lint-filenames:
if: github.repository == 'lucide-icons/lucide'
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
contents: read
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
ref: refs/pull/${{ github.event.pull_request.number }}/merge ref: refs/pull/${{ github.event.pull_request.number }}/merge
- name: Get changed files - name: Get changed files
id: changed-files id: changed-files
uses: tj-actions/changed-files@v35 uses: tj-actions/changed-files@v41
with:
files: icons/*
- name: Generate annotations
run: node ./scripts/lintFilenames.mjs
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
lint-contributors:
if: github.repository == 'lucide-icons/lucide'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v41
with:
files: icons/*
- uses: actions/setup-node@v4
- name: Install simple-git (safer and faster than installing all deps)
run: npm install simple-git
- name: Generate annotations
run: node ./scripts/updateContributors.mjs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FETCH_DEPTH: ${{ github.event.pull_request.commits }}
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
- name: Generate annotations
env:
ANNOTATION_SEVERITY: notice
ANNOTATION_TITLE: Contributors have changed!
ANNOTATION_DESCRIPTION: Don't add people who have only performed automatic optimizations.
run: |
git diff --unified=0 -- icons/*.json | # diff icon metadata (unified=0 gives the correct chunk line number)
perl -ne '/^(\+|- |@)/ && print' | # get chunks (lines that start with "+++", "@@", "+ ", "- ")
perl -pe 's/\n/%0A/' | # url encode line breaks (\n -> %0A)
perl -pe 's/%0A(\+\+\+ b\/)/\n\1/g' | # split chunks(one chunk per line)
perl -pe "s/\+\+\+ b\/([^@]*)%0A@@ -(\d+)[^\s]* \+(\d+)[^@]*@@(.*)/::$ANNOTATION_SEVERITY file=\1,line=\2,endLine=\3,title=$ANNOTATION_TITLE::$ANNOTATION_DESCRIPTION%0A\4/"
# Example for the previous substitution
# input: +++ b/icons/accessibility.json%0A@@ -2,0 +3 @@%0A+ "contributors": ["hi"],%0A@@ -13 +14 @@%0A+}%0A
# output: ::$ANNOTATION_SEVERITY file=icons/accessibility.json,line=2,endLine=3,title=$ANNOTATION_TITLE::$ANNOTATION_DESCRIPTION%0A%0A+ "contributors": ["hi"],%0A@@ -13 +14 @@%0A+}%0A
generate-changed-icons-comment:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v41
with: with:
files: icons/*.svg files: icons/*.svg
- name: Generate 24px dpi preview
id: generate-24px-dpi-preview
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/dpi/24/&.svg\"/> |"
done | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Generate cohesion check random
id: generate-cohesion-check-random
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
for file in $(printf "%s\\n" icons/*.svg | shuf | head -n$(awk -F' ' '{print NF}' <<< '${{ steps.changed-files.outputs.all_changed_files }}')); do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/2/&.svg\"/> |"
done | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Generate cohesion check squares
id: generate-cohesion-check-squares
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
for file in $(printf "%s\\n" icons/*square*.svg | shuf | head -n$(awk -F' ' '{print NF}' <<< '${{ steps.changed-files.outputs.all_changed_files }}')); do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/2/&.svg\"/> |"
done | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Generate 1px stroke-width
id: generate-1px-stroke-width
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/1/&.svg\"/> |"
done | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Generate 2px stroke-width
id: generate-2px-stroke-width
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/2/&.svg\"/> |"
done | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Generate 3px stroke-width
id: generate-3px-stroke-width
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/3/&.svg\"/> |"
done | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Generate X-rays
id: generate-x-rays
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img width=\"400\" title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/$(basename ${file//\.svg/})/&.svg\"/> |"
done | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Find Comment - name: Find Comment
uses: peter-evans/find-comment@v2 uses: peter-evans/find-comment@v2
id: fc id: pr-comment
with: with:
issue-number: ${{ github.event.pull_request.number }} issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]' comment-author: 'github-actions[bot]'
body-includes: Added or changed icons body-includes: Added or changed icons
- name: Generate comment markup
run: node ./scripts/generateChangedIconsCommentMarkup.mjs >> comment-markup.md
id: comment-markup
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
- name: Create or update comment - name: Create or update comment
uses: peter-evans/create-or-update-comment@v2 uses: peter-evans/create-or-update-comment@v3
with: with:
comment-id: ${{ steps.fc.outputs.comment-id }} comment-id: ${{ steps.pr-comment.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }} issue-number: ${{ github.event.pull_request.number }}
body: | body-path: ./comment-markup.md
### Added or changed icons
${{ steps.generate-2px-stroke-width.outputs.body }}<br/>
<details>
<summary>Preview cohesion</summary>
${{ steps.generate-cohesion-check-squares.outputs.body }}<br/>
${{ steps.generate-2px-stroke-width.outputs.body }}<br/>
${{ steps.generate-cohesion-check-random.outputs.body }}<br/>
</details>
<details>
<summary>Preview stroke widths</summary>
${{ steps.generate-1px-stroke-width.outputs.body }}<br/>
${{ steps.generate-2px-stroke-width.outputs.body }}<br/>
${{ steps.generate-3px-stroke-width.outputs.body }}<br/>
</details>
<details>
<summary>DPI Preview (24px)</summary>
${{ steps.generate-24px-dpi-preview.outputs.body }}<br/>
</details>
<details>
<summary>Icon X-rays</summary>
${{ steps.generate-x-rays.outputs.body }}
</details>
edit-mode: replace edit-mode: replace

View File

@@ -39,6 +39,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: pre-release needs: pre-release
strategy: strategy:
fail-fast: false
matrix: matrix:
package: [ package: [
'lucide', 'lucide',
@@ -52,30 +53,14 @@ jobs:
'lucide-svelte', 'lucide-svelte',
] ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 18
cache: 'pnpm'
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with:
version: 7
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
@@ -100,32 +85,15 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [pre-release, lucide-font] needs: [pre-release, lucide-font]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/download-artifact@v2 - uses: actions/download-artifact@v3
- uses: pnpm/action-setup@v2
- uses: actions/setup-node@v3
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
@@ -149,47 +117,27 @@ jobs:
if: github.repository == 'lucide-icons/lucide' if: github.repository == 'lucide-icons/lucide'
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: pre-release needs: pre-release
container: ericfennis/lucide-font:latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3.4.1 - uses: pnpm/action-setup@v2
with: with:
node-version: 16 version: 8
- uses: actions/setup-node@v4
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with: with:
version: 7 node-version: 18
run_install: false cache: 'pnpm'
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install --filter outline-svg run: pnpm install --frozen-lockfile
- name: Outline svg Icons - name: Outline svg Icons
run: pnpm build:outline-icons run: pnpm build:outline-icons
- name: Create directory - name: Create font in ./lucide-font
run: mkdir lucide-font run: pnpm build:font
- name: Build font
run: fontcustom compile "./outlined" -h -n "lucide" -o ./lucide-font -F
- name: "Upload to Artifacts" - name: "Upload to Artifacts"
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v3
with: with:
name: lucide-font name: lucide-font
path: lucide-font path: lucide-font
@@ -203,8 +151,8 @@ jobs:
] ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/download-artifact@v2 - uses: actions/download-artifact@v3
- name: Zip font and icons - name: Zip font and icons
run: | run: |
zip -r lucide-font-${{ needs.pre-release.outputs.VERSION }}.zip lucide-font zip -r lucide-font-${{ needs.pre-release.outputs.VERSION }}.zip lucide-font

View File

@@ -4,7 +4,6 @@ stats
node_modules node_modules
tests tests
scripts scripts
site
src src
build build
babel.config.js babel.config.js

16
.prettierignore Normal file
View File

@@ -0,0 +1,16 @@
pnpm-lock.yaml
# lucide-angular
packages/lucide-angular/.angular/cache
# lucide-static
packages/lucide-static/icons
packages/lucide-static/lib
packages/lucide-static/sprite.svg
packages/lucide-static/tags.json
packages/lucide-static/icon-nodes.json
packages/lucide-static/font
# lucide-svelte
packages/lucide-svelte/src/icons/*.svelte
packages/lucide-svelte/.svelte-kit

View File

@@ -3,5 +3,11 @@
"devs", "devs",
"preact", "preact",
"Preact" "Preact"
] ],
"eslint.enable": true,
"eslint.validate": [
"javascript",
"svg"
],
"svg.preview.background": "transparent"
} }

View File

@@ -33,7 +33,7 @@ Here you can find instructions on how to implement the guidelines with different
#### [Adobe Illustrator Guide](https://lucide.dev/docs/illustrator-guide) #### [Adobe Illustrator Guide](https://lucide.dev/docs/illustrator-guide)
You can also [download an Adobe Illustrator template](https://lucide.dev/templates/illustrator-template.ai). You can also [download an Adobe Illustrator template](https://github.com/lucide-icons/lucide/blob/main/docs/public/templates/illustrator_template.ai).
#### [Inkscape Guide](https://lucide.dev/docs/inkscape-guide) #### [Inkscape Guide](https://lucide.dev/docs/inkscape-guide)
@@ -50,7 +50,7 @@ Seperate them by two PRs; 'pr-01' `arrow`, `arrow-down` and 'pr-02' `bicycle`.
Before creating an icon request, please search to see if someone has requested the icon already. If there is an open request, please add a :+1:. Before creating an icon request, please search to see if someone has requested the icon already. If there is an open request, please add a :+1:.
If the icon has not already been requested, [create an issue](https://github.com/lucide-icons/lucide/issues/new?title=Icon%20Request:) with a title of `Icon request: <icon name>` and add as much information as possible. If the icon has not already been requested, [create an icon request issue](https://github.com/lucide-icons/lucide/issues/new?assignees=&labels=%F0%9F%99%8C+icon+request&projects=&template=01_icon_request.yml) and add as much information as possible.
### Icon Requests from Feather ### Icon Requests from Feather
@@ -72,8 +72,8 @@ pnpm install # Install dependencies, including the workspace packages
To distribute different packages we use PNPM workspaces. Before you start make sure you are familiar with this concept. The concept of working in workspaces is created by Yarn, they have a well written introduction: [yarn workspaces](https://classic.yarnpkg.com/lang/enhttps://lucide.dev/docs/workspaces). To distribute different packages we use PNPM workspaces. Before you start make sure you are familiar with this concept. The concept of working in workspaces is created by Yarn, they have a well written introduction: [yarn workspaces](https://classic.yarnpkg.com/lang/enhttps://lucide.dev/docs/workspaces).
The configured directory for workspaces is the [packages](./packages) directory, located in the root directory. There you will find all the current packages from lucide. The configured directory for workspaces is the [packages](https://github.com/lucide-icons/lucide/tree/main/packages) directory, located in the root directory. There you will find all the current packages from lucide.
There are more workspaces defined, see [`pnpm-workspace.yaml`](./pnpm-workspace.yaml). There are more workspaces defined, see [`pnpm-workspace.yaml`](https://github.com/lucide-icons/lucide/blob/main/pnpm-workspace.yaml).
> Note: One package is not managed by pnpm: **lucide-flutter**, this package is written in Dart and used pub for publishing. > Note: One package is not managed by pnpm: **lucide-flutter**, this package is written in Dart and used pub for publishing.
@@ -144,16 +144,19 @@ Root directories
```sh ```sh
lucide lucide
|
├── docs ├── docs
│ ├── guide
├── icons ├── icons
├── packages ├── packages
── scripts ── scripts
└── site
``` ```
### Docs ### Docs
The lucide.dev website is using [vitepress](https://vitepress.dev/) to generate the static website. The markdown files are located in the docs directory.
### Guides
Detailed documentation about: installation, guides, packages, design guides etc. Detailed documentation about: installation, guides, packages, design guides etc.
### Icons ### Icons
@@ -170,10 +173,6 @@ Includes all the (npm) packages of lucide.
Includes usefully scripts to automate certain jobs. Big part of the scripts is the template generation, for example it generates icon components for all the packages. These scripts are usually executed from the "scripts" section in the package.json. Includes usefully scripts to automate certain jobs. Big part of the scripts is the template generation, for example it generates icon components for all the packages. These scripts are usually executed from the "scripts" section in the package.json.
### site
The lucide.dev website is using [vitepress](https://vitepress.dev/) to generate the static website. The markdown files are located in the docs directory.
## Documentation ## Documentation
The documentation files are located in the [docs](https://github.com/lucide-icons/lucide/tree/main/docs) directory. All these markdown files will be loaded in the build of the lucide.dev website. The documentation files are located in the [docs](https://github.com/lucide-icons/lucide/tree/main/docs) directory. All these markdown files will be loaded in the build of the lucide.dev website.

View File

@@ -11,14 +11,14 @@
Community-run fork of [Feather Icons](https://github.com/feathericons/feather), open for anyone to contribute icons. Community-run fork of [Feather Icons](https://github.com/feathericons/feather), open for anyone to contribute icons.
It began after growing disaffection with the [Feather Icons](https://github.com/feathericons/feather) project moderation. With over 300+ open issues and over 100+ open PRs, the Feather Icons project has been abandoned. This unfortunately means that hundreds of developers and designers wasted their time contributing to Feather Icons with no chance of PRs being accepted. It began after growing dissatisfaction with the [Feather Icons](https://github.com/feathericons/feather) project moderation. With over 300+ open issues and over 100+ open PRs, the Feather Icons project has been abandoned. This unfortunately means that hundreds of developers and designers wasted their time contributing to Feather Icons with no chance of PRs being accepted.
Lucide is trying to expand the icon set as much as possible while staying faithful to the original simplistic design language. We do this as a community of devs and designers and hope that you'll join us! Lucide is trying to expand the icon set as much as possible while staying faithful to the original simplistic design language. We do this as a community of devs and designers and hope that you'll join us!
### Why choose Lucide over Feather Icons ### Why choose Lucide over Feather Icons
- More icons to work with: Lucide already has hundreds of icons more than Feather does. - More icons to work with: Lucide already has hundreds of icons more than Feather does.
- Official librairies and integrations with popular frameworks and design tools. - Official libraries and integrations with popular frameworks and design tools.
- Well maintained code base. - Well maintained code base.
- Active community, regularly growing and improving the set. - Active community, regularly growing and improving the set.
@@ -35,7 +35,6 @@ Lucide is trying to expand the icon set as much as possible while staying faithf
- [Static (svg sprite, font, icons ..)](#static-svg-sprite-font-icons-) - [Static (svg sprite, font, icons ..)](#static-svg-sprite-font-icons-)
- [Figma](#figma) - [Figma](#figma)
- [Laravel](#laravel) - [Laravel](#laravel)
- [Flutter](#flutter)
- [Svelte](#svelte) - [Svelte](#svelte)
- [Solid](#solid) - [Solid](#solid)
- [Hyva](#hyva) - [Hyva](#hyva)
@@ -200,16 +199,6 @@ composer require mallardduck/blade-lucide-icons
For more details, see the [documentation](https://github.com/mallardduck/blade-lucide-icons/blob/main/README.md). For more details, see the [documentation](https://github.com/mallardduck/blade-lucide-icons/blob/main/README.md).
### Flutter
Implementation of Lucide icon library for Flutter applications.
```sh
flutter pub add lucide_icons
```
For more details, see the [pub.dev](https://pub.dev/packages/lucide_icons).
### Svelte ### Svelte
Implementation of the lucide icon library for Svelte applications. Implementation of the lucide icon library for Svelte applications.
@@ -285,6 +274,9 @@ Thank you to all the people who contributed to Lucide!
## Sponsors ## Sponsors
<a href="https://vercel.com?utm_source=lucide&utm_campaign=oss"> <a href="https://vercel.com?utm_source=lucide&utm_campaign=oss">
<img src="/docs/public/vercel.svg" alt="Powered by Vercel" width="200" /> <img src="docs/public/vercel.svg" alt="Powered by Vercel" width="200" />
</a> </a>
<a href="https://www.digitalocean.com/?refcode=b0877a2caebd&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge"><img src="docs/public/digitalocean.svg" width="200" alt="DigitalOcean Referral Badge" /></a>

View File

@@ -1,5 +1,5 @@
{ {
"$schema": "../category.schema.json", "$schema": "../category.schema.json",
"title": "File icons", "title": "File icons",
"icon": "layout" "icon": "panels-top-left"
} }

View File

@@ -1,5 +1,5 @@
{ {
"$schema": "../category.schema.json", "$schema": "../category.schema.json",
"title": "Layout", "title": "Layout",
"icon": "layout" "icon": "panels-top-left"
} }

View File

@@ -12,8 +12,10 @@
}, },
"title": "Lucide Icons category schema", "title": "Lucide Icons category schema",
"type": "object", "type": "object",
"additionalProperties": false,
"required": ["$schema", "icon", "title"],
"properties": { "properties": {
"title": { "$schema": {
"type": "string" "type": "string"
}, },
"description": { "description": {
@@ -22,13 +24,12 @@
"icon": { "icon": {
"type": "string" "type": "string"
}, },
"title": {
"type": "string"
},
"weight": { "weight": {
"type": "integer" "type": "integer"
} }
}, },
"required": [
"title",
"icon"
],
"description": "A JSON Schema for categories defined by Lucide Icons." "description": "A JSON Schema for categories defined by Lucide Icons."
} }

View File

@@ -1,41 +1,53 @@
import { eventHandler, setResponseHeader, defaultContentType } from 'h3' import { eventHandler, setResponseHeader, defaultContentType } from 'h3';
import { renderToString, renderToStaticMarkup } from 'react-dom/server' import { renderToString, renderToStaticMarkup } from 'react-dom/server';
import { createElement } from 'react' import { createElement } from 'react';
import SvgPreview from '../../lib/SvgPreview/index.tsx'; import SvgPreview from '../../lib/SvgPreview/index.tsx';
import iconNodes from '../../data/iconNodes' import iconNodes from '../../data/iconNodes';
import createLucideIcon from 'lucide-react/src/createLucideIcon' import createLucideIcon from 'lucide-react/src/createLucideIcon';
import Backdrop from '../../lib/SvgPreview/Backdrop.tsx'; import Backdrop from '../../lib/SvgPreview/Backdrop.tsx';
export default eventHandler((event) => { export default eventHandler((event) => {
const { params } = event.context const { params } = event.context;
const [name, svgData] = params.data.split('/'); const pathData = params.data.split('/');
const data = svgData.slice(0, -4); const data = pathData.at(-1).slice(0, -4);
const [name] = pathData;
const src = Buffer.from(data, 'base64').toString('utf8'); const src = Buffer.from(data, 'base64').toString('utf8');
const children = [] const children = [];
if (name in iconNodes) { // Finds the longest matching icon to be use as the backdrop.
const iconNode = iconNodes[name] // For `square-dashed-bottom-code` it suggests `square-dashed-bottom-code`.
// For `square-dashed-bottom-i-dont-exist` it suggests `square-dashed-bottom`.
const backdropName = name
.split('-')
.map((_, idx, arr) => arr.slice(0, idx + 1).join('-'))
.reverse()
.find((groupName) => groupName in iconNodes);
if (backdropName) {
const iconNode = iconNodes[backdropName];
const LucideIcon = createLucideIcon(name, iconNode) const LucideIcon = createLucideIcon(backdropName, iconNode);
const svg = renderToStaticMarkup(createElement(LucideIcon)) const svg = renderToStaticMarkup(createElement(LucideIcon));
const backdropString = svg.replace(/<svg[^>]*>|<\/svg>/g, ''); const backdropString = svg.replace(/<svg[^>]*>|<\/svg>/g, '');
children.push(createElement(Backdrop, { backdropString, src })) children.push(
createElement(Backdrop, {
backdropString,
src,
color: name in iconNodes ? 'red' : '#777',
})
);
} }
const svg = Buffer.from( const svg = Buffer.from(
// We can't use jsx here, is not supported here by nitro. // We can't use jsx here, is not supported here by nitro.
renderToString(createElement(SvgPreview, {src, showGrid: true}, children)).replace( renderToString(createElement(SvgPreview, { src, showGrid: true }, children))
/>/,
'><style>@media screen and (prefers-color-scheme: dark) { svg { stroke: #fff } }</style>'
)
).toString('utf8'); ).toString('utf8');
defaultContentType(event, 'image/svg+xml') defaultContentType(event, 'image/svg+xml');
setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000') setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000');
return svg return svg;
}) });

View File

@@ -12,6 +12,7 @@ export default defineConfig({
description, description,
cleanUrls: true, cleanUrls: true,
outDir: '.vercel/output/static', outDir: '.vercel/output/static',
srcExclude: ['**/README.md'],
vite: { vite: {
resolve: { resolve: {
alias: [ alias: [
@@ -103,6 +104,7 @@ export default defineConfig({
{ text: 'Icons', link: '/icons/' }, { text: 'Icons', link: '/icons/' },
{ text: 'Guide', link: '/guide/' }, { text: 'Guide', link: '/guide/' },
{ text: 'Packages', link: '/packages' }, { text: 'Packages', link: '/packages' },
{ text: 'Showcase', link: '/showcase' },
{ text: 'License', link: '/license' }, { text: 'License', link: '/license' },
], ],
sidebar, sidebar,
@@ -117,6 +119,10 @@ export default defineConfig({
editLink: { editLink: {
pattern: 'https://github.com/lucide-icons/lucide/edit/main/docs/:path' pattern: 'https://github.com/lucide-icons/lucide/edit/main/docs/:path'
}, },
carbonAds: {
code: 'CWYIC53U',
placement: 'lucidedev'
}
}, },
sitemap: { sitemap: {
hostname: 'https://lucide.dev/' hostname: 'https://lucide.dev/'

View File

@@ -0,0 +1,50 @@
[
{
"name": "Vercel",
"url": "https://vercel.com",
"image": {
"light": "/company-logos/vercel-light.svg",
"dark": "/company-logos/vercel-dark.svg"
}
},
{
"name": "Supabase",
"url": "https://supabase.com",
"image": {
"light": "/company-logos/supabase-light.svg",
"dark": "/company-logos/supabase-dark.svg"
}
},
{
"name": "Obsidian",
"url": "https://obsidian.md",
"image": {
"light": "/company-logos/obsidian-light.svg",
"dark": "/company-logos/obsidian-dark.svg"
}
},
{
"name": "Open Collective",
"url": "https://opencollective.com",
"image": {
"light": "/company-logos/open-collective-light.svg",
"dark": "/company-logos/open-collective-dark.svg"
}
},
{
"name": "Super",
"url": "https://super.so",
"image": {
"light": "/company-logos/super-light.svg",
"dark": "/company-logos/super-dark.svg"
}
},
{
"name": "Noodle",
"url": "https://noodle.run/",
"image": {
"light": "/company-logos/noodle-light.svg",
"dark": "/company-logos/noodle-dark.svg"
}
}
]

View File

@@ -0,0 +1,18 @@
[
{
"name": "Shadcn/ui",
"url": "https://ui.shadcn.com/",
"image": {
"light": "/library-logos/shadcn-ui-light.svg",
"dark": "/library-logos/shadcn-ui-dark.svg"
}
},
{
"name": "Tamagui",
"url": "https://tamagui.dev/",
"image": {
"light": "/library-logos/tamagui.svg",
"dark": "/library-logos/tamagui.svg"
}
}
]

View File

@@ -1,11 +1,12 @@
import React from 'react'; import React from 'react';
interface BackdropProps { interface BackdropProps {
src: string src: string;
backdropString: string color?: string;
backdropString: string;
} }
const Backdrop = ({ src, backdropString }: BackdropProps): JSX.Element => { const Backdrop = ({ src, color = 'red', backdropString }: BackdropProps): JSX.Element => {
return ( return (
<> <>
<defs xmlns="http://www.w3.org/2000/svg"> <defs xmlns="http://www.w3.org/2000/svg">
@@ -16,8 +17,8 @@ const Backdrop = ({ src, backdropString }: BackdropProps): JSX.Element => {
patternUnits="userSpaceOnUse" patternUnits="userSpaceOnUse"
patternTransform="rotate(45 50 50)" patternTransform="rotate(45 50 50)"
> >
<line stroke="red" strokeWidth={0.1} y2={1} /> <line stroke={color} strokeWidth={0.1} y2={1} />
<line stroke="red" strokeWidth={0.1} y2={1} /> <line stroke={color} strokeWidth={0.1} y2={1} />
</pattern> </pattern>
</defs> </defs>
<mask id="svg-preview-backdrop-mask-outline" maskUnits="userSpaceOnUse"> <mask id="svg-preview-backdrop-mask-outline" maskUnits="userSpaceOnUse">
@@ -29,20 +30,8 @@ const Backdrop = ({ src, backdropString }: BackdropProps): JSX.Element => {
<g dangerouslySetInnerHTML={{ __html: src }} strokeWidth={2.05} /> <g dangerouslySetInnerHTML={{ __html: src }} strokeWidth={2.05} />
<g strokeWidth={1.75} dangerouslySetInnerHTML={{ __html: backdropString }} /> <g strokeWidth={1.75} dangerouslySetInnerHTML={{ __html: backdropString }} />
</mask> </mask>
<g <g strokeWidth={2.25} stroke="url(#pattern)" mask={'url(#svg-preview-backdrop-mask-outline)'}>
strokeWidth={2.25} <rect x="0" y="0" width="24" height="24" fill="url(#pattern)" opacity={0.5} stroke="none" />
stroke="url(#pattern)"
mask={'url(#svg-preview-backdrop-mask-outline)'}
>
<rect
x="0"
y="0"
width="24"
height="24"
fill="url(#pattern)"
opacity={0.5}
stroke="none"
/>
</g> </g>
<rect <rect
x="0" x="0"
@@ -58,14 +47,13 @@ const Backdrop = ({ src, backdropString }: BackdropProps): JSX.Element => {
y="0" y="0"
width="24" width="24"
height="24" height="24"
fill="red" fill={color}
opacity={0.5} opacity={0.5}
stroke="none" stroke="none"
mask={'url(#svg-preview-backdrop-mask-fill)'} mask={'url(#svg-preview-backdrop-mask-fill)'}
/> />
</> </>
) );
} };
export default Backdrop; export default Backdrop;

View File

@@ -183,18 +183,62 @@ const Radii = ({
>) => { >) => {
return ( return (
<g className="svg-preview-radii-group" {...props}> <g className="svg-preview-radii-group" {...props}>
{paths {paths.map(
.filter(({ circle }) => circle) ({ c, prev, next, circle }, i) =>
.map(({ c, prev, next, circle: { x, y, r } }) => circle && (
c.name === 'circle' ? ( <React.Fragment key={i}>
<path d={`M${x} ${y}h.01`} /> {c.name !== "circle" && (
) : ( <path
<> d={`M${prev.x} ${prev.y} ${circle.x} ${circle.y} ${next.x} ${next.y}`}
<path d={`M${prev.x} ${prev.y} ${x} ${y} ${next.x} ${next.y}`} /> />
<circle cy={y} cx={x} r={r} /> )}
</> <circle
) cy={circle.y}
)} cx={circle.x}
r={0.25}
strokeDasharray="0"
stroke={
(Math.round(circle.x * 100) / 100) % 1 !== 0 ||
(Math.round(circle.y * 100) / 100) % 1 !== 0
? "red"
: undefined
}
/>
<circle
cy={circle.y}
cx={circle.x}
r={circle.r}
stroke={
(Math.round(circle.r * 1000) / 1000) % 1 !== 0
? "red"
: undefined
}
/>
</React.Fragment>
),
)}
</g>
);
};
const Handles = ({
paths,
...props
}: { paths: Path[] } & PathProps<
'strokeWidth' | 'stroke' | 'strokeDasharray' | 'strokeOpacity',
any
>) => {
console.log(paths);
return (
<g className="svg-preview-handles-group" {...props}>
{paths.map(({ c, prev, next, cp1, cp2 }) => (
<>
{cp1 && <path d={`M${prev.x} ${prev.y} ${cp1.x} ${cp1.y}`} />}
{cp1 && <circle cy={cp1.y} cx={cp1.x} r={0.25} />}
{cp2 && <path d={`M${next.x} ${next.y} ${cp2.x} ${cp2.y}`} />}
{cp2 && <circle cy={cp2.y} cx={cp2.x} r={0.25} />}
</>
))}
</g> </g>
); );
}; };
@@ -238,6 +282,7 @@ const SvgPreview = React.forwardRef<
<style>{darkModeCss}</style> <style>{darkModeCss}</style>
{showGrid && <Grid strokeWidth={0.1} stroke="#777" strokeOpacity={0.3} radius={1} />} {showGrid && <Grid strokeWidth={0.1} stroke="#777" strokeOpacity={0.3} radius={1} />}
<Shadow paths={paths} strokeWidth={4} stroke="#777" radius={1} strokeOpacity={0.15} /> <Shadow paths={paths} strokeWidth={4} stroke="#777" radius={1} strokeOpacity={0.15} />
<Handles paths={paths} strokeWidth={0.12} stroke="#777" strokeOpacity={0.6} />
<ColoredPath <ColoredPath
paths={paths} paths={paths}
colors={[ colors={[
@@ -263,6 +308,7 @@ const SvgPreview = React.forwardRef<
strokeOpacity={0.3} strokeOpacity={0.3}
/> />
<ControlPath radius={1} paths={paths} pointSize={1} stroke="#fff" strokeWidth={0.125} /> <ControlPath radius={1} paths={paths} pointSize={1} stroke="#fff" strokeWidth={0.125} />
<Handles paths={paths} strokeWidth={0.12} stroke="#FFF" strokeOpacity={0.3} />
{children} {children}
</svg> </svg>
); );

View File

@@ -8,7 +8,9 @@ export type Path = {
prev: Point; prev: Point;
next: Point; next: Point;
isStart: boolean; isStart: boolean;
circle: { x: number; y: number; r: number }; circle?: { x: number; y: number; r: number };
cp1?: Point;
cp2?: Point;
c: ReturnType<typeof getCommands>[number]; c: ReturnType<typeof getCommands>[number];
}; };

View File

@@ -63,7 +63,7 @@ export const getPaths = (src: string) => {
c: typeof commands[number], c: typeof commands[number],
next: Point, next: Point,
d?: string, d?: string,
circle?: Path['circle'] extras?: { circle?: Path['circle']; cp1?: Path['cp1']; cp2?: Path['cp2'] }
) => { ) => {
assert(prev); assert(prev);
paths.push({ paths.push({
@@ -71,7 +71,7 @@ export const getPaths = (src: string) => {
d: d || `M ${prev.x} ${prev.y} L ${next.x} ${next.y}`, d: d || `M ${prev.x} ${prev.y} L ${next.x} ${next.y}`,
prev, prev,
next, next,
circle, ...extras,
isStart: start === prev, isStart: start === prev,
}); });
prev = next; prev = next;
@@ -110,7 +110,10 @@ export const getPaths = (src: string) => {
} }
case SVGPathData.CURVE_TO: { case SVGPathData.CURVE_TO: {
assert(prev); assert(prev);
addPath(c, c, `M ${prev.x} ${prev.y} ${encodeSVGPath(c)}`); addPath(c, c, `M ${prev.x} ${prev.y} ${encodeSVGPath(c)}`, {
cp1: { x: c.x1, y: c.y1 },
cp2: { x: c.x2, y: c.y2 },
});
break; break;
} }
case SVGPathData.SMOOTH_CURVE_TO: { case SVGPathData.SMOOTH_CURVE_TO: {
@@ -146,13 +149,20 @@ export const getPaths = (src: string) => {
y1: prev.y - reflectedCp1.y, y1: prev.y - reflectedCp1.y,
x2: c.x2, x2: c.x2,
y2: c.y2, y2: c.y2,
})}` })}`,
{
cp1: { x: prev.x - reflectedCp1.x, y: prev.y - reflectedCp1.y },
cp2: { x: c.x2, y: c.y2 },
}
); );
break; break;
} }
case SVGPathData.QUAD_TO: { case SVGPathData.QUAD_TO: {
assert(prev); assert(prev);
addPath(c, c, `M ${prev.x} ${prev.y} ${encodeSVGPath(c)}`); addPath(c, c, `M ${prev.x} ${prev.y} ${encodeSVGPath(c)}`, {
cp1: { x: c.x1, y: c.y1 },
cp2: { x: c.x1, y: c.y1 },
});
break; break;
} }
case SVGPathData.SMOOTH_QUAD_TO: { case SVGPathData.SMOOTH_QUAD_TO: {
@@ -197,7 +207,11 @@ export const getPaths = (src: string) => {
y: c.y, y: c.y,
x1: prevCP.x, x1: prevCP.x,
y1: prevCP.y, y1: prevCP.y,
})}` })}`,
{
cp1: { x: prevCP.x, y: prevCP.y },
cp2: { x: prevCP.x, y: prevCP.y },
}
); );
break; break;
} }
@@ -218,7 +232,7 @@ export const getPaths = (src: string) => {
c, c,
c, c,
`M ${prev.x} ${prev.y} A${c.rX} ${c.rY} ${c.xRot} ${c.lArcFlag} ${c.sweepFlag} ${c.x} ${c.y}`, `M ${prev.x} ${prev.y} A${c.rX} ${c.rY} ${c.xRot} ${c.lArcFlag} ${c.sweepFlag} ${c.x} ${c.y}`,
c.rX === c.rY ? { ...center, r: c.rX } : undefined { circle: c.rX === c.rY ? { ...center, r: c.rX } : undefined }
); );
break; break;
} }

View File

@@ -1,41 +1,29 @@
import { import {
BUNDLED_LANGUAGES, bundledLanguages,
type IThemeRegistration type ThemeRegistration
} from 'shiki' } from 'shikiji'
import { import {
getHighlighter, getHighlighter,
} from 'shiki-processor' } from 'shikiji'
type CodeExampleType = { type CodeExampleType = {
title: string, title: string,
lang: string, language: string,
codes: { code: string,
language?: string,
code: string,
metastring?: string,
}[],
}[] }[]
const getIconCodes = (): CodeExampleType => { const getIconCodes = (): CodeExampleType => {
return [ return [
{ {
lang: 'html', language: 'html',
title: 'HTML', title: 'HTML',
codes: [ code: `<i data-lucide="Name"></i>`
{
language: 'html',
code: `<i data-lucide-name="Name"></i>
`,
},
],
}, },
{ {
lang: 'tsx', language: 'tsx',
title: 'React', title: 'React',
codes: [ code: `import { PascalCase } from 'lucide-react';
{
language: 'tsx',
code: `import { PascalCase } from 'lucide-react';
const App = () => { const App = () => {
return ( return (
@@ -45,17 +33,11 @@ const App = () => {
export default App; export default App;
`, `,
},
],
}, },
{ {
lang: 'vue', language: 'vue',
title: 'Vue 3', title: 'Vue',
codes: [ code: `<script setup>
{
language: 'vue',
code: `<script setup>
import { PascalCase } from 'lucide-vue-next'; import { PascalCase } from 'lucide-vue-next';
</script> </script>
@@ -63,33 +45,21 @@ export default App;
<PascalCase /> <PascalCase />
</template> </template>
`, `,
},
],
}, },
{ {
lang: 'svelte', language: 'svelte',
title: 'Svelte', title: 'Svelte',
codes: [ code: `<script>
{
language: 'svelte',
code: `<script>
import { PascalCase } from 'lucide-svelte'; import { PascalCase } from 'lucide-svelte';
</script> </script>
<PascalCase /> <PascalCase />
`, `,
},
],
}, },
{ {
lang: 'preact', language: 'tsx',
title: 'Preact', title: 'Preact',
codes: [ code: `import { PascalCase } from 'lucide-preact';
{
language: 'tsx',
code: `import { PascalCase } from 'lucide-preact';
const App = () => { const App = () => {
return ( return (
@@ -99,17 +69,11 @@ const App = () => {
export default App; export default App;
`, `,
},
],
}, },
{ {
lang: 'solid', language: 'tsx',
title: 'Solid', title: 'Solid',
codes: [ code: `import { PascalCase } from 'lucide-solid';
{
language: 'tsx',
code: `import { PascalCase } from 'lucide-solid';
const App = () => { const App = () => {
return ( return (
@@ -119,17 +83,11 @@ const App = () => {
export default App; export default App;
`, `,
},
],
}, },
{ {
lang: 'angular', language: 'tsx',
title: 'Angular', title: 'Angular',
codes: [ code: `// app.module.ts
{
language: 'tsx',
code: `// app.module.ts
import { LucideAngularModule, PascalCase } from 'lucide-angular'; import { LucideAngularModule, PascalCase } from 'lucide-angular';
@NgModule({ @NgModule({
@@ -141,54 +99,38 @@ import { LucideAngularModule, PascalCase } from 'lucide-angular';
// app.component.html // app.component.html
<lucide-icon name="Name"></lucide-icon> <lucide-icon name="Name"></lucide-icon>
`, `,
},
],
}, },
{ {
lang: 'html', language: 'html',
title: 'Icon Font', title: 'Icon Font',
codes: [ code: `<style>
{
language: 'html',
code: `<style>
@import ('~lucide-static/font/Lucide.css'); @import ('~lucide-static/font/Lucide.css');
</style> </style>
<div class="icon-Name"></div> <div class="icon-Name"></div>
`, `,
}, }
],
},
{
lang: 'dart',
title: 'Flutter',
codes: [
{
language: 'dart',
code: `Icon(LucideIcons.Name);
`,
},
],
},
] ]
} }
export type ThemeOptions = export type ThemeOptions =
| IThemeRegistration | ThemeRegistration
| { light: IThemeRegistration; dark: IThemeRegistration } | { light: ThemeRegistration; dark: ThemeRegistration }
const highLightCode = async (code: string, lang: string, active?: boolean) => { const highLightCode = async (code: string, lang: string, active?: boolean) => {
const highlighter = await getHighlighter({ const highlighter = await getHighlighter({
themes: ['material-theme-palenight'], themes: ['github-light', 'github-dark'],
langs: [...BUNDLED_LANGUAGES], langs: Object.keys(bundledLanguages)
processors: []
}) })
const highlightedCode = highlighter.codeToHtml(code, { const highlightedCode = highlighter.codeToHtml(code, {
lang, lang,
// lineOptions, themes: {
theme: 'material-theme-palenight' light: 'github-light',
}).replace('background-color: #292D3E', '') dark: 'github-dark'
},
defaultColor: false
}).replace('shiki-themes', 'shiki-themes vp-code')
return `<div class="language-${lang} ${active ? 'active' : ''}"> return `<div class="language-${lang} ${active ? 'active' : ''}">
<button title="Copy Code" class="copy"></button> <button title="Copy Code" class="copy"></button>
@@ -201,16 +143,15 @@ const highLightCode = async (code: string, lang: string, active?: boolean) => {
export default async function createCodeExamples() { export default async function createCodeExamples() {
const codes = getIconCodes(); const codes = getIconCodes();
const codeExamplePromises = codes.map(async (codeTemplate, index) => { const codeExamplePromises = codes.map(async ({ title, language, code }, index) => {
const { title, lang, codes } = codeTemplate;
const isFirst = index === 0; const isFirst = index === 0;
const code = await highLightCode(codes[0].code, codes[0].language || lang, isFirst); const codeString = await highLightCode(code, language, isFirst);
return { return {
title, title,
language: codes[0].language || lang, language: language,
code, code: codeString,
}; };
}) })

View File

@@ -10,28 +10,53 @@ const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
{ text: 'Comparison', link: '/guide/comparison' } { text: 'Comparison', link: '/guide/comparison' }
] ]
}, },
// { {
// text: 'Using Icons', text: 'Basics',
// items: [ items: [
// { {
// text: 'How to use icons', text: 'Color',
// link: 'how-to-use-icons' link: '/guide/basics/color'
// }, },
// { {
// text: 'Styling icons', text: 'Sizing',
// link: 'styling-icons' link: '/guide/basics/sizing'
// }, },
// { {
// text: 'Accessibility', text: 'Stroke width',
// link: 'accessibility' link: '/guide/basics/stroke-width'
// }, },
// { ]
// text: 'What should I use', },
// link: 'what-should-i-use' // TODO: Add this section
// }, {
text: 'Advanced',
// ] items: [
// }, // {
// text: 'Accessibility',
// link: '/guide/advanced/accessibility'
// },
{
text: 'Global styling',
link: '/guide/advanced/global-styling'
},
// {
// text: 'Animations',
// },
{
text: 'Filled icons',
link: '/guide/advanced/filled-icons'
},
// {
// text: 'Combining icons',
// },
// {
// text: 'Dynamic imports'
// },
// {
// text: 'Auto importing'
// },
]
},
{ {
text: 'Packages', text: 'Packages',
items: [ items: [
@@ -49,10 +74,6 @@ const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
}, },
{ {
text: 'Lucide Vue', text: 'Lucide Vue',
link: '/guide/packages/lucide-vue'
},
{
text: 'Lucide Vue Next (Vue 3)',
link: '/guide/packages/lucide-vue-next' link: '/guide/packages/lucide-vue-next'
}, },
{ {
@@ -75,10 +96,6 @@ const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
text: 'Lucide Static', text: 'Lucide Static',
link: '/guide/packages/lucide-static' link: '/guide/packages/lucide-static'
}, },
{
text: 'Lucide Flutter',
link: '/guide/packages/lucide-flutter'
},
] ]
}, },
{ {
@@ -103,15 +120,9 @@ const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
] ]
}, },
], ],
// This should be here to keep the sidebar shown on the icons page
'icons': [ 'icons': [
{ text: '', link: '/' }, { text: '', link: '/' },
// { text: 'Categorized', link: '/icons/categorized' },
// {
// text: 'Categories',
// items: [
// ...(getAllCategoryFiles().map((category) => ({ text: category, link: `/icons/category/${category}` })))
// ]
// }
], ],
} }

View File

@@ -7,5 +7,6 @@
<style scoped> <style scoped>
.container { .container {
padding: 32px; padding: 32px;
padding-top: 33px;
} }
</style> </style>

View File

@@ -9,8 +9,6 @@ const props = defineProps<{
}>() }>()
const component = computed(() => props.href ? 'a' : 'div') const component = computed(() => props.href ? 'a' : 'div')
</script> </script>
<template> <template>
@@ -25,7 +23,7 @@ const component = computed(() => props.href ? 'a' : 'div')
</template> </template>
<style> <style>
.badge, a.badge { .badge, a.badge, .vp-doc a.badge {
display: block; display: block;
border: 1px solid transparent; border: 1px solid transparent;
text-align: center; text-align: center;
@@ -36,6 +34,7 @@ const component = computed(() => props.href ? 'a' : 'div')
border-radius: 6px; border-radius: 6px;
background-color: var(--vp-c-bg-alt); background-color: var(--vp-c-bg-alt);
color: var(--vp-c-text-1); color: var(--vp-c-text-1);
text-decoration: none;
/* width: 56px; /* width: 56px;
height: 56px; */ height: 56px; */
font-size: 16px; font-size: 16px;
@@ -59,4 +58,6 @@ const component = computed(() => props.href ? 'a' : 'div')
/* color: var(--vp-button-alt-active-text); /* color: var(--vp-button-alt-active-text);
background-color: var(--vp-button-alt-active-bg); */ background-color: var(--vp-button-alt-active-bg); */
} }
</style> </style>

View File

@@ -94,8 +94,7 @@ const ChevronUp = createLucideIcon('ChevronUp', chevronUp)
.menu { .menu {
position: relative; position: relative;
} }
.menu-items { ul.menu-items {
--menu-offset: 44px;
position: absolute; position: absolute;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -103,7 +102,7 @@ const ChevronUp = createLucideIcon('ChevronUp', chevronUp)
padding: 12px; padding: 12px;
min-width: 128px; min-width: 128px;
border: 1px solid var(--vp-c-divider); border: 1px solid var(--vp-c-divider);
background-color: var(--vp-c-bg); background-color: var(--vp-c-bg-elv);
box-shadow: var(--vp-shadow-3); box-shadow: var(--vp-shadow-3);
transition: background-color 0.5s; transition: background-color 0.5s;
max-height: calc(100vh - var(--vp-nav-height)); max-height: calc(100vh - var(--vp-nav-height));
@@ -124,11 +123,12 @@ const ChevronUp = createLucideIcon('ChevronUp', chevronUp)
color: var(--vp-c-text-1); color: var(--vp-c-text-1);
white-space: nowrap; white-space: nowrap;
transition: background-color .25s,color .25s; transition: background-color .25s,color .25s;
list-style: none;
} }
.menu-item:hover { .menu-item:hover {
color: var(--vp-c-brand); color: var(--vp-c-brand);
background-color: var(--vp-c-bg-elv-mute); background-color: var(--vp-c-default-soft);
} }
.menu-item:active { .menu-item:active {
@@ -170,11 +170,11 @@ const ChevronUp = createLucideIcon('ChevronUp', chevronUp)
} }
.menu-items.bottom { .menu-items.bottom {
top: var(--menu-offset); top: 32px;
} }
.menu-items.top { .menu-items.top {
bottom: var(--menu-offset); bottom: 48px;
} }
.arrow-up-button.top::before { .arrow-up-button.top::before {

View File

@@ -0,0 +1,56 @@
<script setup lang="ts">
import { computed } from 'vue';
const props = defineProps<{
href?: string;
}>()
const isExternal = computed(() => {
return props.href?.startsWith('http') ?? false
})
const component = computed(() => {
return props.href ? 'a' : 'div'
})
const rel = computed(() => {
return isExternal.value ? 'noreferrer noopener' : undefined
})
</script>
<template>
<component
:is="component"
:href="href"
:rel="rel"
class="card"
>
<slot />
</component>
</template>
<style scoped>
.card {
border: 1px solid var(--vp-c-bg-soft);
border-radius: 12px;
background-color: var(--vp-c-bg-soft);
display: flex;
flex-direction: column;
padding: 24px;
text-decoration: none;
}
.card[href] {
display: block;
border: 1px solid var(--vp-c-bg-soft);
border-radius: 12px;
height: 100%;
background-color: var(--vp-c-bg-soft);
transition: border-color .25s,background-color .25s;
}
.card[href]:hover {
border-color: var(--vp-c-brand-1);
}
</style>

View File

@@ -0,0 +1,36 @@
<template>
<div class="grid">
<slot />
</div>
</template>
<style scoped>
.grid {
display: flex;
flex-wrap: wrap;
align-items: stretch;
justify-content: center;
align-content: space-evenly;
box-sizing: border-box;
margin: -8px;
}
.grid > * {
flex-basis: 100%;
box-sizing: border-box;
padding: 8px;
}
@media (min-width: 960px) {
.grid > * {
flex-basis: 50%;
}
}
@media (min-width: 1280px) {
.grid > * {
flex-basis: 33.33%;
}
}
</style>

View File

@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, defineProps, onMounted } from 'vue' import { computed, onMounted } from 'vue'
const props = defineProps<{ const props = defineProps<{
groups: string[] | undefined, groups: string[] | undefined,
groupName: string, groupName: string,

View File

@@ -54,7 +54,7 @@ const value = computed({
flex-shrink: 0; flex-shrink: 0;
} }
.color-picker { .color-picker {
background: var(--color-picker-bg, var(--vp-c-bg-soft)); background: var(--color-picker-bg, var(--vp-c-bg-alt));
border-radius: 8px; border-radius: 8px;
color: var(--vp-c-text-2); color: var(--vp-c-text-2);
padding: 4px 8px; padding: 4px 8px;
@@ -71,10 +71,10 @@ const value = computed({
.color-input-text { .color-input-text {
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: 0 8px; padding: 0 0 0 8px;
border: none; border: none;
background: transparent; background: transparent;
color: var(--vp-c-text-2); color: var(--vp-c-text-1);
font-size: 14px; font-size: 14px;
text-align: left; text-align: left;
border-radius: 8px; border-radius: 8px;

View File

@@ -17,7 +17,7 @@ const SearchIcon = createLucideIcon('search', search)
background: var(--vp-c-bg-soft); background: var(--vp-c-bg-soft);
border-radius: 8px; border-radius: 8px;
color: var(--vp-c-text-2); color: var(--vp-c-text-2);
padding: 12px 16px; padding: 11px 16px;
height: auto; height: auto;
font-size: 14px; font-size: 14px;
/* box-shadow: var(--vp-shadow-4), var(--vp-shadow-2); */ /* box-shadow: var(--vp-shadow-4), var(--vp-shadow-2); */

View File

@@ -0,0 +1,63 @@
<script setup lang="ts">
import { computed } from 'vue';
import CardGrid from './CardGrid.vue';
const props = defineProps<{
title: string,
headingLevel: 1 | 2 | 3 | 4 | 5 | 6,
}>()
const headingElement = computed(() => `h${props.headingLevel}`)
</script>
<template>
<section>
<component :is="headingElement" class="name">{{ title }}</component>
<CardGrid>
<slot />
</CardGrid>
</section>
</template>
<style scoped>
.name {
font-size: 32px;
font-weight: bold;
text-align: center;
margin-bottom: 32px;
}
section {
margin-bottom: 96px;
}
.grid {
display: flex;
flex-wrap: wrap;
align-items: stretch;
justify-content: center;
align-content: space-evenly;
box-sizing: border-box;
margin: -8px;
}
.grid > * {
flex-basis: 100%;
box-sizing: border-box;
padding: 8px;
}
@media (min-width: 960px) {
.grid > * {
flex-basis: 50%;
}
}
@media (min-width: 1280px) {
.grid > * {
flex-basis: 33.33%;
}
}
</style>

View File

@@ -49,7 +49,7 @@ const percentage = computed<string>(() => `${((Number(props.modelValue) - props.
width: 100%; width: 100%;
line-height: 10px; line-height: 10px;
height: 20px; height: 20px;
--bar-color: var(--slider-bar-color, var(--vp-c-bg-soft)); --bar-color: var(--slider-bar-color, var(--vp-input-switch-bg-color));
} }
.slider:hover input{ .slider:hover input{

View File

@@ -10,7 +10,7 @@ import { data } from './HomeHeroBefore.data'
:href="`https://github.com/lucide-icons/lucide/releases/tag/${data.version}`" :href="`https://github.com/lucide-icons/lucide/releases/tag/${data.version}`"
target="_blank" target="_blank"
rel="noreferrer noopener" rel="noreferrer noopener"
>{{ data.version }}</Badge> >v{{ data.version }}</Badge>
</HomeContainer> </HomeContainer>
</template> </template>

View File

@@ -67,7 +67,10 @@ watch(absoluteStrokeWidth, (enabled) => {
Lucide has a lot of customization options to match the icons with your UI. Lucide has a lot of customization options to match the icons with your UI.
</p> </p>
<div class="customizer"> <div
class="customizer"
style="--color-picker-bg: var(--vp-input-switch-bg-color)"
>
<InputField <InputField
id="icon-color" id="icon-color"
label="Color" label="Color"

View File

@@ -1,48 +1,49 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted } from 'vue' import { useCategoryView } from '../../composables/useCategoryView';
import { useCategoryView } from '../../composables/useCategoryView'
interface Header { interface Header {
level: number level: number;
title: string title: string;
slug: string slug: string;
iconCount: number iconCount: number;
link: string link: string;
children: Header[] children: Header[];
} }
type MenuItem = Omit<Header, 'slug' | 'children'> & { type MenuItem = Omit<Header, 'slug' | 'children'> & {
children?: MenuItem[] children?: MenuItem[];
} };
const props = defineProps<{ const props = defineProps<{
headers: MenuItem[] headers: MenuItem[];
root?: boolean root?: boolean;
}>() }>();
const { selectedCategory } = useCategoryView() const { selectedCategory } = useCategoryView();
function onClick(event: Event) { function onClick(event: Event) {
const target = (event.target as HTMLElement).nodeName === 'span' ? (event.target as HTMLElement).parentNode : event.target as HTMLElement const target =
const id = '#' + (target as HTMLAnchorElement).href!.split('#')[1] (event.target as HTMLElement).nodeName === 'span'
const decodedId = decodeURIComponent(id) ? (event.target as HTMLElement).parentNode
: (event.target as HTMLElement);
const href = (target as HTMLAnchorElement)?.href;
selectedCategory.value = decodedId.replace('#', '') if (href) {
const id = '#' + href.split('#')[1];
const decodedId = decodeURIComponent(id);
const heading = document.querySelector<HTMLAnchorElement>(decodedId) selectedCategory.value = decodedId.replace('#', '');
heading?.focus()
const heading = document.querySelector<HTMLAnchorElement>(decodedId);
heading?.focus();
}
} }
</script> </script>
<template> <template>
<ul :class="root ? 'root' : 'nested'"> <ul :class="root ? 'root' : 'nested'">
<li v-for="{ children, link, title, iconCount } in headers"> <li v-for="{ children, link, title, iconCount } in headers">
<a <a class="outline-link" :href="link" @click="onClick" :title="title">
class="outline-link"
:href="link"
@click="onClick"
:title="title"
>
<span> <span>
{{ title }} {{ title }}
</span> </span>

View File

@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref } from 'vue'; import { computed } from 'vue';
import { startCase, camelCase } from 'lodash-es' import { startCase, camelCase } from 'lodash-es'
import ButtonMenu from '../base/ButtonMenu.vue' import ButtonMenu from '../base/ButtonMenu.vue'
import { useIconStyleContext } from '../../composables/useIconStyle'; import { useIconStyleContext } from '../../composables/useIconStyle';

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { IconEntity } from '../../types' import type { IconEntity } from '../../types'
import { computed, ref, watch } from 'vue' import { computed } from 'vue'
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon'; import createLucideIcon from 'lucide-vue-next/src/createLucideIcon';
import IconButton from '../base/IconButton.vue'; import IconButton from '../base/IconButton.vue';
import IconContributors from './IconContributors.vue'; import IconContributors from './IconContributors.vue';
@@ -10,6 +10,7 @@ import { useRouter } from 'vitepress';
import IconInfo from './IconInfo.vue'; import IconInfo from './IconInfo.vue';
import Badge from '../base/Badge.vue'; import Badge from '../base/Badge.vue';
import { computedAsync } from '@vueuse/core'; import { computedAsync } from '@vueuse/core';
import { satisfies } from 'semver';
const props = defineProps<{ const props = defineProps<{
iconName: string iconName: string
@@ -25,6 +26,12 @@ const icon = computedAsync<IconEntity | null>(async () => {
const emit = defineEmits(['close']) const emit = defineEmits(['close'])
const isOpen = computed(() => !!icon.value) const isOpen = computed(() => !!icon.value)
function releaseTagLink(version) {
const shouldAddV = satisfies(version, `<0.266.0`)
return `https://github.com/lucide-icons/lucide/releases/tag/${shouldAddV ? 'v' : ''}${version}`
}
function onClose() { function onClose() {
emit('close') emit('close')
} }
@@ -43,7 +50,7 @@ const Expand = createLucideIcon('Expand', expand)
<Badge <Badge
v-if="icon.createdRelease" v-if="icon.createdRelease"
class="version" class="version"
:href="`https://github.com/lucide-icons/lucide/releases/tag/v${icon.createdRelease.version}`" :href="releaseTagLink(icon.createdRelease.version)"
target="_blank" target="_blank"
rel="noreferrer noopener" rel="noreferrer noopener"
>v{{ icon.createdRelease.version }}</Badge> >v{{ icon.createdRelease.version }}</Badge>

View File

@@ -19,7 +19,11 @@ function setActiveIcon(name: string) {
<template> <template>
<div class="icons"> <div class="icons">
<div class="icon" v-for="icon in icons" :key="icon.name"> <div
class="icon"
v-for="icon in icons"
:key="icon.name"
>
<IconItem <IconItem
v-bind="icon" v-bind="icon"
@setActiveIcon="setActiveIcon(icon.name)" @setActiveIcon="setActiveIcon(icon.name)"

View File

@@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue';
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon'; import createLucideIcon from 'lucide-vue-next/src/createLucideIcon';
import { useMediaQuery } from '@vueuse/core'; import { useMediaQuery } from '@vueuse/core';
import { useRouter } from 'vitepress'; import { useRouter } from 'vitepress';
@@ -27,7 +28,10 @@ const showOverlay = useMediaQuery('(min-width: 860px)');
const { animate, confetti, confettiText } = useConfetti() const { animate, confetti, confettiText } = useConfetti()
const icon = createLucideIcon(props.name, props.iconNode) const icon = computed(() => {
if (!props.name || !props.iconNode) return null
return createLucideIcon(props.name, props.iconNode)
})
async function navigateToIcon(event) { async function navigateToIcon(event) {

View File

@@ -1,93 +1,91 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, defineAsyncComponent } from 'vue' import { ref, computed, defineAsyncComponent } from 'vue';
import type { IconEntity, Category } from '../../types' import type { IconEntity, Category } from '../../types';
import useSearch from '../../composables/useSearch' import useSearch from '../../composables/useSearch';
import InputSearch from '../base/InputSearch.vue' import InputSearch from '../base/InputSearch.vue';
import useSearchInput from '../../composables/useSearchInput' import useSearchInput from '../../composables/useSearchInput';
import StickyBar from './StickyBar.vue' import StickyBar from './StickyBar.vue';
import IconsCategory from './IconsCategory.vue' import IconsCategory from './IconsCategory.vue';
import { useFetch } from '@vueuse/core' import useFetchTags from '../../composables/useFetchTags';
import useFetchTags from '../../composables/useFetchTags' import useFetchCategories from '../../composables/useFetchCategories';
import useFetchCategories from '../../composables/useFetchCategories'
const props = defineProps<{ const props = defineProps<{
icons: IconEntity[] icons: IconEntity[];
categories: Category[] categories: Category[];
iconCategories: Record<string, string[]> iconCategories: Record<string, string[]>;
}>() }>();
const activeIconName = ref(null) const activeIconName = ref(null);
const { searchInput, searchQuery, searchQueryThrottled } = useSearchInput() const { searchInput, searchQuery, searchQueryDebounced } = useSearchInput();
const isSearching = computed(() => !!searchQuery.value) const isSearching = computed(() => !!searchQuery.value);
function setActiveIconName(name: string) { function setActiveIconName(name: string) {
activeIconName.value = name activeIconName.value = name;
} }
const { execute: fetchTags, data: tags } = useFetchTags() const { execute: fetchTags, data: tags } = useFetchTags();
const { execute: fetchCategories, data: categoriesMap } = useFetchCategories() const { execute: fetchCategories, data: categoriesMap } = useFetchCategories();
const mappedIcons = computed(() => { const mappedIcons = computed(() => {
if(tags.value == null) { if (tags.value == null) {
return props.icons return props.icons;
} }
return props.icons.map((icon) => { return props.icons.map((icon) => {
const iconTags = tags.value[icon.name] const iconTags = tags.value[icon.name];
const iconCategories = categoriesMap.value?.[icon.name] ?? [] const iconCategories = categoriesMap.value?.[icon.name] ?? [];
return { return {
...icon, ...icon,
tags: iconTags, tags: iconTags,
categories: iconCategories, categories: iconCategories,
} };
}) });
}) });
const searchResults = useSearch(searchQuery, mappedIcons, [ const searchResults = useSearch(searchQuery, mappedIcons, [
{ name: 'name', weight: 2 }, { name: 'name', weight: 2 },
{ name: 'tags', weight: 1 }, { name: 'tags', weight: 1 },
]) ]);
const categories = computed(() => { const categories = computed(() => {
if( !props.categories?.length || !props.icons?.length ) return [] if (!props.categories?.length || !props.icons?.length) return [];
return props.categories.map(({ name, title }) => { return props.categories
const categoryIcons = props.icons.filter((icon) => { .map(({ name, title }) => {
const iconCategories = props.iconCategories[icon.name] const categoryIcons = props.icons.filter((icon) => {
const iconCategories = props.iconCategories[icon.name];
return iconCategories?.includes(name) return iconCategories?.includes(name);
});
const searchedCategoryIcons = isSearching
? categoryIcons.filter((icon) =>
searchResults.value.some((item) => item?.name === icon?.name)
)
: categoryIcons;
return {
title,
name,
icons: searchedCategoryIcons,
};
}) })
.filter(({ icons }) => icons.length);
const searchedCategoryIcons = isSearching });
? categoryIcons.filter(icon => searchResults.value.some((item) => item?.name === icon?.name))
: categoryIcons;
return {
title,
name,
icons: searchedCategoryIcons,
};
})
.filter(({ icons }) => icons.length)
})
function onFocusSearchInput() { function onFocusSearchInput() {
if (tags.value == null) { if (tags.value == null) {
fetchTags() fetchTags();
} }
if (categoriesMap.value == null) { if (categoriesMap.value == null) {
fetchCategories() fetchCategories();
} }
} }
const NoResults = defineAsyncComponent(() => const NoResults = defineAsyncComponent(() => import('./NoResults.vue'));
import('./NoResults.vue')
)
const IconDetailOverlay = defineAsyncComponent(() => const IconDetailOverlay = defineAsyncComponent(() => import('./IconDetailOverlay.vue'));
import('./IconDetailOverlay.vue')
)
</script> </script>
<template> <template>
@@ -100,11 +98,7 @@ const IconDetailOverlay = defineAsyncComponent(() =>
@focus="onFocusSearchInput" @focus="onFocusSearchInput"
/> />
</StickyBar> </StickyBar>
<NoResults <NoResults v-if="categories.length === 0" :searchQuery="searchQuery" @clear="searchQuery = ''" />
v-if="categories.length === 0"
:searchQuery="searchQuery"
@clear="searchQuery = ''"
/>
<IconsCategory <IconsCategory
v-for="category in categories" v-for="category in categories"
:key="category.name" :key="category.name"

View File

@@ -1,21 +1,21 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch, defineAsyncComponent } from 'vue' import { ref, computed, watch, defineAsyncComponent } from 'vue';
import type { IconEntity } from '../../types' import type { IconEntity } from '../../types';
import { useMediaQuery, useOffsetPagination } from '@vueuse/core' import { useMediaQuery, useOffsetPagination } from '@vueuse/core';
import IconGrid from './IconGrid.vue' import IconGrid from './IconGrid.vue';
import InputSearch from '../base/InputSearch.vue' import InputSearch from '../base/InputSearch.vue';
import useSearch from '../../composables/useSearch' import useSearch from '../../composables/useSearch';
import EndOfPage from '../base/EndOfPage.vue' import EndOfPage from '../base/EndOfPage.vue';
import useSearchInput from '../../composables/useSearchInput' import useSearchInput from '../../composables/useSearchInput';
import StickyBar from './StickyBar.vue' import StickyBar from './StickyBar.vue';
import useFetchTags from '../../composables/useFetchTags' import useFetchTags from '../../composables/useFetchTags';
import useFetchCategories from '../../composables/useFetchCategories' import useFetchCategories from '../../composables/useFetchCategories';
const props = defineProps<{ const props = defineProps<{
icons: IconEntity[] icons: IconEntity[];
}>() }>();
const activeIconName = ref(null) const activeIconName = ref(null);
const isExtraLargeScreen = useMediaQuery('(min-width: 1440px)'); const isExtraLargeScreen = useMediaQuery('(min-width: 1440px)');
const isLargeScreen = useMediaQuery('(min-width: 1280px)'); const isLargeScreen = useMediaQuery('(min-width: 1280px)');
@@ -23,84 +23,78 @@ const isMediumScreen = useMediaQuery('(min-width: 960px)');
const isSmallScreen = useMediaQuery('(min-width: 640px)'); const isSmallScreen = useMediaQuery('(min-width: 640px)');
const pageSize = computed(() => { const pageSize = computed(() => {
if(isExtraLargeScreen.value) { if (isExtraLargeScreen.value) {
return 16 * 20; return 16 * 20;
} }
if(isLargeScreen.value) { if (isLargeScreen.value) {
return 16 * 12; return 16 * 12;
} }
if(isMediumScreen.value) { if (isMediumScreen.value) {
return 13 * 12; return 13 * 12;
} }
if(isSmallScreen.value) { if (isSmallScreen.value) {
return 10 * 10; return 10 * 10;
} }
return 10 * 5; return 10 * 5;
}) });
const { execute: fetchTags, data: tags } = useFetchTags() const { execute: fetchTags, data: tags } = useFetchTags();
const { execute: fetchCategories, data: categories } = useFetchCategories() const { execute: fetchCategories, data: categories } = useFetchCategories();
const mappedIcons = computed(() => { const mappedIcons = computed(() => {
if(tags.value == null) { if (tags.value == null) {
return props.icons return props.icons;
} }
return props.icons.map((icon) => { return props.icons.map((icon) => {
const iconTags = tags.value[icon.name] const iconTags = tags.value[icon.name];
const iconCategories = categories.value?.[icon.name] ?? [] const iconCategories = categories.value?.[icon.name] ?? [];
return { return {
...icon, ...icon,
tags: iconTags, tags: iconTags,
categories: iconCategories, categories: iconCategories,
} };
}) });
}) });
const { searchInput, searchQuery, searchQueryThrottled } = useSearchInput() const { searchInput, searchQuery, searchQueryDebounced } = useSearchInput();
const searchResults = useSearch(searchQueryThrottled, mappedIcons, [ const searchResults = useSearch(searchQueryDebounced, mappedIcons, [
{ name: 'name', weight: 3 }, { name: 'name', weight: 3 },
{ name: 'tags', weight: 2 }, { name: 'tags', weight: 2 },
{ name: 'categories', weight: 1 }, { name: 'categories', weight: 1 },
]) ]);
const { next, currentPage } = useOffsetPagination( { pageSize })
const { next, currentPage } = useOffsetPagination({ pageSize });
const paginatedIcons = computed(() => { const paginatedIcons = computed(() => {
const end = pageSize.value * currentPage.value const end = pageSize.value * currentPage.value;
return searchResults.value.slice(0, end) return searchResults.value.slice(0, end);
}) });
function setActiveIconName(name: string) { function setActiveIconName(name: string) {
activeIconName.value = name activeIconName.value = name;
} }
watch(searchQueryThrottled, (searchString) => { watch(searchQueryDebounced, (searchString) => {
currentPage.value = 1 currentPage.value = 1;
}) });
function onFocusSearchInput() { function onFocusSearchInput() {
if (tags.value == null) { if (tags.value == null) {
fetchTags() fetchTags();
} }
if (categories.value == null) { if (categories.value == null) {
fetchCategories() fetchCategories();
} }
} }
const NoResults = defineAsyncComponent(() => const NoResults = defineAsyncComponent(() => import('./NoResults.vue'));
import('./NoResults.vue')
)
const IconDetailOverlay = defineAsyncComponent(() =>
import('./IconDetailOverlay.vue')
)
const IconDetailOverlay = defineAsyncComponent(() => import('./IconDetailOverlay.vue'));
</script> </script>
<template> <template>
@@ -124,7 +118,7 @@ const IconDetailOverlay = defineAsyncComponent(() =>
:icons="paginatedIcons" :icons="paginatedIcons"
@setActiveIcon="setActiveIconName" @setActiveIcon="setActiveIconName"
/> />
<EndOfPage @end-of-page="next" class="bottom-page"/> <EndOfPage @end-of-page="next" class="bottom-page" />
<IconDetailOverlay <IconDetailOverlay
v-if="activeIconName != null" v-if="activeIconName != null"
:iconName="activeIconName" :iconName="activeIconName"

View File

@@ -36,15 +36,22 @@ const links = computed(() => [
<template> <template>
<footer v-if="theme.footer" class="VPFooter" :class="{ 'has-sidebar': hasSidebar }"> <footer v-if="theme.footer" class="VPFooter" :class="{ 'has-sidebar': hasSidebar }">
<div class="container"> <div class="container">
<p v-if="theme.footer.message" class="message" v-html="theme.footer.message"></p> <div class="sponsors">
<p v-if="theme.footer.copyright" class="copyright" v-html="theme.footer.copyright"></p> <a href="https://vercel.com?utm_source=lucide&utm_campaign=oss" rel="noreferrer noopener">
<img src="/vercel.svg" alt="Powered by Vercel" width="200" />
</a>
<a href="https://www.digitalocean.com/?refcode=b0877a2caebd&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge" rel="noreferrer noopener">
<img src="/digitalocean.svg" alt="Digital Ocean" width="200" />
</a>
</div>
<div class="links"> <div class="links">
<VPLink v-for="link in links" :href="link.href" :key="link.text" :rel="link.href.startsWith('http') ? 'noreferrer noopener': undefined"> <VPLink v-for="link in links" :href="link.href" :key="link.text" :rel="link.href.startsWith('http') ? 'noreferrer noopener': undefined">
{{ link.text }} {{ link.text }}
</VPLink> </VPLink>
<a href="https://vercel.com?utm_source=lucide&utm_campaign=oss" rel="noreferrer noopener"> </div>
<img src="/vercel.svg" alt="Powered by Vercel" width="200" /> <div>
</a> <p v-if="theme.footer.message" class="message" v-html="theme.footer.message"></p>
<p v-if="theme.footer.copyright" class="copyright" v-html="theme.footer.copyright"></p>
</div> </div>
</div> </div>
</footer> </footer>
@@ -67,7 +74,7 @@ const links = computed(() => [
.container { .container {
margin: 0 auto; margin: 0 auto;
max-width: var(--vp-layout-max-width); max-width: calc(var(--vp-layout-max-width) - 64px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@@ -85,7 +92,7 @@ const links = computed(() => [
.message { order: 2; } .message { order: 2; }
.copyright { order: 1; } .copyright { order: 1; }
.links { .links, .sponsors {
display: flex; display: flex;
gap: 32px; gap: 32px;
align-items: center; align-items: center;
@@ -102,7 +109,7 @@ const links = computed(() => [
flex-direction: row-reverse; flex-direction: row-reverse;
} }
.links { .links {
margin-left: auto; margin-right: auto;
} }
} }
</style> </style>

View File

@@ -1,24 +1,30 @@
<script setup lang="ts"> <script setup lang="ts">
import {data} from './PackageList.data' import {data} from './PackageList.data'
import GridSection from '../base/GridSection.vue'
import PackageListItem from "./PackageListItem.vue";</script> import PackageListItem from "./PackageListItem.vue";</script>
<template> <template>
<section class="package-group"> <GridSection
<h1 class="name">Packages</h1> title="Packages"
<div class="grid package-list" ref="container"> :headingLevel="1"
<div v-for="packageData in data.packages" class="item"> class="package-group"
<PackageListItem :packageData="packageData"/> >
</div> <PackageListItem
</div> v-for="packageData in data.packages"
</section> :packageData="packageData"
<section class="package-group"> />
<h2 class="name">Third-party packages</h2> </GridSection>
<div class="grid package-list" ref="container">
<div v-for="packageData in data.thirdPartyPackages" class="item"> <GridSection
<PackageListItem :packageData="packageData"/> title="Third-party packages"
</div> :headingLevel="2"
</div> class="package-group"
</section> >
<PackageListItem
v-for="packageData in data.thirdPartyPackages"
:packageData="packageData"
/>
</GridSection>
</template> </template>
<style scoped> <style scoped>
@@ -26,7 +32,7 @@ import PackageListItem from "./PackageListItem.vue";</script>
font-size: 32px; font-size: 32px;
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
margin-bottom: 24px; margin-bottom: 32px;
} }
.package-group { .package-group {

View File

@@ -2,6 +2,7 @@
import { useRouter } from 'vitepress'; import { useRouter } from 'vitepress';
import {PackageItem} from "../../types"; import {PackageItem} from "../../types";
import VPButton from 'vitepress/dist/client/theme-default/components/VPButton.vue'; import VPButton from 'vitepress/dist/client/theme-default/components/VPButton.vue';
import Card from '../base/Card.vue'
const { go } = useRouter() const { go } = useRouter()
const props = defineProps<{ const props = defineProps<{
@@ -10,48 +11,40 @@ const props = defineProps<{
</script> </script>
<template> <template>
<article class="package"> <div>
<header class="package-header"> <Card class="package">
<div class="package-icon-well"> <header class="package-header">
<img :src="packageData.icon" alt="" class="package-icon" :class="{[packageData.iconClass]: true, light: packageData.iconDark}" /> <div class="package-icon-well">
<img v-if="packageData.iconDark" :src="packageData.iconDark" alt="" class="package-icon dark" :class="packageData.iconClass" /> <img :src="packageData.icon" alt="" class="package-icon" :class="{[packageData.iconClass]: true, light: packageData.iconDark}" />
<img v-if="packageData.iconDark" :src="packageData.iconDark" alt="" class="package-icon dark" :class="packageData.iconClass" />
</div>
<div class="package-title">
<h2 class="title">{{ props.packageData.name }}</h2>
<a v-for="shield in props.packageData.shields" :href="shield.href" class="package-shield" rel="noreferrer noopener">
<img :src="shield.src" :alt="shield.href" />
</a>
</div>
</header>
<div class="package-details">
{{ packageData.description }}
</div> </div>
<div class="package-title"> <footer class="package-footer">
<h2 class="title">{{ props.packageData.name }}</h2> <VPButton
<a v-for="shield in props.packageData.shields" :href="shield.href" class="package-shield" rel="noreferrer noopener"> :href="packageData.documentation"
<img :src="shield.src" :alt="shield.href" /> text="Guide"
</a> theme="brand"
</div> />
</header> <VPButton
<div class="package-details"> :href="packageData.source"
{{ packageData.description }} text="Source"
</div> theme="alt"
<footer class="package-footer"> />
<VPButton </footer>
:href="packageData.documentation" </Card>
text="Guide" </div>
theme="brand"
@click="go(packageData.documentation)"
/>
<VPButton
:href="packageData.source"
text="Source"
theme="alt"
@click="go(packageData.source)"
/>
</footer>
</article>
</template> </template>
<style scoped> <style scoped>
.package {
border: 1px solid var(--vp-c-bg-soft);
border-radius: 12px;
background-color: var(--vp-c-bg-soft);
display: flex;
flex-direction: column;
padding: 24px;
}
.package { .package {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@@ -0,0 +1,72 @@
<script setup lang="ts">
import companies from '../../../data/companiesData.json'
import componentLibraries from '../../../data/componentLibrariesData.json'
import GridSection from '../base/GridSection.vue'
import ShowcaseListItem from "./ShowcaseListItem.vue";
</script>
<template>
<GridSection
title="Used by"
:headingLevel="1"
class="package-group"
>
<ShowcaseListItem
v-for="company in companies"
:showcaseItem="company"
/>
</GridSection>
<GridSection
title="Used in"
:headingLevel="1"
class="package-group"
>
<ShowcaseListItem
v-for="componentLibrary in componentLibraries"
:showcaseItem="componentLibrary"
/>
</GridSection>
</template>
<style scoped>
.name {
font-size: 32px;
font-weight: bold;
text-align: center;
margin-bottom: 32px;
}
.package-group {
margin-bottom: 96px;
}
.grid {
display: flex;
flex-wrap: wrap;
align-items: stretch;
justify-content: center;
align-content: space-evenly;
box-sizing: border-box;
margin: -8px;
}
.grid > * {
flex-basis: 100%;
box-sizing: border-box;
padding: 8px;
}
@media (min-width: 960px) {
.grid > * {
flex-basis: 50%;
}
}
@media (min-width: 1280px) {
.grid > * {
flex-basis: 33.33%;
}
}
</style>

View File

@@ -0,0 +1,52 @@
<script setup lang="ts">
import { useRouter } from 'vitepress';
import { ShowcaseItem } from "../../types";
import Card from '../base/Card.vue'
const { go } = useRouter()
defineProps<{
showcaseItem: ShowcaseItem,
}>()
</script>
<template>
<div>
<Card
class="company"
:href="showcaseItem.url"
:aria-label="showcaseItem.name"
>
<img
:src="showcaseItem.image.light"
class="logo light"
:alt="`${showcaseItem.name} logo`"
/>
<img
:src="showcaseItem.image.dark"
class="logo dark"
:alt="`${showcaseItem.name} logo`"
/>
</Card>
</div>
</template>
<style scoped>
.company {
display: flex;
height: 100%;
padding: 48px 0;
}
.logo {
height:64px;
width: 240px;
margin: auto;
}
html.dark .logo.dark {
display: none;
}
html:not(.dark) .logo.light {
display: none;
}
</style>

View File

@@ -1,43 +1,41 @@
import { refThrottled } from '@vueuse/core'; import { useDebounce } from '@vueuse/core';
import { nextTick, onMounted, ref, watch } from 'vue'; import { nextTick, onMounted, ref, watch } from 'vue';
const useSearchInput = () => { const useSearchInput = () => {
const searchInput = ref() const searchInput = ref();
const searchQuery = ref( const searchQuery = ref<string>('');
typeof window === 'undefined' const searchQueryDebounced = useDebounce<string>(searchQuery, 200);
? ''
: (
new URLSearchParams(window.location.search).get('search')
|| ''
)
)
const searchQueryThrottled = refThrottled(searchQuery, 400)
watch(searchQueryThrottled, (searchString) => { watch(searchQueryDebounced, (searchString) => {
const newUrl = new URL(window.location.href); const newUrl = new URL(window.location.href);
if(searchString === '') { if (searchString === '') {
newUrl.searchParams.delete('search'); newUrl.searchParams.delete('search');
} else { } else {
newUrl.searchParams.set('search', searchString); newUrl.searchParams.set('search', searchString);
} }
nextTick(() => { nextTick(() => {
window.history.replaceState({}, '', newUrl) window.history.replaceState({}, '', newUrl);
}) });
}) });
onMounted(() => { onMounted(() => {
const searchParams = new URLSearchParams(window.location.search); const searchParams = new URLSearchParams(window.location.search);
if(searchParams.has('focus')) {
searchInput.value.focus() if (searchParams.has('search')) {
searchQuery.value = searchParams.get('search');
} }
})
if (searchParams.has('focus')) {
searchInput.value.focus();
}
});
return { return {
searchInput, searchInput,
searchQuery, searchQuery,
searchQueryThrottled searchQueryDebounced,
}; };
}; };

View File

@@ -0,0 +1,34 @@
{
"colors": {
"surface1": "var(--vp-code-block-bg)",
"surface2": "var(--vp-code-block-bg)",
"surface3": "var(--vp-code-line-highlight-color)",
"clickable": "var(--vp-c-text-2)",
"base": "#323232",
"disabled": "#C5C5C5",
"hover": "var(--vp-c-brand)",
"accent": "var(--vp-c-brand)",
"error": "var(--vp-c-red)",
"errorSurface": "#ffeceb"
},
"syntax": {
"plain": "var(--vp-code-editor-plain)",
"comment": {
"color": "var(--vp-code-editor-comment)",
"fontStyle": "italic"
},
"keyword": "var(--vp-code-editor-keyword)",
"tag": "var(--vp-code-editor-tag)",
"punctuation": "var(--vp-code-editor-punctuation)",
"definition": "var(--vp-code-editor-definition)",
"property": "var(--vp-code-editor-property)",
"static": "var(--vp-code-editor-static)",
"string": "var(--vp-code-editor-string)"
},
"font": {
"body": "var(--vp-font-family-base)",
"mono": "var(--vp-font-family-mono)",
"size": "var(--vp-code-font-size)",
"lineHeight": "var(--vp-code-line-height)"
}
}

View File

@@ -5,13 +5,39 @@
--vp-c-brand-dark: #DC5A5A; --vp-c-brand-dark: #DC5A5A;
--vp-c-brand-darker: #C45050; --vp-c-brand-darker: #C45050;
--vp-c-brand-1: #F67373;
--vp-c-brand-2: #FF7070;
--vp-c-brand-3: #F56565;
--vp-c-brand-4: #DC5A5A;
--vp-c-brand-5: #C45050;
--vp-c-bg-alt-up: #fff; --vp-c-bg-alt-up: #fff;
--vp-c-bg-alt-down: #fff; --vp-c-bg-alt-down: #fff;
--vp-code-editor-plain: #24292E;
--vp-code-editor-comment: #6A737D;
--vp-code-editor-keyword: #D73A49;
--vp-code-editor-tag: #22863A;
--vp-code-editor-punctuation: #24292E;
--vp-code-editor-definition: #6F42C1;
--vp-code-editor-property: #005CC5;
--vp-code-editor-static: #F78C6C;
--vp-code-editor-string: #032F62;
} }
.dark { .dark {
--vp-c-bg-alt-up: #1B1B1D; --vp-c-bg-alt-up: #1B1B1D;
--vp-c-bg-alt-down: #0F0F10; --vp-c-bg-alt-down: #0F0F10;
--vp-code-editor-plain: #E1E4E8;
--vp-code-editor-comment: #6A737D;
--vp-code-editor-keyword: #F97583;
--vp-code-editor-tag: #85E89D;
--vp-code-editor-punctuation: #9ECBFF;
--vp-code-editor-definition: #B392F0;
--vp-code-editor-property: #79B8FF;
--vp-code-editor-static: #F78C6C;
--vp-code-editor-string: #9ECBFF;
} }
.VPNavBarTitle .logo { .VPNavBarTitle .logo {
@@ -126,3 +152,56 @@
html:has(* .outline-link:target) { html:has(* .outline-link:target) {
scroll-behavior: smooth; scroll-behavior: smooth;
} */ } */
.sp-wrapper + * {
margin-top: 24px;
}
.sp-wrapper .sp-layout {
border-radius: 8px;
}
.sp-wrapper .sp-tabs-scrollable-container {
border-radius: 8px 8px 0 0;
position: relative;
box-shadow: inset 0 -1px var(--vp-code-tab-divider);
margin-bottom: 0px;
margin-top: -1px;
height: 48px;
padding-bottom: 1px;
}
.sp-wrapper .sp-preview-container {
background-color: transparent;
}
.sp-wrapper .sp-tabs .sp-tab-button {
padding: 0 12px;
line-height: 48px;
height: 48px;
font-size: 14px;
font-weight: 500;
position: relative;
/* box-sizing: content-box; */
}
.sp-wrapper .sp-tabs .sp-tab-button:after {
position: absolute;
right: 8px;
left: 8px;
bottom: 0px;
z-index: 1;
height: 1px;
content: '';
background-color: transparent;
transition: background-color 0.25s;
}
.sp-wrapper .sp-tabs .sp-tab-button[data-active="true"] {
color: var(--vp-code-tab-active-text-color);
}
.sp-wrapper .sp-tabs .sp-tab-button[data-active="true"]:after {
background-color: var(--vp-code-tab-active-bar-color);
}

View File

@@ -44,3 +44,14 @@ export interface Release {
version: string version: string
date: string date: string
} }
interface ShowcaseItemImage {
light: string
dark: string
}
export interface ShowcaseItem {
name: string
url: string
image: ShowcaseItemImage
}

View File

@@ -3,8 +3,6 @@
The Lucide docs website is built with Vitepress: https://vitepress.dev/ The Lucide docs website is built with Vitepress: https://vitepress.dev/
This is Markdown-based documentation powered by Vue. This is Markdown-based documentation powered by Vue.
This is why this file is in txt format.
## Development ## Development
```sh ```sh

View File

@@ -0,0 +1,4 @@
# Accessibility
<!-- Description how you should use svg icons keeping web accessible -->
<!-- See @JanTrichter comment about some information to write this: https://github.com/lucide-icons/lucide/pull/1521#discussion_r1332141390 -->

View File

@@ -0,0 +1,23 @@
import { Star, StarHalf } from "lucide-react";
import "./icon.css";
function App() {
return (
<div className="app">
<div className="star-rating">
<div className="stars">
{ Array.from({ length: 5 }, () => (
<Star fill="#111" strokeWidth={0} />
))}
</div>
<div className="stars rating">
<Star fill="yellow" strokeWidth={0} />
<Star fill="yellow" strokeWidth={0} />
<StarHalf fill="yellow" strokeWidth={0} />
</div>
</div>
</div>
);
}
export default App;

View File

@@ -0,0 +1,20 @@
import App from './App.js?raw'
import styles from '../../../basics/examples/styles.css?raw'
import IconCss from './icon.css?raw'
const files = {
'App.js': {
code: App,
active: true,
},
'icon.css': {
code: IconCss,
readOnly: false,
},
'styles.css': {
code: styles,
hidden: true
},
}
export default files

View File

@@ -0,0 +1,14 @@
.star-rating {
position: relative;
}
.stars {
display: flex;
gap: 4px;
}
.rating {
position: absolute;
top: 0;
}

View File

@@ -0,0 +1,30 @@
import {
TentTree,
Caravan,
FlameKindling,
MountainSnow,
Trees,
Axe,
Map,
CloudMoon,
Sparkles,
} from "lucide-react";
import "./icon.css";
function App() {
return (
<div className="app">
<TentTree />
<Caravan />
<FlameKindling />
<MountainSnow />
<Trees />
<Axe />
<Map />
<CloudMoon />
<Sparkles />
</div>
);
}
export default App;

View File

@@ -0,0 +1,20 @@
import App from './App.js?raw'
import styles from '../../../basics/examples/styles.css?raw'
import IconCss from './icon.css?raw'
const files = {
'icon.css': {
code: IconCss,
readOnly: false,
active: true,
},
'App.js': {
code: App,
},
'styles.css': {
code:styles,
hidden: true
},
}
export default files

View File

@@ -0,0 +1,16 @@
.lucide {
width: 48px;
height: 48px;
stroke-width: 1.5;
}
.lucide * {
vector-effect: non-scaling-stroke;
}
.app {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 6px;
}

View File

@@ -0,0 +1,30 @@
import {
CakeSlice,
Candy,
Apple,
Cookie,
Martini,
IceCream2,
Sandwich,
Wine,
Dessert,
} from "lucide-react";
import "./icon.css";
function App() {
return (
<div className="app">
<CakeSlice />
<Candy />
<Apple />
<Cookie />
<Martini />
<IceCream2 />
<Sandwich />
<Wine />
<Dessert />
</div>
);
}
export default App;

View File

@@ -0,0 +1,20 @@
import App from './App.js?raw'
import styles from '../../../basics/examples/styles.css?raw'
import IconCss from './icon.css?raw'
const files = {
'icon.css': {
code: IconCss,
readOnly: false,
active: true,
},
'App.js': {
code: App,
},
'styles.css': {
code:styles,
hidden: true
},
}
export default files

View File

@@ -0,0 +1,14 @@
.lucide {
/* Change this! */
color: #ffadff;
width: 56px;
height: 56px;
stroke-width: 1px;
}
.app {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 6px;
}

View File

@@ -0,0 +1,31 @@
<script setup>
import { Sandpack } from 'sandpack-vue3'
import sandpackTheme from '../../.vitepress/theme/sandpackTheme.json'
import sizeIconExample from './examples/filled-icon-example/files.ts'
</script>
# Filled Icons
Fills are officially not supported.
However, all SVG properties are available on all icons.
Fill can still be used and will work fine on certain icons.
Example with stars:
<Sandpack
template="react"
:theme="sandpackTheme"
:files="sizeIconExample"
:customSetup='{
dependencies: {
"lucide-react": "latest"
}
}'
:options="{
editorHeight: 480,
editorWidthPercentage: 60,
}"
/>
## Will Lucide have fills in the future?
This feature has been requested several times and discussion is happening at [#458](https://github.com/lucide-icons/lucide/discussions/458).

View File

@@ -0,0 +1,55 @@
<script setup>
import { Sandpack } from 'sandpack-vue3'
import sandpackTheme from '../../.vitepress/theme/sandpackTheme.json'
import globalIconCssExample from './examples/global-styling-css-example/files.ts'
import globalAbsoluteStrokewidthExample from './examples/global-styling-absolute-strokewidth-example/files.ts'
</script>
# Global Styling
Adjusting icons can be done by [color](../basics/color.md), [size](../basics/sizing.md) and [stroke width](../basics/stroke-width.md).
By default, all icons have a **color** value of `currentColor`, a **size** value of `24px`, and a **stroke width** of `2`. Styling icons individually can be done by passing props to the icon component.
## 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.
- The **color** of the icons can be changed using the [`color`](https://developer.mozilla.org/en-US/docs/Web/CSS/color) CSS property.
- The **size** of the icons can be changed using [`width`](https://developer.mozilla.org/en-US/docs/Web/CSS/width) and [`height`](https://developer.mozilla.org/en-US/docs/Web/CSS/height) CSS properties.
- The **stroke width** of the icons can be changed using the [`stroke-width`](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-width) CSS property.
<Sandpack
template="react"
:theme="sandpackTheme"
:files="globalIconCssExample"
:customSetup='{
dependencies: {
"lucide-react": "latest"
}
}'
:options="{
editorHeight: 300,
}"
/>
### Absolute stroke width
For global absolute stroke width styling the `vector-effect: non-scaling-stroke` CSS property can be applied to the children. This will keep the stroke-width the same size no matter the size of the icon. See [absolute-stroke-width](../basics/stroke-width.md#absolute-stroke-width) for more info.
<Sandpack
template="react"
:theme="sandpackTheme"
:files="globalAbsoluteStrokewidthExample"
:customSetup='{
dependencies: {
"lucide-react": "latest"
}
}'
:options="{
editorHeight: 300,
}"
/>

View File

@@ -0,0 +1,52 @@
<script setup>
import { Sandpack } from 'sandpack-vue3'
import sandpackTheme from '../../.vitepress/theme/sandpackTheme.json'
import buttonExampleFiles from './examples/button-example/files.ts'
import iconColorExampleFiles from './examples/color-icon/files.ts'
</script>
# Color
By default, all icons have the color value: `currentColor`. This keyword uses the element's computed text `color` value to represent the icon color.
Read more about [ `currentColor` on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword).
## Adjust the color using the `color` prop
The color can be adjusted by passing the color prop to the element.
<Sandpack
template="react"
:theme="sandpackTheme"
:files="iconColorExampleFiles"
:customSetup='{
dependencies: {
"lucide-react": "latest"
}
}'
:options="{
editorHeight: 295,
editorWidthPercentage: 60,
}"
/>
## Using parent elements text color value
Because the color of lucide icons uses `currentColor`, the color of the icon depends on the computed `color` of the element, or it inherits it from its parent.
For example, if a parent element's color value is `#fff` and one of the children is a lucide icon, the color of the icon will be rendered as `#fff`. This is browser native behavior.
<Sandpack
template="react"
:theme="sandpackTheme"
:files="buttonExampleFiles"
:customSetup='{
dependencies: {
"lucide-react": "latest"
}
}'
:options="{
editorHeight: 320,
editorWidthPercentage: 60,
}"
/>

View File

@@ -0,0 +1,14 @@
import { RollerCoaster } from "lucide-react";
function App() {
return (
<div className="app">
<RollerCoaster
size={96}
absoluteStrokeWidth={true}
/>
</div>
);
}
export default App;

View File

@@ -0,0 +1,15 @@
import App from './App.js?raw'
import styles from '../styles.css?raw'
const files = {
'App.js': {
code: App,
active: true,
},
'styles.css': {
code:styles,
hidden: true
},
}
export default files

View File

@@ -0,0 +1,5 @@
import Button from "./Button";
export default function App() {
return <Button />;
}

View File

@@ -0,0 +1,12 @@
import { ThumbsUp } from "lucide-react";
function LikeButton() {
return (
<button style={{ color: "#fff" }}>
<ThumbsUp />
Like
</button>
);
}
export default LikeButton;

View File

@@ -0,0 +1,21 @@
import App from './App.js?raw'
import Button from './Button.jsx?raw'
import styles from '../styles.css?raw'
const files = {
'App.js': {
code: App,
hidden: true
},
'Button.jsx': {
code: Button,
active: true,
readOnly: false,
},
'styles.css': {
code:styles,
hidden: true
},
}
export default files

View File

@@ -0,0 +1,11 @@
import { Smile } from "lucide-react";
function App() {
return (
<div className="app">
<Smile color="#3e9392" />
</div>
);
}
export default App;

View File

@@ -0,0 +1,15 @@
import App from './App.js?raw'
import styles from '../styles.css?raw'
const files = {
'App.js': {
code: App,
active: true,
},
'styles.css': {
code:styles,
hidden: true
},
}
export default files

View File

@@ -0,0 +1,12 @@
import { Beer } from "lucide-react";
import "./icon.css";
function App() {
return (
<div className="app">
<Beer className="my-beer-icon" />
</div>
);
}
export default App;

View File

@@ -0,0 +1,21 @@
import App from './App.js?raw'
import styles from '../styles.css?raw'
import IconCss from './icon.css?raw'
const files = {
'icon.css': {
code: IconCss,
readOnly: false,
active: true,
},
'App.js': {
code: App,
},
'styles.css': {
code:styles,
hidden: true
},
}
export default files

View File

@@ -0,0 +1,5 @@
.my-beer-icon {
/* Change this! */
width: 64px;
height: 64px;
}

View File

@@ -0,0 +1,11 @@
import { Landmark } from "lucide-react";
function App() {
return (
<div className="app">
<Landmark size={64} />
</div>
);
}
export default App;

View File

@@ -0,0 +1,15 @@
import App from './App.js?raw'
import styles from '../styles.css?raw'
const files = {
'App.js': {
code: App,
active: true,
},
'styles.css': {
code:styles,
hidden: true
},
}
export default files

View File

@@ -0,0 +1,13 @@
import { Star } from "lucide-react";
import "./icon.css";
function App() {
return (
<div className="text-wrapper">
<Star class="my-icon" />
<div>Yes</div>
</div>
);
}
export default App;

View File

@@ -0,0 +1,21 @@
import App from './App.js?raw'
import styles from '../styles.css?raw'
import IconCss from './icon.css?raw'
const files = {
'icon.css': {
code: IconCss,
readOnly: false,
active: true,
},
'App.js': {
code: App,
},
'styles.css': {
code: styles,
hidden: true
},
}
export default files

View File

@@ -0,0 +1,15 @@
.my-icon {
/* Icon size will relative to font-size of .text-wrapper */
width: 1em;
height: 1em;
}
.text-wrapper {
/* Change this! */
font-size: 96px;
/* layout stuff */
display: flex;
gap: 0.25em;
align-items: center;
}

View File

@@ -0,0 +1,11 @@
import { PartyPopper } from "lucide-react";
function App() {
return (
<div>
<PartyPopper className="w-24 h-24" />
</div>
);
}
export default App;

View File

@@ -0,0 +1,15 @@
import App from './App.js?raw'
import styles from '../styles.css?raw'
const files = {
'App.js': {
code: App,
active: true
},
'styles.css': {
code:styles,
hidden: true
},
}
export default files

View File

@@ -0,0 +1,11 @@
import { FolderLock } from "lucide-react";
function App() {
return (
<div className="app">
<FolderLock strokeWidth={1} />
</div>
);
}
export default App;

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