diff --git a/.cspell/custom-words.txt b/.cspell/custom-words.txt index e0e6b2098..f2517f0a6 100644 --- a/.cspell/custom-words.txt +++ b/.cspell/custom-words.txt @@ -9,9 +9,4 @@ strikethrough touchpad ungroup toc - -# Brands -codepen -codesandbox -dribbble -x.com +sunlounger diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index ffae92223..000000000 --- a/.eslintignore +++ /dev/null @@ -1,10 +0,0 @@ -dist -build -coverage -lib -tests -node_modules -.eslintrc.js -docs/images -docs/**/examples/ -packages/lucide-react/dynamicIconImports.js diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index ae2e17576..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,75 +0,0 @@ -const DEFAULT_ATTRS = require('./tools/build-icons/render/default-attrs.json'); - -module.exports = { - root: true, - env: { - browser: true, - node: true, - }, - extends: ['airbnb-base', 'prettier'], - plugins: ['import', '@html-eslint'], - rules: { - 'no-console': 'off', - 'no-param-reassign': 'off', - 'no-shadow': 'off', - 'no-use-before-define': 'off', - 'import/no-extraneous-dependencies': [ - 'error', - { - devDependencies: ['**/*.test.js', '**/*.spec.js', '**/scripts/**'], - }, - ], - 'import/extensions': [ - 'error', - { - pattern: { - mjs: 'always', - json: 'always', - }, - }, - ], - }, - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./docs/tsconfig.json', './packages/*/tsconfig.json'], - ecmaVersion: 'latest', - sourceType: 'module', - }, - overrides: [ - { - files: ['./icons/*.svg'], - parser: '@html-eslint/parser', - rules: { - '@html-eslint/require-doctype': 'off', - '@html-eslint/no-duplicate-attrs': 'error', - '@html-eslint/no-inline-styles': 'error', - '@html-eslint/require-attrs': [ - 'error', - ...Object.entries(DEFAULT_ATTRS).map(([attr, value]) => ({ - tag: 'svg', - attr, - value: String(value), - })), - ], - '@html-eslint/indent': ['error', 2], - '@html-eslint/no-multiple-empty-lines': ['error', { max: 0 }], - '@html-eslint/no-extra-spacing-attrs': [ - 'error', - { - enforceBeforeSelfClose: true, - }, - ], - '@html-eslint/require-closing-tags': [ - 'error', - { - selfClosing: 'always', - allowSelfClosingCustom: true, - }, - ], - '@html-eslint/element-newline': 'error', - '@html-eslint/no-trailing-spaces': 'error', - '@html-eslint/quotes': 'error', - }, - }, - ], -}; diff --git a/.github/DISCUSSION_TEMPLATE/icon-design.yml b/.github/DISCUSSION_TEMPLATE/icon-design.yml new file mode 100644 index 000000000..895c7b9d1 --- /dev/null +++ b/.github/DISCUSSION_TEMPLATE/icon-design.yml @@ -0,0 +1,50 @@ +name: Icon request +description: Suggest a new icon for this project +body: + - type: markdown + attributes: + value: | + Before submitting an icon request check if it has already been requested. If there is an open request, please add a 👍. + + > [!CAUTION] + > New brand logos are **not** allowed, see our official statement: https://github.com/lucide-icons/lucide/blob/main/BRAND_LOGOS_STATEMENT.md. + > + > Existing brand icons have been phased out. Consider using https://simpleicons.org, which offers purpose-built SVGs that are also on a 24×24px grid. + - type: input + id: name + attributes: + label: Icon name + description: What should this icon depict? For multiple icons, provide a comma-separated list. + validations: + required: true + - type: textarea + id: use-cases + attributes: + label: Use cases + description: Why do you need this icon? Include at least two real-life use cases per requested icon, avoiding generic descriptions like "it's a car icon". + placeholder: e.g. I need a star icon to use in my rating system. + validations: + required: true + - type: textarea + id: design-ideas + attributes: + label: Design ideas + description: What should this icon look like? Provide simple, minimalistic icon examples from other sets or your own drafts to help us visualize your request. + validations: + required: true + - type: checkboxes + id: checklist + attributes: + label: Checklist + description: Please review the following checklist before submitting your request. + options: + - label: I have searched if someone has submitted a similar request before and there weren't any. + required: true + - label: I have searched existing icons to make sure it does not already exist and I didn't find any. + required: true + - label: I am not requesting a brand logo and the art is not protected by copyright, see more at https://github.com/lucide-icons/lucide/blob/main/BRAND_LOGOS_STATEMENT.md + required: true + - label: I am not requesting an icon that includes religious, war/violence related, political imagery or hate symbols. + required: true + - label: I have provided appropriate use cases for the icon(s) requested. + required: true diff --git a/.github/ISSUE_TEMPLATE/02_bug_report.yml b/.github/ISSUE_TEMPLATE/02_bug_report.yml index d8567aca2..f5d8918bb 100644 --- a/.github/ISSUE_TEMPLATE/02_bug_report.yml +++ b/.github/ISSUE_TEMPLATE/02_bug_report.yml @@ -13,16 +13,19 @@ body: description: Which Lucide packages are affected? You may select more than one. options: - label: lucide - - label: lucide-angular - - label: lucide-flutter - - label: lucide-preact - label: lucide-react + - label: '@lucide/vue' + - label: '@lucide/svelte' + - label: '@lucide/angular' + - label: '@lucide/astro' - label: lucide-react-native + - label: lucide-preact - label: lucide-solid - - label: lucide-svelte - - label: lucide-vue - - label: lucide-vue-next - - label: lucide-astro + - label: lucide-static + - label: '@lucide/icons' + - label: lucide-vue-next (deprecated) + - label: lucide-svelte (deprecated) + - label: lucide-angular (deprecated) - label: Figma plugin - label: source/main - label: other/not relevant @@ -33,7 +36,7 @@ body: attributes: label: Version description: What version of Lucide are you running? - placeholder: e.g. 0.289.1 + placeholder: e.g. 1.1.0 validations: required: true - type: checkboxes diff --git a/.github/ISSUE_TEMPLATE/04_feature_request.yml b/.github/ISSUE_TEMPLATE/04_feature_request.yml index 63a2469ec..73d354ac8 100644 --- a/.github/ISSUE_TEMPLATE/04_feature_request.yml +++ b/.github/ISSUE_TEMPLATE/04_feature_request.yml @@ -13,19 +13,23 @@ body: description: Which Lucide project do you wish this feature were added to? You may select more than one. options: - label: lucide - - label: lucide-angular - - label: lucide-flutter - - label: lucide-preact - label: lucide-react + - label: '@lucide/vue' + - label: '@lucide/svelte' + - label: '@lucide/angular' + - label: '@lucide/astro' - label: lucide-react-native + - label: lucide-preact - label: lucide-solid - - label: lucide-svelte - - label: lucide-vue - - label: lucide-vue-next - - label: lucide-astro + - label: lucide-static + - label: '@lucide/icons' + - label: lucide-vue-next (deprecated) + - label: lucide-svelte (deprecated) + - label: lucide-angular (deprecated) - label: Figma plugin - label: all JS packages - label: site + - label: other/not relevant validations: required: true - type: textarea diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000..055190392 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,8 @@ +## Reviewing PRs + +When reviewing PRs, please respond in a friendly and constructive manner. + +- First, thank the contributor for their contribution in an enthusiastic way. +- If you have any suggestions for improvement, provide them clearly and concisely. +- If you have any questions about the PR, ask them respectfully. +- Let the contributor know that we have many PRs to review and that we appreciate their patience while we review their contribution. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..a26b1f2f5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,106 @@ +version: 2 + +updates: + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + groups: + react-deps: + patterns: + - '@testing-library/react' + - '@types/prop-types' + - '@types/react' + - '@vitejs/plugin-react' + - 'react' + - 'react-dom' + vue-deps: + patterns: + - '@testing-library/vue' + - '@vitejs/plugin-vue' + - '@vue/test-utils' + - 'vue' + svelte-deps: + patterns: + - '@sveltejs/*' + - '@testing-library/svelte' + - '@tsconfig/svelte' + - 'svelte' + - 'svelte-check' + - 'svelte-preprocess' + solid-deps: + patterns: + - '@babel/*' + - '@rollup/plugin-babel' + - '@solidjs/testing-library' + - 'babel-preset-solid' + - 'solid-js' + - 'vite-plugin-solid' + react-native-deps: + patterns: + - 'react-native' + - 'react-native-svg' + angular-deps: + patterns: + - '@angular/*' + - '@angular-eslint/*' + - '@vitest/browser-playwright' + - 'angular-eslint' + - 'ng-packagr' + - 'rxjs' + - 'tslib' + preact-deps: + patterns: + - '@preact/preset-vite' + - '@testing-library/preact' + - 'preact' + astro-deps: + patterns: + - '@astrojs/*' + - 'astro' + testing-deps: + patterns: + - '@testing-library/*' + - '@vitest/*' + - 'jest-serializer-html' + - 'jsdom' + - 'linkedom' + - 'vitest' + build-deps: + patterns: + - '@rollup/*' + - '@vitejs/*' + - 'esbuild' + - 'rollup' + - 'rollup-plugin-*' + - 'typescript' + - 'vite' + - 'vite-plugin-*' + linting-deps: + patterns: + - '@eslint/*' + - '@html-eslint/*' + - '@typescript-eslint/*' + - 'angular-eslint' + - 'cspell' + - 'eslint' + - 'eslint-*' + - 'husky' + - 'lint-staged' + - 'prettier' + - 'prettier-plugin-*' + types-deps: + patterns: + - '@types/*' + remaining-deps: + patterns: + - '*' + + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly + groups: + github-actions: + patterns: + - '*' diff --git a/.github/instructions/metadata.instructions.md b/.github/instructions/metadata.instructions.md new file mode 100644 index 000000000..05aacbae1 --- /dev/null +++ b/.github/instructions/metadata.instructions.md @@ -0,0 +1,20 @@ +--- +applyTo: "icons/*.json" +--- +# JSON Metadata Descriptor + +The schema for the JSON metadata descriptor can be found in `icon.schema.json`. It defines the required and optional properties for the JSON files that accompany each icon. The JSON metadata descriptor should be placed in the same directory as the SVG file of the icon and should have the same name as the SVG file, but with a `.json` extension. For example, if the SVG file is named `home.svg`, the JSON metadata descriptor should be named `home.json`. + +## Contributors + +The `contributors` property is a required array of GitHub usernames for the people who created or contributed to the icon. It is used to give credit to contributors and to track the icon's history. Add the PR author to the `contributors` array if they are not already listed and they have made a significant contribution to the icon's SVG. + +## Tags + +The `tags` property is an array of strings that describe the icon and can be used for searching. +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 + +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. diff --git a/.github/labeler.yml b/.github/labeler.yml index b690d1926..aeb274b50 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -36,63 +36,62 @@ - any-glob-to-any-file: - 'packages/lucide/*' -# For changes in the lucide React package +# For changes in the Lucide React package ⚛️ react package: - changed-files: - any-glob-to-any-file: - 'packages/lucide-react/*' -# For changes in the lucide React Native package +# For changes in the Lucide React Native package ⚛️ react native package: - changed-files: - any-glob-to-any-file: - 'packages/lucide-react-native/*' -# For changes in the lucide vue packages +# For changes in the Lucide vue packages 💎 vue package: - changed-files: - any-glob-to-any-file: - - 'packages/lucide-vue/*' - - 'packages/lucide-vue-next/*' + - 'packages/vue/*' -# For changes in the lucide angular package +# For changes in the Lucide angular package 🅰️ angular package: - changed-files: - any-glob-to-any-file: - - 'packages/lucide-angular/*' + - 'packages/angular/*' -# For changes in the lucide preact package +# For changes in the Lucide preact package ⚛️ preact package: - changed-files: - any-glob-to-any-file: - 'packages/lucide-preact/*' -# For changes in the lucide svelte package +# For changes in the Lucide svelte package 🧣 svelte package: - changed-files: - any-glob-to-any-file: - - 'packages/lucide-svelte/*' + - 'packages/svelte/*' -# For changes in the lucide solid package +# For changes in the Lucide solid package 🪝 solid package: - changed-files: - any-glob-to-any-file: - 'packages/lucide-solid/*' -# For changes in the lucide astro package +# For changes in the Lucide astro package 🚀 astro package: - changed-files: - any-glob-to-any-file: - 'packages/astro/*' -# For changes in the lucide static package +# For changes in the @lucide/icons package +❇️ lucide-icons: + - changed-files: + - any-glob-to-any-file: + - 'packages/lucide-icons/*' + +# For changes in the Lucide static package 🪨 static package: - changed-files: - any-glob-to-any-file: - 'packages/lucide-static/*' - -# For changes in the lucide flutter package -🏹 flutter package: - - changed-files: - - any-glob-to-any-file: - - 'packages/lucide-flutter/*' diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7efa7e6d6..3bf6bfff1 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -41,13 +41,15 @@ Common scopes: icons, docs, studio, site, dev ### Naming -- [ ] I've read and followed the [naming conventions](https://lucide.dev/guide/design/icon-design-guide#naming-conventions) +- [ ] I've read and followed the [naming conventions](https://lucide.dev/contribute/icon-design-guide#naming-conventions) - [ ] I've named icons by what they are rather than their use case. - [ ] I've provided meta JSON files in `icons/[iconName].json`. ### Design -- [ ] I've read and followed the [icon design guidelines](https://lucide.dev/guide/design/icon-design-guide) + +- [ ] I've read and followed the [icon design guidelines](https://lucide.dev/contribute/icon-design-guide) +- [ ] I've made sure that the icons don't [already exist](https://lucide.dev/icons), including the [Lab directory](https://github.com/lucide-icons/lucide/tree/main/lab). - [ ] I've made sure that the icons look sharp on low DPI displays. - [ ] I've made sure that the icons look consistent with the icon set in size, optical volume and density. - [ ] I've made sure that the icons are visually centered. diff --git a/.github/workflows/angular.yml b/.github/workflows/angular.yml new file mode 100644 index 000000000..764d077ec --- /dev/null +++ b/.github/workflows/angular.yml @@ -0,0 +1,44 @@ +name: Lucide Angular checks + +on: + pull_request: + paths: + - packages/angular/** + - tools/build-icons/** + - pnpm-lock.yaml + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + cache: 'pnpm' + node-version-file: 'package.json' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm --filter @lucide/angular build + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + cache: 'pnpm' + node-version-file: 'package.json' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Test + run: pnpm --filter @lucide/angular test diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 638d7cc2d..c410bd739 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,21 +7,67 @@ on: paths: - icons/**/*.svg -permissions: - id-token: write # Required for OIDC - contents: write + workflow_dispatch: + inputs: + version: + description: Version + required: true + tag: + required: true + description: NPM tag + default: 'latest' + type: choice + options: + - latest + - next + - beta + - alpha + +permissions: {} jobs: - create-release: - if: github.repository == 'lucide-icons/lucide' && startsWith(github.event.head_commit.message, 'feat(icons)') + check-dispatch-gate: + if: github.repository == 'lucide-icons/lucide' && + startsWith(github.event.head_commit.message, 'feat(icons)') && + github.event_name != 'workflow_dispatch' runs-on: ubuntu-latest + permissions: + contents: read + outputs: + RELEASE_ENVIRONMENT: ${{ steps.environment.outputs.RELEASE_ENVIRONMENT }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Fetch tags + run: git fetch --all --tags + + - name: Check if latest tag was created today + id: environment + run: | + LATEST_TAG=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1) + TAG_DATE=$(git log -1 --format=%cs "$LATEST_TAG") + TODAY=$(date +%Y-%m-%d) + + if [ "$TAG_DATE" == "$TODAY" ]; then + echo "::warning::A release tag already exists for today ($TODAY): $LATEST_TAG. Manual approval will be required to proceed." + echo "RELEASE_ENVIRONMENT=Icon Release Gated" >> $GITHUB_OUTPUT + else + echo "RELEASE_ENVIRONMENT=Icon Release" >> $GITHUB_OUTPUT + fi + + create-release: + if: github.repository == 'lucide-icons/lucide' + needs: check-dispatch-gate + environment: ${{ needs.check-dispatch-gate.outputs.RELEASE_ENVIRONMENT }} + runs-on: ubuntu-latest + permissions: + contents: write # Required to create the release and tag outputs: VERSION: ${{ steps.new-version.outputs.NEW_VERSION }} - steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' @@ -34,7 +80,7 @@ jobs: - name: Get latest tag id: latest-tag - run: echo "LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_OUTPUT + run: echo "LATEST_TAG=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1)" >> $GITHUB_OUTPUT - name: Log latest tag run: echo '${{ steps.latest-tag.outputs.LATEST_TAG }}' @@ -56,7 +102,7 @@ jobs: echo '${{ steps.change-log.outputs.CHANGE_LOG }}' - name: Create Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 with: tag_name: ${{ steps.new-version.outputs.NEW_VERSION }} name: Version ${{ steps.new-version.outputs.NEW_VERSION }} @@ -67,5 +113,19 @@ jobs: needs: create-release uses: './.github/workflows/release.yml' secrets: inherit + permissions: + id-token: write # Required for OIDC (npm provenance) + contents: write # Required to upload release assets with: version: ${{ needs.create-release.outputs.VERSION }} + + dispatch-release: + if: github.repository == 'lucide-icons/lucide' && github.event_name == 'workflow_dispatch' + uses: './.github/workflows/release.yml' + secrets: inherit + permissions: + id-token: write # Required for OIDC (npm provenance) + contents: write # Required to upload release assets + with: + version: ${{ inputs.version }} + tag: ${{ inputs.tag }} diff --git a/.github/workflows/close-issue-with-banned-phrases.yml b/.github/workflows/close-issue-with-banned-phrases.yml index abd2d7c7f..5fb35811d 100644 --- a/.github/workflows/close-issue-with-banned-phrases.yml +++ b/.github/workflows/close-issue-with-banned-phrases.yml @@ -4,14 +4,21 @@ on: issues: types: [opened] +permissions: {} + +env: + GH_TOKEN: ${{ github.token }} + jobs: block_phrases: + if: github.repository == 'lucide-icons/lucide' runs-on: ubuntu-latest permissions: + contents: read issues: write steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Load stopwords from JSON & check issue title & body if: contains(github.event.issue.labels.*.name, '🙌 icon request') @@ -28,12 +35,12 @@ jobs: { [ -n "$ICON_NAME_SECTION" ] && echo "$ICON_NAME_SECTION" | grep -iqE "$SAFE_KEY|$SAFE_VALUE"; }; then gh issue close ${{ github.event.issue.number }} \ - --reason "not_planned" \ + --reason "not planned" \ --comment "It looks like this request is about **${VALUE}**, which is a brand logo. Lucide **does not accept** brand logos, and we do not plan to add them in the future. This is due to a combination of **legal restrictions**, **design consistency concerns**, and **practical maintenance reasons**. - [Click here to read our official statement about brand logos in Lucide.](./BRAND_LOGOS_STATEMENT.md) + [Click here to read our official statement about brand logos in Lucide.](https://github.com/lucide-icons/lucide/blob/main/BRAND_LOGOS_STATEMENT.md) You can [search for similar issues.](https://github.com/lucide-icons/lucide/issues?q=is%3Aissue+${VALUE}) @@ -43,6 +50,3 @@ jobs: exit 0 fi done - -env: - GH_TOKEN: ${{ github.token }} diff --git a/.github/workflows/close-stale-prs.yml b/.github/workflows/close-stale-prs.yml index 0b47315f4..7704f341c 100644 --- a/.github/workflows/close-stale-prs.yml +++ b/.github/workflows/close-stale-prs.yml @@ -3,13 +3,16 @@ on: schedule: - cron: '45 1 * * *' +permissions: {} + jobs: stale: + if: github.repository == 'lucide-icons/lucide' runs-on: ubuntu-latest permissions: pull-requests: write steps: - - uses: actions/stale@v9 + - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-pr-message: This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 5 days. diff --git a/.github/workflows/comment-icon-preview.yml b/.github/workflows/comment-icon-preview.yml index 1ba1aa89e..b9f813e64 100644 --- a/.github/workflows/comment-icon-preview.yml +++ b/.github/workflows/comment-icon-preview.yml @@ -6,15 +6,22 @@ on: types: - completed +permissions: {} + jobs: upload: runs-on: ubuntu-latest + permissions: + contents: read + actions: read # Required to download the artifact from the triggering run + pull-requests: write if: > + github.repository == 'lucide-icons/lucide' && github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' steps: - name: 'Download artifact' - uses: actions/github-script@v7 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ @@ -42,7 +49,7 @@ jobs: id: pr-number - name: Find Comment - uses: peter-evans/find-comment@v2 + uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0 id: pr-comment with: issue-number: ${{ steps.pr-number.outputs.number }} @@ -50,7 +57,7 @@ jobs: body-includes: Added or changed icons - name: Create or update comment - uses: peter-evans/create-or-update-comment@v3 + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0 with: comment-id: ${{ steps.pr-comment.outputs.comment-id }} issue-number: ${{ steps.pr-number.outputs.number }} diff --git a/.github/workflows/icons.yml b/.github/workflows/icons.yml new file mode 100644 index 000000000..e4d53a6f9 --- /dev/null +++ b/.github/workflows/icons.yml @@ -0,0 +1,46 @@ +name: Lucide Icons Checks + +on: + pull_request: + paths: + - packages/icons/** + - packages/shared/** + - tools/build-icons/** + - tools/rollup-plugins/** + - pnpm-lock.yaml + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + cache: 'pnpm' + node-version-file: 'package.json' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm --filter @lucide/icons build + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + cache: 'pnpm' + node-version-file: 'package.json' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Test + run: pnpm --filter @lucide/icons test diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 7dc5c2879..75de3b3bb 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -2,12 +2,15 @@ name: 'Pull Request Labeler' on: - pull_request_target +permissions: {} + jobs: triage: + if: github.repository == 'lucide-icons/lucide' permissions: contents: read pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: actions/labeler@v5 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: actions/labeler@bf12e9b00b37c5c0ca2b87b79b2daf7891dbda13 # v7.0.0 diff --git a/.github/workflows/lint-code.yml b/.github/workflows/lint-code.yml index f2aeefc1b..edaec6611 100644 --- a/.github/workflows/lint-code.yml +++ b/.github/workflows/lint-code.yml @@ -1,17 +1,18 @@ -name: Linting PR +name: Linting PR code on: pull_request: - paths-ignore: - - icons/*.svg + +permissions: + contents: read jobs: lint-code: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' diff --git a/.github/workflows/lint-pr-title.yml b/.github/workflows/lint-pr-title.yml index d5f7ce8a3..ef9abcf61 100644 --- a/.github/workflows/lint-pr-title.yml +++ b/.github/workflows/lint-pr-title.yml @@ -1,4 +1,4 @@ -name: Linting PR +name: Linting PR title on: pull_request: @@ -7,12 +7,16 @@ on: - edited - reopened +permissions: + contents: read + pull-requests: read # Required to read the PR title + jobs: lint-pr-title: name: PR Title Lint runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@v5 + - uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/linting-icons.yml b/.github/workflows/linting-icons.yml index fc399cd3a..0f69ba490 100644 --- a/.github/workflows/linting-icons.yml +++ b/.github/workflows/linting-icons.yml @@ -1,9 +1,15 @@ name: Linting Icons on: + push: + branches: + - next pull_request: paths: - 'icons/*' + - 'lab/*' + +permissions: {} jobs: lint-filenames: @@ -13,27 +19,54 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: + cache: 'pnpm' node-version-file: 'package.json' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + - name: Get changed files id: changed-files - uses: tj-actions/changed-files@v46 + uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6 with: - files: icons/* + files: | + icons/* + lab/* - name: Generate annotations run: node ./scripts/lintFilenames.mts env: CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} + check-lab-icons: + name: Check Lab Icons + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + cache: 'pnpm' + node-version-file: 'package.json' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Check lab icons do not already exist in icons + run: node ./scripts/checkLabIcons.mts + lint-aliases: name: Check Uniqueness of Aliases runs-on: ubuntu-latest permissions: contents: read steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Check Uniqueness of Aliases run: "! cat <(printf \"%s\\n\" icons/*.json | while read -r name; do basename \"$name\" .json; done) <(jq -cr 'select(.aliases) | .aliases[] | if type==\"string\" then . else .name end' icons/*.json) | sort | uniq -c | grep -ve '^\\s*1 '" diff --git a/.github/workflows/lucide-angular.yml b/.github/workflows/lucide-angular.yml deleted file mode 100644 index 0812c0ea4..000000000 --- a/.github/workflows/lucide-angular.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Lucide Angular checks - -on: - pull_request: - paths: - - packages/lucide-angular/** - - tools/build-icons/** - - pnpm-lock.yaml - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 - with: - cache: 'pnpm' - node-version-file: 'package.json' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build - run: pnpm --filter lucide-angular build - - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 - with: - cache: 'pnpm' - node-version-file: 'package.json' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Test - run: pnpm --filter lucide-angular test diff --git a/.github/workflows/lucide-astro.yml b/.github/workflows/lucide-astro.yml index 74b9043c3..47a1fc8dd 100644 --- a/.github/workflows/lucide-astro.yml +++ b/.github/workflows/lucide-astro.yml @@ -1,6 +1,9 @@ name: Lucide Astro Checks on: + push: + branches: + - next pull_request: paths: - packages/astro/** @@ -8,13 +11,16 @@ on: - tools/build-icons/** - pnpm-lock.yaml +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v2 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version-file: 'package.json' cache: 'pnpm' @@ -28,9 +34,9 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2 - - uses: actions/setup-node@v3.8.1 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version-file: 'package.json' cache: 'pnpm' diff --git a/.github/workflows/lucide-font.yml b/.github/workflows/lucide-font.yml index 19430dea3..7548723cb 100644 --- a/.github/workflows/lucide-font.yml +++ b/.github/workflows/lucide-font.yml @@ -1,18 +1,24 @@ name: Lucide font checks on: + push: + branches: + - next pull_request: paths: - tools/build-font/** - pnpm-lock.yaml +permissions: + contents: read + jobs: lucide-font: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' @@ -20,14 +26,14 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Outline svg Icons - run: pnpm build:outline-icons + - name: Execute unit tests for build-font + run: pnpm test:font - name: Create font in ./lucide-font run: pnpm build:font - name: 'Upload to Artifacts' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: lucide-font path: lucide-font diff --git a/.github/workflows/lucide-lab.yml b/.github/workflows/lucide-lab.yml new file mode 100644 index 000000000..323cb3595 --- /dev/null +++ b/.github/workflows/lucide-lab.yml @@ -0,0 +1,30 @@ +name: Lucide Lab checks + +on: + pull_request: + paths: + - packages/lab/** + - packages/shared/** + - tools/build-icons/** + - tools/rollup-plugins/** + - pnpm-lock.yaml + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + cache: 'pnpm' + node-version-file: 'package.json' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm --filter @lucide/lab build diff --git a/.github/workflows/lucide-preact.yml b/.github/workflows/lucide-preact.yml index 1da3cf236..f842c1b47 100644 --- a/.github/workflows/lucide-preact.yml +++ b/.github/workflows/lucide-preact.yml @@ -1,6 +1,9 @@ name: Lucide Preact Checks on: + push: + branches: + - next pull_request: paths: - packages/lucide-preact/** @@ -9,13 +12,16 @@ on: - tools/rollup-plugins/** - pnpm-lock.yaml +permissions: + contents: read + jobs: lucide-preact: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' diff --git a/.github/workflows/lucide-react-native.yml b/.github/workflows/lucide-react-native.yml index 7ed5cc039..6f8d83079 100644 --- a/.github/workflows/lucide-react-native.yml +++ b/.github/workflows/lucide-react-native.yml @@ -1,6 +1,9 @@ name: Lucide React Native checks on: + push: + branches: + - next pull_request: paths: - packages/lucide-react-native/** @@ -9,13 +12,16 @@ on: - tools/rollup-plugins/** - pnpm-lock.yaml +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' @@ -29,9 +35,9 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' diff --git a/.github/workflows/lucide-react.yml b/.github/workflows/lucide-react.yml index 2fe551f81..7d00a1ba5 100644 --- a/.github/workflows/lucide-react.yml +++ b/.github/workflows/lucide-react.yml @@ -1,6 +1,9 @@ name: Lucide React Checks on: + push: + branches: + - next pull_request: paths: - packages/lucide-react/** @@ -10,13 +13,16 @@ on: - scripts/generateNextJSAliases.mjs - pnpm-lock.yaml +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' @@ -30,9 +36,9 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' diff --git a/.github/workflows/lucide-shared.yml b/.github/workflows/lucide-shared.yml index 69e7268db..efea0dc77 100644 --- a/.github/workflows/lucide-shared.yml +++ b/.github/workflows/lucide-shared.yml @@ -1,18 +1,24 @@ name: Lucide Shared Checks on: + push: + branches: + - next pull_request: paths: - packages/shared/** - pnpm-lock.yaml +permissions: + contents: read + jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' diff --git a/.github/workflows/lucide-solid.yml b/.github/workflows/lucide-solid.yml index 9c5e07424..d78602a35 100644 --- a/.github/workflows/lucide-solid.yml +++ b/.github/workflows/lucide-solid.yml @@ -1,6 +1,9 @@ name: Lucide Solid Checks on: + push: + branches: + - next pull_request: paths: - packages/lucide-solid/** @@ -9,13 +12,16 @@ on: - tools/rollup-plugins/** - pnpm-lock.yaml +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' @@ -29,9 +35,9 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' diff --git a/.github/workflows/lucide-static.yml b/.github/workflows/lucide-static.yml index aa604eaa5..fee24bf72 100644 --- a/.github/workflows/lucide-static.yml +++ b/.github/workflows/lucide-static.yml @@ -7,13 +7,16 @@ on: - tools/build-icons/** - pnpm-lock.yaml +permissions: + contents: read + jobs: lucide-static: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' diff --git a/.github/workflows/lucide-svelte-5.yml b/.github/workflows/lucide-svelte-5.yml index 64863d714..4f48fcf19 100644 --- a/.github/workflows/lucide-svelte-5.yml +++ b/.github/workflows/lucide-svelte-5.yml @@ -1,6 +1,9 @@ name: Lucide Svelte 5 checks on: + push: + branches: + - next pull_request: paths: - packages/svelte/** @@ -9,13 +12,16 @@ on: - tools/rollup-plugins/** - pnpm-lock.yaml +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' @@ -29,9 +35,9 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' @@ -41,3 +47,19 @@ jobs: - name: Test run: pnpm --filter @lucide/svelte test + + typecheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + cache: 'pnpm' + node-version-file: 'package.json' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Test + run: pnpm --filter @lucide/svelte typecheck diff --git a/.github/workflows/lucide-svelte.yml b/.github/workflows/lucide-svelte.yml deleted file mode 100644 index ec4d8e8e8..000000000 --- a/.github/workflows/lucide-svelte.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Lucide Svelte checks - -on: - pull_request: - paths: - - packages/lucide-svelte/** - - packages/shared/** - - tools/build-icons/** - - tools/rollup-plugins/** - - pnpm-lock.yaml - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 - with: - cache: 'pnpm' - node-version-file: 'package.json' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build - run: pnpm --filter lucide-svelte build - - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 - with: - cache: 'pnpm' - node-version-file: 'package.json' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Test - run: pnpm --filter lucide-svelte test diff --git a/.github/workflows/lucide-vue-next.yml b/.github/workflows/lucide-vue-next.yml deleted file mode 100644 index eb2ff1663..000000000 --- a/.github/workflows/lucide-vue-next.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Lucide Vue Next checks - -on: - pull_request: - paths: - - packages/lucide-vue-next/** - - packages/shared/** - - tools/build-icons/** - - tools/rollup-plugins/** - - pnpm-lock.yaml - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 - with: - cache: 'pnpm' - node-version-file: 'package.json' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build - run: pnpm --filter lucide-vue-next build - - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 - with: - cache: 'pnpm' - node-version-file: 'package.json' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Test - run: pnpm --filter lucide-vue-next test diff --git a/.github/workflows/lucide-vue.yml b/.github/workflows/lucide-vue.yml new file mode 100644 index 000000000..e4e4ee9b6 --- /dev/null +++ b/.github/workflows/lucide-vue.yml @@ -0,0 +1,49 @@ +name: Lucide Vue checks + +on: + push: + branches: + - next + pull_request: + paths: + - packages/vue/** + - packages/shared/** + - tools/build-icons/** + - tools/rollup-plugins/** + - pnpm-lock.yaml + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + cache: 'pnpm' + node-version-file: 'package.json' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm --filter @lucide/vue build + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + cache: 'pnpm' + node-version-file: 'package.json' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Test + run: pnpm --filter @lucide/vue test diff --git a/.github/workflows/lucide.yml b/.github/workflows/lucide.yml index 57fe6947d..844d2647f 100644 --- a/.github/workflows/lucide.yml +++ b/.github/workflows/lucide.yml @@ -1,6 +1,9 @@ name: Lucide checks on: + push: + branches: + - next pull_request: paths: - packages/lucide/** @@ -8,13 +11,16 @@ on: - tools/rollup-plugins/** - pnpm-lock.yaml +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' @@ -28,9 +34,9 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' diff --git a/.github/workflows/pull-request-icon-preview.yml b/.github/workflows/pull-request-icon-preview.yml index 814673683..62112e892 100644 --- a/.github/workflows/pull-request-icon-preview.yml +++ b/.github/workflows/pull-request-icon-preview.yml @@ -5,27 +5,30 @@ on: paths: - 'icons/*.svg' +permissions: {} + jobs: generate-changed-icons-comment: name: Generate Changed Icons Comment + if: github.repository == 'lucide-icons/lucide' runs-on: ubuntu-latest permissions: contents: read pull-requests: write steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version-file: 'package.json' - name: Get changed files id: changed-files - uses: tj-actions/changed-files@v46 + uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6 with: files: icons/*.svg - - uses: actions/setup-node@v6 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - name: Install svgson for code preview (safer and faster than installing all deps) run: npm install svgson@5.3.1 --force @@ -40,7 +43,7 @@ jobs: env: CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: pr_number path: pr/ diff --git a/.github/workflows/pull-request-tags-suggestions.yml b/.github/workflows/pull-request-metadata-suggestions.yml similarity index 63% rename from .github/workflows/pull-request-tags-suggestions.yml rename to .github/workflows/pull-request-metadata-suggestions.yml index 141998cac..cc1586da7 100644 --- a/.github/workflows/pull-request-tags-suggestions.yml +++ b/.github/workflows/pull-request-metadata-suggestions.yml @@ -1,13 +1,16 @@ -name: Pull request tags suggestions +name: Pull request metadata suggestions on: pull_request_target: paths: - 'icons/*.json' +permissions: {} + jobs: - pull-request-tags-suggestions: - name: Pull Request Tags Suggestions + pull-request-metadata-suggestions: + name: Pull Request Metadata Suggestions + if: github.repository == 'lucide-icons/lucide' runs-on: ubuntu-latest permissions: contents: read @@ -16,11 +19,11 @@ jobs: steps: # We checkout the main branch of main repository for security reasons. # This is to prevent the workflow from running on a forked repository. - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: lucide-icons/lucide - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' @@ -29,7 +32,7 @@ jobs: run: pnpm install --frozen-lockfile - name: Generate comment markup - run: node ./scripts/suggestTags.mts + run: node ./scripts/suggestMetaData.mts env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} PULL_REQUEST_NUMBER: ${{ github.event.number }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0b146f718..e200da21f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,24 +11,19 @@ on: required: true description: Version type: string + tag: + description: NPM tag + default: 'latest' + type: string - workflow_dispatch: - inputs: - version: - description: Version - required: true - -permissions: - id-token: write # Required for OIDC - contents: write +permissions: {} jobs: - pre-release: + prepare: if: github.repository == 'lucide-icons/lucide' && contains('["ericfennis", "karsa-mistmere", "jguddas"]', github.actor) runs-on: ubuntu-latest outputs: VERSION: ${{ steps.get_version.outputs.VERSION }} - steps: - name: Get the version id: get_version @@ -41,7 +36,7 @@ jobs: release: if: github.repository == 'lucide-icons/lucide' runs-on: ubuntu-latest - needs: pre-release + needs: prepare permissions: id-token: write # Required for OIDC contents: read @@ -53,18 +48,18 @@ jobs: 'lucide', 'lucide-react', 'lucide-react-native', - 'lucide-vue-next', - 'lucide-angular', 'lucide-preact', 'lucide-solid', - 'lucide-svelte', + '@lucide/angular', '@lucide/astro', + '@lucide/icons', '@lucide/svelte', + '@lucide/vue', ] steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' @@ -73,7 +68,7 @@ jobs: run: pnpm install --frozen-lockfile - name: Set new version - run: pnpm --filter ${{ matrix.package }} version --new-version ${{ needs.pre-release.outputs.VERSION }} --no-git-tag-version + run: pnpm version ${{ needs.prepare.outputs.VERSION }} --filter ${{ matrix.package }} --fail-if-no-match --no-git-tag-version - name: Build run: pnpm --filter ${{ matrix.package }} build @@ -82,23 +77,27 @@ jobs: run: pnpm --filter ${{ matrix.package }} test - name: Publish - run: pnpm --filter ${{ matrix.package }} publish --access public --no-git-checks --ignore-scripts + run: pnpm --filter ${{ matrix.package }} publish --access public --no-git-checks --ignore-scripts --tag ${{ inputs.tag }} env: NPM_CONFIG_PROVENANCE: true lucide-static: if: github.repository == 'lucide-icons/lucide' runs-on: ubuntu-latest - needs: [pre-release, lucide-font] + needs: [prepare, lucide-font] permissions: id-token: write # Required for OIDC contents: read steps: - - uses: actions/checkout@v6 - - uses: actions/download-artifact@v4 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: lucide-font + path: lucide-font + + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' @@ -107,7 +106,7 @@ jobs: run: pnpm install --frozen-lockfile - name: Set new version - run: pnpm --filter lucide-static version --new-version ${{ needs.pre-release.outputs.VERSION }} --no-git-tag-version + run: pnpm version ${{ needs.prepare.outputs.VERSION }} --filter lucide-static --no-git-tag-version - name: Move Font run: cp -r lucide-font packages/lucide-static/font @@ -116,18 +115,20 @@ jobs: run: pnpm --filter lucide-static build - name: Publish - run: pnpm --filter lucide-static publish --no-git-checks + run: pnpm --filter lucide-static publish --no-git-checks --ignore-scripts --tag ${{ inputs.tag }} --access public env: NPM_CONFIG_PROVENANCE: true lucide-font: if: github.repository == 'lucide-icons/lucide' runs-on: ubuntu-latest - needs: pre-release + needs: prepare + permissions: + contents: read steps: - - uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: cache: 'pnpm' node-version-file: 'package.json' @@ -135,37 +136,43 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Outline svg Icons - run: pnpm build:outline-icons + - name: Execute unit tests for build-font + run: pnpm test:font - name: Create font in ./lucide-font - run: pnpm build:font + run: pnpm build:font --saveCodePoints + env: + BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }} - name: 'Upload to Artifacts' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: lucide-font path: lucide-font post-release: - if: github.repository == 'lucide-icons/lucide' + if: github.repository == 'lucide-icons/lucide' && github.event_name != 'workflow_call' runs-on: ubuntu-latest - needs: [pre-release, lucide-font] + needs: [prepare, lucide-font] permissions: - id-token: write # Required for OIDC - contents: write + contents: write # Required to upload the release assets steps: - - uses: actions/checkout@v6 - - uses: actions/download-artifact@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: lucide-font + path: lucide-font + - name: Zip font and icons run: | - zip -r lucide-font-${{ needs.pre-release.outputs.VERSION }}.zip lucide-font - zip -r lucide-icons-${{ needs.pre-release.outputs.VERSION }}.zip icons + zip -r lucide-font-${{ needs.prepare.outputs.VERSION }}.zip lucide-font + zip -r lucide-icons-${{ needs.prepare.outputs.VERSION }}.zip icons - name: Release zip and fonts - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 with: - tag_name: ${{ needs.pre-release.outputs.VERSION }} + tag_name: ${{ needs.prepare.outputs.VERSION }} + files: | - lucide-font-${{ needs.pre-release.outputs.VERSION }}.zip - lucide-icons-${{ needs.pre-release.outputs.VERSION }}.zip + lucide-font-${{ needs.prepare.outputs.VERSION }}.zip + lucide-icons-${{ needs.prepare.outputs.VERSION }}.zip diff --git a/.github/workflows/repo-journal.yml b/.github/workflows/repo-journal.yml new file mode 100644 index 000000000..b457fe47f --- /dev/null +++ b/.github/workflows/repo-journal.yml @@ -0,0 +1,45 @@ +name: Weekly Repo Report +on: + workflow_dispatch: + # Run this workflow every Monday at 07:00 UTC + schedule: + - cron: '0 7 * * 1' + +permissions: + contents: read + +jobs: + weekly-summary: + if: github.repository == 'lucide-icons/lucide' + runs-on: ubuntu-latest + steps: + - name: Set up Node.js environment + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + + - name: Install Copilot CLI + run: npm install -g @github/copilot + + - name: Run the prompt + env: + COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} + run: | + copilot -p "${{ vars.REPO_REPORT_PROMPT }} Write the details to summary.md" --allow-tool='shell(git:*)' --allow-tool=write --no-ask-user + cat summary.md >> "$GITHUB_STEP_SUMMARY" + + - name: Post report to Discord (private channel) + env: + DISCORD_WEBHOOK_URL: ${{ secrets.LUCIDE_DISCORD_WEBHOOK }} + run: | + jq -Rs '{ + embeds: [{ + title: "📊 Weekly Repo Report", + description: (.[0:4096]), + color: 5814783 + }] + }' summary.md > payload.json + curl -sS --fail -X POST \ + -H "Content-Type: application/json" \ + -d @payload.json \ + "$DISCORD_WEBHOOK_URL" diff --git a/.github/workflows/request-review.yml b/.github/workflows/request-review.yml index 666de1a21..3139435f8 100644 --- a/.github/workflows/request-review.yml +++ b/.github/workflows/request-review.yml @@ -1,25 +1,27 @@ -name: 'Request Review' +name: Request Review on: - pull_request_target: + pull_request: types: [opened] paths: - icons/*.svg +permissions: {} + jobs: request-review: - if: github.event.pull_request.draft == false + if: github.repository == 'lucide-icons/lucide' && github.event.pull_request.draft == false runs-on: ubuntu-latest permissions: contents: read pull-requests: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 ref: refs/pull/${{ github.event.pull_request.number }}/merge - name: Get changed files id: changed-files - uses: tj-actions/changed-files@v41 + uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6 with: files: icons/*.svg - run: | diff --git a/.gitignore b/.gitignore index 41a9f0839..0ad3cb108 100644 --- a/.gitignore +++ b/.gitignore @@ -14,24 +14,32 @@ coverage stats *.log outlined +lucide-font packages/**/src/icons/*.js packages/**/src/icons/*.ts packages/**/src/icons/*.tsx packages/**/src/aliases/*.ts packages/**/src/aliases.ts !packages/**/src/aliases/index.ts +packages/**/src/utils/*.ts +!packages/shared/src/utils/*.ts packages/**/src/dynamicIconImports.ts packages/**/DynamicIcon.d.ts packages/**/dynamicIconImports.js +packages/**/dynamicIconImports.mjs packages/**/dynamicIconImports.d.ts +packages/**/dynamicIconImports.d.mts packages/**/dynamicIconImports.js.map +packages/**/dynamicIconImports.mjs.map packages/**/dynamic.d.ts +packages/**/dynamic.d.mts packages/**/dynamic.mjs.map packages/**/dynamic.mjs packages/**/LICENSE categories.json tags.json .vercel +package-lock.json # docs docs/.vitepress/cache @@ -40,11 +48,16 @@ docs/.vitepress/.temp docs/.vitepress/data/iconNodes docs/.vitepress/data/iconMetaData.ts docs/.vitepress/data/releaseMetaData.json -docs/.vitepress/data/releaseMetaData +docs/.vitepress/data/releaseMetadata docs/.vitepress/data/categoriesData.json docs/.vitepress/data/iconDetails docs/.vitepress/data/relatedIcons.json docs/.vitepress/data/brandStopwords.json +docs/.vitepress/data/iconPopularity +docs/.vitepress/data/lab/iconNodes +docs/.vitepress/data/lab/iconMetaData.ts +docs/.vitepress/data/lab/iconPopularity docs/.vercel docs/.nitro -.gitignore +docs/public/og/** +!docs/public/og/general.png diff --git a/.prettierignore b/.prettierignore index c150f271b..435726b81 100644 --- a/.prettierignore +++ b/.prettierignore @@ -7,8 +7,8 @@ docs/.vitepress/cache docs/.vitepress/data docs/.nitro -# lucide-angular -packages/lucide-angular/.angular/cache +# @lucide/angular +packages/angular/.angular # lucide-static packages/lucide-static/icons @@ -17,7 +17,8 @@ packages/lucide-static/sprite.svg packages/lucide-static/tags.json packages/lucide-static/icon-nodes.json packages/lucide-static/font +packages/svelte/.svelte-kit # lucide-svelte -packages/lucide-svelte/src/icons/*.svelte -packages/lucide-svelte/.svelte-kit +packages/svelte/src/icons/*.svelte +packages/svelte/.svelte-kit diff --git a/.vscode/settings.json b/.vscode/settings.json index f179cbc07..9c7cfd29c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { - "cSpell.words": ["devs", "preact", "Preact"], + "cSpell.words": ["devs", "linecap", "linejoin", "preact", "Preact"], "eslint.enable": true, "eslint.validate": ["javascript", "svg"], - "svg.preview.background": "transparent" + "svg.preview.background": "editor" } diff --git a/BRAND_LOGOS_STATEMENT.md b/BRAND_LOGOS_STATEMENT.md index 9ca7c149b..6a7404c79 100644 --- a/BRAND_LOGOS_STATEMENT.md +++ b/BRAND_LOGOS_STATEMENT.md @@ -1,4 +1,6 @@ -# Our Official Stance on Including Brand Logos in Lucide +# Brand Logos Statement + +Our official stance on including brand logos in Lucide ## TL;DR @@ -37,7 +39,7 @@ This means adding them could: Lucide is all about **visual consistency**. Adding brand logos would: -- Break [our own design rules](https://lucide.dev/guide/design/icon-design-guide#icon-design-principles) for shapes, proportions, and stroke. +- Break [our own design rules](https://lucide.dev/contribute/icon-design-guide#icon-design-principles) for shapes, proportions, and stroke. - Mix two fundamentally different categories of graphics (pictograms vs. corporate logos). - Create a library where a subset of icons will always look "out of place". diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index bd8e14ad0..da613c8d4 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,74 +1,90 @@ # Contributor Covenant Code of Conduct +This Code of Conduct outlines our expectations for participant behavior as well as the consequences for unacceptable behavior within our community. We are committed to providing a welcoming, safe, and inclusive environment for all members of our community. + ## Our Pledge -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -nationality, personal appearance, race, religion, or sexual identity and -orientation. +We pledge to make our community welcoming, safe, and equitable for all. -## Our Standards +We are committed to fostering an environment that respects and promotes the dignity, rights, and contributions of all individuals, regardless of characteristics including race, ethnicity, caste, color, age, physical characteristics, neurodiversity, disability, sex or gender, gender identity or expression, sexual orientation, language, philosophy or religion, national or social origin, socio-economic position, level of education, or other status. The same privileges of participation are extended to everyone who participates in good faith and in accordance with this Covenant. -Examples of behavior that contributes to creating a positive environment -include: +## Encouraged Behaviors -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +While acknowledging differences in social norms, we all strive to meet our community's expectations for positive behavior. We also understand that our words and actions may be interpreted differently than we intend based on culture, background, or native language. -Examples of unacceptable behavior by participants include: +With these considerations in mind, we agree to behave mindfully toward each other and act in ways that center our shared values, including: -* The use of sexualized language or imagery and unwelcome sexual attention or -advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting +1. Respecting the **purpose of our community**, our activities, and our ways of gathering. +2. Engaging **kindly and honestly** with others. +3. Respecting **different viewpoints** and experiences. +4. **Taking responsibility** for our actions and contributions. +5. Gracefully giving and accepting **constructive feedback**. +6. Committing to **repairing harm** when it occurs. +7. Behaving in other ways that promote and sustain the **well-being of our community**. -## Our Responsibilities -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. +## Restricted Behaviors + +We agree to restrict the following behaviors in our community. Instances, threats, and promotion of these behaviors are violations of this Code of Conduct. + +1. **Harassment.** Violating explicitly expressed boundaries or engaging in unnecessary personal attention after any clear request to stop. +2. **Character attacks.** Making insulting, demeaning, or pejorative comments directed at a community member or group of people. +3. **Stereotyping or discrimination.** Characterizing anyone’s personality or behavior on the basis of immutable identities or traits. +4. **Sexualization.** Behaving in a way that would generally be considered inappropriately intimate in the context or purpose of the community. +5. **Violating confidentiality**. Sharing or acting on someone's personal or private information without their permission. +6. **Endangerment.** Causing, encouraging, or threatening violence or other harm toward any person or group. +7. Behaving in other ways that **threaten the well-being** of our community. + +### Other Restrictions + +1. **Misleading identity.** Impersonating someone else for any reason, or pretending to be someone else to evade enforcement actions. +2. **Failing to credit sources.** Not properly crediting the sources of content you contribute. +3. **Promotional materials**. Sharing marketing or other commercial content in a way that is outside the norms of the community. +4. **Irresponsible communication.** Failing to responsibly present content which includes, links or describes any other restricted behaviors. + + +## Reporting an Issue + +Tensions can occur between community members even when they are trying their best to collaborate. Not every conflict represents a code of conduct violation, and this Code of Conduct reinforces encouraged behaviors and norms that can help avoid conflicts and minimize harm. + +When an incident does occur, it is important to report it promptly. To report a possible violation, email: [info@lucide.dev](mailto:info@lucide.dev) + +Community Moderators take reports of violations seriously and will make every effort to respond in a timely manner. They will investigate all reports of code of conduct violations, reviewing messages, logs, and recordings, or interviewing witnesses and other participants. Community Moderators will keep investigation and enforcement actions as transparent as possible while prioritizing safety and confidentiality. In order to honor these values, enforcement actions are carried out in private with the involved parties, but communicating to the whole community may be part of a mutually agreed upon resolution. + + +## Addressing and Repairing Harm + +If an investigation by the Community Moderators finds that this Code of Conduct has been violated, the following enforcement ladder may be used to determine how best to repair harm, based on the incident's impact on the individuals involved and the community as a whole. Depending on the severity of a violation, lower rungs on the ladder may be skipped. + +1) Warning + 1) Event: A violation involving a single incident or series of incidents. + 2) Consequence: A private, written warning from the Community Moderators. + 3) Repair: Examples of repair include a private written apology, acknowledgement of responsibility, and seeking clarification on expectations. +2) Temporarily Limited Activities + 1) Event: A repeated incidence of a violation that previously resulted in a warning, or the first incidence of a more serious violation. + 2) Consequence: A private, written warning with a time-limited cooldown period designed to underscore the seriousness of the situation and give the community members involved time to process the incident. The cooldown period may be limited to particular communication channels or interactions with particular community members. + 3) Repair: Examples of repair may include making an apology, using the cooldown period to reflect on actions and impact, and being thoughtful about re-entering community spaces after the period is over. +3) Temporary Suspension + 1) Event: A pattern of repeated violation which the Community Moderators have tried to address with warnings, or a single serious violation. + 2) Consequence: A private written warning with conditions for return from suspension. In general, temporary suspensions give the person being suspended time to reflect upon their behavior and possible corrective actions. + 3) Repair: Examples of repair include respecting the spirit of the suspension, meeting the specified conditions for return, and being thoughtful about how to reintegrate with the community when the suspension is lifted. +4) Permanent Ban + 1) Event: A pattern of repeated code of conduct violations that other steps on the ladder have failed to resolve, or a violation so serious that the Community Moderators determine there is no way to keep the community safe with this person as a member. + 2) Consequence: Access to all community spaces, tools, and communication channels is removed. In general, permanent bans should be rarely used, should have strong reasoning behind them, and should only be resorted to if working through other remedies has failed to change the behavior. + 3) Repair: There is no possible repair in cases of this severity. + +This enforcement ladder is intended as a guideline. It does not limit the ability of Community Managers to use their discretion and judgment, in keeping with the best interests of our community. -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. ## Scope -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public or other spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event. -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at johnletey@gmail.com. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. ## Attribution -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] +This Code of Conduct is adapted from the Contributor Covenant, version 3.0, permanently available at [https://www.contributor-covenant.org/version/3/0/](https://www.contributor-covenant.org/version/3/0/). -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ +Contributor Covenant is stewarded by the Organization for Ethical Source and licensed under CC BY-SA 4.0. To view a copy of this license, visit [https://creativecommons.org/licenses/by-sa/4.0/](https://creativecommons.org/licenses/by-sa/4.0/) + +For answers to common questions about Contributor Covenant, see the FAQ at [https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq). Translations are provided at [https://www.contributor-covenant.org/translations](https://www.contributor-covenant.org/translations). Additional enforcement and community guideline resources can be found at [https://www.contributor-covenant.org/resources](https://www.contributor-covenant.org/resources). The enforcement ladder was inspired by the work of [Mozilla’s code of conduct team](https://github.com/mozilla/inclusion). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 898485681..ac7ea7869 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,4 @@ - -# Contribution Guidelines +# Contribution Guide :+1::tada: First off, thanks for taking the time to contribute! :tada::+1: @@ -19,31 +18,33 @@ Guidelines for pull requests: - __Make sure the target of your pull request is the relevant branch__. Most of bug fixes or new feature should go to the `main` branch. - __Include only related work__. If your pull request has unrelated commits, it won't be accepted. -### Icon Pull Requests +### Contributing Icons + +We love contributions of new icons from the community! If you want to contribute new icons, please follow the guidelines below. #### Guidelines Please make sure you follow the icon guidelines, that should be followed to keep quality and consistency when making icons for Lucide. -Read it here: [ICON_GUIDELINES](https://lucide.dev/docs/icon-design-guide). +Read it here: [ICON_GUIDELINES](https://lucide.dev/contribute/icon-design-guide). #### Lucide Studio -For formatting and adjusting SVG icons, [@jguddas](https://github.com/jguddas) made a great tool called [Lucide Studio](https://studio.lucide.dev/). It is a web-based SVG editor that allows you to edit and adjust icons in the Lucide style. You can use it to create new icons or modify existing ones. +For formatting and adjusting SVG icons, [@jguddas](https://github.com/jguddas) made a great tool called [Lucide Studio](https://studio.lucide.dev/?utm_source=lucide.dev&utm_medium=contributing-guide). It is a web-based SVG editor that allows you to edit and adjust icons in the Lucide style. You can use it to create new icons or modify existing ones. #### Editor guides Here you can find instructions on how to implement the guidelines with different vector graphics editors: -##### [Adobe Illustrator Guide](https://lucide.dev/docs/illustrator-guide) +##### [Adobe Illustrator Guide](https://lucide.dev/contribute/illustrator-guide) -You can also [download an Adobe Illustrator template](https://github.com/lucide-icons/lucide/blob/main/docs/public/templates/illustrator_template.ai). +You can also [download an Adobe Illustrator template](https://lucide.dev/templates/illustrator_template.ai). -##### [Inkscape Guide](https://lucide.dev/docs/inkscape-guide) +##### [Inkscape Guide](https://lucide.dev/contribute/inkscape-guide) -##### [Figma Guide](https://lucide.dev/docs/figma-guide) +##### [Figma Guide](https://lucide.dev/contribute/figma-guide) -##### [Affinity Designer Guide](https://lucide.dev/guide/design/affinity-designer-guide) +##### [Affinity Designer Guide](https://lucide.dev/contribute/affinity-designer-guide) #### Submitting Multiple Icons @@ -191,7 +192,7 @@ Detailed documentation about: installation, guides, packages, design guides etc. ### Icons -All the icons of lucide in SVG format. These will be used as source for all the packages and other distributions for the lucide icons. +All the icons of Lucide in SVG format. These will be used as source for all the packages and other distributions for the Lucide icons. ### Packages diff --git a/LICENSE b/LICENSE index 46e696218..718bb3f0e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ ISC License -Copyright (c) for portions of Lucide are held by Cole Bemis 2013-2023 as part of Feather (MIT). All other copyright (c) for Lucide are held by Lucide Contributors 2025. +Copyright (c) 2026 Lucide Icons and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -16,9 +16,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --- -The MIT License (MIT) (for portions derived from Feather) +The following Lucide icons are derived from the Feather project: -Copyright (c) 2013-2023 Cole Bemis +airplay, alert-circle, alert-octagon, alert-triangle, aperture, arrow-down-circle, arrow-down-left, arrow-down-right, arrow-down, arrow-left-circle, arrow-left, arrow-right-circle, arrow-right, arrow-up-circle, arrow-up-left, arrow-up-right, arrow-up, at-sign, calendar, cast, check, chevron-down, chevron-left, chevron-right, chevron-up, chevrons-down, chevrons-left, chevrons-right, chevrons-up, circle, clipboard, clock, code, columns, command, compass, corner-down-left, corner-down-right, corner-left-down, corner-left-up, corner-right-down, corner-right-up, corner-up-left, corner-up-right, crosshair, database, divide-circle, divide-square, dollar-sign, download, external-link, feather, frown, hash, headphones, help-circle, info, italic, key, layout, life-buoy, link-2, link, loader, lock, log-in, log-out, maximize, meh, minimize, minimize-2, minus-circle, minus-square, minus, monitor, moon, more-horizontal, more-vertical, move, music, navigation-2, navigation, octagon, pause-circle, percent, plus-circle, plus-square, plus, power, radio, rss, search, server, share, shopping-bag, sidebar, smartphone, smile, square, table-2, tablet, target, terminal, trash-2, trash, triangle, tv, type, upload, x-circle, x-octagon, x-square, x, zoom-in, zoom-out + +The MIT License (MIT) (for the icons listed above) + +Copyright (c) 2013-present Cole Bemis Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 1d2ea701c..a33e9026d 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@
@@ -26,26 +26,26 @@
# Lucide
-Lucide is an open-source icon library that provides 1000+ vector (svg) files for displaying icons and symbols in digital and non-digital projects. The library aims to make it easier for designers and developers to incorporate icons into their projects by providing several official [packages](https://lucide.dev/packages) to make it easier to use these icons in your project.
+Lucide is an open-source icon library that provides 1600+ vector (svg) files for displaying icons and symbols in digital and non-digital projects. The library aims to make it easier for designers and developers to incorporate icons into their projects by providing several official [packages](https://lucide.dev/packages) to make it easier to use these icons in your project.
## Packages
| Logo | Package | Version | Downloads | Links |
| ---- | ------- | ------- | --------- | ----- |
-| | **`lucide`** | [](https://www.npmjs.com/package/lucide) |  | [Docs](https://lucide.dev/guide/packages/lucide) · [Source](./packages/lucide) |
-|
| **`lucide-react`** | [](https://www.npmjs.com/package/lucide-react) |  | [Docs](https://lucide.dev/guide/packages/lucide-react) · [Source](./packages/lucide-react) |
-|
| **`lucide-vue-next`** | [](https://www.npmjs.com/package/lucide-vue-next) |  | [Docs](https://lucide.dev/guide/packages/lucide-vue-next) · [Source](./packages/lucide-vue-next) |
-|
| **`lucide-svelte`** | [](https://www.npmjs.com/package/lucide-svelte) |  | [Docs](https://lucide.dev/guide/packages/lucide-svelte) · [Source](./packages/lucide-svelte) |
-|
| **`lucide-solid`** | [](https://www.npmjs.com/package/lucide-solid) |  | [Docs](https://lucide.dev/guide/packages/lucide-solid) · [Source](./packages/lucide-solid) |
-|
| **`lucide-preact`** | [](https://www.npmjs.com/package/lucide-preact) |  | [Docs](https://lucide.dev/guide/packages/lucide-preact) · [Source](./packages/lucide-preact) |
-|
| **`lucide-react-native`** | [](https://www.npmjs.com/package/lucide-react-native) |  | [Docs](https://lucide.dev/guide/packages/lucide-react-native) · [Source](./packages/lucide-react-native) |
-|
| **`lucide-angular`** | [](https://www.npmjs.com/package/lucide-angular) |  | [Docs](https://lucide.dev/guide/packages/lucide-angular) · [Source](./packages/lucide-angular) |
-|
| **`@lucide/astro`** | [](https://www.npmjs.com/package/@lucide/astro) |  | [Docs](https://lucide.dev/guide/packages/lucide-astro) · [Source](./packages/astro) |
-|
| **`lucide-static`** | [](https://www.npmjs.com/package/lucide-static) |  | [Docs](https://lucide.dev/guide/packages/lucide-static) · [Source](./packages/lucide-static) |
+|
| **`lucide`** | [](https://www.npmjs.com/package/lucide) |  | [Docs](https://lucide.dev/guide/lucide) · [Source](./packages/lucide) |
+|
| **`lucide-react`** | [](https://www.npmjs.com/package/lucide-react) |  | [Docs](https://lucide.dev/guide/react) · [Source](./packages/lucide-react) |
+|
| **`@lucide/vue`** | [](https://www.npmjs.com/package/@lucide/vue) |  | [Docs](https://lucide.dev/guide/vue) · [Source](./packages/vue) |
+|
| **`@lucide/svelte`** | [](https://www.npmjs.com/package/@lucide/svelte) |  | [Docs](https://lucide.dev/guide/svelte) · [Source](./packages/svelte) |
+|
| **`lucide-solid`** | [](https://www.npmjs.com/package/lucide-solid) |  | [Docs](https://lucide.dev/guide/solid) · [Source](./packages/lucide-solid) |
+|
| **`lucide-preact`** | [](https://www.npmjs.com/package/lucide-preact) |  | [Docs](https://lucide.dev/guide/preact) · [Source](./packages/lucide-preact) |
+|
| **`lucide-react-native`** | [](https://www.npmjs.com/package/lucide-react-native) |  | [Docs](https://lucide.dev/guide/react-native) · [Source](./packages/lucide-react-native) |
+|
| **`@lucide/angular`** | [](https://www.npmjs.com/package/@lucide/angular) |  | [Docs](https://lucide.dev/guide/angular) · [Source](./packages/angular) |
+|
| **`@lucide/astro`** | [](https://www.npmjs.com/package/@lucide/astro) |  | [Docs](https://lucide.dev/guide/astro) · [Source](./packages/astro) |
+|
| **`lucide-static`** | [](https://www.npmjs.com/package/lucide-static) |  | [Docs](https://lucide.dev/guide/static) · [Source](./packages/lucide-static) |
### Figma
-The lucide figma plugin.
+The Lucide Figma plugin.
Visit [Figma community page](https://www.figma.com/community/plugin/939567362549682242/Lucide-Icons) to install the plugin.
@@ -80,6 +80,8 @@ Thank you to all the people who contributed to Lucide!
+[//]: <> (Sponsors)
+
## Sponsors
@@ -88,7 +90,19 @@ Thank you to all the people who contributed to Lucide!
+### Hero backers 🦸
+
+
+
### Awesome backers 🍺
-
-
+
+
+
+### Backers ☕
+
+
+
+### Other contributors 💸
+
+You can find all our past and non-recurring financial contributors at [our Open Collective page](https://opencollective.com/lucide-icons).
diff --git a/brand-stopwords.json b/brand-stopwords.json
index 77c9ae265..04816fa5c 100644
--- a/brand-stopwords.json
+++ b/brand-stopwords.json
@@ -54,10 +54,8 @@
"jira": "Jira",
"kotlin": "Kotlin",
"kubernetes": "Kubernetes",
- "less": "Less",
"leetcode": "LeetCode",
"leet-code": "LeetCode",
- "line": "LINE",
"linkedin": "LinkedIn",
"lua": "Lua",
"mariadb": "MariaDB",
@@ -70,7 +68,7 @@
"nestjs": "NestJS",
"netflix": "Netflix",
"netlify": "Netlify",
- "next": "Next.js",
+ "nextjs": "Next.js",
"nodejs": "Node.js",
"notion": "Notion",
"nostr": "Nostr",
@@ -106,7 +104,8 @@
"shopify": "Shopify",
"skype": "Skype",
"slack": "Slack",
- "solid": "SolidJS",
+ "snapchat": "Snapchat",
+ "solidjs": "SolidJS",
"soundcloud": "SoundCloud",
"spotify": "Spotify",
"sqlite": "SQLite",
@@ -145,6 +144,5 @@
"xbox": "Xbox",
"yarn": "Yarn",
"youtube": "YouTube",
- "zig": "Zig",
- "zoom": "Zoom"
+ "zig": "Zig"
}
diff --git a/categories/brands.json b/categories/brands.json
deleted file mode 100644
index c48c4b3b0..000000000
--- a/categories/brands.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "$schema": "../category.schema.json",
- "title": "Brands",
- "icon": "facebook"
-}
diff --git a/categories/emoji.json b/categories/emoji.json
index 78442db1d..2bd590877 100644
--- a/categories/emoji.json
+++ b/categories/emoji.json
@@ -1,5 +1,5 @@
{
"$schema": "../category.schema.json",
"title": "Emoji",
- "icon": "smile"
+ "icon": "face-slightly-smiling"
}
diff --git a/categories/navigation.json b/categories/navigation.json
index 86a3e5503..0c46693cb 100644
--- a/categories/navigation.json
+++ b/categories/navigation.json
@@ -1,5 +1,5 @@
{
"$schema": "../category.schema.json",
- "title": "Navigation, Maps, and POIs",
+ "title": "Navigation & Places",
"icon": "compass"
}
diff --git a/docs/.vitepress/api/categories/index.get.ts b/docs/.vitepress/api/categories/index.get.ts
index 76e1f95de..0ac20a3e5 100644
--- a/docs/.vitepress/api/categories/index.get.ts
+++ b/docs/.vitepress/api/categories/index.get.ts
@@ -1,3 +1,4 @@
+import { eventHandler, setResponseHeader } from 'h3';
import iconMetaData from '../../data/iconMetaData';
export default eventHandler((event) => {
diff --git a/docs/.vitepress/api/figma/data.ts b/docs/.vitepress/api/figma/data.ts
index 1c938c998..cde37f140 100644
--- a/docs/.vitepress/api/figma/data.ts
+++ b/docs/.vitepress/api/figma/data.ts
@@ -1,3 +1,4 @@
+import { eventHandler, setResponseHeader } from 'h3';
import iconNodes from '../../data/iconNodes/index.ts';
import { IconNodeWithKeys } from '../../theme/types';
import iconMetaData from '../../data/iconMetaData';
diff --git a/docs/.vitepress/api/gh-icon/[...data].get.ts b/docs/.vitepress/api/gh-icon/[...data].get.tsx
similarity index 73%
rename from docs/.vitepress/api/gh-icon/[...data].get.ts
rename to docs/.vitepress/api/gh-icon/[...data].get.tsx
index fc3505cce..b74ce7dc3 100644
--- a/docs/.vitepress/api/gh-icon/[...data].get.ts
+++ b/docs/.vitepress/api/gh-icon/[...data].get.tsx
@@ -1,6 +1,6 @@
import { eventHandler, setResponseHeader, defaultContentType } from 'h3';
import { renderToString, renderToStaticMarkup } from 'react-dom/server';
-import { createElement } from 'react';
+import React from 'react';
import SvgPreview from '../../lib/SvgPreview/index.tsx';
import iconNodes from '../../data/iconNodes';
import createLucideIcon from 'lucide-react/src/createLucideIcon';
@@ -34,36 +34,29 @@ export default eventHandler((event) => {
const iconNode = iconNodes[backdropName];
const LucideIcon = createLucideIcon(backdropName, iconNode);
- const svg = renderToStaticMarkup(createElement(LucideIcon));
+ const svg = renderToStaticMarkup(