Compare commits

..
Author SHA1 Message Date
Eric Fennis 1e37a6c4ec Add automatic comment for generating missing issue 2026-09-04 10:45:58 +02:00
3ccaafa69b feat(icons): added square-alert Icon (#3687)
* Add square alert icon

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

* Reorder elements in square-alert.svg

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

* Add newline at end of square-alert.json

linting fix

* changed path to line

* Add missing contributors to square-alert.json

* Update square-alert.json

* docs(square-alert): add use cases

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

* fix: review comments

* Update icons/square-exclamation-point.json

* Update square-exclamation-point.json

---------

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

* Update icons/can-soda.svg

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

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

---------

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

* Adjust the property name

* Remove this section

---------

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

* Added icons/virus.json

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


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

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

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

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

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

* fix(icons): changed 'engine' icon

* Apply suggestions from code review

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

* Update engine.svg

* Add contributor 'jamiemlaw' to engine.json

* Apply suggestion from @github-actions[bot]

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

---------

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

* Added icons/credit-card-reader.json

* Updated icons/credit-card-reader.json

* Potential fix for pull request finding

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

* Updated icons/credit-card-reader.svg

* Updated icons/credit-card-reader.json

* Update credit-card-reader.json

---------

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

* Added icons/stairwell.json

* Update icons/stairwell.json

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

* Updated icons/stairwell.svg

* Updated icons/stairwell.json

* Update icons/stairwell.json

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

* Updated icons/door-closed.svg

* Updated icons/door-open.svg

* Update door-closed-locked.svg

* Update door-closed.svg

* Update door-open.svg

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

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

* Update door-stairwell.json

---------

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

* Fix SVG path data for virus-off icon

* renamed virus to germ, implemented feedback

* Refactor SVG paths for consistency and clarity

* Update germ.json

* Update germ-off.json

---------

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

* use case

* Update icons/lighthouse.json

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

* Update icons/lighthouse.json

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

* Update icons/lighthouse.json

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

* icon change

* updated use cases to match guide

* Update lighthouse.json

* Update lighthouse.svg

* Update lighthouse.svg

---------

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


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

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

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

* Added icons/shopping-cart-plus.json

* feat(icons): add shopping-cart variants

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

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

* fix(icons): update shopping-cart variants

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

* Update shopping-cart.json

* Update shopping-cart-minus.svg

* Update shopping-cart-plus.svg

* Update shopping-cart-plus.json

* Update shopping-cart-minus.json

---------

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

* Added icons/shrimp-off.json

* Update icons/shrimp-off.json

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

* Updated icons/shrimp.svg

* Updated icons/shrimp-off.svg

* Apply suggestion from @jguddas

* Potential fix for pull request finding

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

* Update shrimp-off.json

* Potential fix for pull request finding

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

* Update icons/shrimp-off.json

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

* Update shrimp.json

* Update shrimp-off.json

* Update shrimp-off.json

---------

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

* Added icons/bridge.json

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

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

* Apply suggestion from @karsa-mistmere

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

* Add empty use-cases array to bridge.json

* Update bridge.json

---------

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

* cleaned using lucide studio

* added use cases and tags

* Update can.svg

* Update can.json

---------

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

* Update icons/mail-pen.svg

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

* Update mail-pen.svg

* Update mail-pen.json

Added contributors from mail & missing metadata

---------

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

* updated icons/whistle.svg

* updated whistle-icon

* Fix indentation

* Update whistle icon from karsa

* Update whistle.json

* Potential fix for pull request finding

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

* Update whistle.json

---------

Co-authored-by: timmy471 <timilehin.ayantunji@etranzact.com>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
2026-09-01 15:33:00 +02:00
Karsa c5a83d26ff fix(icons): added RWD metadata to monitor, tablet & smartphone icons (#4775) 2026-09-01 09:09:51 +02:00
69 changed files with 5774 additions and 1689 deletions
+55 -1
View File
@@ -15,6 +15,60 @@ The `tags` property is an array of strings that describe the icon and can be use
Validate the tags against the `icon.schema.json` to ensure they are correctly formatted and adhere to the defined structure.
Provide tag suggestions based on the name of the icon and the use cases provided in the PR description. Use the existing tags in the repository as a reference for consistency and to avoid duplicates. Don't suggest words like: 'icon' and preferably use single words. Tags should always be in lowercase, and may also contain spaces (e.g. `magnifying glass`). The name of icon should not be included in the tags, as it is already specified.
# Categories
## Categories
The `categories` property is an array of strings that specify the categories to which the icon belongs, such as "devices", "interface", "media", etc. See the `categories` property in the `icon.schema.json` for more details on the allowed values. The categories should be chosen based on the use cases provided in the PR description and the existing categories in the repository. The categories should be relevant to the icon and should help users find the icon when searching for specific types of icons. The name of icon should not be included in the categories, as it is already specified. Suggest categories based on the name of the icon and the use cases provided in the PR description. Use the existing categories in the repository as a reference for consistency and to avoid duplicates. Categories should always be in lowercase and should not contain spaces.
## Use Cases
The `use-cases` property is an array of strings that describe the specific scenarios in which the icon would be used. Each use case should be concise and clearly convey the context in which the icon is applicable. Use the existing use cases in the repository as a reference for consistency and to avoid duplicates.
### Writing icon use-cases
A use-case tells a reader **where and why an icon would be used in a real interface**. Each entry should let someone who has never seen the icon understand what it's for.
### Format
- Write each use-case as a short phrase, not a sentence. Start with a present participle verb: *Representing…*, *Indicating…*, *Marking…*, *Showing…*, *Confirming…*, *Toggling…*, *Categorizing…*, *Searching…*.
- Keep it to roughly 4–12 words. One clear idea per entry.
- No trailing period. No leading bullet, number, or dash (the surrounding format supplies that).
- Give each icon 1–4 use-cases, ordered most-common first. Prefer fewer strong entries over many weak or repetitive ones.
### Voice
- Write from the interface's perspective, describing the function: "Indicating a low battery charge level" — not the requester's story ("I need an icon that shows…").
- Name the concrete context where useful: *in smart home apps*, *in navigation apps*, *in text editors*, *on maps*. Context is what makes a use-case self-explanatory.
- Be neutral and factual. No first person, no marketing adjectives ("perfect for", "ideal", "beautiful"), no emoji.
### What to exclude
- **The requester's personal narrative.** "I'm building a SvelteKit UI and need…" → drop the framing, keep the function.
- **References to other issues, PRs, or icons by ID.** No "As provided in #1865", "complementary to git-branch-plus", "same as above", "see #2055".
- **Design/implementation chatter.** Bezier offsets, grid alignment, path cuts, "the icon works perfectly" — none of that is a use-case.
- **Restating the icon's name.** For `microchip`, "microchip" is not a use-case; describe what it represents ("Representing processors, chips, or embedded hardware").
- **Links, image tags, emoji, and markdown artifacts.**
- **Meta-commentary.** "Self-explanatory", "lots and lots of use cases", "obvious :)".
### Cross-contamination
When a request covers several icons at once, assign each use-case only to the icon it actually describes. A bullet prefixed with another icon's name belongs to that icon, not this one. Don't let `briefcase-medical`'s meanings leak into `briefcase-business`.
### Variants
Related icons should get **variant-specific** wording, not one shared blurb. `battery-low` → "Indicating a low battery charge level"; `battery-full` → "…full…". `square-arrow-right-enter` → sign in / join; `-exit` → sign out / export. Resist copying the same line across a family.
## Examples
Good:
- `ambulance` → "Directing users to nearby emergency services in navigation apps"
- `calendar-sync` → "Representing recurring events, promotions, or limited-time offers"
- `globe-x` → "Indicating a device or application is offline or unreachable"
- `heading-2` → "Applying a level-2 heading in text editors"
Poor → fixed:
- ~~"I need a firewall icon :-)"~~ → "Representing firewalls and firewall rules on cybersecurity platforms"
- ~~"As above"~~ → "Signifying a deal, agreement, or partnership"
- ~~"microchip"~~ → "Representing processors, chips, or embedded hardware"
- ~~"Same use cases as the other currency symbols, except Turkish lira"~~ → "Displaying prices or amounts in Turkish lira"
+1 -1
View File
@@ -102,7 +102,7 @@ jobs:
echo '${{ steps.change-log.outputs.CHANGE_LOG }}'
- name: Create Release
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
with:
tag_name: ${{ steps.new-version.outputs.NEW_VERSION }}
name: Version ${{ steps.new-version.outputs.NEW_VERSION }}
@@ -0,0 +1,82 @@
name: Pull request missing issue
on:
pull_request_target:
types:
- opened
- edited
- synchronize
- ready_for_review
paths:
- 'icons/*.svg'
permissions: {}
# Two events landing close together (a push right after opening) would
# otherwise both find no existing comment and post one each.
concurrency:
group: missing-issue-${{ github.event.number }}
cancel-in-progress: true
jobs:
pull-request-missing-issue:
name: Pull Request Missing Issue
if: github.repository == 'lucide-icons/lucide' && github.event.pull_request.draft == false
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write # Required to post and update the comment on the pull request
steps:
# We checkout the main branch of main repository for security reasons.
# The script never runs code from the pull request, it only reads the
# pull request's icons through the GitHub API.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: lucide-icons/lucide
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
cache: 'pnpm'
node-version-file: 'package.json'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate comment markup
id: markup
run: node ./scripts/generateMissingIssueComment.mts
env:
PULL_REQUEST_NUMBER: ${{ github.event.number }}
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Find comment
uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0
id: pr-comment
with:
issue-number: ${{ github.event.number }}
comment-author: 'github-actions[bot]'
body-includes: lucide-missing-issue-comment
- name: Post missing issue comment
if: steps.markup.outputs.action == 'nag'
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
with:
comment-id: ${{ steps.pr-comment.outputs.comment-id }}
issue-number: ${{ github.event.number }}
body-path: missing-issue-comment.md
edit-mode: replace
# Linking an issue from the pull request's Development sidebar fires no
# event, so the comment resolves on the next edit or push instead.
- name: Resolve missing issue comment
if: steps.markup.outputs.action == 'resolve' && steps.pr-comment.outputs.comment-id != ''
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
with:
comment-id: ${{ steps.pr-comment.outputs.comment-id }}
issue-number: ${{ github.event.number }}
body: |
<!-- lucide-missing-issue-comment -->
Thanks for linking an issue for this icon design! ✅
edit-mode: replace
+1 -1
View File
@@ -169,7 +169,7 @@ jobs:
zip -r lucide-icons-${{ needs.prepare.outputs.VERSION }}.zip icons
- name: Release zip and fonts
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
with:
tag_name: ${{ needs.prepare.outputs.VERSION }}
+1 -1
View File
@@ -3,7 +3,7 @@
.next
.obsidian
.now
.cache
.idea
.env
node_modules
dist
+1 -1
View File
@@ -68,6 +68,6 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"sandpack-vue3": "3.1.12",
"vue": "^3.5.41"
"vue": "^3.5.42"
}
}
File diff suppressed because one or more lines are too long
+36
View File
@@ -0,0 +1,36 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"Nykoula",
"jamiemlaw"
],
"use-cases": [
"Representing crossing infrastructure in navigation apps",
"Marking river crossings or connecting routes on maps",
"Showing clearance-limited transit zones in maritime dashboards"
],
"tags": [
"overpass",
"cross over",
"traverse",
"viaduct",
"suspension",
"infrastructure",
"transportation",
"crossing",
"road",
"river",
"gate",
"golden",
"travel",
"landmark",
"route",
"maritime",
"clearance"
],
"categories": [
"travel",
"transportation",
"buildings"
]
}
+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="M10 9.728V16" />
<path d="M14 9.728V16" />
<path d="M18 20V4" />
<path d="m22 11-4-4A7.5 7.5 0 0 1 6 7l-4 4" />
<path d="M22 16H2" />
<path d="M6 20V4" />
</svg>

After

Width:  |  Height:  |  Size: 384 B

+25
View File
@@ -0,0 +1,25 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"karsa-mistmere",
"jaynewey"
],
"use-cases": [
"representing canned drinks like soda or beer",
"representing canned foods like soup or legumes",
"representing litter/waste"
],
"tags": [
"beverage",
"drink",
"food",
"soda",
"tin",
"beer",
"alcohol",
"waste"
],
"categories": [
"food-beverage"
]
}
+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="m17 22 1.664-2.496a2 2 0 00.336-1.11V5.606a2 2 0 00-.336-1.11L17 2" />
<path d="M18 22H6" />
<path d="M18 2H6" />
<path d="M5 17h14" />
<path d="M5 7h14" />
<path d="m7 22-1.664-2.496A2 2 0 015 18.394V5.606a2 2 0 01.336-1.11L7 2" />
</svg>

After

Width:  |  Height:  |  Size: 462 B

+28
View File
@@ -0,0 +1,28 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"l0uisgrange",
"karsa-mistmere"
],
"use-cases": [
"Representing canned food in grocery or delivery apps",
"Labelling pantry items or nonperishable inventory",
"Indicating metal recycling or recyclable containers",
"Denoting canned ingredients in recipe or meal-planning interfaces"
],
"tags": [
"food",
"storage",
"groceries",
"tin",
"metal",
"recyclable",
"container",
"pantry",
"grocery",
"preserved"
],
"categories": [
"food-beverage"
]
}
+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="M21 10.5a9 2.5 0 01-18 0v8a9 2.5 0 0018 0z" />
<path d="M21 10.5A9 2.5 25.32 004.59 3.47 9 2.5 25.32 0021 10.5" />
<path d="M3 10.5a9 2.5 0 016.527-2.405" />
<path d="M9 16.858a31 31 0 006 0" />
</svg>

After

Width:  |  Height:  |  Size: 420 B

+38
View File
@@ -0,0 +1,38 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"jguddas",
"karsa-mistmere"
],
"use-cases": [
"Processing card payments at checkout terminals",
"Locating ATMs or payment kiosks on maps",
"Indicating card-present transactions in finance apps",
"Showing contactless or chip card payment options"
],
"tags": [
"bank",
"purchase",
"payment",
"cc",
"atm",
"terminal",
"checkout",
"kiosk",
"pos",
"point of sale",
"transaction",
"contactless",
"chip",
"swipe",
"tap",
"banking",
"finance",
"retail"
],
"categories": [
"finance",
"navigation",
"shopping"
]
}
+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="M15 16v1" />
<path d="M16.963 7.734A1 1 0 0015.999 7H8.003a1 1 0 00-.964.734L4.073 18.467A2 2 0 006 21h12a2 2 0 001.927-2.532z" />
<path d="M2.678 8.5A2 2 0 012 7V5a2 2 0 012-2h16a2 2 0 012 2v2a2 2 0 01-.676 1.499" />
<path d="m9 21 2-14" />
</svg>

After

Width:  |  Height:  |  Size: 467 B

+5 -5
View File
@@ -9,9 +9,9 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M10 12h.01" />
<path d="M18 9V6a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v14" />
<path d="M2 20h8" />
<path d="M20 17v-2a2 2 0 1 0-4 0v2" />
<rect x="14" y="17" width="8" height="5" rx="1" />
<path d="M19 8V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16" />
<path d="M2 21h8" />
<path d="M20 16v-2a2 2 0 00-4 0v2" />
<path d="M9 12h.01" />
<rect x="14" y="16" width="8" height="5" rx="1" />
</svg>

Before

Width:  |  Height:  |  Size: 407 B

After

Width:  |  Height:  |  Size: 403 B

+3 -3
View File
@@ -9,7 +9,7 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M10 12h.01" />
<path d="M18 20V6a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v14" />
<path d="M2 20h20" />
<path d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16" />
<path d="M2 21h20" />
<path d="M9 12h.01" />
</svg>

Before

Width:  |  Height:  |  Size: 315 B

After

Width:  |  Height:  |  Size: 312 B

+4 -4
View File
@@ -9,9 +9,9 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M11 20H2" />
<path d="M11 4.562v16.157a1 1 0 0 0 1.242.97L19 20V5.562a2 2 0 0 0-1.515-1.94l-4-1A2 2 0 0 0 11 4.561z" />
<path d="M11 4H8a2 2 0 0 0-2 2v14" />
<path d="M10 21H2" />
<path d="M10 4a2 2 0 012.36-1.968l5.41.992A1.5 1.5 0 0119 4.5V21l-7.876.992A1 1 0 0110 21z" />
<path d="M10.268 3H7a2 2 0 00-2 2v16" />
<path d="M14 12h.01" />
<path d="M22 20h-3" />
<path d="M22 21h-3" />
</svg>

Before

Width:  |  Height:  |  Size: 432 B

After

Width:  |  Height:  |  Size: 423 B

+40
View File
@@ -0,0 +1,40 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"jguddas",
"karsa-mistmere"
],
"use-cases": [
"Indicating stair access in building navigation",
"Showing floor levels in building directories",
"Marking where an item is located by floor",
"Directing users to take stairs instead of elevators"
],
"tags": [
"staircase",
"stairway",
"stairs",
"steps",
"ladder",
"transition",
"access",
"structure",
"espiral",
"building",
"vertical",
"movement",
"floor",
"level",
"entrance",
"entry",
"exit",
"egress",
"route",
"indoor",
"emergency exit"
],
"categories": [
"home",
"travel"
]
}
+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 17v-3a1 1 0 011-1h6" />
<path d="M19 17h-9a1 1 0 00-1 1v3" />
<path d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16" />
<path d="M19 9h-3a1 1 0 00-1 1v3" />
<path d="M22 21H2" />
</svg>

After

Width:  |  Height:  |  Size: 405 B

+34
View File
@@ -0,0 +1,34 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"benhaube",
"jamiemlaw"
],
"use-cases": [
"Indicating engine health or need of repair",
"Representing the engine category in a parts list",
"Representing automotive repair",
"showing a check engine warning on a dashboard",
"marking scheduled vehicle maintenance",
"filtering vehicle parts in an online catalog",
"labeling automotive diagnostic reports"
],
"tags": [
"vehicle",
"power",
"energy",
"drive",
"repair",
"car",
"motor",
"mechanical",
"diagnostics",
"maintenance",
"warning",
"dashboard",
"parts"
],
"categories": [
"transportation"
]
}
+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="M10 3h6" />
<path d="M13 3v4" />
<path d="M2 10v6" />
<path d="M2 13h4" />
<path d="M6 16a2 2 0 002 2h1a2 2 0 011.6.8l.3.4a2 2 0 001.6.8h2.264a2 2 0 001.789-1.106l1.67-3.341a1 1 0 01.895-.553H21a1 1 0 001-1v-4a1 1 0 00-1-1h-3.5a1 1 0 01-.8-.4l-.9-1.2A1 1 0 0015 7h-4a1 1 0 00-.8.4l-.9 1.2a1 1 0 01-.8.4H7a1 1 0 00-1 1z" />
</svg>

After

Width:  |  Height:  |  Size: 550 B

+49
View File
@@ -0,0 +1,49 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"rrod497",
"karsa-mistmere"
],
"use-cases": [
"Indicating sanitized or disinfected surfaces",
"Marking bacteria-free products or environments",
"Showing infection prevention or contamination control",
"Representing antimicrobial treatment in medical interfaces"
],
"tags": [
"virus",
"microbe",
"bacterium",
"bacteria",
"germ",
"organism",
"cilia",
"pathogen",
"infection",
"disease",
"contagion",
"contamination",
"microbiology",
"health",
"medicine",
"biology",
"science",
"microorganism",
"pandemic",
"epidemic",
"outbreak",
"amoeba",
"flu",
"security",
"single cell",
"unicellular",
"vaccine",
"immunity",
"quarantine"
],
"categories": [
"medical",
"science",
"security"
]
}
+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="m11 2 .925 1.848" />
<path d="M13 15h.01" />
<path d="M13.424 7.768a2 2 0 112.808 2.808" />
<path d="m16 21-1-2.472" />
<path d="M16.988 16.988A12 12 0 019 20a5 5 0 01-2.759-9.171 8.8 8.8 0 002.307-2.28" />
<path d="m19 2-1 1.804" />
<path d="m2 19 2.746-1.373" />
<path d="m2 2 20 20" />
<path d="m22 16-2.474-2.13a12 12 0 001.376-3.786 6 6 0 00-10.313-5.151" />
<path d="m22 5-1.804 1" />
<path d="m3 10 2 2" />
<path d="M9 16h.01" />
<path d="M9 20v2" />
</svg>

After

Width:  |  Height:  |  Size: 701 B

+49
View File
@@ -0,0 +1,49 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"rrod497",
"karsa-mistmere"
],
"use-cases": [
"Representing bacteria or single-celled organisms",
"Indicating contamination or infectious disease",
"Marking microbiology research or laboratory samples",
"Showing microbes in hygiene and sanitation interfaces"
],
"tags": [
"virus",
"microbe",
"bacterium",
"bacteria",
"germ",
"organism",
"cilia",
"pathogen",
"infection",
"disease",
"contagion",
"contamination",
"microbiology",
"health",
"medicine",
"biology",
"science",
"microorganism",
"pandemic",
"epidemic",
"outbreak",
"amoeba",
"flu",
"security",
"single cell",
"unicellular",
"vaccine",
"immunity",
"quarantine"
],
"categories": [
"medical",
"science",
"security"
]
}
+24
View File
@@ -0,0 +1,24 @@
<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 2 .925 1.848" />
<path d="M13 15h.01" />
<path d="m16 21-1-2.472" />
<path d="m19 2-1 1.804" />
<path d="m2 19 2.746-1.373" />
<path d="m22 16-2.474-2.13" />
<path d="m22 5-1.804 1" />
<path d="m3 10 2 2" />
<path d="M9 16h.01" />
<path d="M9 20v2" />
<path d="M9.33 7.035c-.51 1.478-1.786 2.93-3.09 3.794A5 5 0 009 20a12.1 12.1 0 0011.902-9.916A6 6 0 009.33 7.035" />
<circle cx="15" cy="9" r="2" />
</svg>

After

Width:  |  Height:  |  Size: 646 B

+45
View File
@@ -0,0 +1,45 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"xougui",
"karsa-mistmere"
],
"use-cases": [
"Marking coastal landmarks or harbor entrances on maps",
"Indicating navigation beacons in maritime dashboards",
"Flagging maritime safety or beacon maintenance tasks",
"Representing guidance or guiding light in onboarding or help interfaces"
],
"tags": [
"lighthouse",
"beacon",
"coast",
"navigation",
"tower",
"sea",
"ocean",
"maritime",
"guide",
"safety",
"light",
"shine",
"port",
"marine",
"faro",
"signal",
"nautical",
"harbor",
"shore",
"lightbeam",
"wayfinding",
"guidance",
"onboarding",
"help",
"landmark"
],
"categories": [
"buildings",
"navigation",
"travel"
]
}
+24
View File
@@ -0,0 +1,24 @@
<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 3V2" />
<path d="M16.066 16.865 7 22l2-11V6a3 3 0 016 0v5l2 11" />
<path d="m19.792 4.5.866-.5" />
<path d="m19.797 13.5.866.5" />
<path d="M21 9h1" />
<path d="M3 9H2" />
<path d="m4.203 13.5-.866.5" />
<path d="M4.208 4.5 3.342 4" />
<path d="M5.5 22h13" />
<path d="m7.932 16.875 7.377-4.178" />
<path d="M8 11h8" />
<path d="M8 7h8" />
</svg>

After

Width:  |  Height:  |  Size: 585 B

+31
View File
@@ -0,0 +1,31 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"colebemis",
"karsa-mistmere",
"ericfennis",
"jguddas",
"jennieboops"
],
"use-cases": [
"Composing or editing email messages",
"Drafting letters in mail interfaces",
"Editing email addresses on settings pages"
],
"tags": [
"email",
"message",
"letter",
"pen",
"edit",
"compose",
"draft",
"write",
"writing",
"create",
"reply"
],
"categories": [
"mail"
]
}
+15
View File
@@ -0,0 +1,15 @@
<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="M15.506 17.646A2 2 0 0015 18.5l-.837 2.87a.5.5 0 00.62.62l2.87-.837a2 2 0 00.854-.506l3.013-3.009a1 1 0 00-3.004-3.004z" />
<path d="M22 10.346V6a2 2 0 00-2-2H4a2 2 0 00-2 2v12a2 2 0 002 2h6.396" />
<path d="m22 7-8.991 5.727a2 2 0 01-2.009 0L2 7" />
</svg>

After

Width:  |  Height:  |  Size: 474 B

+6
View File
@@ -8,9 +8,15 @@
"use-cases": [],
"tags": [
"tv",
"computer",
"screen",
"display",
"desktop",
"external display",
"screen sharing",
"connected",
"success",
"verified",
"running",
"active",
"virtual machine",
+7 -4
View File
@@ -9,6 +9,12 @@
],
"use-cases": [],
"tags": [
"tv",
"computer",
"screen",
"display",
"desktop",
"external display",
"virtual machine",
"virtual desktop",
"vm",
@@ -20,10 +26,7 @@
"software as a service",
"saas",
"workstation",
"environment",
"tv",
"screen",
"display"
"environment"
],
"categories": [
"connectivity",
+3 -1
View File
@@ -8,13 +8,15 @@
"use-cases": [],
"tags": [
"tv",
"computer",
"screen",
"display",
"desktop",
"external display",
"virtual machine",
"vm",
"executable",
"settings",
"cog",
"edit",
"gear",
"configuration",
+6
View File
@@ -8,9 +8,15 @@
"use-cases": [],
"tags": [
"tv",
"computer",
"screen",
"display",
"desktop",
"external display",
"screen sharing",
"status",
"notification",
"indicator",
"running",
"active",
"virtual machine",
+6 -1
View File
@@ -8,10 +8,15 @@
"use-cases": [],
"tags": [
"tv",
"computer",
"screen",
"display",
"desktop",
"download"
"external display",
"screen sharing",
"download",
"remote",
"cast"
],
"categories": [
"connectivity",
+11 -1
View File
@@ -7,7 +7,17 @@
],
"use-cases": [],
"tags": [
"share"
"tv",
"computer",
"screen",
"display",
"desktop",
"external display",
"screen sharing",
"offline",
"disabled",
"disconnected",
"power"
],
"categories": [
"connectivity",
+4
View File
@@ -8,12 +8,16 @@
"use-cases": [],
"tags": [
"tv",
"computer",
"screen",
"display",
"desktop",
"external display",
"screen sharing",
"video",
"movie",
"film",
"pause",
"suspend",
"hibernate",
"boot",
+4
View File
@@ -8,12 +8,16 @@
"use-cases": [],
"tags": [
"tv",
"computer",
"screen",
"display",
"desktop",
"external display",
"screen sharing",
"video",
"movie",
"film",
"play",
"running",
"start",
"boot",
+12 -4
View File
@@ -6,17 +6,25 @@
"jguddas",
"ericfennis"
],
"use-cases": [],
"use-cases": [
"Showing synchronization between desktop and mobile devices",
"Representing responsive previews across screen sizes",
"Indicating casting or screen sharing to a display"
],
"tags": [
"smartphone",
"phone",
"cellphone",
"device",
"mobile",
"desktop",
"monitor",
"screen",
"display",
"external display",
"screen sharing",
"responsive",
"screens"
"screens",
"sync",
"cast"
],
"categories": [
"connectivity",
+11 -2
View File
@@ -6,9 +6,18 @@
],
"use-cases": [],
"tags": [
"devices",
"tv",
"computer",
"screen",
"display",
"desktop",
"external display",
"connect",
"cast"
"cast",
"audio",
"sound",
"volume",
"presentation"
],
"categories": [
"connectivity",
+3
View File
@@ -8,9 +8,12 @@
"use-cases": [],
"tags": [
"tv",
"computer",
"screen",
"display",
"desktop",
"external display",
"screen sharing",
"video",
"movie",
"film",
+5 -1
View File
@@ -8,12 +8,16 @@
"use-cases": [],
"tags": [
"tv",
"computer",
"screen",
"display",
"desktop",
"external display",
"upload",
"connect",
"remote",
"screen share"
"screen sharing",
"cast"
],
"categories": [
"connectivity",
+6
View File
@@ -8,12 +8,18 @@
"use-cases": [],
"tags": [
"tv",
"computer",
"screen",
"display",
"desktop",
"external display",
"screen sharing",
"virtual machine",
"vm",
"close",
"error",
"failed",
"disconnected",
"stop",
"suspend",
"remove",
+9 -1
View File
@@ -7,11 +7,19 @@
"jguddas",
"karsa-mistmere"
],
"use-cases": [],
"use-cases": [
"Representing desktop displays and computer monitors",
"Showing screen-sharing or external display settings",
"Indicating virtual machines in infrastructure dashboards"
],
"tags": [
"tv",
"computer",
"desktop",
"screen",
"display",
"external display",
"screen sharing",
"virtual machine",
"vm"
],
+35
View File
@@ -0,0 +1,35 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"ajay199210",
"jguddas",
"ericfennis",
"karsa-mistmere"
],
"use-cases": [
"Removing products from a shopping cart",
"Updating order contents in ecommerce apps",
"Indicating fewer items in a purchase"
],
"tags": [
"trolley",
"cart",
"basket",
"e-commerce",
"ecommerce",
"store",
"purchase",
"products",
"items",
"checkout",
"order",
"retail",
"remove",
"decrease",
"quantity",
"subtract"
],
"categories": [
"shopping"
]
}
+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="M16 5h6" />
<path d="m2.05 2.05 1.099-.028a1 1 0 011.008.815l2.69 14.347A1 1 0 007.83 18H18" />
<path d="M4.564 5H12" />
<path d="M6.25 14h12.712a2 2 0 001.991-1.57l.514-3.113" />
<circle cx="18" cy="20" r="2" />
<circle cx="8" cy="20" r="2" />
</svg>

After

Width:  |  Height:  |  Size: 474 B

+35
View File
@@ -0,0 +1,35 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"ajay199210",
"jguddas",
"ericfennis",
"karsa-mistmere"
],
"use-cases": [
"Adding products to a shopping cart",
"Saving products for purchase in ecommerce apps",
"Confirming items were added to an order"
],
"tags": [
"trolley",
"cart",
"basket",
"e-commerce",
"ecommerce",
"store",
"purchase",
"products",
"items",
"checkout",
"order",
"retail",
"add",
"increase",
"quantity",
"buy"
],
"categories": [
"shopping"
]
}
+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="M16 5h6" />
<path d="M19 2v6" />
<path d="m2.05 2.05 1.099-.028a1 1 0 011.008.815l2.69 14.347A1 1 0 007.83 18H18" />
<path d="M4.564 5H12" />
<path d="M6.25 14h12.712a2 2 0 001.991-1.57l.172-1.041" />
<circle cx="18" cy="20" r="2" />
<circle cx="8" cy="20" r="2" />
</svg>

After

Width:  |  Height:  |  Size: 497 B

+36
View File
@@ -0,0 +1,36 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"karsa-mistmere",
"jguddas"
],
"use-cases": [
"Indicating shellfish allergen information",
"Marking seafood-free items on a menu"
],
"tags": [
"marine",
"creature",
"fisherman",
"ocean",
"fresh",
"cuisine",
"marine-life",
"seafood",
"shellfish",
"crustacean",
"prawn",
"scallop",
"whelk",
"arthropod",
"littleneck",
"quahog",
"allergy",
"intolerance",
"diet"
],
"categories": [
"animals",
"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="M10 2a3.28 3.28 0 003.227 1.798l6.17-.561A1 1 0 1119.614 8H13.5" />
<path d="M11 20c-.5.5-1.12 1-2.5 1a1 1 0 010-5H12a7 7 0 003.283-.817" />
<path d="M11 22c-.5-.5-1.12-1-2.5-1a6.5 6.5 0 01-5.63-3.25 6.44 6.44 0 015.236-9.744" />
<path d="M18.04 12.54A7 7 0 0019 9V8" />
<path d="m2 2 20 20" />
<path d="M8 16c-2 0-4.5-4-4-6" />
<path d="M9.43 9.33A8.5 8.5 0 0010 16" />
</svg>

After

Width:  |  Height:  |  Size: 602 B

+9 -2
View File
@@ -14,9 +14,16 @@
"arthropod",
"littleneck",
"quahog",
"cherrystone"
"marine",
"creature",
"fisherman",
"ocean",
"fresh",
"cuisine",
"marine-life"
],
"categories": [
"animals"
"animals",
"food-beverage"
]
}
+5 -5
View File
@@ -9,9 +9,9 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M11 12h.01" />
<path d="M13 22c.5-.5 1.12-1 2.5-1-1.38 0-2-.5-2.5-1" />
<path d="M14 2a3.28 3.28 0 0 1-3.227 1.798l-6.17-.561A2.387 2.387 0 1 0 4.387 8H15.5a1 1 0 0 1 0 13 1 1 0 0 0 0-5H12a7 7 0 0 1-7-7V8" />
<path d="M14 8a8.5 8.5 0 0 1 0 8" />
<path d="M16 16c2 0 4.5-4 4-6" />
<path d="M10 2a3.28 3.28 0 003.227 1.798l6.17-.561A1 1 0 1119.614 8H8.5a6.44 6.44 0 00-5.63 9.75A6.5 6.5 0 008.5 21c1.38 0 2-.5 2.5-1" />
<path d="M10 8a8.5 8.5 0 000 8" />
<path d="M11 22c-.5-.5-1.12-1-2.5-1a1 1 0 010-5H12a7 7 0 007-7V8" />
<path d="M13 12h.01" />
<path d="M8 16c-2 0-4.5-4-4-6" />
</svg>

Before

Width:  |  Height:  |  Size: 507 B

After

Width:  |  Height:  |  Size: 518 B

+11 -2
View File
@@ -5,12 +5,21 @@
"mittalyashu",
"ericfennis"
],
"use-cases": [],
"use-cases": [
"Representing mobile phones in device settings",
"Showing mobile access or app availability",
"Indicating phone-based communication channels"
],
"tags": [
"phone",
"cellphone",
"device",
"screen"
"mobile",
"screen",
"display",
"touchscreen",
"portable",
"responsive"
],
"categories": [
"connectivity",
+31
View File
@@ -0,0 +1,31 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"viralcodex",
"colebemis",
"ericfennis"
],
"use-cases": [
"Indicating application or system warnings or alerts",
"Highlighting important notifications that require user attention",
"Representing caution states for different components or elements",
"Marking validation errors, invalid input or configuration issues",
"Displaying diagnostic or troubleshooting information"
],
"tags": [
"warning",
"alert",
"danger",
"exclamation mark",
"rectangle",
"square",
"notification",
"attention",
"important",
"caution"
],
"categories": [
"notifications",
"shapes"
]
}
+15
View File
@@ -0,0 +1,15 @@
<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"
>
<rect width="18" height="18" x="3" y="3" rx="2" />
<line x1="12" x2="12" y1="8" y2="12" />
<line x1="12" x2="12.01" y1="16" y2="16" />
</svg>

After

Width:  |  Height:  |  Size: 349 B

+14 -3
View File
@@ -3,13 +3,24 @@
"contributors": [
"danielbayley"
],
"use-cases": [],
"use-cases": [
"Previewing layouts across mobile device sizes",
"Testing responsive behavior on handheld screens",
"Representing mobile-first design workflows"
],
"tags": [
"phone",
"cellphone",
"device",
"mobile",
"screen",
"display",
"touchscreen",
"portable",
"responsive",
"screens",
"browser",
"testing",
"mobile"
"testing"
],
"categories": [
"devices",
+11 -2
View File
@@ -4,9 +4,18 @@
"colebemis",
"ericfennis"
],
"use-cases": [],
"use-cases": [
"Representing tablet devices in responsive layouts",
"Showing touch-based interfaces on larger mobile screens"
],
"tags": [
"device"
"device",
"mobile",
"screen",
"display",
"touchscreen",
"portable",
"responsive"
],
"categories": [
"devices"
+45
View File
@@ -0,0 +1,45 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"karsa-mistmere"
],
"use-cases": [
"Indicating no malware threats in security tools",
"Showing cleared infections in healthcare apps",
"Marking reduced infection risk in health dashboards",
"Representing blocked pathogens in science content"
],
"tags": [
"pathogen",
"infection",
"disease",
"illness",
"contagion",
"outbreak",
"pandemic",
"epidemic",
"covid",
"coronavirus",
"germ",
"microbe",
"microorganism",
"biology",
"medical",
"healthcare",
"malware",
"cybersecurity",
"threat",
"antivirus",
"blocked",
"removed",
"clean",
"safe",
"prevention",
"quarantine"
],
"categories": [
"medical",
"science",
"security"
]
}
+32
View File
@@ -0,0 +1,32 @@
<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="M10.01 10h.01" />
<path d="M12 14.991h.01" />
<path d="M12 22v-3" />
<path d="M12 2v3" />
<path d="M13 22h-2" />
<path d="M13 2h-2" />
<path d="m16.5 19.794-1-1.733" />
<path d="m16.5 4.205-1 1.732" />
<path d="M18.891 13.235a7 7 0 00-8.126-8.126" />
<path d="m19.794 7.5-1.732 1" />
<path d="M2 12h3" />
<path d="M2 13v-2" />
<path d="m2 2 20 20" />
<path d="M22 12h-3" />
<path d="M22 13v-2" />
<path d="m4.206 16.5 1.732-1" />
<path d="m4.206 7.5 1.732 1" />
<path d="M7.05 7.05a7 7 0 009.9 9.9" />
<path d="m7.5 19.794 1-1.733" />
<path d="M9 12h.01" />
</svg>

After

Width:  |  Height:  |  Size: 815 B

+38
View File
@@ -0,0 +1,38 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"karsa-mistmere"
],
"use-cases": [
"Representing viral infections in healthcare apps",
"Indicating malware threats in security tools",
"Showing disease outbreaks in public health dashboards",
"Labeling pathogens in biology or science content"
],
"tags": [
"pathogen",
"infection",
"disease",
"illness",
"contagion",
"outbreak",
"pandemic",
"epidemic",
"covid",
"coronavirus",
"germ",
"microbe",
"microorganism",
"biology",
"medical",
"healthcare",
"malware",
"cybersecurity",
"threat"
],
"categories": [
"medical",
"science",
"security"
]
}
+32
View File
@@ -0,0 +1,32 @@
<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.991h.01" />
<path d="M12 22v-3" />
<path d="M12 2v3" />
<path d="M13 22h-2" />
<path d="M13 2h-2" />
<path d="M13.99 10H14" />
<path d="m16.5 19.794-1-1.733" />
<path d="m16.5 4.205-1 1.732" />
<path d="m19.794 16.5-1.732-1" />
<path d="m19.794 7.5-1.732 1" />
<path d="M2 12h3" />
<path d="M2 13v-2" />
<path d="M22 12h-3" />
<path d="M22 13v-2" />
<path d="m4.206 16.5 1.732-1" />
<path d="m4.206 7.5 1.732 1" />
<path d="m7.5 19.794 1-1.733" />
<path d="m7.5 4.205 1 1.732" />
<path d="M9 12h.01" />
<circle cx="12" cy="12" r="7" />
</svg>

After

Width:  |  Height:  |  Size: 800 B

+41
View File
@@ -0,0 +1,41 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"briz123",
"UsamaKhan",
"ajokt123",
"timmy471",
"jguddas",
"karsa-mistmere"
],
"use-cases": [
"Representing coaches or referees in sports apps",
"Signaling alerts in training interfaces",
"Indicating traffic control or public safety roles",
"Marking lifeguard equipment in safety systems"
],
"tags": [
"alert",
"signal",
"sound",
"blow",
"noise",
"coach",
"trainer",
"referee",
"gym",
"game",
"training",
"sports",
"traffic cops",
"police",
"lifeguard",
"safety",
"rescue",
"emergency"
],
"categories": [
"sports",
"notifications"
]
}
+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="M10 6v4" />
<path d="M21 6a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-5.675A7 7 0 1 1 9 6z" />
</svg>

After

Width:  |  Height:  |  Size: 304 B

+1 -1
View File
@@ -26,8 +26,8 @@
"generate:sponsors": "node scripts/updateSponsors.mts",
"generate:contributors": "node ./scripts/updateContributors.mts icons/*.svg",
"generate:nextJSAliases": "node ./scripts/generateNextJSAliases.mts",
"icon-usage": "node ./scripts/iconUsage.mts",
"suggest:metadata": "node ./scripts/suggestMetaData.mts",
"check:missing-issue": "node ./scripts/generateMissingIssueComment.mts",
"suggest:metadata:watch": "node --env-file .env --watch ./scripts/suggestMetaData.mts",
"postinstall": "husky install",
"lint:es": "eslint .",
+2 -2
View File
@@ -47,12 +47,12 @@
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/vue": "^8.1.0",
"@vitejs/plugin-vue": "^6.0.8",
"@vue/test-utils": "2.4.11",
"@vue/test-utils": "2.5.0",
"rollup": "^4.62.2",
"rollup-plugin-dts": "^6.4.1",
"typescript": "^5.9.3",
"vite": "^7.3.6",
"vue": "^3.5.41"
"vue": "^3.5.42"
},
"peerDependencies": {
"vue": ">=3.0.1"
+151 -157
View File
@@ -130,22 +130,22 @@ importers:
dependencies:
'@floating-ui/vue':
specifier: ^1.1.11
version: 1.1.11(vue@3.5.41(typescript@6.0.3))
version: 1.1.11(vue@3.5.42(typescript@6.0.3))
'@headlessui/vue':
specifier: ^1.7.23
version: 1.7.23(vue@3.5.41(typescript@6.0.3))
version: 1.7.23(vue@3.5.42(typescript@6.0.3))
'@lucide/vue':
specifier: workspace:*
version: link:../packages/vue
'@vueuse/components':
specifier: ^14.3.0
version: 14.3.0(vue@3.5.41(typescript@6.0.3))
version: 14.3.0(vue@3.5.42(typescript@6.0.3))
'@vueuse/core':
specifier: ^14.3.0
version: 14.3.0(vue@3.5.41(typescript@6.0.3))
version: 14.3.0(vue@3.5.42(typescript@6.0.3))
'@vueuse/integrations':
specifier: ^14.3.0
version: 14.3.0(focus-trap@7.8.0)(fuse.js@7.5.0)(vue@3.5.41(typescript@6.0.3))
version: 14.3.0(focus-trap@7.8.0)(fuse.js@7.5.0)(vue@3.5.42(typescript@6.0.3))
element-to-path:
specifier: ^1.2.1
version: 1.2.1
@@ -166,7 +166,7 @@ importers:
version: link:../packages/lucide-react
motion-v:
specifier: 1.10.3
version: 1.10.3(@vueuse/core@14.3.0(vue@3.5.41(typescript@6.0.3)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(vue@3.5.41(typescript@6.0.3))
version: 1.10.3(@vueuse/core@14.3.0(vue@3.5.42(typescript@6.0.3)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(vue@3.5.42(typescript@6.0.3))
react:
specifier: 18.2.0
version: 18.2.0
@@ -175,10 +175,10 @@ importers:
version: 18.2.0(react@18.2.0)
sandpack-vue3:
specifier: 3.1.12
version: 3.1.12(vue@3.5.41(typescript@6.0.3))
version: 3.1.12(vue@3.5.42(typescript@6.0.3))
vue:
specifier: ^3.5.41
version: 3.5.41(typescript@6.0.3)
specifier: ^3.5.42
version: 3.5.42(typescript@6.0.3)
devDependencies:
'@lucide/build-icons':
specifier: workspace:*
@@ -738,13 +738,13 @@ importers:
version: 6.9.1
'@testing-library/vue':
specifier: ^8.1.0
version: 8.1.0(@vue/compiler-dom@3.5.41)(@vue/compiler-sfc@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@5.9.3))
version: 8.1.0(@vue/compiler-dom@3.5.42)(@vue/compiler-sfc@3.5.42)(@vue/server-renderer@3.5.42)(vue@3.5.42(typescript@5.9.3))
'@vitejs/plugin-vue':
specifier: ^6.0.8
version: 6.0.8(vite@7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))
version: 6.0.8(vite@7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0))(vue@3.5.42(typescript@5.9.3))
'@vue/test-utils':
specifier: 2.4.11
version: 2.4.11(@vue/compiler-dom@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@5.9.3))
specifier: 2.5.0
version: 2.5.0(@vue/compiler-dom@3.5.42)(@vue/server-renderer@3.5.42)(vue@3.5.42(typescript@5.9.3))
rollup:
specifier: ^4.62.2
version: 4.62.2
@@ -758,8 +758,8 @@ importers:
specifier: ^7.3.6
version: 7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0)
vue:
specifier: ^3.5.41
version: 3.5.41(typescript@5.9.3)
specifier: ^3.5.42
version: 3.5.42(typescript@5.9.3)
tools/build-font:
dependencies:
@@ -3836,8 +3836,8 @@ packages:
'@octokit/types@9.3.2':
resolution: {integrity: sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==}
'@one-ini/wasm@0.1.1':
resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
'@one-ini/wasm@0.2.1':
resolution: {integrity: sha512-TUqERXGNTifZ9y2g3wPxQrw3HpHv/02DsW3D90T9x0hhonrL1ZqpSmNrU2XkoIq0fP1N6gZfVQzy2Fw1ZvGBNg==}
'@open-draft/deferred-promise@2.2.0':
resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==}
@@ -5283,17 +5283,17 @@ packages:
'@vscode/l10n@0.0.18':
resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==}
'@vue/compiler-core@3.5.41':
resolution: {integrity: sha512-q0Xtv/F9w2YO/7htQhtiL+Ev2WCJbe5N2hc+XfgyKkEKqWpSxknmT8QOuGdEKNdjPq0c3F7rNpFkTo3Kfrm7pg==}
'@vue/compiler-core@3.5.42':
resolution: {integrity: sha512-2Ye1ilMtKXxl8qZUrQ5j0CdgenFp/HFQmta6rfRyfEsTG69L6Wk+tWuNoHYHMx9E8tF2Slvdg1FuwDvAXdy1LQ==}
'@vue/compiler-dom@3.5.41':
resolution: {integrity: sha512-oKacVfNglLvGjnS6BXOlGL7EyG2h8X03pqXCjzotRZUaXGjbrTJUnVAQjrCqUnS+lyu31nwQjZY/d817GmCnfw==}
'@vue/compiler-dom@3.5.42':
resolution: {integrity: sha512-qbhQZEFmycr+ni/qyuccS4sucNN7VAbDfbkvNxWOX2VfgFm90MNs3/UhRNKoPMEIVn0F8gdlYjLPvqxHwHeQOA==}
'@vue/compiler-sfc@3.5.41':
resolution: {integrity: sha512-XJhip7R2wy6vX3knCxdZN4KracFaZUef58s1KYewqluedHIJaPIVfXoYT7MF1F8nCvv6k8bWWxDC8opMkg1VTQ==}
'@vue/compiler-sfc@3.5.42':
resolution: {integrity: sha512-fkCAFB4okcAANGMThboWnScp/gzWjU0ZSkVnjTIiplmMDq2uq0tIB3j+xVu4rhv5rvOgBySCysudmbMd6xRRqw==}
'@vue/compiler-ssr@3.5.41':
resolution: {integrity: sha512-U3v5OejKEGqOI0Wy0+Sz7hGuIFZHA4LSXzrNM3IMIeDyJEBBfTpX26n3SDgToRpP2bLc9FfI2j/kSgcJ8Emq5A==}
'@vue/compiler-ssr@3.5.42':
resolution: {integrity: sha512-xmLk3wLkbizPAiLyomjgFFosf2ys9b5Ghb+oh/k2tnvipNz8OFrQOiTcWCzyK7MpBp9KkyGtfvgfLUivbmuGYA==}
'@vue/devtools-api@7.7.10':
resolution: {integrity: sha512-KxtEpUOOpFz/qOGRrAwA36QF7DqIA+FXgCYit9mk9wjbaZt0sXOFz81ElOZtKA4HbWHUdwNjZHBFsFFyp5BZiA==}
@@ -5304,26 +5304,26 @@ packages:
'@vue/devtools-shared@7.7.10':
resolution: {integrity: sha512-wOPslzB8vTvpxwdaOcR2qAbwmuSP0L+rhpoC6Cf56V3Jip+HWb7PQQXOUPgBNQARpXsbQX/+mvi8kKucmBGRwQ==}
'@vue/reactivity@3.5.41':
resolution: {integrity: sha512-rznsqKM0np0x18EjzF8x88MpEhdNsffbvFbckLL5+oUKz1BxAImEmO7J1ArRYSyo6aQaVoBDp7jEkT91OOxydA==}
'@vue/reactivity@3.5.42':
resolution: {integrity: sha512-TzNNfKpb7hDxbQltwAut8VDQA5YP+BuRlxntHUuRjyKwlMvmAPbs3unhCvieijifY6vFfVBwsS7wG/C7uq+bEQ==}
'@vue/runtime-core@3.5.41':
resolution: {integrity: sha512-Vcry58hiAKwGen9Z1jUZE0feFsNArPCMOImYI8el48A9Idf6DuQYD0U05zZIF2Iad1hGhPSvcbBbAOhNr55fhg==}
'@vue/runtime-core@3.5.42':
resolution: {integrity: sha512-9uACtuHs7vJGkm5Bp3xu4xRDLFTIYy5DgxpToVjqGIAhAEKwQfsaLvKINhM6nFVp6bZPRFGdDqd1g52MqKsotA==}
'@vue/runtime-dom@3.5.41':
resolution: {integrity: sha512-3vVBahVBS9+U6cmXBLyb8nE6/yYo4J/CGI9eVFs3KiMc0YHuudwKyShTD65jtJy/L9PUUxNAFu4cj4LiJ0UFbw==}
'@vue/runtime-dom@3.5.42':
resolution: {integrity: sha512-rsCmhiWLaRxGltLwhlCWyYkFn7WAbKRh0q17eZ1A6Dq6eqc2ACQ61IIryxz0LrsvCzHSilLA9JHovVwM8CNE2g==}
'@vue/server-renderer@3.5.41':
resolution: {integrity: sha512-n6hx/pNFfbD6SuyeuMVkvqox8bwf/ET9JlA/kAz/imw8sw++wkqKe2mHX5KutjPpbKE4Z56yTHszoOjGMI9igQ==}
'@vue/server-renderer@3.5.42':
resolution: {integrity: sha512-2++5dUyYS4gvo7xQXSECUDhB7TS0aOl5SeVfC5qSq1Jgfhjvegw1zqhwTIR3imZ+QYPJQw9gfcFvXGAjGZ7ajQ==}
'@vue/shared@3.5.39':
resolution: {integrity: sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==}
'@vue/shared@3.5.41':
resolution: {integrity: sha512-IOnwSCma8j+9xJT6b8H0dEYidC80NsYmNMlZxRsukYcSoGaDBohog5hDxzeUXdFeGWFA++vWvxqOmrr96VlqMA==}
'@vue/shared@3.5.42':
resolution: {integrity: sha512-2rPxex1jQf4jvl9MOHl6YaXCPcrNqz/FstMOEh3QWY+/OME9nQTvl9WYeCwhW7AFjaR0SnngZGlp/wkR6rkI6g==}
'@vue/test-utils@2.4.11':
resolution: {integrity: sha512-GDqaqZsA6m2E5vNzej0aYiIb6BX8xV9pNSbbbXKOfEYwg7ZNblVX8suyqmUBThq8VIrgAJNxn+z72hVtUeiWHA==}
'@vue/test-utils@2.5.0':
resolution: {integrity: sha512-6Clu5EKR/r6cDPYrKsu+8wenciWJJ3rhS9OEGsfDlZeZIhlJeEPGIZQHxE4lHRJCzPSq3EWMsFxQUqCvrbHQuQ==}
peerDependencies:
'@vue/compiler-dom': 3.x
'@vue/server-renderer': 3.x
@@ -5453,10 +5453,6 @@ packages:
a-sync-waterfall@1.0.1:
resolution: {integrity: sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==}
abbrev@2.0.0:
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
abbrev@3.0.1:
resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==}
engines: {node: ^18.17.0 || >=20.5.0}
@@ -5465,6 +5461,10 @@ packages:
resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==}
engines: {node: ^20.17.0 || >=22.9.0}
abbrev@5.0.0:
resolution: {integrity: sha512-/XrFJgzQQQHpti1raDJC6m4ws6aNktmjBlhk8Fdlk7LwCEuDoieEJJY9OFHjfiFJFFRM2tK+Ky/IsfbbmlMu1w==}
engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0}
abort-controller@3.0.0:
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
engines: {node: '>=6.5'}
@@ -6153,10 +6153,6 @@ packages:
comma-separated-tokens@2.0.3:
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
commander@10.0.1:
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
engines: {node: '>=14'}
commander@11.1.0:
resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
engines: {node: '>=16'}
@@ -6680,9 +6676,9 @@ packages:
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
editorconfig@1.0.7:
resolution: {integrity: sha512-e0GOtq/aTQhVdNyDU9e02+wz9oDDM+SIOQxWME2QRjzRX5yyLAuHDE+0aE8vHb9XRC8XD37eO2u57+F09JqFhw==}
engines: {node: '>=14'}
editorconfig@3.0.2:
resolution: {integrity: sha512-T0ix8GhtxyKVfUFEcvdNDt3YGqlwkFHbD4/5bgFUDgFmxhI/cSRAeJ87/Sz//Cq8Eam6JX/e23RkoFO71P7aAA==}
engines: {node: '>=20'}
hasBin: true
ee-first@1.1.1:
@@ -7978,8 +7974,8 @@ packages:
jpeg-js@0.4.4:
resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==}
js-beautify@1.15.4:
resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==}
js-beautify@2.0.3:
resolution: {integrity: sha512-cyFbh3tkPhknnTD/0bLf0T0yy2ZIbqL05mttzbt4y1Zfr7NxqXQZ62dkBLKs3oHH/lpjmDRAnciJiSUyOy8XwQ==}
engines: {node: '>=14'}
hasBin: true
@@ -8774,9 +8770,9 @@ packages:
resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==}
engines: {node: '>=18'}
nopt@7.2.1:
resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
nopt@10.0.1:
resolution: {integrity: sha512-df3sBr/6ax9hSGuC3CspvLlbnX8cP5L5nZwXF8cGN8l0zSWR6BvzmQ6jPUKjvo6+/xdpkNvEcucBNUdBeeV13g==}
engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0}
hasBin: true
nopt@8.1.0:
@@ -10973,8 +10969,8 @@ packages:
'@vue/composition-api':
optional: true
vue@3.5.41:
resolution: {integrity: sha512-2laE0p+aK+/AOPG/XL/WepOs/GlK755LJ1XECi9kDUrz1FKNw8rb2Xzlw9JS1rqEV55nb0ttsKxVlTCcd+R5cg==}
vue@3.5.42:
resolution: {integrity: sha512-4RyHQTbQvOPs3MfvUO1Sg0YRrKNnA0mAVtvpd12Tg1fKDN7OHBUl1IqSn8zGJjK9nI3NkNp8cgTpVrSZC5TTcA==}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
@@ -13548,11 +13544,11 @@ snapshots:
'@floating-ui/utils@0.2.12': {}
'@floating-ui/vue@1.1.11(vue@3.5.41(typescript@6.0.3))':
'@floating-ui/vue@1.1.11(vue@3.5.42(typescript@6.0.3))':
dependencies:
'@floating-ui/dom': 1.8.0
'@floating-ui/utils': 0.2.12
vue-demi: 0.14.10(vue@3.5.41(typescript@6.0.3))
vue-demi: 0.14.10(vue@3.5.42(typescript@6.0.3))
transitivePeerDependencies:
- '@vue/composition-api'
- vue
@@ -13562,10 +13558,10 @@ snapshots:
'@harperfast/extended-iterable@1.0.3':
optional: true
'@headlessui/vue@1.7.23(vue@3.5.41(typescript@6.0.3))':
'@headlessui/vue@1.7.23(vue@3.5.42(typescript@6.0.3))':
dependencies:
'@tanstack/vue-virtual': 3.13.32(vue@3.5.41(typescript@6.0.3))
vue: 3.5.41(typescript@6.0.3)
'@tanstack/vue-virtual': 3.13.32(vue@3.5.42(typescript@6.0.3))
vue: 3.5.42(typescript@6.0.3)
'@hono/node-server@1.19.14(hono@4.12.30)':
dependencies:
@@ -14625,7 +14621,7 @@ snapshots:
dependencies:
'@octokit/openapi-types': 18.1.1
'@one-ini/wasm@0.1.1': {}
'@one-ini/wasm@0.2.1': {}
'@open-draft/deferred-promise@2.2.0': {}
@@ -15434,10 +15430,10 @@ snapshots:
'@tanstack/virtual-core@3.17.4': {}
'@tanstack/vue-virtual@3.13.32(vue@3.5.41(typescript@6.0.3))':
'@tanstack/vue-virtual@3.13.32(vue@3.5.42(typescript@6.0.3))':
dependencies:
'@tanstack/virtual-core': 3.17.4
vue: 3.5.41(typescript@6.0.3)
vue: 3.5.42(typescript@6.0.3)
'@testing-library/dom@10.4.1':
dependencies:
@@ -15519,14 +15515,14 @@ snapshots:
vite: 7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0)
vitest: 4.1.10(@types/node@26.1.1)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(jsdom@27.4.0(supports-color@10.2.2))(vite@7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0))
'@testing-library/vue@8.1.0(@vue/compiler-dom@3.5.41)(@vue/compiler-sfc@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@5.9.3))':
'@testing-library/vue@8.1.0(@vue/compiler-dom@3.5.42)(@vue/compiler-sfc@3.5.42)(@vue/server-renderer@3.5.42)(vue@3.5.42(typescript@5.9.3))':
dependencies:
'@babel/runtime': 7.29.7
'@testing-library/dom': 9.3.4
'@vue/test-utils': 2.4.11(@vue/compiler-dom@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@5.9.3))
vue: 3.5.41(typescript@5.9.3)
'@vue/test-utils': 2.5.0(@vue/compiler-dom@3.5.42)(@vue/server-renderer@3.5.42)(vue@3.5.42(typescript@5.9.3))
vue: 3.5.42(typescript@5.9.3)
optionalDependencies:
'@vue/compiler-sfc': 3.5.41
'@vue/compiler-sfc': 3.5.42
transitivePeerDependencies:
- '@vue/compiler-dom'
- '@vue/server-renderer'
@@ -16073,16 +16069,16 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@vitejs/plugin-vue@5.2.4(vite@7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3))':
'@vitejs/plugin-vue@5.2.4(vite@7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0))(vue@3.5.42(typescript@6.0.3))':
dependencies:
vite: 7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0)
vue: 3.5.41(typescript@6.0.3)
vue: 3.5.42(typescript@6.0.3)
'@vitejs/plugin-vue@6.0.8(vite@7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))':
'@vitejs/plugin-vue@6.0.8(vite@7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0))(vue@3.5.42(typescript@5.9.3))':
dependencies:
'@rolldown/pluginutils': 1.0.1
vite: 7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0)
vue: 3.5.41(typescript@5.9.3)
vue: 3.5.42(typescript@5.9.3)
'@vitest/browser-playwright@4.1.10(playwright@1.58.2)(vite@7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0))(vitest@4.1.10)':
dependencies:
@@ -16238,35 +16234,35 @@ snapshots:
'@vscode/l10n@0.0.18': {}
'@vue/compiler-core@3.5.41':
'@vue/compiler-core@3.5.42':
dependencies:
'@babel/parser': 7.29.8
'@vue/shared': 3.5.41
'@vue/shared': 3.5.42
entities: 7.0.1
estree-walker: 2.0.2
source-map-js: 1.2.1
'@vue/compiler-dom@3.5.41':
'@vue/compiler-dom@3.5.42':
dependencies:
'@vue/compiler-core': 3.5.41
'@vue/shared': 3.5.41
'@vue/compiler-core': 3.5.42
'@vue/shared': 3.5.42
'@vue/compiler-sfc@3.5.41':
'@vue/compiler-sfc@3.5.42':
dependencies:
'@babel/parser': 7.29.8
'@vue/compiler-core': 3.5.41
'@vue/compiler-dom': 3.5.41
'@vue/compiler-ssr': 3.5.41
'@vue/shared': 3.5.41
'@vue/compiler-core': 3.5.42
'@vue/compiler-dom': 3.5.42
'@vue/compiler-ssr': 3.5.42
'@vue/shared': 3.5.42
estree-walker: 2.0.2
magic-string: 0.30.21
postcss: 8.5.19
source-map-js: 1.2.1
'@vue/compiler-ssr@3.5.41':
'@vue/compiler-ssr@3.5.42':
dependencies:
'@vue/compiler-dom': 3.5.41
'@vue/shared': 3.5.41
'@vue/compiler-dom': 3.5.42
'@vue/shared': 3.5.42
'@vue/devtools-api@7.7.10':
dependencies:
@@ -16286,79 +16282,79 @@ snapshots:
dependencies:
rfdc: 1.4.1
'@vue/reactivity@3.5.41':
'@vue/reactivity@3.5.42':
dependencies:
'@vue/shared': 3.5.41
'@vue/shared': 3.5.42
'@vue/runtime-core@3.5.41':
'@vue/runtime-core@3.5.42':
dependencies:
'@vue/reactivity': 3.5.41
'@vue/shared': 3.5.41
'@vue/reactivity': 3.5.42
'@vue/shared': 3.5.42
'@vue/runtime-dom@3.5.41':
'@vue/runtime-dom@3.5.42':
dependencies:
'@vue/reactivity': 3.5.41
'@vue/runtime-core': 3.5.41
'@vue/shared': 3.5.41
'@vue/reactivity': 3.5.42
'@vue/runtime-core': 3.5.42
'@vue/shared': 3.5.42
csstype: 3.2.3
'@vue/server-renderer@3.5.41':
'@vue/server-renderer@3.5.42':
dependencies:
'@vue/compiler-ssr': 3.5.41
'@vue/runtime-dom': 3.5.41
'@vue/shared': 3.5.41
'@vue/compiler-ssr': 3.5.42
'@vue/runtime-dom': 3.5.42
'@vue/shared': 3.5.42
'@vue/shared@3.5.39': {}
'@vue/shared@3.5.41': {}
'@vue/shared@3.5.42': {}
'@vue/test-utils@2.4.11(@vue/compiler-dom@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@5.9.3))':
'@vue/test-utils@2.5.0(@vue/compiler-dom@3.5.42)(@vue/server-renderer@3.5.42)(vue@3.5.42(typescript@5.9.3))':
dependencies:
'@vue/compiler-dom': 3.5.41
js-beautify: 1.15.4
vue: 3.5.41(typescript@5.9.3)
'@vue/compiler-dom': 3.5.42
js-beautify: 2.0.3
vue: 3.5.42(typescript@5.9.3)
vue-component-type-helpers: 3.3.9
optionalDependencies:
'@vue/server-renderer': 3.5.41
'@vue/server-renderer': 3.5.42
'@vueuse/components@14.3.0(vue@3.5.41(typescript@6.0.3))':
'@vueuse/components@14.3.0(vue@3.5.42(typescript@6.0.3))':
dependencies:
'@vueuse/core': 14.3.0(vue@3.5.41(typescript@6.0.3))
'@vueuse/shared': 14.3.0(vue@3.5.41(typescript@6.0.3))
vue: 3.5.41(typescript@6.0.3)
'@vueuse/core': 14.3.0(vue@3.5.42(typescript@6.0.3))
'@vueuse/shared': 14.3.0(vue@3.5.42(typescript@6.0.3))
vue: 3.5.42(typescript@6.0.3)
'@vueuse/core@12.8.2(typescript@6.0.3)':
dependencies:
'@types/web-bluetooth': 0.0.21
'@vueuse/metadata': 12.8.2
'@vueuse/shared': 12.8.2(typescript@6.0.3)
vue: 3.5.41(typescript@6.0.3)
vue: 3.5.42(typescript@6.0.3)
transitivePeerDependencies:
- typescript
'@vueuse/core@14.3.0(vue@3.5.41(typescript@6.0.3))':
'@vueuse/core@14.3.0(vue@3.5.42(typescript@6.0.3))':
dependencies:
'@types/web-bluetooth': 0.0.21
'@vueuse/metadata': 14.3.0
'@vueuse/shared': 14.3.0(vue@3.5.41(typescript@6.0.3))
vue: 3.5.41(typescript@6.0.3)
'@vueuse/shared': 14.3.0(vue@3.5.42(typescript@6.0.3))
vue: 3.5.42(typescript@6.0.3)
'@vueuse/integrations@12.8.2(focus-trap@7.8.0)(fuse.js@7.5.0)(typescript@6.0.3)':
dependencies:
'@vueuse/core': 12.8.2(typescript@6.0.3)
'@vueuse/shared': 12.8.2(typescript@6.0.3)
vue: 3.5.41(typescript@6.0.3)
vue: 3.5.42(typescript@6.0.3)
optionalDependencies:
focus-trap: 7.8.0
fuse.js: 7.5.0
transitivePeerDependencies:
- typescript
'@vueuse/integrations@14.3.0(focus-trap@7.8.0)(fuse.js@7.5.0)(vue@3.5.41(typescript@6.0.3))':
'@vueuse/integrations@14.3.0(focus-trap@7.8.0)(fuse.js@7.5.0)(vue@3.5.42(typescript@6.0.3))':
dependencies:
'@vueuse/core': 14.3.0(vue@3.5.41(typescript@6.0.3))
'@vueuse/shared': 14.3.0(vue@3.5.41(typescript@6.0.3))
vue: 3.5.41(typescript@6.0.3)
'@vueuse/core': 14.3.0(vue@3.5.42(typescript@6.0.3))
'@vueuse/shared': 14.3.0(vue@3.5.42(typescript@6.0.3))
vue: 3.5.42(typescript@6.0.3)
optionalDependencies:
focus-trap: 7.8.0
fuse.js: 7.5.0
@@ -16369,13 +16365,13 @@ snapshots:
'@vueuse/shared@12.8.2(typescript@6.0.3)':
dependencies:
vue: 3.5.41(typescript@6.0.3)
vue: 3.5.42(typescript@6.0.3)
transitivePeerDependencies:
- typescript
'@vueuse/shared@14.3.0(vue@3.5.41(typescript@6.0.3))':
'@vueuse/shared@14.3.0(vue@3.5.42(typescript@6.0.3))':
dependencies:
vue: 3.5.41(typescript@6.0.3)
vue: 3.5.42(typescript@6.0.3)
'@xmldom/xmldom@0.9.10': {}
@@ -16383,12 +16379,12 @@ snapshots:
a-sync-waterfall@1.0.1: {}
abbrev@2.0.0: {}
abbrev@3.0.1: {}
abbrev@4.0.0: {}
abbrev@5.0.0: {}
abort-controller@3.0.0:
dependencies:
event-target-shim: 5.0.1
@@ -16540,12 +16536,12 @@ snapshots:
ansi-styles@6.2.3: {}
ansi-to-vue3@0.1.2(vue@3.5.41(typescript@6.0.3)):
ansi-to-vue3@0.1.2(vue@3.5.42(typescript@6.0.3)):
dependencies:
anser: 2.3.5
escape-carriage: 1.3.1
optionalDependencies:
vue: 3.5.41(typescript@6.0.3)
vue: 3.5.42(typescript@6.0.3)
any-base@1.1.0: {}
@@ -17300,8 +17296,6 @@ snapshots:
comma-separated-tokens@2.0.3: {}
commander@10.0.1: {}
commander@11.1.0: {}
commander@12.1.0: {}
@@ -17835,11 +17829,11 @@ snapshots:
eastasianwidth@0.2.0: {}
editorconfig@1.0.7:
editorconfig@3.0.2:
dependencies:
'@one-ini/wasm': 0.1.1
commander: 10.0.1
minimatch: 9.0.9
'@one-ini/wasm': 0.2.1
commander: 14.0.3
minimatch: 10.2.5
semver: 7.8.5
ee-first@1.1.1: {}
@@ -19352,13 +19346,13 @@ snapshots:
jpeg-js@0.4.4: {}
js-beautify@1.15.4:
js-beautify@2.0.3:
dependencies:
config-chain: 1.1.13
editorconfig: 1.0.7
glob: 10.5.0
editorconfig: 3.0.2
glob: 13.0.6
js-cookie: 3.0.8
nopt: 7.2.1
nopt: 10.0.1
js-cookie@3.0.8: {}
@@ -20301,13 +20295,13 @@ snapshots:
motion-utils@12.39.0: {}
motion-v@1.10.3(@vueuse/core@14.3.0(vue@3.5.41(typescript@6.0.3)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(vue@3.5.41(typescript@6.0.3)):
motion-v@1.10.3(@vueuse/core@14.3.0(vue@3.5.42(typescript@6.0.3)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(vue@3.5.42(typescript@6.0.3)):
dependencies:
'@vueuse/core': 14.3.0(vue@3.5.41(typescript@6.0.3))
'@vueuse/core': 14.3.0(vue@3.5.42(typescript@6.0.3))
framer-motion: 12.42.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
hey-listen: 1.0.8
motion-dom: 12.42.2
vue: 3.5.41(typescript@6.0.3)
vue: 3.5.42(typescript@6.0.3)
transitivePeerDependencies:
- '@emotion/is-prop-valid'
- react
@@ -20594,9 +20588,9 @@ snapshots:
node-releases@2.0.51: {}
nopt@7.2.1:
nopt@10.0.1:
dependencies:
abbrev: 2.0.0
abbrev: 5.0.0
nopt@8.1.0:
dependencies:
@@ -21706,7 +21700,7 @@ snapshots:
safer-buffer@2.1.2: {}
sandpack-vue3@3.1.12(vue@3.5.41(typescript@6.0.3)):
sandpack-vue3@3.1.12(vue@3.5.42(typescript@6.0.3)):
dependencies:
'@codemirror/autocomplete': 6.20.3
'@codemirror/commands': 6.10.4
@@ -21719,12 +21713,12 @@ snapshots:
'@codesandbox/sandpack-client': 2.19.8
'@lezer/highlight': 1.2.3
'@stitches/core': 1.2.8
ansi-to-vue3: 0.1.2(vue@3.5.41(typescript@6.0.3))
ansi-to-vue3: 0.1.2(vue@3.5.42(typescript@6.0.3))
clean-set: 1.1.2
dequal: 2.0.3
lz-string: 1.5.0
optionalDependencies:
vue: 3.5.41(typescript@6.0.3)
vue: 3.5.42(typescript@6.0.3)
sass-formatter@0.7.9:
dependencies:
@@ -23124,7 +23118,7 @@ snapshots:
'@shikijs/transformers': 2.5.0
'@shikijs/types': 2.5.0
'@types/markdown-it': 14.1.2
'@vitejs/plugin-vue': 5.2.4(vite@7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.3))
'@vitejs/plugin-vue': 5.2.4(vite@7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0))(vue@3.5.42(typescript@6.0.3))
'@vue/devtools-api': 7.7.10
'@vue/shared': 3.5.39
'@vueuse/core': 12.8.2(typescript@6.0.3)
@@ -23134,7 +23128,7 @@ snapshots:
minisearch: 7.2.0
shiki: 2.5.0
vite: 7.3.6(@types/node@26.1.1)(jiti@2.7.0)(less@4.6.7)(sass@1.101.0)(stylus@0.56.0(supports-color@10.2.2))(terser@5.49.0)(yaml@2.9.0)
vue: 3.5.41(typescript@6.0.3)
vue: 3.5.42(typescript@6.0.3)
optionalDependencies:
postcss: 8.5.19
transitivePeerDependencies:
@@ -23247,27 +23241,27 @@ snapshots:
vue-component-type-helpers@3.3.9: {}
vue-demi@0.14.10(vue@3.5.41(typescript@6.0.3)):
vue-demi@0.14.10(vue@3.5.42(typescript@6.0.3)):
dependencies:
vue: 3.5.41(typescript@6.0.3)
vue: 3.5.42(typescript@6.0.3)
vue@3.5.41(typescript@5.9.3):
vue@3.5.42(typescript@5.9.3):
dependencies:
'@vue/compiler-dom': 3.5.41
'@vue/compiler-sfc': 3.5.41
'@vue/runtime-dom': 3.5.41
'@vue/server-renderer': 3.5.41
'@vue/shared': 3.5.41
'@vue/compiler-dom': 3.5.42
'@vue/compiler-sfc': 3.5.42
'@vue/runtime-dom': 3.5.42
'@vue/server-renderer': 3.5.42
'@vue/shared': 3.5.42
optionalDependencies:
typescript: 5.9.3
vue@3.5.41(typescript@6.0.3):
vue@3.5.42(typescript@6.0.3):
dependencies:
'@vue/compiler-dom': 3.5.41
'@vue/compiler-sfc': 3.5.41
'@vue/runtime-dom': 3.5.41
'@vue/server-renderer': 3.5.41
'@vue/shared': 3.5.41
'@vue/compiler-dom': 3.5.42
'@vue/compiler-sfc': 3.5.42
'@vue/runtime-dom': 3.5.42
'@vue/server-renderer': 3.5.42
'@vue/shared': 3.5.42
optionalDependencies:
typescript: 6.0.3
+328
View File
@@ -0,0 +1,328 @@
import { Octokit } from '@octokit/rest';
import fs from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { minifySvg } from '../tools/build-helpers/helpers.ts';
// Resolve repo paths relative to this script so they work no matter which
// directory the script is invoked from (the workflow runs it from the repo root).
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
const repoRoot = path.join(scriptDir, '..');
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
const pullRequestNumber = Number(process.env.PULL_REQUEST_NUMBER);
const commitSha = process.env.COMMIT_SHA ?? 'HEAD';
const useFileSystem = process.env.USE_FILE_SYSTEM === 'true';
const dryRun = process.env.DRY_RUN === 'true';
const owner = 'lucide-icons';
const repo = 'lucide';
// Marker that lets `peter-evans/find-comment` recognise our own comment so we
// update it in place instead of stacking a new nag on every PR edit. It must
// stay distinct from the `### Added or changed icons` marker used by the icon
// preview bot, or the two workflows would overwrite each other.
const COMMENT_MARKER = '<!-- lucide-missing-issue-comment -->';
const COMMENT_FILE = 'missing-issue-comment.md';
const ICON_NAME_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;
const GH_ICON_BASE_URL = 'https://lucide.dev/api/gh-icon';
const STUDIO_BASE_URL = 'https://studio.lucide.dev/edit';
const ISSUE_TEMPLATE = '01_icon_request.yml';
type Action = 'nag' | 'resolve' | 'none';
// Only these two fields of a pull request file entry are used. `octokit.paginate`
// is avoided in favour of a plain page loop because
// `@octokit/plugin-paginate-rest` and `@octokit/plugin-rest-endpoint-methods`
// resolve to different `@octokit/types` versions (9.3.2 and 10.0.0), which makes
// `paginate`'s overloads unresolvable.
type PullRequestFile = { filename: string; status: string };
if (!Number.isInteger(pullRequestNumber)) {
console.error('PULL_REQUEST_NUMBER env variable is not a valid number');
process.exit(1);
}
/** Reports back to the workflow which of the three comment steps should run. */
async function setAction(action: Action) {
console.log(`action=${action}`);
if (process.env.GITHUB_OUTPUT) {
await fs.appendFile(process.env.GITHUB_OUTPUT, `action=${action}\n`);
}
}
/**
* Reads a file as it exists on the pull request's head commit, returning null
* when it is not there. A fork's head commit is reachable from this repository
* through `refs/pull/<number>/head`, so the fork is never checked out.
*
* Everything this returns is contributor-controlled, so callers must treat it
* strictly as data.
*/
async function readPullRequestFile(filename: string) {
if (useFileSystem) {
try {
return await fs.readFile(path.join(repoRoot, filename), 'utf-8');
} catch {
return null;
}
}
try {
// `repos.getContent` returns base64 in a JSON envelope. Reading the raw
// url instead would hand back an ArrayBuffer for `image/svg+xml`.
const { data } = await octokit.repos.getContent({
owner,
repo,
path: filename,
ref: commitSha,
});
if (Array.isArray(data) || data.type !== 'file' || data.content == null) return null;
return Buffer.from(data.content, 'base64').toString('utf-8');
} catch (error) {
// A 404 means either no metadata file yet, or the fork force pushed past
// the sha in the event payload.
if ((error as { status?: number }).status === 404) return null;
throw error;
}
}
/**
* Pulls the `### Icon use case` section out of a pull request description, as
* laid out by `.github/pull_request_template.md`. HTML comments are stripped
* *after* matching so an untouched template — where the section contains
* nothing but the instructional comment — yields an empty string rather than
* pasting our own instructions into the new issue.
*/
function extractUseCasesFromDescription(pullRequestBody: string) {
const match = pullRequestBody.match(
/^#{2,4}[ \t]*Icon use cases?[ \t]*(?:<!--[\s\S]*?-->)?[ \t]*$([\s\S]*?)(?=^#{1,4}[ \t]|$(?![\s\S]))/im,
);
if (!match) return '';
return match[1]
.replace(/<!--[\s\S]*?-->/g, '')
.split('\n')
.map((line) => line.trim())
.filter(Boolean)
.join('\n');
}
/** Prefers the icon's own metadata, falling back to the PR description. */
function getUseCases(metadata: unknown, pullRequestBody: string) {
const useCases =
metadata != null && typeof metadata === 'object'
? (metadata as Record<string, unknown>)['use-cases']
: undefined;
if (Array.isArray(useCases)) {
const entries = useCases.filter(
(useCase): useCase is string => typeof useCase === 'string' && useCase.trim() !== '',
);
if (entries.length > 0) {
return entries.map((useCase) => `- ${useCase.trim()}`).join('\n');
}
}
return extractUseCasesFromDescription(pullRequestBody);
}
/**
* Builds a link to the icon request form with every field pre-filled. Linking to
* the form (rather than a free-form `?body=`) means GitHub applies the template's
* `🙌 icon request` label and renders the `### Icon name` heading that
* `close-issue-with-banned-phrases.yml` relies on.
*/
function buildIssueUrl(name: string, svgContent: string, useCases: string) {
// The gh-icon API and Lucide Studio both want the bare icon children, so drop
// the `<svg>` wrapper. One base64 encoding then serves the preview image and
// the studio link, matching `docs/.vitepress/theme/components/icons/IconPreview.vue`.
const innerSvg = minifySvg(svgContent).replace(/<svg[^>]*>|<\/svg>/g, '');
const base64 = Buffer.from(innerSvg).toString('base64');
const studioUrl = `${STUDIO_BASE_URL}?value=${encodeURIComponent(base64)}&name=${name}&utm_source=github.com&utm_medium=pr-comment`;
const designIdeas = `<a title="Open lucide studio" target="_blank" href="${studioUrl}"><img alt="${name}" width="200px" src="${GH_ICON_BASE_URL}/${base64}.svg"/><br/>Open lucide studio</a>`;
// `URLSearchParams` is deliberate: it escapes the literal `+` and `(` `)`
// characters that appear in base64 and in use cases, where `encodeURI` would
// leave `+` to be decoded back into a space and corrupt the payload, and a
// stray `)` would end the markdown link early.
const params = new URLSearchParams({
template: ISSUE_TEMPLATE,
title: `${name} Icon Design`,
name,
'use-cases': useCases,
'design-ideas': designIdeas,
});
// Spaces are serialised as `+`, which only decodes back to a space under
// form decoding. `%20` means a space under both that and plain url decoding,
// so the link cannot be misread whichever way GitHub parses it.
const query = params.toString().replaceAll('+', '%20');
return `https://github.com/${owner}/${repo}/issues/new?${query}`;
}
const { data: pullRequest } = await octokit.pulls.get({
owner,
repo,
pull_number: pullRequestNumber,
});
const pullRequestBody = pullRequest.body ?? '';
// `closingIssuesReferences` covers both `closes #123` keywords in the description
// and issues linked by hand through the Development sidebar. A bare `#123`
// mention deliberately does not count as a link.
const { repository } = await octokit.graphql<{
repository: { pullRequest: { closingIssuesReferences: { totalCount: number } } };
}>(
`query ($owner: String!, $repo: String!, $number: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $number) {
closingIssuesReferences(first: 1) {
totalCount
}
}
}
}`,
{ owner, repo, number: pullRequestNumber },
);
if (repository.pullRequest.closingIssuesReferences.totalCount > 0) {
console.log(`Pull request #${pullRequestNumber} references an issue.`);
await setAction('resolve');
process.exit(0);
}
const files: PullRequestFile[] = [];
// A pull request adding a family of icons can hold well over a hundred files,
// and `listFiles` pages at a hundred at a time.
for (let page = 1; ; page += 1) {
const { data } = await octokit.pulls.listFiles({
owner,
repo,
pull_number: pullRequestNumber,
per_page: 100,
page,
});
files.push(...data);
if (data.length < 100) break;
}
// An icon that leaves `lab/` in the same pull request is being promoted out of
// the lab rather than designed from scratch, so it already had its discussion.
const promotedLabIcons = new Set(
files
.filter((file) => file.status === 'removed' && /^lab\/[^/]+\.svg$/.test(file.filename))
.map((file) => path.basename(file.filename, '.svg')),
);
// Only brand new icons need a design issue; redesigns of existing icons already
// have one, and renames are not new designs. Sorted so re-runs of the same pull
// request produce an identical comment instead of reshuffling the links.
const addedIcons = files
.filter(
(file) =>
file.status === 'added' &&
/^icons\/[^/]+\.svg$/.test(file.filename) &&
!promotedLabIcons.has(path.basename(file.filename, '.svg')),
)
.sort((a, b) => a.filename.localeCompare(b.filename));
if (addedIcons.length === 0) {
console.log('No added icons found');
await setAction('none');
process.exit(0);
}
const issueLinks = (
await Promise.all(
addedIcons.map(async ({ filename }) => {
const name = path.basename(filename, '.svg');
// The filename comes from a fork and ends up rendered in our comment, so
// anything that is not a plain icon slug is skipped rather than trusted.
if (!ICON_NAME_PATTERN.test(name)) {
console.log(`Skipping "${filename}": not a valid icon name.`);
return null;
}
const svgContent = await readPullRequestFile(filename);
if (svgContent == null) {
console.log(`Could not read ${filename}. Skipping.`);
return null;
}
const metadataContent = await readPullRequestFile(`icons/${name}.json`);
let metadata: unknown;
if (metadataContent != null) {
try {
metadata = JSON.parse(metadataContent);
} catch {
// A malformed metadata file is `lint:json:icons`' problem, not ours.
console.log(`Could not parse icons/${name}.json. Falling back to the PR description.`);
}
}
const useCases = getUseCases(metadata, pullRequestBody);
const issueUrl = buildIssueUrl(name, svgContent, useCases);
return `[Create an issue for the \`${name}\` icon](${issueUrl})`;
}),
)
).filter((link): link is string => link !== null);
if (issueLinks.length === 0) {
console.log('No valid added icons found');
await setAction('none');
process.exit(0);
}
const linkList = issueLinks.map((link) => `- ${link}`).join('\n');
// A pull request adding a whole icon family would otherwise bury the message
// under a wall of links, so collapse the list at the same threshold
// `generateChangedIconsCommentMarkup.mts` uses to switch layout.
const callToAction =
issueLinks.length === 1
? `Click here to create an issue for this design: ${issueLinks[0]}`
: issueLinks.length < 8
? `Click here to create an issue for these designs:\n${linkList}`
: `<details>
<summary>Click here to create an issue for each of these ${issueLinks.length} designs</summary>
${linkList}
</details>`;
const commentMarkup = `${COMMENT_MARKER}
It looks like your PR for a new icon design does not reference an issue.
Please create an issue for the design discussion. And reference it in the PR.
${callToAction}
Thank you for your contribution!
`;
if (dryRun) {
console.log(commentMarkup);
} else {
await fs.writeFile(path.join(process.cwd(), COMMENT_FILE), commentMarkup);
}
await setAction('nag');
-41
View File
@@ -1,41 +0,0 @@
# Lucide Icon Usage Estimator
Run with:
```sh
pnpm icon-usage trash trash-2
```
The default is a bounded first pass over `lucide-react`, with two GitHub search pages and up to 200 candidate files validated per query slice. Use `--all-packages` to include every supported package, or `--thorough` for the previous broader limits of 10 pages and 1,000 candidate files per query slice.
GitHub code search requires authentication, so set `GITHUB_TOKEN` or pass `--token-env <NAME>`.
Use `--verbose` or `-v` to print detailed progress logs to stderr, including queries, pages, cache hits, retries, content validation, and matches.
## Method
The script uses GitHub REST `GET /search/code` with package-scoped, code-extension-scoped queries, then fetches each returned file and validates common Lucide import styles before counting a repository. Counts are deduplicated by `owner/repository`.
Output includes overall repository counts and per-package statistics. Per-package statistics are computed from validated matches for that package, so a repository using `trash` via `lucide-react` and `trash-2` via another package is represented correctly in both the overall totals and each package section.
Supported packages are `lucide-react`, `@lucide/vue`, `@lucide/svelte`, `@lucide/angular`, `@lucide/astro`, `lucide-preact`, `lucide-solid`, `lucide`, and `@lucide/lab`. The default package is `lucide-react` because all packages plus file-scope slicing is slow for broad icons; use `--all-packages` when that broader sample is needed.
Searches are split across relevant implementation file scopes using REST code search qualifiers such as `language:typescript`, `language:javascript`, `extension:vue`, and `extension:svelte`. Returned paths are still filtered by expected extensions before content is fetched, so Markdown and prompt/spec files are intentionally excluded by default because they frequently contain examples or generated implementation notes rather than live package usage.
By default, queries exclude forks, archived repositories, generated files, and vendored files using GitHub code search qualifiers. Use `--include-forks`, `--include-archived`, `--include-generated`, or `--include-vendored` to include them.
## GitHub API Limits
GitHub REST code search is authenticated and rate-limited to 10 requests per minute. Each query can return at most 1,000 results, with up to 100 results per page. Search only covers default branches and files smaller than 384 KB.
`total_count` and `incomplete_results` come from GitHub search and are recorded in JSON metadata. If a query exceeds the 1,000-result cap or returns `incomplete_results: true`, the script reports a warning and the result should be treated as incomplete rather than exhaustive.
GitHub's newer code search syntax is usable for public code search queries and supports qualifiers such as `NOT is:fork`, `NOT is:archived`, `NOT is:generated`, and `NOT is:vendored`, but the documented REST code search endpoint remains capped for result retrieval.
## Practical Strategy For Broad Icons
For common icons that hit search caps, use the script output as lower-bound or sampled evidence. The most defensible follow-up is to narrow query slices and cite them separately, for example by package, language/path, or repository cohorts, while preserving the JSON metadata for every query performed.
## Known Biases
Only public GitHub repositories visible to the token are observable. Private repositories and consumers outside GitHub are absent. GitHub is not representative of every Lucide consumer. Framework/package usage can differ materially. GitHub indexing may be incomplete or delayed. Generated or vendored code can still create false positives when GitHub does not identify it. Very common icons may exceed GitHub search-result caps.
File diff suppressed because it is too large Load Diff