Compare commits

...
Author SHA1 Message Date
91a1359b5e feat(icons): added circle-fading-check icon (#4089)
* Added icons/circle-fading-check.svg

* Added icons/circle-fading-check.json

* Refactor SVG paths in circle-fading-check.svg

* Add empty use-cases array to circle-fading-check.json

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

* Update metadata

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-11-04 16:03:14 +01:00
Ilya VredandEric 90e8041a35 feat(icons): added opacity icon (#4222)
* Added icons/opacity.svg

* Added icons/opacity.json

* Updated icons/opacity.svg

* Updated icons/opacity.json

* Adjust usecases

---------

Co-authored-by: Eric <eric.fennis@gmail.com>
2026-11-04 15:56:22 +01:00
Eric FennisandKarsa 3898742b6a feat(icons): added package-question-mark icon (#5155)
* Add metadata

* Add more tags to `package.json`

* Update icons/package-question-mark.json

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

---------

Co-authored-by: Karsa <contact@karsa.org>
2026-11-04 15:29:36 +01:00
Eric FennisandKarsa a4a0e20ff5 feat(icons): added package-pen icon (#5154)
* Add package pen icon

* Update icons/package-pen.json

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

* update metadata

---------

Co-authored-by: Karsa <contact@karsa.org>
2026-11-04 15:26:37 +01:00
Eric Fennis 1980e3d59b chore(icons): Renamed *-warning and *-alert to *-exclamation-point (#5143)
* Rename icons

* Update other file

* Remove deprecation booleans
2026-11-03 15:49:26 +01:00
aa0b77386c feat(icons): added mango icon (#4902)
* feat: add mango icon

* fix: adjust mango icon leaf and body shape

* refactor: switch to rrod497's mango design, expand metadata

* Update use cases for mango in icons/mango.json

Removed outdated use cases and added updated ones for mango.

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

* Apply suggestion from @karsa-mistmere

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

* Update mango.json

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-11-03 14:16:15 +01:00
Bin 7bb15b80a3 fix(docs): keep sponsor tiers within content width (#5149) 2026-11-03 09:41:31 +01:00
Eric FennisandClaude Opus 5.5 4b203ec9b6 chore(deps): Fix security vulnerabilities alerts (#5147)
* Upgrade deps

* Fix security alerts

* Keep incompatible consumers off minimatch 11 and file-type 21

The security overrides forced minimatch 11 and file-type 21 onto every
consumer, which broke ESLint (eslint-plugin-import-x imports the removed
makeRe) and the font build (jimp 0.22 calls file-type's removed
fromBuffer). glob 7 and @eslint/eslintrc also rely on the minimatch 3
callable export. Scope those consumers back to their compatible lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Remove minimatch override

* Fix font build

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 20:58:02 +01:00
Eric FennisandCopilot Autofix powered by AI 58c85b4758 fix(dev): avoid polynomial regex backtracking in toCamelCase helper (#5148)
* fix(dev): avoid polynomial regex backtracking in toCamelCase helper

* Add test for toCamelCase with non-word character separators

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

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-11-02 20:18:25 +01:00
Eric Fennis b196797ede Update deps (#5146) 2026-11-02 18:39:06 +01:00
dependabot[bot]Claude Opus 5.5dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
7ebbb6abc3 chore(deps-dev): bump the solid-deps group across 1 directory with 6 updates (#5142)
* chore(deps-dev): bump the solid-deps group across 1 directory with 6 updates

Bumps the solid-deps group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) | `7.29.7` | `8.0.10` |
| [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) | `7.29.7` | `8.0.7` |
| [@babel/preset-typescript](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-typescript) | `7.29.7` | `8.0.7` |
| [@rollup/plugin-babel](https://github.com/rollup/plugins/tree/HEAD/packages/babel) | `6.1.0` | `7.1.0` |
| [@solidjs/testing-library](https://github.com/solidjs/solid-testing-library) | `0.8.10` | `1.0.0-rc.2` |
| [vite-plugin-solid](https://github.com/solidjs/solid-vite-plugin) | `2.11.14` | `2.11.15` |



Updates `@babel/core` from 7.29.7 to 8.0.10
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v8.0.10/packages/babel-core)

Updates `@babel/preset-env` from 7.29.7 to 8.0.7
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v8.0.7/packages/babel-preset-env)

Updates `@babel/preset-typescript` from 7.29.7 to 8.0.7
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v8.0.7/packages/babel-preset-typescript)

Updates `@rollup/plugin-babel` from 6.1.0 to 7.1.0
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/babel/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/babel-v7.1.0/packages/babel)

Updates `@solidjs/testing-library` from 0.8.10 to 1.0.0-rc.2
- [Commits](https://github.com/solidjs/solid-testing-library/commits)

Updates `vite-plugin-solid` from 2.11.14 to 2.11.15
- [Release notes](https://github.com/solidjs/solid-vite-plugin/releases)
- [Changelog](https://github.com/solidjs/solid-vite-plugin/blob/main/CHANGELOG.md)
- [Commits](https://github.com/solidjs/solid-vite-plugin/compare/vite-plugin-solid@2.11.14...vite-plugin-solid@2.11.15)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-version: 8.0.10
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: solid-deps
- dependency-name: "@babel/preset-env"
  dependency-version: 8.0.7
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: solid-deps
- dependency-name: "@babel/preset-typescript"
  dependency-version: 8.0.7
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: solid-deps
- dependency-name: "@rollup/plugin-babel"
  dependency-version: 7.1.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: solid-deps
- dependency-name: "@solidjs/testing-library"
  dependency-version: 1.0.0-rc.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: solid-deps
- dependency-name: vite-plugin-solid
  dependency-version: 2.11.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: solid-deps
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(solid): make Solid builds work with Babel 8

- Drop the `bugfixes` option from `@babel/preset-env`; it was removed in
  Babel 8 because bugfix plugins are now always enabled.
- Enable the `jsx` parser plugin for `.jsx`/`.tsx` files. Babel 8's
  `@babel/preset-typescript` no longer does this, and babel-preset-solid's
  Babel 7 `@babel/plugin-syntax-jsx` skips it when TypeScript is enabled.
- Keep `@solidjs/testing-library` at `^0.8.10` for lucide-solid. The 1.x
  line targets Solid 2 (peer `solid-js >=2`) and breaks the Solid 1 tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G9u8FhrFFoA9JwQHtymeAf

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-11-02 18:24:15 +01:00
dependabot[bot]Claude Opus 5.5dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
5beea9bf83 chore(deps-dev): bump react-native from 0.88.0 to 0.88.1 in the react-native-deps group across 1 directory (#5134)
* chore(deps-dev): bump react-native

Bumps the react-native-deps group with 1 update in the / directory: [react-native](https://github.com/react/react-native/tree/HEAD/packages/react-native).


Updates `react-native` from 0.88.0 to 0.88.1
- [Release notes](https://github.com/react/react-native/releases)
- [Changelog](https://github.com/react/react-native/blob/main/CHANGELOG.md)
- [Commits](https://github.com/react/react-native/commits/v0.88.1/packages/react-native)

---
updated-dependencies:
- dependency-name: react-native
  dependency-version: 0.88.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react-native-deps
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(deps): regenerate pnpm-lock.yaml for react-native 0.88.1

Dependabot's lockfile for this bump added a second, peer-less
`vitest@5.0.3` snapshot and pointed `@vitest/coverage-v8` / `@vitest/ui`
at it. That loaded two vitest instances, which broke snapshot tests in
lucide, lucide-react, lucide-vue and lucide-react-native ("The snapshot
state ... is not found. Did you call 'SnapshotClient.setup()'?"). It also
pulled unrelated @types/node and @babel/* bumps into other importers.

Regenerated with pnpm 11.22.0 from the base lockfile, so it now only
changes the react-native tree and hermes-compiler.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G9u8Fhnpt1Di4KhMFtKbb2

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-11-02 18:06:07 +01:00
dependabot[bot]Claude Opus 5.5dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Eric
c06c5f0703 chore(deps-dev): bump the angular-deps group across 1 directory with 15 updates (#5114)
* chore(deps-dev): bump the angular-deps group across 1 directory with 15 updates

Bumps the angular-deps group with 15 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@angular-eslint/builder](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/builder) | `22.5.0` | `22.6.0` |
| [@angular-eslint/schematics](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/schematics) | `22.5.0` | `22.6.0` |
| [@angular/build](https://github.com/angular/angular-cli) | `22.2.2` | `22.2.5` |
| [@angular/cli](https://github.com/angular/angular-cli) | `22.2.2` | `22.2.5` |
| [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) | `22.2.2` | `22.2.4` |
| [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) | `22.2.2` | `22.2.4` |
| [@angular/compiler-cli](https://github.com/angular/angular/tree/HEAD/packages/compiler-cli) | `22.2.2` | `22.2.4` |
| [@angular/core](https://github.com/angular/angular/tree/HEAD/packages/core) | `22.2.2` | `22.2.4` |
| [@angular/forms](https://github.com/angular/angular/tree/HEAD/packages/forms) | `22.2.2` | `22.2.4` |
| [@angular/platform-browser](https://github.com/angular/angular/tree/HEAD/packages/platform-browser) | `22.2.2` | `22.2.4` |
| [@angular/platform-server](https://github.com/angular/angular/tree/HEAD/packages/platform-server) | `22.2.2` | `22.2.4` |
| [@angular/router](https://github.com/angular/angular/tree/HEAD/packages/router) | `22.2.2` | `22.2.4` |
| [@vitest/browser-playwright](https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser-playwright) | `5.0.3` | `5.0.5` |
| [angular-eslint](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/angular-eslint) | `22.5.0` | `22.6.0` |
| [ng-packagr](https://github.com/ng-packagr/ng-packagr) | `22.2.4` | `22.2.5` |



Updates `@angular-eslint/builder` from 22.5.0 to 22.6.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/builder/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v22.6.0/packages/builder)

Updates `@angular-eslint/schematics` from 22.5.0 to 22.6.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/schematics/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v22.6.0/packages/schematics)

Updates `@angular/build` from 22.2.2 to 22.2.5
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/v22.2.5/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/v22.2.2...v22.2.5)

Updates `@angular/cli` from 22.2.2 to 22.2.5
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/v22.2.5/CHANGELOG.md)
- [Commits](https://github.com/angular/angular-cli/compare/v22.2.2...v22.2.5)

Updates `@angular/common` from 22.2.2 to 22.2.4
- [Release notes](https://github.com/angular/angular/releases)
- [Commits](https://github.com/angular/angular/commits/v22.2.4/packages/common)

Updates `@angular/compiler` from 22.2.2 to 22.2.4
- [Release notes](https://github.com/angular/angular/releases)
- [Commits](https://github.com/angular/angular/commits/v22.2.4/packages/compiler)

Updates `@angular/compiler-cli` from 22.2.2 to 22.2.4
- [Release notes](https://github.com/angular/angular/releases)
- [Commits](https://github.com/angular/angular/commits/v22.2.4/packages/compiler-cli)

Updates `@angular/core` from 22.2.2 to 22.2.4
- [Release notes](https://github.com/angular/angular/releases)
- [Commits](https://github.com/angular/angular/commits/v22.2.4/packages/core)

Updates `@angular/forms` from 22.2.2 to 22.2.4
- [Release notes](https://github.com/angular/angular/releases)
- [Commits](https://github.com/angular/angular/commits/v22.2.4/packages/forms)

Updates `@angular/platform-browser` from 22.2.2 to 22.2.4
- [Release notes](https://github.com/angular/angular/releases)
- [Commits](https://github.com/angular/angular/commits/v22.2.4/packages/platform-browser)

Updates `@angular/platform-server` from 22.2.2 to 22.2.4
- [Release notes](https://github.com/angular/angular/releases)
- [Commits](https://github.com/angular/angular/commits/v22.2.4/packages/platform-server)

Updates `@angular/router` from 22.2.2 to 22.2.4
- [Release notes](https://github.com/angular/angular/releases)
- [Commits](https://github.com/angular/angular/commits/v22.2.4/packages/router)

Updates `@vitest/browser-playwright` from 5.0.3 to 5.0.5
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v5.0.5/packages/browser-playwright)

Updates `angular-eslint` from 22.5.0 to 22.6.0
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/angular-eslint/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v22.6.0/packages/angular-eslint)

Updates `ng-packagr` from 22.2.4 to 22.2.5
- [Release notes](https://github.com/ng-packagr/ng-packagr/releases)
- [Changelog](https://github.com/ng-packagr/ng-packagr/blob/22.2.5/CHANGELOG.md)
- [Commits](https://github.com/ng-packagr/ng-packagr/compare/22.2.4...22.2.5)

---
updated-dependencies:
- dependency-name: "@angular-eslint/builder"
  dependency-version: 22.6.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: angular-deps
- dependency-name: "@angular-eslint/schematics"
  dependency-version: 22.6.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: angular-deps
- dependency-name: "@angular/build"
  dependency-version: 22.2.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular-deps
- dependency-name: "@angular/cli"
  dependency-version: 22.2.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular-deps
- dependency-name: "@angular/common"
  dependency-version: 22.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular-deps
- dependency-name: "@angular/compiler"
  dependency-version: 22.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular-deps
- dependency-name: "@angular/compiler-cli"
  dependency-version: 22.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular-deps
- dependency-name: "@angular/core"
  dependency-version: 22.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular-deps
- dependency-name: "@angular/forms"
  dependency-version: 22.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular-deps
- dependency-name: "@angular/platform-browser"
  dependency-version: 22.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular-deps
- dependency-name: "@angular/platform-server"
  dependency-version: 22.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular-deps
- dependency-name: "@angular/router"
  dependency-version: 22.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular-deps
- dependency-name: "@vitest/browser-playwright"
  dependency-version: 5.0.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular-deps
- dependency-name: angular-eslint
  dependency-version: 22.6.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: angular-deps
- dependency-name: ng-packagr
  dependency-version: 22.2.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular-deps
...

Signed-off-by: dependabot[bot] <support@github.com>

* Dedupe deps

* fix(deps): align vitest override with @vitest/* 5.0.5

The workspace override pinned vitest to 5.0.3 while package.json files
already ask for 5.0.5, and this PR moves @vitest/browser-playwright to
5.0.5. That left @vitest/browser, mocker, utils and spy at 5.0.5 next
to a vitest 5.0.3 runtime, so the browser-mode packages were out of
sync with vitest. This broke:

- `expect.element` and jest-dom matcher types (Svelte, Nuxt, Solid 2)
- snapshot state in @lucide/vue tests ("snapshot state ... not found")

Bump the override to 5.0.5 so the whole vitest family resolves to a
single version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G9u8FeiSseTUuaZQjh6Z2N

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Eric <eric.fennis@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-11-02 18:00:37 +01:00
Vugar BakhishovandVugar Bakhishov 588113e359 test(build-icons): cover Windows file URL imports (#4862)
* fix(dev): import icon templates with file URLs

Convert the resolved template path to an encoded file URL so the Node.js ESM loader accepts Windows paths and URL characters.

* fix(dev): import icon metadata with file URLs

Encode metadata file paths before dynamic JSON import, including Windows drive paths and URL characters.

* test(dev): cover icon build assets in paths with URL characters

Run the icon CLI in a Node process with a small SVG and metadata fixture; verify generation and metadata in a path containing spaces, # and %.

* test(build-icons): cover Windows file URL imports

---------

Co-authored-by: Vugar Bakhishov <vugarbbakhishov-hub@users.noreply.github.com>
2026-11-02 18:00:04 +01:00
DrashtiC07andEric 08193b1ef5 feat(lab): added cup-bubble-tea icon (#5098)
* feat(icons): add boba icon

* feat(lab): add boba icon

* Rename icon

* Update design

---------

Co-authored-by: Eric <eric.fennis@gmail.com>
2026-11-02 17:34:13 +01:00
e5e55d2b65 feat(lab): added soldering-iron icon (#4850)
* feat(icons): add soldering iron

* fix(icons): consolidate soldering iron use cases

* fix(icons): refine soldering iron geometry

* fix(icons): update soldering iron design and credits

* Update soldering-iron.json

removed solder tag, since part of the name

* Move `soldering-iron` icon to lab

---------

Co-authored-by: Peter Jamrozinski <peter.jamrozinski@johnsonfit.com>
Co-authored-by: Karsa <contact@karsa.org>
Co-authored-by: Eric <eric.fennis@gmail.com>
2026-11-02 17:28:09 +01:00
Jonathen Wilksgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Eric
01d130afdd feat(lab): added flask-conical-titration icon (#4428)
* Added icons/titration.svg

* Added icons/titration.json

* Update icons/titration.json

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

* Move to lab

* Update metadata and code

* standardize capitalization in use-cases for consistency

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Eric <eric.fennis@gmail.com>
2026-11-02 17:22:03 +01:00
89 changed files with 2983 additions and 3008 deletions
@@ -12,6 +12,6 @@
"@octokit/rest": "^22.0.1",
"dotenv": "^17.4.2",
"openai": "^7.9.0",
"zod": "^4.5.4"
"zod": "^4.6.7"
}
}
@@ -56,7 +56,7 @@ When checking or adding a `$group:` marker:
- A marker must be exactly `"$group:"` followed by the name of an existing file in `groups/`, without the `.json` extension, in lowercase kebab-case.
- `$group:` is allowed **only** inside `tags`. It is not valid in `categories` or `contributors`.
- Groups are named after the variant suffix: `file-plus` uses `$group:plus`, `file-question-mark` uses `$group:question-mark`. Suffixes with the same meaning share a group: `mail-warning` uses `$group:exclamation-mark`, and every currency suffix uses `$group:currency`.
- Groups are named after the variant suffix: `file-plus` uses `$group:plus`, `file-question-mark` uses `$group:question-mark`. Suffixes with the same meaning share a group: `mail-exclamation-point` uses `$group:exclamation-mark`, and every currency suffix uses `$group:currency`.
- The same suffix can mean different things in different contexts — `-off` means "disabled" on `wifi-off` but "allergy free" on `wheat-off` — so only use the group when the icon carries the group's meaning, and keep context-specific tags as literals.
- Do not repeat a tag a group already provides, and do not use the same group twice in one array.
- Conventional order: the `$extends:` base icon first, then `$group:` markers, then the icon's own literal tags.
+1 -1
View File
@@ -2,5 +2,5 @@
"$schema": "../category.schema.json",
"title": "Notifications",
"description": "Icons for alerts, status updates, reminders, approvals, and attention states.",
"icon": "triangle-alert"
"icon": "triangle-exclamation-point"
}
@@ -6,7 +6,7 @@ import Calendar from '../../../data/iconDetails/calendar.ts';
import Clock from '../../../data/iconDetails/clock.ts';
import Bug from '../../../data/iconDetails/bug.ts';
import Rocket from '../../../data/iconDetails/rocket.ts';
import TriangleAlert from '../../../data/iconDetails/triangle-alert.ts';
import TriangleExclamationPoint from '../../../data/iconDetails/triangle-exclamation-point.ts';
import PartyPopper from '../../../data/iconDetails/party-popper.ts';
import Scissors from '../../../data/iconDetails/scissors.ts';
import Copy from '../../../data/iconDetails/copy.ts';
@@ -41,7 +41,7 @@ const CalendarIcon = createLucideIcon('calendar', Calendar.iconNode);
const ClockIcon = createLucideIcon('clock', Clock.iconNode);
const BugIcon = createLucideIcon('bug', Bug.iconNode);
const RocketIcon = createLucideIcon('rocket', Rocket.iconNode);
const AlertTriangleIcon = createLucideIcon('alert-triangle', TriangleAlert.iconNode);
const TriangleExclamationPointIcon = createLucideIcon('triangle-exclamation-point', TriangleExclamationPoint.iconNode);
const ScissorsIcon = createLucideIcon('scissors', Scissors.iconNode);
const CopyIcon = createLucideIcon('copy', Copy.iconNode);
const SaveIcon = createLucideIcon('save', Save.iconNode);
@@ -128,7 +128,7 @@ const prettyName = props.name
>
<div class="placeholder"></div>
<div class="badge badge-red">
<AlertTriangleIcon :size="20" />
<TriangleExclamationPointIcon :size="20" />
Alert
</div>
</div>
@@ -117,8 +117,6 @@ function scrollTrack(direction: 1 | -1) {
.tiers {
padding-top: 96px;
padding-bottom: 48px;
/* The track bleeds to the right edge of the viewport. */
overflow-x: clip;
}
.tiers-header {
@@ -165,7 +163,6 @@ function scrollTrack(direction: 1 | -1) {
.track-wrapper {
position: relative;
margin-right: min(-24px, calc((1152px - 100vw) / 2));
}
.track {
@@ -178,12 +175,16 @@ function scrollTrack(direction: 1 | -1) {
padding-bottom: 12px;
padding-right: 24px;
scroll-padding-right: 24px;
scrollbar-width: thin;
scrollbar-width: none;
scroll-snap-align: center;
scroll-padding-left: 24px;
scroll-padding-right: 24px;
}
.track::-webkit-scrollbar {
display: none;
}
.track:focus-visible {
outline: 2px solid var(--vp-c-brand-1);
outline-offset: 4px;
@@ -3,7 +3,7 @@ description: Learn the best practices for writing use cases for Lucide icons.
---
<script setup>
import { batteryLow, creditCard, crop, handshake, heading2, microchip, search, squareLetterP, triangleAlert, wifiOff } from '~/.vitepress/data/iconNodes';
import { batteryLow, creditCard, crop, handshake, heading2, microchip, search, squareLetterP, triangleExclamationPoint, wifiOff } from '~/.vitepress/data/iconNodes';
import LucideIcon from '~/.vitepress/theme/components/base/LucideIcon.vue';
</script>
@@ -120,10 +120,10 @@ The period adds **unnecessary punctuation** and makes entries inconsistent.
Use plain text only. Formatting belongs in documentation, not metadata values.
:::: example
::: do <LucideIcon name="triangle-alert" :iconNode="triangleAlert" /> Warning users about a destructive action
::: do <LucideIcon name="triangle-exclamation-point" :iconNode="triangleExclamationPoint" /> Warning users about a destructive action
This works in search, generated pages, and other places that use metadata.
:::
::: dont <LucideIcon name="triangle-alert" :iconNode="triangleAlert" /> <span>**Warning** users about a destructive action ⚠️</span>
::: dont <LucideIcon name="triangle-exclamation-point" :iconNode="triangleExclamationPoint" /> <span>**Warning** users about a destructive action ⚠️</span>
Markdown and emoji can **show up in generated UI** and make metadata **harder to reuse**.
:::
::::
+1 -1
View File
@@ -31,7 +31,7 @@ You can then reference the registered icons by name:
```html [app.html]
<svg lucideIcon="square-check"></svg>
<svg lucideIcon="circle-alert"></svg>
<svg lucideIcon="circle-exclamation-point"></svg>
```
## How names are resolved
+3 -3
View File
@@ -42,12 +42,12 @@
"h3": "^1.15.11",
"markdown-it": "^15.0.3",
"markdown-it-container": "^4.0.0",
"nitropack": "^2.13.4",
"nitropack": "^2.13.5",
"rollup-plugin-copy": "^3.5.0",
"semver": "^7.8.5",
"sharp": "^0.35.5",
"shiki": "^4.4.3",
"simple-git": "^4.0.1",
"shiki": "^4.5.0",
"simple-git": "^4.0.2",
"sitemap": "^9.0.1",
"svg-path-commander": "^2.3.3",
"svg-pathdata": "^9.0.0",
@@ -15,5 +15,10 @@
"categories": [
"account",
"social"
],
"aliases": [
{
"name": "badge-alert"
}
]
}

Before

Width:  |  Height:  |  Size: 471 B

After

Width:  |  Height:  |  Size: 471 B

@@ -12,5 +12,10 @@
],
"categories": [
"$extends:battery"
],
"aliases": [
{
"name": "battery-warning"
}
]
}

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 393 B

@@ -15,5 +15,10 @@
],
"categories": [
"$extends:book"
],
"aliases": [
{
"name": "book-alert"
}
]
}

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 359 B

@@ -16,6 +16,9 @@
"name": "alert-circle",
"deprecationReason": "alias.name",
"deprecated": true
},
{
"name": "circle-alert"
}
]
}

Before

Width:  |  Height:  |  Size: 332 B

After

Width:  |  Height:  |  Size: 332 B

+23
View File
@@ -0,0 +1,23 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"n2duc"
],
"use-cases": [
"Indicating a submission or payment that is still being verified",
"Showing a deployment, upload, or backup that is finishing up",
"Marking a task as partially completed or awaiting final approval",
"Displaying a step in a progress tracker that is in progress"
],
"tags": [
"$group:check",
"pending",
"progress",
"processing",
"verifying",
"loading"
],
"categories": [
"notifications"
]
}
+18
View File
@@ -0,0 +1,18 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M12 2a10 10 0 017.38 16.75" />
<path d="m16 9-5.5 5.5L8 12" />
<path d="M2.5 8.875a10 10 0 00-.5 3" />
<path d="M2.83 16a10 10 0 002.43 3.4" />
<path d="M4.636 5.235a10 10 0 01.891-.857" />
<path d="M8.644 21.42a10 10 0 007.631-.38" />
</svg>

After

Width:  |  Height:  |  Size: 465 B

@@ -13,5 +13,10 @@
],
"categories": [
"$extends:clock"
],
"aliases": [
{
"name": "clock-alert"
}
]
}

Before

Width:  |  Height:  |  Size: 332 B

After

Width:  |  Height:  |  Size: 332 B

@@ -19,5 +19,10 @@
"development",
"notifications",
"weather"
],
"aliases": [
{
"name": "cloud-alert"
}
]
}

Before

Width:  |  Height:  |  Size: 331 B

After

Width:  |  Height:  |  Size: 331 B

@@ -13,5 +13,13 @@
"categories": [
"mail",
"notifications"
],
"aliases": [
{
"name": "mail-warning"
},
{
"name": "mail-alert"
}
]
}

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 393 B

+30
View File
@@ -0,0 +1,30 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"Prsenapati09",
"rrod497"
],
"use-cases": [
"Representing tropical fruit in food and grocery apps",
"Indicating produce sections in shopping interfaces",
"Labeling tropical fruit filters in recipe and nutrition apps",
"Highlighting seasonal fruit in marketplaces"
],
"tags": [
"fruit",
"food",
"tropical",
"summer",
"exotic",
"healthy",
"ripe",
"yellow",
"juice",
"smoothie",
"snack",
"produce"
],
"categories": [
"food-beverage"
]
}
+14
View File
@@ -0,0 +1,14 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="m17 6 3-3" />
<path d="M7 22a4 4 0 01-2.62-7.023A2 2 0 005 13.383V10a8 8 0 1116 0A12 12 0 019 22z" />
</svg>

After

Width:  |  Height:  |  Size: 323 B

@@ -17,5 +17,13 @@
"categories": [
"$extends:message-circle",
"notifications"
],
"aliases": [
{
"name": "message-circle-warning"
},
{
"name": "message-circle-alert"
}
]
}

Before

Width:  |  Height:  |  Size: 396 B

After

Width:  |  Height:  |  Size: 396 B

@@ -16,5 +16,13 @@
"categories": [
"$extends:message-square",
"notifications"
],
"aliases": [
{
"name": "message-square-warning"
},
{
"name": "message-square-alert"
}
]
}

Before

Width:  |  Height:  |  Size: 388 B

After

Width:  |  Height:  |  Size: 388 B

@@ -18,6 +18,9 @@
"name": "alert-octagon",
"deprecationReason": "alias.name",
"deprecated": true
},
{
"name": "octagon-alert"
}
]
}

Before

Width:  |  Height:  |  Size: 510 B

After

Width:  |  Height:  |  Size: 510 B

+32
View File
@@ -0,0 +1,32 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"ilyavred",
"jamiemlaw"
],
"use-cases": [
"Setting the opacity of layers or objects in graphic editors",
"Adjusting the opacity of fills, strokes, or other object attributes",
"Adjusting the alpha channel in color pickers",
"Indicating that a layer or element is semi-transparent"
],
"tags": [
"opacity",
"opaque",
"transparency",
"visibility",
"fade",
"lens",
"glass",
"blur",
"filter",
"clear",
"mask",
"cover",
"gradient"
],
"categories": [
"design",
"photography"
]
}
+25
View File
@@ -0,0 +1,25 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M12 3h.01" />
<path d="M12 9h.01" />
<path d="M15 6h.01" />
<path d="M18 3h.01" />
<path d="M21 6v13a2 2 0 0 1-2 2H6" />
<path d="M3 12h.01" />
<path d="M3 18h.01" />
<path d="M3 6h.01" />
<path d="M6 15h.01" />
<path d="M6 3h.01" />
<path d="M6 9h.01" />
<path d="M9 12h.01" />
<path d="M9 6h.01" />
</svg>

After

Width:  |  Height:  |  Size: 544 B

+19
View File
@@ -0,0 +1,19 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"$extends:package"
],
"use-cases": [
"Editing recipient addresses or package contents in shipping systems",
"Modifying customer orders before shipment",
"Updating product listings in inventory or e-commerce platforms",
"Editing software package manifests or metadata"
],
"tags": [
"$extends:package",
"$group:pen"
],
"categories": [
"$extends:package"
]
}
+17
View File
@@ -0,0 +1,17 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M12 14.34V12l8.71-5" />
<path d="M16.511 21.141a2 2 0 0 0 .854-.506l4.013-4.009a1 1 0 1 0-3.004-3.004l-4.01 4.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .599.626z" />
<path d="M21 9.114V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l5.087 2.907" />
<path d="M3.29 7 12 12" />
<path d="m7.5 4.27 9 5.15" />
</svg>

After

Width:  |  Height:  |  Size: 564 B

+24
View File
@@ -0,0 +1,24 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"$extends:package"
],
"use-cases": [
"Marking an unknown or unrecognized package in a package registry",
"Indicating a dependency that is still being resolved in a package manager",
"Indicating a lost or missing delivery package",
"Showing a shipment with an unknown delivery status"
],
"tags": [
"$extends:package",
"$group:question-mark",
"unresolved",
"placeholder",
"pending",
"lost",
"dependency"
],
"categories": [
"$extends:package"
]
}
+18
View File
@@ -0,0 +1,18 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M12 22V12l8.71-5" />
<path d="M17 15.27c.2-.4.5-.8.9-1a2.1 2.1 0 0 1 2.6.4c.3.4.5.8.5 1.3 0 1.3-2 2-2 2" />
<path d="M19 21.99h.01" />
<path d="M21 10.342V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l2.33-1.332" />
<path d="M3.29 7 12 12" />
<path d="m7.5 4.27 9 5.15" />
</svg>

After

Width:  |  Height:  |  Size: 550 B

+8 -1
View File
@@ -21,7 +21,14 @@
"packed",
"archive",
"zip",
"module"
"module",
"shipping",
"recipient",
"inventory",
"logistics",
"tracking",
"order",
"product"
],
"categories": [
"files",
@@ -15,5 +15,10 @@
],
"categories": [
"$extends:search"
],
"aliases": [
{
"name": "search-alert"
}
]
}

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 322 B

@@ -59,5 +59,10 @@
"development",
"notifications",
"gaming"
],
"aliases": [
{
"name": "shield-alert"
}
]
}

Before

Width:  |  Height:  |  Size: 435 B

After

Width:  |  Height:  |  Size: 435 B

@@ -21,6 +21,9 @@
"name": "alert-triangle",
"deprecationReason": "alias.name",
"deprecated": true
},
{
"name": "triangle-alert"
}
]
}

Before

Width:  |  Height:  |  Size: 345 B

After

Width:  |  Height:  |  Size: 345 B

@@ -19,9 +19,9 @@
"@types/react": "19.3.0",
"@types/react-dom": "19.3.0",
"@vitejs/plugin-react": "^6.1.2",
"@vitest/browser-playwright": "5.0.3",
"@vitest/browser-playwright": "5.0.5",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vitest": "5.0.5",
"vitest-browser-react": "2.3.0"
}
@@ -21,13 +21,13 @@
},
"devDependencies": {
"@react-router/dev": "8.3.1",
"@types/node": "^26.1.1",
"@types/node": "^26.4.1",
"@types/react": "19.3.0",
"@types/react-dom": "19.3.0",
"@vitejs/plugin-react": "^6.1.2",
"@vitest/browser-playwright": "5.0.3",
"@vitest/browser-playwright": "5.0.5",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vitest": "5.0.5",
"vitest-browser-react": "2.3.0"
}
@@ -20,9 +20,9 @@
"@types/react": "19.3.0",
"@types/react-dom": "19.3.0",
"@vitejs/plugin-react": "^6.1.2",
"@vitest/browser-playwright": "5.0.3",
"@vitest/browser-playwright": "5.0.5",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vitest": "5.0.5",
"vitest-browser-react": "2.3.0"
}
@@ -17,13 +17,13 @@
"react-dom": "19.3.1"
},
"devDependencies": {
"@types/node": "^26.1.1",
"@types/node": "^26.4.1",
"@types/react": "19.3.0",
"@types/react-dom": "19.3.0",
"@vitejs/plugin-react": "^6.1.2",
"@vitest/browser-playwright": "5.0.3",
"@vitest/browser-playwright": "5.0.5",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vitest": "5.0.5",
"vitest-browser-react": "2.3.0"
}
+2 -2
View File
@@ -18,10 +18,10 @@
"@types/react": "19.3.0",
"@types/react-dom": "19.3.0",
"@vitejs/plugin-react": "^6.1.2",
"@vitest/browser-playwright": "5.0.3",
"@vitest/browser-playwright": "5.0.5",
"playwright": "1.64.1",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vitest": "5.0.5",
"vitest-browser-react": "2.3.0"
}
@@ -17,13 +17,13 @@
"solid-js": "next"
},
"devDependencies": {
"@solidjs/testing-library": "1.0.0-beta.3",
"@solidjs/testing-library": "1.0.0-rc.2",
"@solidjs/vite-plugin": "3.0.0-next.47",
"@vitest/browser-playwright": "5.0.3",
"@vitest/browser-playwright": "5.0.5",
"filesystem-routing": "0.4.0",
"playwright": "1.64.1",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vitest": "5.0.5"
}
}
@@ -15,13 +15,13 @@
"@solidjs/start": "2.0.5",
"lucide-solid": "workspace:*",
"nitro": "3.0.260903-beta",
"solid-js": "1.9.15"
"solid-js": "1.9.18"
},
"devDependencies": {
"@vitest/browser-playwright": "5.0.3",
"@vitest/browser-playwright": "5.0.5",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite-plugin-solid": "^2.11.14",
"vite": "^8.3.5",
"vite-plugin-solid": "^2.11.15",
"vitest": "5.0.5",
"vitest-browser-solid": "1.0.1"
},
+4 -4
View File
@@ -11,14 +11,14 @@
},
"dependencies": {
"lucide-solid": "workspace:*",
"solid-js": "1.9.15"
"solid-js": "1.9.18"
},
"devDependencies": {
"@vitest/browser-playwright": "5.0.3",
"@vitest/browser-playwright": "5.0.5",
"playwright": "1.64.1",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite-plugin-solid": "^2.11.14",
"vite": "^8.3.5",
"vite-plugin-solid": "^2.11.15",
"vitest": "5.0.5",
"vitest-browser-solid": "1.0.1"
}
@@ -21,11 +21,11 @@
"@sveltejs/adapter-auto": "^8.0.0",
"@sveltejs/kit": "^3.1.1",
"@sveltejs/vite-plugin-svelte": "^7.3.1",
"@vitest/browser-playwright": "5.0.3",
"@vitest/browser-playwright": "5.0.5",
"playwright": "1.64.1",
"svelte-check": "^4.7.7",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vitest": "5.0.5",
"vitest-browser-svelte": "3.1.0"
}
+3 -3
View File
@@ -16,12 +16,12 @@
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^7.3.1",
"@tsconfig/svelte": "^5.0.8",
"@types/node": "^26.1.1",
"@vitest/browser-playwright": "5.0.3",
"@types/node": "^26.4.1",
"@vitest/browser-playwright": "5.0.5",
"playwright": "1.64.1",
"svelte-check": "^4.7.7",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vitest": "5.0.5",
"vitest-browser-svelte": "3.1.0"
}
+3 -3
View File
@@ -11,15 +11,15 @@
},
"dependencies": {
"@lucide/vue": "workspace:*",
"nuxt": "4.6.2",
"nuxt": "4.6.3",
"vue": "3.5.44",
"vue-router": "5.3.1"
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.10",
"@vitest/browser-playwright": "5.0.3",
"@vitest/browser-playwright": "5.0.5",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vitest": "5.0.5",
"vitest-browser-vue": "3.1.0",
"vue-tsc": "^3.3.11"
+2 -2
View File
@@ -17,9 +17,9 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.10",
"@vitest/browser-playwright": "5.0.3",
"@vitest/browser-playwright": "5.0.5",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vitest": "5.0.5",
"vitest-browser-vue": "3.1.0",
"vue-tsc": "^3.3.11"
+3 -3
View File
@@ -15,13 +15,13 @@
},
"devDependencies": {
"@tsconfig/node24": "^24.0.5",
"@types/node": "^26.1.1",
"@types/node": "^26.4.1",
"@vitejs/plugin-vue": "^6.0.10",
"@vitest/browser-playwright": "5.0.3",
"@vitest/browser-playwright": "5.0.5",
"@vue/tsconfig": "^0.9.1",
"playwright": "1.64.1",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vitest": "5.0.5",
"vitest-browser-vue": "3.1.0",
"vue-tsc": "^3.3.11"
+23
View File
@@ -0,0 +1,23 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"karsa-mistmere",
"DrashtiC07"
],
"tags": [
"drink",
"tea",
"boba",
"bubble tea",
"tapioca",
"milk tea",
"cafe",
"straw",
"pearls",
"beverage",
"cold drink"
],
"categories": [
"food-beverage"
]
}
+19
View File
@@ -0,0 +1,19 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M11 14h.01" />
<path d="M11 18h.01" />
<path d="M14 16h.01" />
<path d="m14 2-2 2.5" />
<path d="M5 10h14" />
<path d="m6 10 1.5 10.2a2 2 0 002 1.8h5a2 2 0 002-1.8L18 10" />
<path d="M6.5 10a1 1 0 0111 0" />
</svg>

After

Width:  |  Height:  |  Size: 439 B

+38
View File
@@ -0,0 +1,38 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"jwlinqx",
"karsa-mistmere"
],
"use-cases": [
"Labeling titration procedures in lab information management systems",
"Marking assay workflows like Karl Fischer or potentiometric titration in pharmaceutical QC dashboards",
"Marking acid-base or redox titration lessons on chemistry e-learning platforms",
"Indicating chlorine residual, alkalinity, or hardness titration tests in water treatment monitoring tools",
"Denoting titratable acidity or free-SO₂ titration tools in brewing and winemaking apps",
"Marking the water-testing section for drop-count titration kit results in pool, spa, and aquarium care apps",
"Flagging TAN/TBN titration steps in oil analysis reports",
"Logging fat or acidity titration entries in food and dairy QA systems",
"Representing dissolved oxygen or soil pH titration workflows in environmental field-study apps"
],
"tags": [
"chemical",
"reaction",
"measurement",
"volume",
"solution",
"precision",
"droplet",
"pipette",
"lab",
"chemistry",
"beaker",
"erlenmeyer",
"experiment",
"test"
],
"categories": [
"science",
"medical"
]
}
+16
View File
@@ -0,0 +1,16 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M12 4v2" />
<path d="M14 10v4a2 2 0 00.245.96l2.51 4.08A2 2 0 0115 22H9a2 2 0 01-1.755-2.96l2.51-4.08A2 2 0 0010 14v-4" />
<path d="M14 2a2 2 0 01-4 0" />
<path d="M9 10h6" />
</svg>

After

Width:  |  Height:  |  Size: 401 B

+30
View File
@@ -0,0 +1,30 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"psjdev",
"karsa-mistmere"
],
"use-cases": [
"Representing electronics assembly and repair",
"Indicating circuit-board rework or modification",
"Marking soldering steps in repair instructions",
"Marking hot-tip hazards in safety documentation"
],
"tags": [
"electronics",
"repair",
"circuit",
"heat",
"workshop",
"assembly",
"pcb",
"flux",
"desolder",
"rework",
"smd",
"diy"
],
"categories": [
"tools"
]
}
+16
View File
@@ -0,0 +1,16 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M11.356 9.356a1.2 1.2 0 010-1.712l.351-.351A1 1 0 0112.414 7h1.172a1 1 0 00.707-.293l3.351-3.351a1.2 1.2 0 011.712 0l1.288 1.288a1.2 1.2 0 010 1.712l-3.351 3.351a1 1 0 00-.293.707v1.172a1 1 0 01-.293.707l-.351.351a1.2 1.2 0 01-1.712 0z" />
<path d="m11.5 9.5-7.243 7.244a2 2 0 00-.407.586l-1.798 3.956a.5.5 0 00.662.662L6.67 20.15a2 2 0 00.586-.406L14.5 12.5" />
<path d="m20 4 .293-.293A2.4 2.4 0 0122 3" />
<path d="M3 2q2 2.5 0 5 -2 2.5 0 5" />
</svg>

After

Width:  |  Height:  |  Size: 673 B

+2 -2
View File
@@ -84,13 +84,13 @@
"prettier": "3.9.6",
"prettier-plugin-astro": "^0.14.1",
"semver": "^7.8.5",
"simple-git": "^4.0.1",
"simple-git": "^4.0.2",
"svgo": "^4.1.0",
"svgson": "^5.3.1",
"typescript": "^6.0.3",
"typescript-eslint": "^8.69.0",
"vitest": "5.0.5",
"yargs": "^18.1.0"
"yargs": "^18.2.0"
},
"engines": {
"node": ">=24.11.1"
+15 -15
View File
@@ -42,23 +42,23 @@
]
},
"devDependencies": {
"@angular-eslint/builder": "~22.5.0",
"@angular-eslint/schematics": "~22.5.0",
"@angular/build": "^22.2.2",
"@angular/cli": "^22.2.2",
"@angular/common": "^22.2.2",
"@angular/compiler": "^22.2.2",
"@angular/compiler-cli": "^22.2.2",
"@angular/core": "^22.2.2",
"@angular/forms": "^22.2.2",
"@angular/platform-browser": "^22.2.2",
"@angular/platform-server": "^22.2.2",
"@angular/router": "^22.2.2",
"@angular-eslint/builder": "~22.6.0",
"@angular-eslint/schematics": "~22.6.0",
"@angular/build": "^22.2.5",
"@angular/cli": "^22.2.5",
"@angular/common": "^22.2.4",
"@angular/compiler": "^22.2.4",
"@angular/compiler-cli": "^22.2.4",
"@angular/core": "^22.2.4",
"@angular/forms": "^22.2.4",
"@angular/platform-browser": "^22.2.4",
"@angular/platform-server": "^22.2.4",
"@angular/router": "^22.2.4",
"@lucide/build-icons": "workspace:*",
"@lucide/helpers": "workspace:*",
"@vitest/browser-playwright": "^5.0.3",
"angular-eslint": "22.5.0",
"ng-packagr": "^22.2.4",
"@vitest/browser-playwright": "^5.0.5",
"angular-eslint": "22.6.0",
"ng-packagr": "^22.2.5",
"rxjs": "~7.8.2",
"tslib": "^2.8.1",
"typescript": "^6.0.3"
@@ -3,20 +3,20 @@ import { bootstrapApplication, provideClientHydration } from '@angular/platform-
import { provideServerRendering, renderApplication } from '@angular/platform-server';
import { LucideDynamicIcon } from './lucide-dynamic-icon';
import { provideLucideIcons } from './lucide-icons';
import { LucideBadgeAlert } from './icons/badge-alert';
import { LucideBadgeExclamationPoint } from './icons/badge-exclamation-point';
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'lucide-static-hydration-root',
template: `<svg lucideBadgeAlert [nonScalingStroke]="true"></svg>`,
imports: [LucideBadgeAlert],
template: `<svg lucideBadgeExclamationPoint [nonScalingStroke]="true"></svg>`,
imports: [LucideBadgeExclamationPoint],
})
class StaticHydrationRootComponent {}
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'lucide-dynamic-hydration-root',
template: `<svg [lucideIcon]="'badge-alert'"></svg>`,
template: `<svg [lucideIcon]="'badge-exclamation-point'"></svg>`,
imports: [LucideDynamicIcon],
})
class DynamicHydrationRootComponent {}
@@ -60,7 +60,7 @@ describe('Lucide hydration', () => {
);
(globalThis as { ngServerMode?: boolean }).ngServerMode = false;
const serverDocument = new DOMParser().parseFromString(html, 'text/html');
expectBadgeAlertShapeNodes(serverDocument.querySelector('svg') as SVGSVGElement);
expectBadgeExclamationPointShapeNodes(serverDocument.querySelector('svg') as SVGSVGElement);
document.head.innerHTML = serverDocument.head.innerHTML;
document.body.innerHTML = serverDocument.body.innerHTML;
@@ -75,7 +75,7 @@ describe('Lucide hydration', () => {
return document.querySelector('svg') as SVGSVGElement;
}
function expectBadgeAlertShapeNodes(svg: SVGSVGElement) {
function expectBadgeExclamationPointShapeNodes(svg: SVGSVGElement) {
expect(Array.from(svg.children).map((child) => child.tagName.toLowerCase())).toEqual([
'path',
'line',
@@ -89,7 +89,7 @@ describe('Lucide hydration', () => {
'lucide-static-hydration-root',
);
expectBadgeAlertShapeNodes(svg);
expectBadgeExclamationPointShapeNodes(svg);
for (const child of Array.from(svg.children)) {
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
}
@@ -99,9 +99,9 @@ describe('Lucide hydration', () => {
const svg = await renderAndHydrate(
DynamicHydrationRootComponent,
'lucide-dynamic-hydration-root',
[provideLucideIcons(LucideBadgeAlert)],
[provideLucideIcons(LucideBadgeExclamationPoint)],
);
expectBadgeAlertShapeNodes(svg);
expectBadgeExclamationPointShapeNodes(svg);
});
});
+2 -2
View File
@@ -66,11 +66,11 @@
"@rollup/plugin-replace": "^6.0.3",
"@testing-library/jest-dom": "^7.0.1",
"jest-serializer-html": "^7.1.0",
"rollup": "^4.65.0",
"rollup": "^4.65.1",
"rollup-plugin-dts": "^6.5.1",
"rollup-plugin-preserve-directives": "^0.4.0",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vitest": "5.0.5"
}
}
+1 -1
View File
@@ -45,7 +45,7 @@
"@lucide/rollup-plugins": "workspace:*",
"@types/node": "^26.4.1",
"prettier": "3.9.6",
"rollup": "^4.65.0",
"rollup": "^4.65.1",
"rollup-plugin-dts": "^6.5.1",
"svgson": "^5.3.1",
"typescript": "^6.0.3"
+2 -2
View File
@@ -56,10 +56,10 @@
"@testing-library/preact": "^3.2.6",
"jest-serializer-html": "^7.1.0",
"preact": "^11.1.0",
"rollup": "^4.65.0",
"rollup": "^4.65.1",
"rollup-plugin-dts": "^6.5.1",
"typescript": "^6.0.3",
"vite": "^8.3.3"
"vite": "^8.3.5"
},
"peerDependencies": {
"preact": "^10.27.2 || ^11.0.0-0"
+3 -3
View File
@@ -77,12 +77,12 @@
"jest-serializer-html": "^7.1.0",
"react": "19.3.1",
"react-dom": "19.3.1",
"react-native": "^0.88.0",
"react-native": "^0.88.1",
"react-native-svg": "^15.16.0",
"rollup": "^4.65.0",
"rollup": "^4.65.1",
"rollup-plugin-dts": "^6.5.1",
"typescript": "^6.0.3",
"vite": "^8.3.3"
"vite": "^8.3.5"
},
"peerDependencies": {
"@types/react": "*",
+3 -3
View File
@@ -108,17 +108,17 @@
"@lucide/shared": "workspace:*",
"@testing-library/jest-dom": "^7.0.1",
"@testing-library/react": "^16.3.3",
"@types/node": "^25.9.1",
"@types/node": "^25.9.5",
"@types/react": "^19.3.0",
"@vitejs/plugin-react": "^6.1.2",
"jest-serializer-html": "^7.1.0",
"react": "19.3.1",
"react-dom": "19.3.1",
"rollup": "^4.65.0",
"rollup": "^4.65.1",
"rollup-plugin-dts": "^6.5.1",
"rollup-plugin-preserve-directives": "^0.4.0",
"typescript": "^6.0.3",
"vite": "^8.3.3"
"vite": "^8.3.5"
},
"peerDependencies": {
"@types/react": "*",
@@ -0,0 +1,59 @@
// @vitest-environment node
import { afterEach, expect, it } from 'vitest';
import { spawnSync } from 'node:child_process';
import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const fixtureDirectories: string[] = [];
afterEach(() => {
fixtureDirectories.splice(0).forEach((directory) => {
rmSync(directory, { recursive: true, force: true });
});
});
it('builds icons with templates and metadata in paths containing URL characters', () => {
const directory = mkdtempSync(path.join(tmpdir(), 'lucide-build-icons #%-'));
fixtureDirectories.push(directory);
const input = path.join(directory, 'input');
const output = path.join(directory, 'output');
const template = path.join(directory, 'template.mjs');
mkdirSync(input);
writeFileSync(
path.join(input, 'sample.svg'),
'<svg xmlns="http://www.w3.org/2000/svg"><path d="M1 1h2" /></svg>',
);
writeFileSync(path.join(input, 'sample.json'), JSON.stringify({ aliases: ['sample-alias'] }));
writeFileSync(
template,
'export default ({ iconData }) => "export default " + JSON.stringify(iconData);',
);
const cli = fileURLToPath(new URL('../../../tools/build-icons/cli.ts', import.meta.url));
const result = spawnSync(
process.execPath,
[
cli,
`--input=${input}`,
`--output=${output}`,
`--templateSrc=${template}`,
'--pretty=false',
'--silent',
],
{ encoding: 'utf8', timeout: 30_000 },
);
expect(result.error).toBeUndefined();
expect(result.status, result.stderr).toBe(0);
expect(result.stderr).toBe('');
const generatedIcon = readFileSync(path.join(output, 'icons', 'sample.js'), 'utf8');
expect(JSON.parse(generatedIcon.replace(/^export default /, ''))).toMatchObject({
name: 'sample',
aliases: ['sample-alias'],
node: [['path', { d: 'M1 1h2' }]],
});
expect(readFileSync(path.join(output, 'icons', 'index.js'), 'utf8')).toContain('sample');
});
+8 -8
View File
@@ -68,24 +68,24 @@
"test:watch": "vitest watch"
},
"devDependencies": {
"@babel/core": "^7.29.7",
"@babel/preset-env": "^7.29.7",
"@babel/preset-typescript": "^7.29.7",
"@babel/core": "^8.0.10",
"@babel/preset-env": "^8.0.7",
"@babel/preset-typescript": "^8.0.7",
"@lucide/build-icons": "workspace:*",
"@lucide/rollup-plugins": "workspace:*",
"@lucide/shared": "workspace:*",
"@rollup/plugin-babel": "^6.1.0",
"@rollup/plugin-babel": "^7.1.0",
"@solidjs/testing-library": "^0.8.10",
"@testing-library/jest-dom": "^7.0.1",
"babel-preset-solid": "^1.9.15",
"esbuild": "^0.28.2",
"jest-serializer-html": "^7.1.0",
"rollup": "^4.65.1",
"rollup-plugin-dts": "^6.5.1",
"rollup": "^4.65.0",
"solid-js": "^1.9.15",
"solid-js": "^1.9.18",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite-plugin-solid": "^2.11.14"
"vite": "^8.3.5",
"vite-plugin-solid": "^2.11.15"
},
"peerDependencies": {
"solid-js": "^1.4.7"
+4 -1
View File
@@ -43,8 +43,11 @@ const configs = bundles
presets: [
'babel-preset-solid',
'@babel/preset-typescript',
['@babel/preset-env', { bugfixes: true, targets: 'last 2 years' }],
['@babel/preset-env', { targets: 'last 2 years' }],
],
// Babel 8's @babel/preset-typescript no longer enables JSX parsing for .tsx files,
// and babel-preset-solid's Babel 7 JSX syntax plugin skips it when TypeScript is enabled.
overrides: [{ test: /\.[jt]sx$/, parserOpts: { plugins: ['jsx'] } }],
}),
...plugins({
pkg,
+1 -1
View File
@@ -43,7 +43,7 @@
"@lucide/rollup-plugins": "workspace:*",
"@types/node": "^26.4.1",
"prettier": "3.9.6",
"rollup": "^4.65.0",
"rollup": "^4.65.1",
"rollup-plugin-dts": "^6.5.1",
"svgson": "^5.3.1"
}
+3 -3
View File
@@ -48,11 +48,11 @@
"@lucide/shared": "workspace:*",
"@rollup/plugin-replace": "^6.0.3",
"@testing-library/jest-dom": "^7.0.1",
"@types/node": "^25.9.1",
"@types/node": "^25.9.5",
"jest-serializer-html": "^7.1.0",
"rollup": "^4.65.0",
"rollup": "^4.65.1",
"rollup-plugin-dts": "^6.5.1",
"typescript": "^6.0.3",
"vite": "^8.3.3"
"vite": "^8.3.5"
}
}
+1 -1
View File
@@ -22,6 +22,6 @@
},
"devDependencies": {
"@types/node": "^26.4.1",
"vite": "^8.3.3"
"vite": "^8.3.5"
}
}
+6 -6
View File
@@ -68,13 +68,13 @@
"test:watch": "vitest watch"
},
"devDependencies": {
"@babel/core": "^7.29.7",
"@babel/preset-env": "^7.29.7",
"@babel/preset-typescript": "^7.29.7",
"@babel/core": "^8.0.10",
"@babel/preset-env": "^8.0.7",
"@babel/preset-typescript": "^8.0.7",
"@lucide/build-icons": "workspace:*",
"@lucide/rollup-plugins": "workspace:*",
"@lucide/shared": "workspace:*",
"@rollup/plugin-babel": "^6.1.0",
"@rollup/plugin-babel": "^7.1.0",
"@solidjs/testing-library": "next",
"@solidjs/vite-plugin": "next",
"@solidjs/web": "next",
@@ -82,11 +82,11 @@
"babel-preset-solid": "next",
"esbuild": "^0.28.2",
"jest-serializer-html": "^7.1.0",
"rollup": "^4.65.1",
"rollup-plugin-dts": "^6.5.1",
"rollup": "^4.65.0",
"solid-js": "next",
"typescript": "^6.0.3",
"vite": "^8.3.3"
"vite": "^8.3.5"
},
"peerDependencies": {
"solid-js": "^2.0.0-rc.0"
+4 -1
View File
@@ -43,8 +43,11 @@ const configs = bundles
presets: [
'babel-preset-solid',
'@babel/preset-typescript',
['@babel/preset-env', { bugfixes: true, targets: 'last 2 years' }],
['@babel/preset-env', { targets: 'last 2 years' }],
],
// Babel 8's @babel/preset-typescript no longer enables JSX parsing for .tsx files,
// and babel-preset-solid's Babel 7 JSX syntax plugin skips it when TypeScript is enabled.
overrides: [{ test: /\.[jt]sx$/, parserOpts: { plugins: ['jsx'] } }],
}),
...plugins({
pkg,
+1 -1
View File
@@ -76,7 +76,7 @@
"svelte-check": "^4.7.7",
"svelte-preprocess": "^6.0.5",
"typescript": "^6.0.3",
"vite": "^8.3.3"
"vite": "^8.3.5"
},
"peerDependencies": {
"svelte": "^5"
+2 -2
View File
@@ -48,10 +48,10 @@
"@testing-library/vue": "^8.1.0",
"@vitejs/plugin-vue": "^6.0.10",
"@vue/test-utils": "2.5.1",
"rollup": "^4.65.0",
"rollup": "^4.65.1",
"rollup-plugin-dts": "^6.5.1",
"typescript": "^6.0.3",
"vite": "^8.3.3",
"vite": "^8.3.5",
"vue": "^3.5.44"
},
"peerDependencies": {
+2307 -2886
View File
File diff suppressed because it is too large Load Diff
+9 -3
View File
@@ -12,10 +12,16 @@ overrides:
semver: ^7.7.3
vite-prerender-plugin: 0.5.12
webpack-dev-middleware: ^5.3.4
vitest: '5.0.3'
vitest: '5.0.5'
vite: '^8.3.3'
minimatch@>=9.0.0 <9.0.6: ^9.0.6
minimatch@>=9.0.0 <9.0.7: ^9.0.7
zod@<4.6.6: ^4.6.6
brace-expansion@<1.1.21: ^1.1.21
decode-uri-component@<=0.5.0: ^0.5.1
deepmerge@>=4.2.0 <=4.3.1: ^4.3.1
file-type@>=13.0.0 <21.3.1: ^21.3.1
'@jimp/core>file-type': ^16.5.4
glob@>=9.0.0 <=14.0.1: ^14.0.2
hono@>=4.12.4 <4.13.11: ^4.13.11
allowBuilds:
'@parcel/watcher': false
+1 -1
View File
@@ -1,7 +1,7 @@
import path from 'path';
import fs from 'fs';
import { promisify } from 'util';
import simpleGit from 'simple-git';
import { simpleGit } from 'simple-git';
import { type IconMetadata } from '../../tools/build-icons/types.ts';
/**
+3
View File
@@ -5,6 +5,9 @@
"description": "A internal used package with helpers.",
"main": "helpers.ts",
"types": "helpers.ts",
"scripts": {
"test": "vitest run"
},
"author": "",
"license": "ISC",
"type": "module",
@@ -0,0 +1,42 @@
import { describe, expect, it } from 'vitest';
import { toCamelCase } from './toCamelCase.ts';
describe('toCamelCase', () => {
it('converts kebab-case icon names', () => {
expect(toCamelCase('arrow-up')).toBe('arrowUp');
expect(toCamelCase('circle-arrow-out-down-left')).toBe('circleArrowOutDownLeft');
expect(toCamelCase('arrow-up-0-1')).toBe('arrowUp01');
});
it('treats whitespace, hyphens and underscores as separators', () => {
expect(toCamelCase('foo_bar')).toBe('fooBar');
expect(toCamelCase('foo bar')).toBe('fooBar');
expect(toCamelCase('foo\tbar')).toBe('fooBar');
expect(toCamelCase('foo - _\tbar')).toBe('fooBar');
expect(toCamelCase('-foo')).toBe('Foo');
});
it('lowercases only a leading capital letter', () => {
expect(toCamelCase('Foo-bar')).toBe('fooBar');
expect(toCamelCase('FooBar')).toBe('fooBar');
expect(toCamelCase('alreadyCamelCase')).toBe('alreadyCamelCase');
});
it('keeps separators that are not followed by a word character', () => {
expect(toCamelCase('foo-')).toBe('foo-');
expect(toCamelCase('foo__')).toBe('foo__');
expect(toCamelCase('foo\t!')).toBe('foo\t!');
expect(toCamelCase('')).toBe('');
});
it('handles long runs of tabs in linear time', () => {
const input = `a${'\t'.repeat(100_000)}!`;
const start = performance.now();
const result = toCamelCase(input);
const duration = performance.now() - start;
expect(result).toBe(input);
expect(duration).toBeLessThan(100);
});
});
+2 -2
View File
@@ -5,6 +5,6 @@
* @returns {string} A camelized string
*/
export const toCamelCase = (string: string): string =>
string.replace(/^([A-Z])|[\s-_]+(\w)/g, (match, p1, p2) =>
p2 ? p2.toUpperCase() : p1.toLowerCase(),
string.replace(/^([A-Z])|[\s-_]+(\w)?/g, (match, p1, p2) =>
p1 ? p1.toLowerCase() : p2 ? p2.toUpperCase() : match,
);
+1 -1
View File
@@ -11,7 +11,7 @@
"@rollup/plugin-node-resolve": "^16.0.3",
"@rollup/plugin-replace": "^6.0.3",
"esbuild": "^0.28.2",
"rollup": "^4.65.0",
"rollup": "^4.65.1",
"rollup-plugin-esbuild": "^6.2.1",
"rollup-plugin-license": "^3.7.1",
"rollup-plugin-summary": "^3.0.1",