From 0724851934f681ceab586264552828c404f34bd7 Mon Sep 17 00:00:00 2001 From: Jakob Guddas Date: Tue, 23 Apr 2024 19:56:04 +0200 Subject: [PATCH 01/14] Updated icons/bold.svg (#2060) --- icons/bold.svg | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/icons/bold.svg b/icons/bold.svg index 6694d8b6db..1e51bba6f3 100644 --- a/icons/bold.svg +++ b/icons/bold.svg @@ -9,6 +9,5 @@ stroke-linecap="round" stroke-linejoin="round" > - - + From df100bde73892da2650c41b5bafde8a47b85700a Mon Sep 17 00:00:00 2001 From: Jakob Guddas Date: Wed, 24 Apr 2024 09:00:01 +0200 Subject: [PATCH 02/14] fix(icons): changed `save-all` icon (#2065) * Updated icons/save-all.svg * Updated icons/save-all.json * Updated icons/save-all.svg * Updated icons/save-all.json --- icons/save-all.svg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/icons/save-all.svg b/icons/save-all.svg index 04fe769abf..cc427bbdc6 100644 --- a/icons/save-all.svg +++ b/icons/save-all.svg @@ -9,8 +9,8 @@ stroke-linecap="round" stroke-linejoin="round" > - - - + + + From ad7ae84987649412f92a1a527f3b172e83c674c3 Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Wed, 24 Apr 2024 09:08:01 +0200 Subject: [PATCH 03/14] Split up workflows (#2093) --- .github/workflows/lucide-angular.yml | 17 ++++++++++++++++- .github/workflows/lucide-preact.yml | 3 --- .github/workflows/lucide-react-native.yml | 3 --- .github/workflows/lucide-react.yml | 17 ++++++++++++++++- .github/workflows/lucide-solid.yml | 17 ++++++++++++++++- .github/workflows/lucide-svelte.yml | 17 ++++++++++++++++- .github/workflows/lucide-vue-next.yml | 17 ++++++++++++++++- .github/workflows/lucide-vue.yml | 17 ++++++++++++++++- .github/workflows/lucide.yml | 17 ++++++++++++++++- .github/workflows/pull-request.yml | 6 ++++-- packages/lucide-preact/package.json | 2 +- packages/lucide-react-native/package.json | 4 ++-- packages/lucide-react/package.json | 2 +- packages/lucide-solid/package.json | 6 ++++-- packages/lucide-svelte/package.json | 2 +- packages/lucide-vue-next/package.json | 2 +- packages/lucide-vue/package.json | 2 +- packages/lucide/package.json | 6 +++--- 18 files changed, 130 insertions(+), 27 deletions(-) diff --git a/.github/workflows/lucide-angular.yml b/.github/workflows/lucide-angular.yml index d31c0859b8..46c9a6e589 100644 --- a/.github/workflows/lucide-angular.yml +++ b/.github/workflows/lucide-angular.yml @@ -8,7 +8,7 @@ on: - pnpm-lock.yaml jobs: - lucide-angular: + build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -26,5 +26,20 @@ jobs: - name: Build run: pnpm --filter lucide-angular build + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + with: + version: 8 + - uses: actions/setup-node@v3.8.1 + with: + node-version: 18 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + - name: Test run: pnpm --filter lucide-angular test diff --git a/.github/workflows/lucide-preact.yml b/.github/workflows/lucide-preact.yml index 0c071d1b6b..c6c598d7a8 100644 --- a/.github/workflows/lucide-preact.yml +++ b/.github/workflows/lucide-preact.yml @@ -24,8 +24,5 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Build - run: pnpm --filter lucide-preact build - - name: Test run: pnpm --filter lucide-preact test diff --git a/.github/workflows/lucide-react-native.yml b/.github/workflows/lucide-react-native.yml index f8be337e10..c683413035 100644 --- a/.github/workflows/lucide-react-native.yml +++ b/.github/workflows/lucide-react-native.yml @@ -24,8 +24,5 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Build - run: pnpm --filter lucide-react-native build - - name: Test run: pnpm --filter lucide-react-native test diff --git a/.github/workflows/lucide-react.yml b/.github/workflows/lucide-react.yml index ff11e530a3..b5b2b92e24 100644 --- a/.github/workflows/lucide-react.yml +++ b/.github/workflows/lucide-react.yml @@ -10,7 +10,7 @@ on: - pnpm-lock.yaml jobs: - lucide-react: + build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -28,5 +28,20 @@ jobs: - name: Build run: pnpm --filter lucide-react build + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + with: + version: 8 + - uses: actions/setup-node@v3.8.1 + with: + node-version: 18 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + - name: Test run: pnpm --filter lucide-react test diff --git a/.github/workflows/lucide-solid.yml b/.github/workflows/lucide-solid.yml index d32f98a1b5..6f67075f34 100644 --- a/.github/workflows/lucide-solid.yml +++ b/.github/workflows/lucide-solid.yml @@ -9,7 +9,7 @@ on: - pnpm-lock.yaml jobs: - lucide-solid: + build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -27,5 +27,20 @@ jobs: - name: Build run: pnpm --filter lucide-solid build + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + with: + version: 8 + - uses: actions/setup-node@v3.8.1 + with: + node-version: 18 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + - name: Test run: pnpm --filter lucide-solid test diff --git a/.github/workflows/lucide-svelte.yml b/.github/workflows/lucide-svelte.yml index 07088c6fb9..4fa768db29 100644 --- a/.github/workflows/lucide-svelte.yml +++ b/.github/workflows/lucide-svelte.yml @@ -9,7 +9,7 @@ on: - pnpm-lock.yaml jobs: - lucide-svelte: + build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -27,5 +27,20 @@ jobs: - name: Build run: pnpm --filter lucide-svelte build + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + with: + version: 8 + - uses: actions/setup-node@v3.8.1 + with: + node-version: 18 + cache: 'pnpm' + + - 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 index 68fd57a84b..07310b8e9d 100644 --- a/.github/workflows/lucide-vue-next.yml +++ b/.github/workflows/lucide-vue-next.yml @@ -9,7 +9,7 @@ on: - pnpm-lock.yaml jobs: - lucide-vue-next: + build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -27,5 +27,20 @@ jobs: - name: Build run: pnpm --filter lucide-vue-next build + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + with: + version: 8 + - uses: actions/setup-node@v3.8.1 + with: + node-version: 18 + cache: 'pnpm' + + - 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 index 94f2052ee9..c409956dcd 100644 --- a/.github/workflows/lucide-vue.yml +++ b/.github/workflows/lucide-vue.yml @@ -9,7 +9,7 @@ on: - pnpm-lock.yaml jobs: - lucide-vue: + build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -27,5 +27,20 @@ jobs: - name: Build run: pnpm --filter lucide-vue build + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + with: + version: 8 + - uses: actions/setup-node@v3.8.1 + with: + node-version: 18 + cache: 'pnpm' + + - 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 369d0a9e1a..9f8083cdf2 100644 --- a/.github/workflows/lucide.yml +++ b/.github/workflows/lucide.yml @@ -9,7 +9,7 @@ on: - pnpm-lock.yaml jobs: - lucide: + build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -27,5 +27,20 @@ jobs: - name: Build run: pnpm --filter lucide build + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + with: + version: 8 + - uses: actions/setup-node@v3.8.1 + with: + node-version: 18 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + - name: Test run: pnpm --filter lucide test diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index d80b39eec8..8ded86c1a1 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -45,8 +45,9 @@ jobs: with: files: icons/* - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@v2 - name: Install simple-git (safer and faster than installing all deps) - run: npm install simple-git + run: pnpm install simple-git - name: Generate annotations run: node ./scripts/updateContributors.mjs env: @@ -95,8 +96,9 @@ jobs: body-includes: Added or changed icons - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@v2 - name: Install svgson for code preview (safer and faster than installing all deps) - run: npm install svgson + run: pnpm install svgson - name: Generate comment markup run: node ./scripts/generateChangedIconsCommentMarkup.mjs >> comment-markup.md diff --git a/packages/lucide-preact/package.json b/packages/lucide-preact/package.json index f584e8c14a..b00cc367f6 100644 --- a/packages/lucide-preact/package.json +++ b/packages/lucide-preact/package.json @@ -38,7 +38,7 @@ "clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.js", "build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey --withAliases --aliasesFileExtension=.ts --iconFileExtension=.ts --exportFileName=index.ts", "build:bundles": "rollup -c ./rollup.config.mjs", - "test": "vitest run", + "test": "pnpm build:icons && vitest run", "version": "pnpm version --git-tag-version=false" }, "devDependencies": { diff --git a/packages/lucide-react-native/package.json b/packages/lucide-react-native/package.json index 269fe54534..2e3605b234 100644 --- a/packages/lucide-react-native/package.json +++ b/packages/lucide-react-native/package.json @@ -36,10 +36,10 @@ "scripts": { "build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:bundles", "copy:license": "cp ../../LICENSE ./LICENSE", - "clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.js", + "clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.ts", "build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey --iconFileExtension=.ts --exportFileName=index.ts --withAliases --aliasesFileExtension=.ts", "build:bundles": "rollup -c ./rollup.config.mjs", - "test": "vitest run", + "test": "pnpm build:icons && vitest run", "version": "pnpm version --git-tag-version=false" }, "devDependencies": { diff --git a/packages/lucide-react/package.json b/packages/lucide-react/package.json index c1ca4fa3ca..e453e374f7 100644 --- a/packages/lucide-react/package.json +++ b/packages/lucide-react/package.json @@ -44,7 +44,7 @@ "build:bundles": "rollup -c ./rollup.config.mjs", "typecheck": "tsc", "typecheck:watch": "tsc -w", - "test": "vitest run", + "test": "pnpm build:icons && vitest run", "test:watch": "vitest watch", "version": "pnpm version --git-tag-version=false" }, diff --git a/packages/lucide-solid/package.json b/packages/lucide-solid/package.json index 9928edc952..c879bcbef1 100644 --- a/packages/lucide-solid/package.json +++ b/packages/lucide-solid/package.json @@ -44,10 +44,12 @@ "scripts": { "build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:bundle", "copy:license": "cp ../../LICENSE ./LICENSE", - "clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.js", + "clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.ts", + "build:transpile": "tsc --jsx preserve -t es2020 --rootDir src --outDir dist --noEmit false", + "build:version": "node ./scripts/replaceVersion.mjs", "build:bundle": "rollup -c rollup.config.mjs", "build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey --withAliases --aliasesFileExtension=.ts --iconFileExtension=.tsx --exportFileName=index.ts", - "test": "vitest run", + "test": "pnpm build:icons && vitest run", "version": "pnpm version --git-tag-version=false" }, "devDependencies": { diff --git a/packages/lucide-svelte/package.json b/packages/lucide-svelte/package.json index 7898ed92cf..cab5227d88 100644 --- a/packages/lucide-svelte/package.json +++ b/packages/lucide-svelte/package.json @@ -51,7 +51,7 @@ "build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --exportFileName=index.ts --iconFileExtension=.svelte --importImportFileExtension=.svelte --withAliases --aliasesFileExtension=.ts --aliasImportFileExtension=.svelte --pretty=false", "build:package": "svelte-package --input ./src", "build:license": "node ./scripts/appendBlockComments.mjs", - "test": "vitest run", + "test": "pnpm build:icons && vitest run", "version": "pnpm version --git-tag-version=false" }, "devDependencies": { diff --git a/packages/lucide-vue-next/package.json b/packages/lucide-vue-next/package.json index 063513574a..f04a91fce4 100644 --- a/packages/lucide-vue-next/package.json +++ b/packages/lucide-vue-next/package.json @@ -40,7 +40,7 @@ "clean": "rm -rf dist && rm -rf ./src/icons/*.ts", "build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey --withAliases --aliasesFileExtension=.ts --iconFileExtension=.ts --exportFileName=index.ts", "build:bundles": "rollup -c ./rollup.config.mjs", - "test": "vitest run", + "test": "pnpm build:icons && vitest run", "version": "pnpm version --git-tag-version=false" }, "devDependencies": { diff --git a/packages/lucide-vue/package.json b/packages/lucide-vue/package.json index 140938fcf3..ce7240d829 100644 --- a/packages/lucide-vue/package.json +++ b/packages/lucide-vue/package.json @@ -39,7 +39,7 @@ "clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.js", "build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey --withAliases --aliasesFileExtension=.ts --iconFileExtension=.ts --exportFileName=index.ts", "build:bundles": "rollup -c ./rollup.config.mjs", - "test": "vitest run", + "test": "pnpm build:icons && vitest run", "version": "pnpm version --git-tag-version=false" }, "devDependencies": { diff --git a/packages/lucide/package.json b/packages/lucide/package.json index d3feaf43d7..a76b99bfdb 100644 --- a/packages/lucide/package.json +++ b/packages/lucide/package.json @@ -33,12 +33,12 @@ "dist" ], "scripts": { - "build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:bundles", + "build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:bundle", "copy:license": "cp ../../LICENSE ./LICENSE", "clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.ts", "build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --iconFileExtension=.ts --withAliases --aliasNamesOnly --aliasesFileExtension=.ts --exportFileName=index.ts", - "build:bundles": "rollup -c rollup.config.mjs", - "test": "vitest run", + "build:bundle": "rollup -c rollup.config.mjs", + "test": "pnpm build:icons && vitest run", "version": "pnpm version --git-tag-version=false" }, "devDependencies": { From 305e282e198487bb9894c4596eac6ae2938a49f2 Mon Sep 17 00:00:00 2001 From: Jakob Guddas Date: Wed, 24 Apr 2024 09:09:33 +0200 Subject: [PATCH 04/14] fix(icons): changed `search-code` icon (#1953) * Updated icons/search-code.svg * Updated icons/search-code.json * fix: magic apply changes --------- Co-authored-by: Eric Fennis --- icons/file-code.svg | 6 +++--- icons/message-circle-code.svg | 6 +++--- icons/message-square-code.svg | 4 ++-- icons/search-code.json | 3 ++- icons/search-code.svg | 6 +++--- icons/square-code.svg | 4 ++-- icons/square-dashed-bottom-code.svg | 6 +++--- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/icons/file-code.svg b/icons/file-code.svg index 6816afe03e..6f672c88f7 100644 --- a/icons/file-code.svg +++ b/icons/file-code.svg @@ -9,8 +9,8 @@ stroke-linecap="round" stroke-linejoin="round" > - + + - - + diff --git a/icons/message-circle-code.svg b/icons/message-circle-code.svg index 3fb207857d..9ae877eb48 100644 --- a/icons/message-circle-code.svg +++ b/icons/message-circle-code.svg @@ -9,7 +9,7 @@ stroke-linecap="round" stroke-linejoin="round" > - - - + + + diff --git a/icons/message-square-code.svg b/icons/message-square-code.svg index d7649e1aae..31452f8d6d 100644 --- a/icons/message-square-code.svg +++ b/icons/message-square-code.svg @@ -9,7 +9,7 @@ stroke-linecap="round" stroke-linejoin="round" > + + - - diff --git a/icons/search-code.json b/icons/search-code.json index 0c2b2491ce..7e3325cc57 100644 --- a/icons/search-code.json +++ b/icons/search-code.json @@ -1,7 +1,8 @@ { "$schema": "../icon.schema.json", "contributors": [ - "danielbayley" + "danielbayley", + "jguddas" ], "tags": [ "find", diff --git a/icons/search-code.svg b/icons/search-code.svg index 09d671f1b3..983add47a7 100644 --- a/icons/search-code.svg +++ b/icons/search-code.svg @@ -9,8 +9,8 @@ stroke-linecap="round" stroke-linejoin="round" > - - - + + + diff --git a/icons/square-code.svg b/icons/square-code.svg index 5bd0c81c94..0ac856560e 100644 --- a/icons/square-code.svg +++ b/icons/square-code.svg @@ -9,7 +9,7 @@ stroke-linecap="round" stroke-linejoin="round" > + + - - diff --git a/icons/square-dashed-bottom-code.svg b/icons/square-dashed-bottom-code.svg index 25b604a121..8b1c517896 100644 --- a/icons/square-dashed-bottom-code.svg +++ b/icons/square-dashed-bottom-code.svg @@ -9,9 +9,9 @@ stroke-linecap="round" stroke-linejoin="round" > - - + + + - From 45e82a51b822c0a00c069123fb92c9641d704d0b Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Wed, 24 Apr 2024 17:43:51 +0200 Subject: [PATCH 05/14] docs: Update readme files (#2102) * Update lucide readme * Add Readme and update package.jsons * Update readme * Update package logos * Update darkmode logos * Update title build font readme --- README.md | 5 +- .../package-logos/dark/lucide-angular.svg | 27 +++ .../package-logos/dark/lucide-preact.svg | 15 ++ .../dark/lucide-react-native.svg | 26 +++ .../package-logos/dark/lucide-react.svg | 15 ++ .../package-logos/dark/lucide-solid.svg | 39 ++++ .../package-logos/dark/lucide-static.svg | 16 ++ .../package-logos/dark/lucide-svelte.svg | 13 ++ docs/public/package-logos/dark/lucide-vue.svg | 13 ++ docs/public/package-logos/dark/lucide.svg | 13 ++ docs/public/package-logos/lucide-angular.svg | 40 ++-- docs/public/package-logos/lucide-flutter.svg | 15 -- docs/public/package-logos/lucide-preact.svg | 28 +-- .../package-logos/lucide-react-native.svg | 40 ++-- docs/public/package-logos/lucide-react.svg | 28 +-- docs/public/package-logos/lucide-solid.svg | 81 ++++---- docs/public/package-logos/lucide-static.svg | 30 +-- docs/public/package-logos/lucide-svelte.svg | 24 +-- docs/public/package-logos/lucide-vue-next.svg | 15 -- docs/public/package-logos/lucide-vue.svg | 25 ++- docs/public/package-logos/lucide.svg | 24 +-- docs/public/sponsors/scipress.svg | 6 + packages/lucide-angular/README.md | 105 +++-------- packages/lucide-preact/README.md | 73 +++---- packages/lucide-react-native/README.md | 67 +++---- packages/lucide-react/README.md | 137 +++----------- packages/lucide-solid/README.md | 75 +++----- packages/lucide-static/README.md | 178 +++--------------- packages/lucide-svelte/README.md | 88 +++------ packages/lucide-vue-next/README.md | 98 +++------- packages/lucide-vue/README.md | 120 +++--------- packages/lucide/README.md | 112 +++-------- tools/build-font/README.md | 3 + tools/build-font/package.json | 2 +- tools/build-icons/README.md | 3 + tools/build-icons/package.json | 3 +- tools/outline-svg/README.md | 3 + tools/outline-svg/package.json | 4 +- tools/rollup-plugins/README.md | 3 + tools/rollup-plugins/package.json | 3 +- 40 files changed, 600 insertions(+), 1015 deletions(-) create mode 100644 docs/public/package-logos/dark/lucide-angular.svg create mode 100644 docs/public/package-logos/dark/lucide-preact.svg create mode 100644 docs/public/package-logos/dark/lucide-react-native.svg create mode 100644 docs/public/package-logos/dark/lucide-react.svg create mode 100644 docs/public/package-logos/dark/lucide-solid.svg create mode 100644 docs/public/package-logos/dark/lucide-static.svg create mode 100644 docs/public/package-logos/dark/lucide-svelte.svg create mode 100644 docs/public/package-logos/dark/lucide-vue.svg create mode 100644 docs/public/package-logos/dark/lucide.svg delete mode 100644 docs/public/package-logos/lucide-flutter.svg delete mode 100644 docs/public/package-logos/lucide-vue-next.svg create mode 100644 docs/public/sponsors/scipress.svg create mode 100644 tools/build-font/README.md create mode 100644 tools/build-icons/README.md create mode 100644 tools/outline-svg/README.md create mode 100644 tools/rollup-plugins/README.md diff --git a/README.md b/README.md index 81235994f3..90e655232e 100644 --- a/README.md +++ b/README.md @@ -274,9 +274,12 @@ Thank you to all the people who contributed to Lucide! ## Sponsors - Powered by Vercel DigitalOcean Referral Badge + +### Awesome backer 🍺 + +Scipress sponsor badge diff --git a/docs/public/package-logos/dark/lucide-angular.svg b/docs/public/package-logos/dark/lucide-angular.svg new file mode 100644 index 0000000000..10d366c4e8 --- /dev/null +++ b/docs/public/package-logos/dark/lucide-angular.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/public/package-logos/dark/lucide-preact.svg b/docs/public/package-logos/dark/lucide-preact.svg new file mode 100644 index 0000000000..04c69d57e7 --- /dev/null +++ b/docs/public/package-logos/dark/lucide-preact.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/docs/public/package-logos/dark/lucide-react-native.svg b/docs/public/package-logos/dark/lucide-react-native.svg new file mode 100644 index 0000000000..99245bd2f7 --- /dev/null +++ b/docs/public/package-logos/dark/lucide-react-native.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/public/package-logos/dark/lucide-react.svg b/docs/public/package-logos/dark/lucide-react.svg new file mode 100644 index 0000000000..62aac8c145 --- /dev/null +++ b/docs/public/package-logos/dark/lucide-react.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/docs/public/package-logos/dark/lucide-solid.svg b/docs/public/package-logos/dark/lucide-solid.svg new file mode 100644 index 0000000000..adb63e1b72 --- /dev/null +++ b/docs/public/package-logos/dark/lucide-solid.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/public/package-logos/dark/lucide-static.svg b/docs/public/package-logos/dark/lucide-static.svg new file mode 100644 index 0000000000..84106a2068 --- /dev/null +++ b/docs/public/package-logos/dark/lucide-static.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/docs/public/package-logos/dark/lucide-svelte.svg b/docs/public/package-logos/dark/lucide-svelte.svg new file mode 100644 index 0000000000..e7caa49126 --- /dev/null +++ b/docs/public/package-logos/dark/lucide-svelte.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/public/package-logos/dark/lucide-vue.svg b/docs/public/package-logos/dark/lucide-vue.svg new file mode 100644 index 0000000000..74961aa18a --- /dev/null +++ b/docs/public/package-logos/dark/lucide-vue.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/public/package-logos/dark/lucide.svg b/docs/public/package-logos/dark/lucide.svg new file mode 100644 index 0000000000..2a13662333 --- /dev/null +++ b/docs/public/package-logos/dark/lucide.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/public/package-logos/lucide-angular.svg b/docs/public/package-logos/lucide-angular.svg index 9aff8cde63..3ffd2d6cbf 100644 --- a/docs/public/package-logos/lucide-angular.svg +++ b/docs/public/package-logos/lucide-angular.svg @@ -1,15 +1,27 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/public/package-logos/lucide-flutter.svg b/docs/public/package-logos/lucide-flutter.svg deleted file mode 100644 index 3313619aed..0000000000 --- a/docs/public/package-logos/lucide-flutter.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/docs/public/package-logos/lucide-preact.svg b/docs/public/package-logos/lucide-preact.svg index 7659de9d3b..98a2227a6b 100644 --- a/docs/public/package-logos/lucide-preact.svg +++ b/docs/public/package-logos/lucide-preact.svg @@ -1,15 +1,15 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/docs/public/package-logos/lucide-react-native.svg b/docs/public/package-logos/lucide-react-native.svg index 5bcafa4367..5400d4ad0f 100644 --- a/docs/public/package-logos/lucide-react-native.svg +++ b/docs/public/package-logos/lucide-react-native.svg @@ -1,16 +1,26 @@ - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/public/package-logos/lucide-react.svg b/docs/public/package-logos/lucide-react.svg index 9dc73199af..2e638d272c 100644 --- a/docs/public/package-logos/lucide-react.svg +++ b/docs/public/package-logos/lucide-react.svg @@ -1,15 +1,15 @@ - - - - - - - - - + + + + + + + + + + + + + + diff --git a/docs/public/package-logos/lucide-solid.svg b/docs/public/package-logos/lucide-solid.svg index caab9f37fb..21304bd454 100644 --- a/docs/public/package-logos/lucide-solid.svg +++ b/docs/public/package-logos/lucide-solid.svg @@ -1,44 +1,39 @@ - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/public/package-logos/lucide-static.svg b/docs/public/package-logos/lucide-static.svg index d3df584111..9dfa969926 100644 --- a/docs/public/package-logos/lucide-static.svg +++ b/docs/public/package-logos/lucide-static.svg @@ -1,16 +1,16 @@ - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/docs/public/package-logos/lucide-svelte.svg b/docs/public/package-logos/lucide-svelte.svg index df5863ce42..4ab04e88d5 100644 --- a/docs/public/package-logos/lucide-svelte.svg +++ b/docs/public/package-logos/lucide-svelte.svg @@ -1,13 +1,13 @@ - - - - - - - - - + + + + + + + + + + + + diff --git a/docs/public/package-logos/lucide-vue-next.svg b/docs/public/package-logos/lucide-vue-next.svg deleted file mode 100644 index 304cb803a4..0000000000 --- a/docs/public/package-logos/lucide-vue-next.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - diff --git a/docs/public/package-logos/lucide-vue.svg b/docs/public/package-logos/lucide-vue.svg index 3f30d654ed..6a21dbb8ad 100644 --- a/docs/public/package-logos/lucide-vue.svg +++ b/docs/public/package-logos/lucide-vue.svg @@ -1,14 +1,13 @@ - - - - - - - - - - + + + + + + + + + + + + diff --git a/docs/public/package-logos/lucide.svg b/docs/public/package-logos/lucide.svg index 709b337849..8c2a462e02 100644 --- a/docs/public/package-logos/lucide.svg +++ b/docs/public/package-logos/lucide.svg @@ -1,13 +1,13 @@ - - - - - - - - - + + + + + + + + + + + + diff --git a/docs/public/sponsors/scipress.svg b/docs/public/sponsors/scipress.svg new file mode 100644 index 0000000000..12f5f09054 --- /dev/null +++ b/docs/public/sponsors/scipress.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/lucide-angular/README.md b/packages/lucide-angular/README.md index 2450b502e6..d3bb79dfe8 100644 --- a/packages/lucide-angular/README.md +++ b/packages/lucide-angular/README.md @@ -1,3 +1,12 @@ +

+ + Lucide Angular - Implementation of the lucide icon library for angular applications. + + + Lucide Angular - Implementation of the lucide icon library for angular applications. + +

+ # Lucide Angular Implementation of the lucide icon library for angular applications. @@ -16,96 +25,26 @@ or npm install lucide-angular ``` -## How to use - -### Step 1: Import `LucideAngularModule` - -In any Angular module you wish to use Lucide icons in, you have to import `LucideAngularModule`, and pick any icons you wish to use: - -```js -import { LucideAngularModule, File, Home, Menu, UserCheck } from 'lucide-angular'; - -@NgModule({ - imports: [ - LucideAngularModule.pick({File, Home, Menu, UserCheck}) - ] -}) -export class AppModule { } -``` - -### Step 2: Use the icons in templates - -Within your templates you may now use one of the following component tags to insert an icon: - -```html - - - - -``` - -### Props - -You can pass additional props to adjust the icon appearance. - -| name | type | default | -| ------------------ | --------- | ------------ | -| `size` | _number_ | 24 | -| `color` | _string_ | currentColor | -| `strokeWidth` | _number_ | 2 | -| `absoluteStrokeWidth` | _boolean_ | true | - -```html - -``` - -### Global configuration - -You can inject the `LucideIconConfig` service in your root component to globally configure the default property values as defined above. - -### Styling using a custom CSS class - -Any extra HTML attribute is ignored, but the `class` attribute -is passed onto the internal SVG image element and it can be used to style it: - -```css -svg.my-icon { - width: 12px; - height: 12px; - stroke-width: 3; -} -``` - -## Injecting multiple icon providers +## Documentation -You may provide additional icons using the `LUCIDE_ICONS` injection token, -which accepts multiple providers of the interface `LucideIconsProviderInterface` -with the utility class `LucideIconsProvider` available for easier usage: +For full documentation, visit [lucide.dev](https://lucide.dev/guide/packages/lucide-angular) -```js -import { LUCIDE_ICONS, LucideIconProvider } from 'lucide-angular'; -import { MyIcon } from './icons/my-icon'; +## Community -const myIcons = {MyIcon}; +Join the [Discord server](https://discord.gg/EH6nSts) to chat with the maintainers and other users. -@NgModule({ - providers: [ - {provide: LUCIDE_ICONS, multi: true, useValue: new LucideIconProvider(myIcons)}, - ] -}) -export class AppModule { } -``` +## License -To add custom icons, you will first need to convert them to an [svgson format](https://github.com/elrumordelaluz/svgson). +Lucide is licensed under the ICS license. See [LICENSE](https://lucide.dev/license). -## Loading all icons +## Sponsors -> :warning: You may also opt to import all icons if necessary using the following format but be aware that this will significantly increase your application build size. + + Powered by Vercel + -```js -import { icons } from 'lucide-angular'; +DigitalOcean Referral Badge -... +### Awesome backer 🍺 -LucideAngularModule.pick(icons) -``` +Scipress sponsor badge diff --git a/packages/lucide-preact/README.md b/packages/lucide-preact/README.md index ec0e9df54d..153224112f 100644 --- a/packages/lucide-preact/README.md +++ b/packages/lucide-preact/README.md @@ -1,3 +1,12 @@ +

+ + Lucide Preact - Implementation of the lucide icon library for preact applications. + + + Lucide Preact - Implementation of the lucide icon library for preact applications. + +

+ # Lucide Preact Implementation of the lucide icon library for preact applications. @@ -16,64 +25,26 @@ or npm install lucide-preact ``` -## How to use - -It's build with ESmodules so it's completely tree-shakable. -Each icon can be imported as a preact component. - -### Example - -You can pass additional props to adjust the icon. - -```js -import { Camera } from 'lucide-preact'; -// Returns PreactComponent - -// Usage -const App = () => { - return ; -}; - -export default App; -``` - -### Props +## Documentation -| name | type | default | -| ------------- | -------- | ------------ | -| `size` | _Number_ | 24 | -| `color` | _String_ | currentColor | -| `strokeWidth` | _Number_ | 2 | +For full documentation, visit [lucide.dev](https://lucide.dev/guide/packages/lucide-preact) -### Custom props / svg attributes +## Community -You can also pass custom props that will be added in the as attributes. With that you can modify the icons look by passing svg attributes. - -```js -// Usage -const App = () => { - return ; -}; -``` +Join the [Discord server](https://discord.gg/EH6nSts) to chat with the maintainers and other users. -> svg attributes in preact aren't transformed, so if want to change e.g. the `stroke-linejoin` you need to pass it in kebabcase, the way svg spec is written so. See this topic in the [preact documentation](https://preactjs.com/guide/v10/differences-to-react/#svg-inside-jsx). +## License -### One generic icon component +Lucide is licensed under the ICS license. See [LICENSE](https://lucide.dev/license). -It is possible to create one generic icon component to load icons. +## Sponsors -> :warning: Example below importing all EsModules, caution using this example, not recommended when you using bundlers, your application build size will grow strongly. + + Powered by Vercel + -#### Icon Component Example +DigitalOcean Referral Badge -```js -import * as icons from 'lucide-preact'; +### Awesome backer 🍺 -const Icon = ({ name, color, size }) => { - const LucideIcon = icons[name]; - - return ; -}; - -export default Icon; -``` +Scipress sponsor badge diff --git a/packages/lucide-react-native/README.md b/packages/lucide-react-native/README.md index 561b845447..4fed29661b 100644 --- a/packages/lucide-react-native/README.md +++ b/packages/lucide-react-native/README.md @@ -1,3 +1,13 @@ +

+ + Lucide React Native - Implementation of the lucide icon library for React Native applications. + + + Lucide React Native - Implementation of the lucide icon library for React Native applications. + +

+ + # Lucide React Native Implementation of the lucide icon library for React Native applications. @@ -18,57 +28,26 @@ or npm install lucide-react-native ``` -## How to use +## Documentation -It's built with ES modules so it's completely tree-shakable. -Each icon can be imported as a react component. +For full documentation, visit [lucide.dev](https://lucide.dev/guide/packages/lucide-react-native) -### Example +## Community -You can pass additional props to adjust the icon. +Join the [Discord server](https://discord.gg/EH6nSts) to chat with the maintainers and other users. -```js -import { Camera } from 'lucide-react-native'; +## License -const App = () => { - return ; -}; - -export default App; -``` +Lucide is licensed under the ICS license. See [LICENSE](https://lucide.dev/license). -### Props +## Sponsors -| name | type | default | -| ------------- | -------- | ------------ | -| `size` | _Number_ | 24 | -| `color` | _String_ | currentColor | -| `strokeWidth` | _Number_ | 2 | + + Powered by Vercel + -### Custom props - -You can also pass custom props that will be added in the svg as attributes. - -```js -const App = () => { - return ; -}; -``` +DigitalOcean Referral Badge -### Generic icon component +### Awesome backer 🍺 -It is possible to create a generic icon component to load icons. - -> :warning: The example below is importing all ES modules. This is **not** recommended when you using a bundler since your application build size will grow substantially. - -```js -import * as icons from 'lucide-react-native'; - -const Icon = ({ name, color, size }) => { - const LucideIcon = icons[name]; - - return ; -}; - -export default Icon; -``` +Scipress sponsor badge diff --git a/packages/lucide-react/README.md b/packages/lucide-react/README.md index beeb4b9c4e..2bb1c106c5 100644 --- a/packages/lucide-react/README.md +++ b/packages/lucide-react/README.md @@ -1,3 +1,13 @@ +

+ + Lucide React - Implementation of the lucide icon library for preact applications. + + + Lucide React - Implementation of the lucide icon library for preact applications. + +

+ + # Lucide React Implementation of the lucide icon library for react applications. @@ -16,127 +26,26 @@ or npm install lucide-react ``` -## How to use - -It's built with ES modules so it's completely tree-shakable. -Each icon can be imported as a react component. - -### Example - -You can pass additional props to adjust the icon. - -```js -import { Camera } from 'lucide-react'; - -const App = () => { - return ; -}; - -export default App; -``` - -### Props +## Documentation -| name | type | default | -| ------------- | -------- | ------------ | -| `size` | _Number_ | 24 | -| `color` | _String_ | currentColor | -| `strokeWidth` | _Number_ | 2 | +For full documentation, visit [lucide.dev](https://lucide.dev/guide/packages/lucide-react) -### Custom props +## Community -You can also pass custom props that will be added in the svg as attributes. - -```js -const App = () => { - return ; -}; -``` - -### Generic icon component - -It is possible to create a generic icon component to load icons. - -> :warning: The example below is importing all ES modules. This is **not** recommended when you using a bundler since your application build size will grow substantially. - -```js -import { icons } from 'lucide-react'; - -const Icon = ({ name, color, size }) => { - const LucideIcon = icons[name]; - - return ; -}; - -export default Icon; -``` +Join the [Discord server](https://discord.gg/EH6nSts) to chat with the maintainers and other users. -#### With Dynamic Imports +## License -Lucide react exports a dynamic import map `dynamicIconImports`. Useful for applications that want to show icons dynamically by icon name. For example when using a content management system with where icon names are stored in a database. +Lucide is licensed under the ICS license. See [LICENSE](https://lucide.dev/license). -When using client side rendering, it will fetch the icon component when it's needed. This will reduce the initial bundle size. +## Sponsors -The keys of the dynamic import map are the lucide original icon names. + + Powered by Vercel + -Example with React suspense: +DigitalOcean Referral Badge -```tsx -import React, { lazy, Suspense } from 'react'; -import { LucideProps } from 'lucide-react'; -import dynamicIconImports from 'lucide-react/dynamicIconImports'; +### Awesome backer 🍺 -const fallback =
- -interface IconProps extends Omit { - name: keyof typeof dynamicIconImports; -} - -const Icon = ({ name, ...props }: IconProps) => { - const LucideIcon = lazy(dynamicIconImports[name]); - - return ( - - - - ); -} - -export default Icon -``` - -##### NextJS Example - -In NextJS, [the dynamic function](https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading#nextdynamic) can be used to dynamically load the icon component. - -To make dynamic imports work with NextJS, you need to add `lucide-react` to the [`transpilePackages`](https://nextjs.org/docs/app/api-reference/next-config-js/transpilePackages) option in your `next.config.js` like this: - -```js -/** @type {import('next').NextConfig} */ -const nextConfig = { - transpilePackages: ['lucide-react'] // add this -} - -module.exports = nextConfig - -``` - -You can then start using it: - -```tsx -import dynamic from 'next/dynamic' -import { LucideProps } from 'lucide-react'; -import dynamicIconImports from 'lucide-react/dynamicIconImports'; - -interface IconProps extends LucideProps { - name: keyof typeof dynamicIconImports; -} - -const Icon = ({ name, ...props }: IconProps) => { - const LucideIcon = dynamic(dynamicIconImports[name]) - - return ; -}; - -export default Icon; -``` +Scipress sponsor badge diff --git a/packages/lucide-solid/README.md b/packages/lucide-solid/README.md index 211c91ce19..8e6187ed7e 100644 --- a/packages/lucide-solid/README.md +++ b/packages/lucide-solid/README.md @@ -1,3 +1,13 @@ +

+ + Lucide Solid - Implementation of the lucide icon library for solid applications. + + + Lucide Solid - Implementation of the lucide icon library for solid applications. + +

+ + # Lucide Solid Implementation of the lucide icon library for solid applications. @@ -16,65 +26,26 @@ or npm install lucide-solid ``` -## How to use - -It's build with ESmodules so it's completely tree-shakable. -Each icon can be imported as a solid component. - -### Example - -You can pass additional props to adjust the icon. - -```js -import { Camera } from 'lucide-solid'; -// Returns SolidComponent - -// Usage -const App = () => { - return ; -}; - -export default App; -``` - -### Props +## Documentation -| name | type | default | -| ------------- | -------- | ------------ | -| `size` | _Number_ | 24 | -| `color` | _String_ | currentColor | -| `strokeWidth` | _Number_ | 2 | +For full documentation, visit [lucide.dev](https://lucide.dev/guide/packages/lucide-solid) -### Custom props / svg attributes +## Community -You can also pass custom props that will be added in the as attributes. With that you can modify the icons look by passing svg attributes. +Join the [Discord server](https://discord.gg/EH6nSts) to chat with the maintainers and other users. -```js -// Usage -const App = () => { - return ; -}; -``` +## License -### One generic icon component +Lucide is licensed under the ICS license. See [LICENSE](https://lucide.dev/license). -It is possible to create one generic icon component to load icons. +## Sponsors -> :warning: Example below importing all EsModules, caution using this example, not recommended when you using bundlers, your application build size will grow strongly. + + Powered by Vercel + -#### Icon Component Example +DigitalOcean Referral Badge -```tsx -import * as icons from 'lucide-solid'; -import type { LucideProps } from 'lucide-solid'; -import { splitProps } from 'solid-js'; -import { Dynamic } from 'solid-js/web'; +### Awesome backer 🍺 -const Icon = (props: { name: keyof typeof icons } & LucideProps) => { - const [local, others] = splitProps(props, ["name"]); - - return -}; - -export default Icon; -``` +Scipress sponsor badge diff --git a/packages/lucide-static/README.md b/packages/lucide-static/README.md index 93fa392c77..3011c7b05b 100644 --- a/packages/lucide-static/README.md +++ b/packages/lucide-static/README.md @@ -1,3 +1,13 @@ +

+ + Lucide Static - Implementation of the lucide icon library for web applications. + + + Lucide Static - Implementation of the lucide icon library for web applications. + +

+ + # Lucide Static This package include the following lucide implementations: @@ -30,168 +40,26 @@ or npm install lucide-static ``` -### CDN - -```html - - - - - -``` - -## Usage - -Checkout the [codesandbox examples](https://codesandbox.io/s/using-the-svg-sprite-lz1kk). - -### SVG Files - -#### Svg file as image - -To use it in for example html: - -```html - - -``` - -```css -.home-icon { - background-image: url(~lucide-static/icons/home.svg); -} -``` - -Make sure you have the correct webpack loaders to make this work. [url-loader](https://v4.webpack.js.org/loaders/url-loader/) - -#### Svg file Inline - -You can simply import each svg by targeting `lucide-static/icons/{icon-name}.svg`. -To use svgs in your project you can for example use a [svg loader](https://v4.webpack.js.org/loaders/svg-inline-loader/). - -```js -import arrowRightIcon from 'lucide-static/icons/arrow-right'; - -// return string of a svg -``` - -### SVG Sprite +## Documentation -You may need additional loader for this. +For full documentation, visit [lucide.dev](https://lucide.dev/guide/packages/lucide-static) -```html - - - - - - - - -...sprite svg -``` - -If you'd prefer, you can use CSS to hold your base SVG properties - -```css -.lucide-icon { - width: 24px; - height: 24px; - stroke: currentColor; - fill: none; - stroke-width: 2; - stroke-linecap: round; - stroke-linejoin: round; -} -``` - -and update the svg as follows - -```svg - - - - - ...sprite svg - -``` - -### Icon Font - -```css -@import ('~lucide-static/font/lucide.css'); -``` - -```html -
-``` - -### Node.js - -To use lucide icons in your Nodejs project you can import each icon as: - -```js -const { messageSquare } = require('lucide-static/lib'); -``` +## Community -> Note: Each icon name is in camelCase. - -#### Example in node.js project - -```js -const express = require('express'); -const { messageSquare } = require('lucide-static/lib'); -const app = express(); -const port = 3000; - -app.get('/', (req, res) => { - res.send(` - - - - Page Title - - -

Lucide Icons

-

This is a lucide icon ${messageSquare}

- - - - `); -}); - -app.listen(port, () => { - console.log(`Example app listening at http://localhost:${port}`); -}); -``` +Join the [Discord server](https://discord.gg/EH6nSts) to chat with the maintainers and other users. -## Contributing +## License -For more info on how to contribute please see the [contribution guidelines](https://github.com/lucide-icons/lucide/blob/main/CONTRIBUTING.md). +Lucide is licensed under the ICS license. See [LICENSE](https://lucide.dev/license). -Caught a mistake or want to contribute to the documentation? [Edit this page on Github](https://github.com/lucide-icons/lucide/blob/main/README.md) +## Sponsors -## Community + + Powered by Vercel + -Join the community on our [Discord](https://discord.gg/EH6nSts) server! +DigitalOcean Referral Badge -## License +### Awesome backer 🍺 -Lucide is totally free for commercial use and personally use, this software is licensed under the [ISC License](https://github.com/lucide-icons/lucide/blob/main/LICENSE). +Scipress sponsor badge diff --git a/packages/lucide-svelte/README.md b/packages/lucide-svelte/README.md index d60241a719..43f6954335 100644 --- a/packages/lucide-svelte/README.md +++ b/packages/lucide-svelte/README.md @@ -1,3 +1,13 @@ +

+ + Lucide Svelte - Implementation of the lucide icon library for svelte applications. + + + Lucide Svelte - Implementation of the lucide icon library for web applications. + +

+ + # Lucide Svelte Implementation of the lucide icon library for svelte applications. @@ -16,78 +26,26 @@ or npm install lucide-svelte ``` -## How to use - -All the icons are Svelte components, that ouputs Svg elements. So each icon can be imported and used as a component. This also helps with the use of threeshaking so you only import the icons you use. +## Documentation -### Example +For full documentation, visit [lucide.dev](https://lucide.dev/guide/packages/lucide-svelte) -Default usage: +## Community -```sv - +Join the [Discord server](https://discord.gg/EH6nSts) to chat with the maintainers and other users. - -``` - -You can pass additional props to adjust the icon. +## License -```sv - +Lucide is licensed under the ICS license. See [LICENSE](https://lucide.dev/license). - -``` +## Sponsors -### Available props + + Powered by Vercel + -| name | type | default | -| ------------- | -------- | ------------ | -| `size` | _Number_ | 24 | -| `color` | _String_ | currentColor | -| `strokeWidth` | _Number_ | 2 | -| `*` | _String_ | - | - -- All SVGProps are available to style the svgs. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation) - -### Example of custom props - -```sv - - - -``` +DigitalOcean Referral Badge -This results a filled phone icon. +### Awesome backer 🍺 -### One generic icon component - -It is possible to create one generic icon component to load icons. - -> :warning: Example below importing all EsModules, caution using this example, not recommended when you bundle your application,the build size will grow strongly. Because it will import all the icons. - -#### Icon Component Example - -```svelte - - - -``` - -##### Then you can use it like this - -```svelte - - - -``` +Scipress sponsor badge diff --git a/packages/lucide-vue-next/README.md b/packages/lucide-vue-next/README.md index 565dc7c490..29cd486804 100644 --- a/packages/lucide-vue-next/README.md +++ b/packages/lucide-vue-next/README.md @@ -1,3 +1,12 @@ +

+ + Lucide Vue Next - Implementation of the lucide icon library for Vue 3 applications. + + + Lucide Vue Next - Implementation of the lucide icon library for Vue 3 applications. + +

+ # Lucide Vue Next Implementation of the lucide icon library for Vue 3 applications. @@ -18,89 +27,26 @@ or npm install lucide-vue-next ``` -## How to use - -It's build with ESmodules so it's completely tree-shakable. -Each icon can be imported as a vue component. - -### Example - -You can pass additional props to adjust the icon. +## Documentation -```vue - +For full documentation, visit [lucide.dev](https://lucide.dev/guide/packages/lucide-vue-next) - -``` - -### Props +Join the [Discord server](https://discord.gg/EH6nSts) to chat with the maintainers and other users. -| name | type | default | -| ----------------------- | --------- | ------------ | -| `size` | *number* | 24 | -| `color` | *string* | currentColor | -| `stroke-width` | *number* | 2 | -| `absolute-stroke-width` | *boolean* | false | -| `default-class` | *string* | lucide-icon | +## License -### Custom props +Lucide is licensed under the ICS license. See [LICENSE](https://lucide.dev/license). -You can also pass custom props that will be added in the svg as attributes. - -```vue - -``` +## Sponsors -### One generic icon component + + Powered by Vercel + -It is possible to create one generic icon component to load icons. +DigitalOcean Referral Badge -> :warning: Example below importing all EsModules, caution using this example, not recommended when you using bundlers, your application build size will grow strongly. +### Awesome backer 🍺 -#### Icon Component Example - -```vue - - - -``` - -##### Then you can use it like this - -```vue - -``` +Scipress sponsor badge diff --git a/packages/lucide-vue/README.md b/packages/lucide-vue/README.md index b1007b0e5e..daa1df6110 100644 --- a/packages/lucide-vue/README.md +++ b/packages/lucide-vue/README.md @@ -1,3 +1,12 @@ +

+ + Lucide Vue - Implementation of the lucide icon library for Vue applications. + + + Lucide Vue - Implementation of the lucide icon library for Vue applications. + +

+ # Lucide Vue Implementation of the lucide icon library for Vue applications. @@ -18,111 +27,26 @@ or npm install lucide-vue ``` -## How to use - -It's build with ESmodules so it's completely tree-shakable. -Each icon can be imported as a vue component. +## Documentation -### Example +For full documentation, visit [lucide.dev](https://lucide.dev/guide/packages/lucide-vue) -You can pass additional props to adjust the icon. +## Community -```vue - +Join the [Discord server](https://discord.gg/EH6nSts) to chat with the maintainers and other users. - -``` +## License -### Props +Lucide is licensed under the ICS license. See [LICENSE](https://lucide.dev/license). -| name | type | default | -| ----------------------- | --------- | ------------ | -| `size` | *number* | 24 | -| `color` | *string* | currentColor | -| `stroke-width` | *number* | 2 | -| `absolute-stroke-width` | *boolean* | false | -| `default-class` | *string* | lucide-icon | +## Sponsors -### Custom props - -You can also pass custom props that will be added in the svg as attributes. - -```vue - -``` + + Powered by Vercel + -### One generic icon component +DigitalOcean Referral Badge -It is possible to create one generic icon component to load icons. - -> :warning: Example below importing all EsModules, caution using this example, not recommended when you using bundlers, your application build size will grow strongly. - -#### Icon Component Example - -```vue - - - -``` +### Awesome backer 🍺 -##### Then you can use it like this - -```vue - -``` - -## Use with [@nuxt/components](https://github.com/nuxt/components#readme) - -### Setup - -In your `nuxt.config.js`, add `lucide-vue/nuxt` to your `buildModules` - -```js -export default { - buildModules: ['lucide-vue/nuxt'] -}; -``` - -### How to use - -Icon components are prefixed with `Icon`. Use icon components without importing them. - -### Example - -```html - -``` +Scipress sponsor badge diff --git a/packages/lucide/README.md b/packages/lucide/README.md index b75cd96374..ea5a29bb1b 100644 --- a/packages/lucide/README.md +++ b/packages/lucide/README.md @@ -1,3 +1,12 @@ +

+ + Lucide - Implementation of the lucide icon library for web applications. + + + Lucide - Implementation of the lucide icon library for web applications. + +

+ # Lucide Implementation of the lucide icon library for web applications. @@ -10,7 +19,9 @@ Implementation of the lucide icon library for web applications. npm install lucide ``` -or +```sh +pnpm install lucide +``` ```sh yarn add lucide @@ -26,99 +37,26 @@ yarn add lucide ``` -## Usage - -### With unpkg - -Here is a complete example with unpkg - -```html - - - - - - - - - -``` - -### With ESModules - -To reduce bundle size, lucide is built to be fully tree-shakable. -The `createIcons` function will search for HTMLElements with the attribute `data-lucide` and replace it with the svg from the given icon name. - -```html - - -``` - -```js -import { createIcons, icons } from 'lucide'; - -// Caution, this will import all the icons and bundle them. -createIcons({ icons }); - -// Recommended way, to include only the icons you need. -import { createIcons, Menu, ArrowRight, Globe } from 'lucide'; - -createIcons({ - icons: { - Menu, - ArrowRight, - Globe - } -}); -``` - -#### Additional Options - -In the `createIcons` function you can pass some extra parameters to adjust the `nameAttr` or add custom attributes like for example classes. - -Here is a full example: +## Documentation -```js -import { createIcons } from 'lucide'; +For full documentation, visit [lucide.dev](https://lucide.dev/guide/packages/lucide) -createIcons({ - attrs: { - class: ['my-custom-class', 'icon'], - 'stroke-width': 1, - stroke: '#333' - }, - nameAttr: 'data-lucide' // attribute for the icon name. -}); -``` +## Community -#### Treeshake the library, only use the icons you use +Join the [Discord server](https://discord.gg/EH6nSts) to chat with the maintainers and other users. -```js -import { createIcons, Menu, ArrowRight, Globe } from 'lucide'; +## License -createIcons({ - icons: { - Menu, - ArrowRight, - Globe - } -}); -``` +Lucide is licensed under the ICS license. See [LICENSE](https://lucide.dev/license). -#### Custom Element binding +## Sponsors -```js -import { createElement, Menu } from 'lucide'; + + Powered by Vercel + -const menuIcon = createElement(Menu); // Returns HTMLElement (svg) +DigitalOcean Referral Badge -// set custom attributes with browser native functions -menuIcon.setAttribute('stroke', '#333'); -menuIcon.classList.add('my-icon-class'); +### Awesome backer 🍺 -// Append HTMLElement in webpage -const myApp = document.getElementById('app'); -myApp.appendChild(menuIcon); -``` +Scipress sponsor badge diff --git a/tools/build-font/README.md b/tools/build-font/README.md new file mode 100644 index 0000000000..51786ac75a --- /dev/null +++ b/tools/build-font/README.md @@ -0,0 +1,3 @@ +# @lucide/build-font + +A internal used package to build the font. diff --git a/tools/build-font/package.json b/tools/build-font/package.json index 3eaa776579..da862f312d 100644 --- a/tools/build-font/package.json +++ b/tools/build-font/package.json @@ -1,8 +1,8 @@ { "name": "build-font", + "description": "A internal used package to build the font.", "private": true, "version": "1.0.0", - "description": "", "main": "index.js", "scripts": { "start": "node ./main.mjs" diff --git a/tools/build-icons/README.md b/tools/build-icons/README.md new file mode 100644 index 0000000000..c01c3fcb8a --- /dev/null +++ b/tools/build-icons/README.md @@ -0,0 +1,3 @@ +# @lucide/build-icons + +A internal used package to build icon code files for the lucide icon library packages. diff --git a/tools/build-icons/package.json b/tools/build-icons/package.json index 56e70c0cd2..92beb4610e 100644 --- a/tools/build-icons/package.json +++ b/tools/build-icons/package.json @@ -1,8 +1,7 @@ { "name": "@lucide/build-icons", - "private": true, + "description": "A internal used package to build icon code files for the lucide icon library packages.", "version": "1.0.0", - "description": "", "main": "index.mjs", "type": "module", "scripts": { diff --git a/tools/outline-svg/README.md b/tools/outline-svg/README.md new file mode 100644 index 0000000000..dab688975d --- /dev/null +++ b/tools/outline-svg/README.md @@ -0,0 +1,3 @@ +# @lucide/outline-svg + +A internal used package to outline SVGs. diff --git a/tools/outline-svg/package.json b/tools/outline-svg/package.json index 3d2e93c336..dc4f49ce02 100644 --- a/tools/outline-svg/package.json +++ b/tools/outline-svg/package.json @@ -1,8 +1,8 @@ { - "name": "outline-svg", + "name": "@lucide/outline-svg", + "description": "A internal used package to outline SVGs.", "private": true, "version": "2.0.0", - "description": "", "main": "index.js", "scripts": { "start": "node ./main.mjs" diff --git a/tools/rollup-plugins/README.md b/tools/rollup-plugins/README.md new file mode 100644 index 0000000000..6caba5acd3 --- /dev/null +++ b/tools/rollup-plugins/README.md @@ -0,0 +1,3 @@ +# @lucide/rollup-plugins + +A internal used package with a collection of rollup plugins used to build the lucide icon library packages. diff --git a/tools/rollup-plugins/package.json b/tools/rollup-plugins/package.json index a86e398036..26ea9604b3 100644 --- a/tools/rollup-plugins/package.json +++ b/tools/rollup-plugins/package.json @@ -1,8 +1,7 @@ { "name": "@lucide/rollup-plugins", - "private": true, "version": "1.0.0", - "description": "", + "description": "A internal used package with a collection of rollup plugins used to build the lucide icon library packages.", "main": "plugins.js", "module": "plugins.js", "author": "", From 09420cbca53283a4890edd380a98a3feccdfc0af Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Thu, 25 Apr 2024 09:45:07 +0200 Subject: [PATCH 06/14] docs: Fix dark logo paths --- README.md | 9 ++++++++- docs/public/lucide-logo-repo-dark.svg | 10 ++++++++++ docs/public/lucide-logo-repo.svg | 17 +++++++++-------- packages/lucide-angular/README.md | 4 ++-- packages/lucide-preact/README.md | 4 ++-- packages/lucide-react-native/README.md | 4 ++-- packages/lucide-react/README.md | 4 ++-- packages/lucide-solid/README.md | 4 ++-- packages/lucide-static/README.md | 4 ++-- packages/lucide-svelte/README.md | 4 ++-- packages/lucide-vue-next/README.md | 4 ++-- packages/lucide-vue/README.md | 4 ++-- 12 files changed, 45 insertions(+), 27 deletions(-) create mode 100644 docs/public/lucide-logo-repo-dark.svg diff --git a/README.md b/README.md index 90e655232e..6076562c33 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,11 @@ -

Lucide Logo

+

+ + Lucide - Beautiful & consistent icon toolkit made by the community. Open-source project and a fork of Feather Icons. + + + Lucide - Beautiful & consistent icon toolkit made by the community. Open-source project and a fork of Feather Icons. + +

license npm package diff --git a/docs/public/lucide-logo-repo-dark.svg b/docs/public/lucide-logo-repo-dark.svg new file mode 100644 index 0000000000..7466579c0b --- /dev/null +++ b/docs/public/lucide-logo-repo-dark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/docs/public/lucide-logo-repo.svg b/docs/public/lucide-logo-repo.svg index 582d573df3..40c27061a2 100644 --- a/docs/public/lucide-logo-repo.svg +++ b/docs/public/lucide-logo-repo.svg @@ -1,9 +1,10 @@ - - - - - - - - + + + + + + + + + diff --git a/packages/lucide-angular/README.md b/packages/lucide-angular/README.md index d3bb79dfe8..2b999823a6 100644 --- a/packages/lucide-angular/README.md +++ b/packages/lucide-angular/README.md @@ -1,9 +1,9 @@

- Lucide Angular - Implementation of the lucide icon library for angular applications. + Lucide Angular - Implementation of the lucide icon library for angular applications. - Lucide Angular - Implementation of the lucide icon library for angular applications. + Lucide Angular - Implementation of the lucide icon library for angular applications.

diff --git a/packages/lucide-preact/README.md b/packages/lucide-preact/README.md index 153224112f..5e3bed209b 100644 --- a/packages/lucide-preact/README.md +++ b/packages/lucide-preact/README.md @@ -1,9 +1,9 @@

- Lucide Preact - Implementation of the lucide icon library for preact applications. + Lucide Preact - Implementation of the lucide icon library for preact applications. - Lucide Preact - Implementation of the lucide icon library for preact applications. + Lucide Preact - Implementation of the lucide icon library for preact applications.

diff --git a/packages/lucide-react-native/README.md b/packages/lucide-react-native/README.md index 4fed29661b..94ae70dd3c 100644 --- a/packages/lucide-react-native/README.md +++ b/packages/lucide-react-native/README.md @@ -1,9 +1,9 @@

- Lucide React Native - Implementation of the lucide icon library for React Native applications. + Lucide React Native - Implementation of the lucide icon library for React Native applications. - Lucide React Native - Implementation of the lucide icon library for React Native applications. + Lucide React Native - Implementation of the lucide icon library for React Native applications.

diff --git a/packages/lucide-react/README.md b/packages/lucide-react/README.md index 2bb1c106c5..9306272422 100644 --- a/packages/lucide-react/README.md +++ b/packages/lucide-react/README.md @@ -1,9 +1,9 @@

- Lucide React - Implementation of the lucide icon library for preact applications. + Lucide React - Implementation of the lucide icon library for react applications. - Lucide React - Implementation of the lucide icon library for preact applications. + Lucide React - Implementation of the lucide icon library for react applications.

diff --git a/packages/lucide-solid/README.md b/packages/lucide-solid/README.md index 8e6187ed7e..afe374e4cc 100644 --- a/packages/lucide-solid/README.md +++ b/packages/lucide-solid/README.md @@ -1,9 +1,9 @@

- Lucide Solid - Implementation of the lucide icon library for solid applications. + Lucide Solid - Implementation of the lucide icon library for solid applications. - Lucide Solid - Implementation of the lucide icon library for solid applications. + Lucide Solid - Implementation of the lucide icon library for solid applications.

diff --git a/packages/lucide-static/README.md b/packages/lucide-static/README.md index 3011c7b05b..30fe4355bd 100644 --- a/packages/lucide-static/README.md +++ b/packages/lucide-static/README.md @@ -1,9 +1,9 @@

- Lucide Static - Implementation of the lucide icon library for web applications. + Lucide Static - Implementation of the lucide icon library for web applications. - Lucide Static - Implementation of the lucide icon library for web applications. + Lucide Static - Implementation of the lucide icon library for web applications.

diff --git a/packages/lucide-svelte/README.md b/packages/lucide-svelte/README.md index 43f6954335..3d168b9d66 100644 --- a/packages/lucide-svelte/README.md +++ b/packages/lucide-svelte/README.md @@ -1,9 +1,9 @@

- Lucide Svelte - Implementation of the lucide icon library for svelte applications. + Lucide Svelte - Implementation of the lucide icon library for svelte applications. - Lucide Svelte - Implementation of the lucide icon library for web applications. + Lucide Svelte - Implementation of the lucide icon library for web applications.

diff --git a/packages/lucide-vue-next/README.md b/packages/lucide-vue-next/README.md index 29cd486804..d22df55eef 100644 --- a/packages/lucide-vue-next/README.md +++ b/packages/lucide-vue-next/README.md @@ -1,9 +1,9 @@

- Lucide Vue Next - Implementation of the lucide icon library for Vue 3 applications. + Lucide Vue Next - Implementation of the lucide icon library for Vue 3 applications. - Lucide Vue Next - Implementation of the lucide icon library for Vue 3 applications. + Lucide Vue Next - Implementation of the lucide icon library for Vue 3 applications.

diff --git a/packages/lucide-vue/README.md b/packages/lucide-vue/README.md index daa1df6110..3029ac15c4 100644 --- a/packages/lucide-vue/README.md +++ b/packages/lucide-vue/README.md @@ -1,9 +1,9 @@

- Lucide Vue - Implementation of the lucide icon library for Vue applications. + Lucide Vue - Implementation of the lucide icon library for Vue applications. - Lucide Vue - Implementation of the lucide icon library for Vue applications. + Lucide Vue - Implementation of the lucide icon library for Vue applications.

From b593355537a0f01013cb1fe04ea21f5847b6c08a Mon Sep 17 00:00:00 2001 From: Kyle Angelo Galendez Date: Fri, 26 Apr 2024 16:40:08 +0800 Subject: [PATCH 07/14] Add more OS (#2100) This includes ChromeOS, iOS, and Android to ensure the report is concise as possible. --- .github/ISSUE_TEMPLATE/03_bug_report_site.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/03_bug_report_site.yml b/.github/ISSUE_TEMPLATE/03_bug_report_site.yml index 36438cf439..8b1cda4afc 100644 --- a/.github/ISSUE_TEMPLATE/03_bug_report_site.yml +++ b/.github/ISSUE_TEMPLATE/03_bug_report_site.yml @@ -30,6 +30,9 @@ body: - label: Windows - label: Linux - label: macOS + - label: ChromeOS + - label: iOS + - label: Android - label: Other/not relevant - type: textarea id: description From e8ccd3df7ec7b8d9f4f0080d243d3d9070829d44 Mon Sep 17 00:00:00 2001 From: Kyle Angelo Galendez Date: Fri, 26 Apr 2024 16:40:29 +0800 Subject: [PATCH 08/14] Add more OS (#2101) This includes ChromeOS, iOS, and Android to ensure the report is concise as possible. --- .github/ISSUE_TEMPLATE/02_bug_report.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/02_bug_report.yml b/.github/ISSUE_TEMPLATE/02_bug_report.yml index 57b78728f5..21dd4e1f2c 100644 --- a/.github/ISSUE_TEMPLATE/02_bug_report.yml +++ b/.github/ISSUE_TEMPLATE/02_bug_report.yml @@ -69,6 +69,9 @@ body: - label: Windows - label: Linux - label: macOS + - label: ChromeOS + - label: iOS + - label: Android - label: Other/not relevant - type: textarea id: description From dff21721736a61b32f84f7caebab73b2e29b451b Mon Sep 17 00:00:00 2001 From: Jakob Guddas Date: Fri, 26 Apr 2024 10:42:33 +0200 Subject: [PATCH 09/14] Updated icons/printer.svg (#2066) --- icons/printer.svg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/icons/printer.svg b/icons/printer.svg index f08af6236e..dfa0a608eb 100644 --- a/icons/printer.svg +++ b/icons/printer.svg @@ -9,7 +9,7 @@ stroke-linecap="round" stroke-linejoin="round" > - - + + From 8c1e56a7bf1b70f689453ad46db14311fb305759 Mon Sep 17 00:00:00 2001 From: Jakob Guddas Date: Fri, 26 Apr 2024 10:59:23 +0200 Subject: [PATCH 10/14] fix(icons): arcify `activity` icon (#2058) * Updated icons/activity.svg * Updated icons/activity.svg * Updated icons/activity.json * Updated icons/activity.svg * Updated icons/activity.svg * Update icons/activity.svg Co-authored-by: Karsa --------- Co-authored-by: Karsa --- icons/activity.json | 3 ++- icons/activity.svg | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/icons/activity.json b/icons/activity.json index d3e2abd739..05107c172b 100644 --- a/icons/activity.json +++ b/icons/activity.json @@ -1,7 +1,8 @@ { "$schema": "../icon.schema.json", "contributors": [ - "colebemis" + "colebemis", + "jguddas" ], "tags": [ "pulse", diff --git a/icons/activity.svg b/icons/activity.svg index c07f903f8f..629b81c9fd 100644 --- a/icons/activity.svg +++ b/icons/activity.svg @@ -9,5 +9,5 @@ stroke-linecap="round" stroke-linejoin="round" > - + From d4df54211778fab91115f43ad69726f4ee4f4a05 Mon Sep 17 00:00:00 2001 From: Kyle Angelo Galendez Date: Fri, 26 Apr 2024 21:40:50 +0800 Subject: [PATCH 11/14] feat(icons): added `grid-2x2-check` icon (#2084) * Added icons/grid-2x2-check.svg * Added icons/grid-2x2-check.json * Updated icons/grid-2x2-check.json * Arcify grid-2x2-check.svg * Unarcify the check --- icons/grid-2x2-check.json | 32 ++++++++++++++++++++++++++++++++ icons/grid-2x2-check.svg | 14 ++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 icons/grid-2x2-check.json create mode 100644 icons/grid-2x2-check.svg diff --git a/icons/grid-2x2-check.json b/icons/grid-2x2-check.json new file mode 100644 index 0000000000..20348266cb --- /dev/null +++ b/icons/grid-2x2-check.json @@ -0,0 +1,32 @@ +{ + "$schema": "../icon.schema.json", + "contributors": [ + "danielbayley", + "chessurisme" + ], + "tags": [ + "table", + "rows", + "columns", + "blocks", + "plot", + "land", + "geometry", + "measure", + "data", + "size", + "width", + "height", + "distance", + "surface area", + "square meter", + "acre" + ], + "categories": [ + "text", + "layout", + "design", + "shapes", + "maths" + ] +} diff --git a/icons/grid-2x2-check.svg b/icons/grid-2x2-check.svg new file mode 100644 index 0000000000..fb5c0d9a43 --- /dev/null +++ b/icons/grid-2x2-check.svg @@ -0,0 +1,14 @@ + + + + From 54ef137b49013c324f409068c55f84c0cf137194 Mon Sep 17 00:00:00 2001 From: Kyle Angelo Galendez Date: Fri, 26 Apr 2024 21:41:08 +0800 Subject: [PATCH 12/14] feat(icons): added `grid-2x2-x` icon (#2085) * Added icons/grid-2x2-x.svg * Added icons/grid-2x2-x.json * Archify grid-2x2-x.svg --- icons/grid-2x2-x.json | 32 ++++++++++++++++++++++++++++++++ icons/grid-2x2-x.svg | 15 +++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 icons/grid-2x2-x.json create mode 100644 icons/grid-2x2-x.svg diff --git a/icons/grid-2x2-x.json b/icons/grid-2x2-x.json new file mode 100644 index 0000000000..08b3b720d0 --- /dev/null +++ b/icons/grid-2x2-x.json @@ -0,0 +1,32 @@ +{ + "$schema": "../icon.schema.json", + "contributors": [ + "danielbayley", + "chessurisme" + ], + "tags": [ + "table", + "rows", + "columns", + "data", + "blocks", + "plot", + "land", + "geometry", + "measure", + "size", + "width", + "height", + "distance", + "surface area", + "square meter", + "acre" + ], + "categories": [ + "text", + "layout", + "design", + "shapes", + "maths" + ] +} diff --git a/icons/grid-2x2-x.svg b/icons/grid-2x2-x.svg new file mode 100644 index 0000000000..86105dc160 --- /dev/null +++ b/icons/grid-2x2-x.svg @@ -0,0 +1,15 @@ + + + + + From 65deefa53c89905b33274399f7cddd77edd384e3 Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Fri, 26 Apr 2024 16:25:44 +0200 Subject: [PATCH 13/14] ci: Revert pnpm in pull-request.yml --- .github/workflows/pull-request.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 8ded86c1a1..d80b39eec8 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -45,9 +45,8 @@ jobs: with: files: icons/* - uses: actions/setup-node@v4 - - uses: pnpm/action-setup@v2 - name: Install simple-git (safer and faster than installing all deps) - run: pnpm install simple-git + run: npm install simple-git - name: Generate annotations run: node ./scripts/updateContributors.mjs env: @@ -96,9 +95,8 @@ jobs: body-includes: Added or changed icons - uses: actions/setup-node@v4 - - uses: pnpm/action-setup@v2 - name: Install svgson for code preview (safer and faster than installing all deps) - run: pnpm install svgson + run: npm install svgson - name: Generate comment markup run: node ./scripts/generateChangedIconsCommentMarkup.mjs >> comment-markup.md From e50582e93e7b1cfa34082eca38e2fc0f9f1fc991 Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Fri, 26 Apr 2024 17:59:04 +0200 Subject: [PATCH 14/14] feat(icon-component): Creating icons with iconNodes (#1997) * Add useIconComponent, lucide-react * Add concept useIconComponent * add useIconComponents to packages * Add icon component * Add icon component * Add tests for react packages * Reset changes in icons * Add types * Add support for Icon components in Lucide Vue Next * update tests * Update tests * Enable Svelte component * Fix lucide-react-native tests * Update Solid package * update snapshots * Add docs * add docs * Update tests * Formatting * Formatting * Update package lock * Remove `useIconComponent` * Update guides * Update exports preact and solid package * Formatting * Format createIcons.ts * Add lucide lab repo link in docs --- .prettierignore | 4 + docs/guide/packages/lucide-angular.md | 17 + docs/guide/packages/lucide-preact.md | 20 + docs/guide/packages/lucide-react-native.md | 20 + docs/guide/packages/lucide-react.md | 20 + docs/guide/packages/lucide-solid.md | 20 + docs/guide/packages/lucide-svelte.md | 21 ++ docs/guide/packages/lucide-vue-next.md | 30 +- docs/guide/packages/lucide.md | 15 + packages/lucide-preact/src/Icon.ts | 50 +++ .../lucide-preact/src/createLucideIcon.ts | 47 +-- packages/lucide-preact/src/lucide-preact.ts | 3 + packages/lucide-preact/src/types.ts | 12 + packages/lucide-preact/tests/Icon.spec.tsx | 33 ++ .../tests/__snapshots__/Icon.spec.tsx.snap | 29 ++ .../createLucideIcon.spec.tsx.snap | 29 ++ .../__snapshots__/lucide-preact.spec.tsx.snap | 8 +- .../tests/createLucideIcon.spec.tsx | 15 + .../tests/lucide-preact.spec.tsx | 50 ++- packages/lucide-preact/tests/setupVitest.js | 9 +- packages/lucide-preact/tests/testIconNodes.ts | 22 ++ packages/lucide-react-native/package.json | 1 + packages/lucide-react-native/src/Icon.ts | 69 ++++ .../src/createLucideIcon.ts | 12 +- .../src/lucide-react-native.ts | 10 +- packages/lucide-react-native/src/types.ts | 12 + .../lucide-react-native/tests/Icon.spec.tsx | 35 ++ .../tests/__snapshots__/Icon.spec.tsx.snap | 48 +++ .../lucide-react-native.spec.tsx.snap | 2 - .../tests/lucide-react-native.spec.tsx | 36 +- .../tests/testIconNodes.ts | 22 ++ packages/lucide-react/src/Icon.ts | 59 +++ packages/lucide-react/src/createLucideIcon.ts | 74 +--- packages/lucide-react/src/lucide-react.ts | 10 +- packages/lucide-react/src/types.ts | 15 + packages/lucide-react/tests/Icon.spec.tsx | 33 ++ .../tests/__snapshots__/Icon.spec.tsx.snap | 29 ++ .../createLucideIcon.spec.tsx.snap | 29 ++ .../dynamicImports.spec.tsx.snap | 36 ++ .../__snapshots__/lucide-react.spec.tsx.snap | 43 +-- .../tests/createLucideIcon.spec.tsx | 15 + .../tests/dynamicImports.spec.tsx | 38 ++ .../lucide-react/tests/lucide-react.spec.tsx | 85 ++--- packages/lucide-react/tests/testIconNodes.ts | 22 ++ packages/lucide-solid/src/Icon.tsx | 13 +- packages/lucide-solid/src/lucide-solid.ts | 3 + packages/lucide-solid/src/types.ts | 2 + packages/lucide-solid/tests/Icon.spec.tsx | 33 ++ .../tests/__snapshots__/Icon.spec.tsx.snap | 33 ++ .../__snapshots__/lucide-solid.spec.tsx.snap | 6 +- packages/lucide-solid/tests/testIconNodes.ts | 22 ++ packages/lucide-svelte/package.json | 2 + packages/lucide-svelte/src/Icon.svelte | 12 +- packages/lucide-svelte/src/lucide-svelte.ts | 1 + packages/lucide-svelte/tests/Icon.spec.ts | 33 ++ .../tests/__snapshots__/Icon.spec.ts.snap | 36 ++ .../__snapshots__/lucide-svelte.spec.ts.snap | 8 +- packages/lucide-svelte/tests/testIconNodes.ts | 21 ++ packages/lucide-vue-next/package.json | 9 +- packages/lucide-vue-next/src/Icon.ts | 30 ++ .../lucide-vue-next/src/createLucideIcon.ts | 39 +- .../lucide-vue-next/src/lucide-vue-next.ts | 4 + packages/lucide-vue-next/src/types.ts | 13 + packages/lucide-vue-next/tests/Icon.spec.ts | 33 ++ .../tests/__snapshots__/Icon.spec.ts.snap | 29 ++ .../lucide-vue-next.spec.ts.snap | 2 - .../tests/lucide-vue-next.spec.ts | 43 ++- packages/lucide-vue-next/tests/setupVitest.js | 2 +- .../lucide-vue-next/tests/testIconNodes.ts | 22 ++ packages/lucide/src/createIcons.ts | 37 ++ packages/lucide/src/lucide.ts | 40 +- packages/shared/src/index.ts | 1 + packages/shared/src/utility-types.ts | 16 + packages/shared/src/utils.ts | 31 +- pnpm-lock.yaml | 346 ++++++++++++++---- tools/build-icons/{main.mjs => cli.mjs} | 0 tools/build-icons/package.json | 4 +- 77 files changed, 1706 insertions(+), 429 deletions(-) create mode 100644 packages/lucide-preact/src/Icon.ts create mode 100644 packages/lucide-preact/src/types.ts create mode 100644 packages/lucide-preact/tests/Icon.spec.tsx create mode 100644 packages/lucide-preact/tests/__snapshots__/Icon.spec.tsx.snap create mode 100644 packages/lucide-preact/tests/__snapshots__/createLucideIcon.spec.tsx.snap create mode 100644 packages/lucide-preact/tests/createLucideIcon.spec.tsx create mode 100644 packages/lucide-preact/tests/testIconNodes.ts create mode 100644 packages/lucide-react-native/src/Icon.ts create mode 100644 packages/lucide-react-native/src/types.ts create mode 100644 packages/lucide-react-native/tests/Icon.spec.tsx create mode 100644 packages/lucide-react-native/tests/__snapshots__/Icon.spec.tsx.snap create mode 100644 packages/lucide-react-native/tests/testIconNodes.ts create mode 100644 packages/lucide-react/src/Icon.ts create mode 100644 packages/lucide-react/src/types.ts create mode 100644 packages/lucide-react/tests/Icon.spec.tsx create mode 100644 packages/lucide-react/tests/__snapshots__/Icon.spec.tsx.snap create mode 100644 packages/lucide-react/tests/__snapshots__/createLucideIcon.spec.tsx.snap create mode 100644 packages/lucide-react/tests/__snapshots__/dynamicImports.spec.tsx.snap create mode 100644 packages/lucide-react/tests/createLucideIcon.spec.tsx create mode 100644 packages/lucide-react/tests/dynamicImports.spec.tsx create mode 100644 packages/lucide-react/tests/testIconNodes.ts create mode 100644 packages/lucide-solid/tests/Icon.spec.tsx create mode 100644 packages/lucide-solid/tests/__snapshots__/Icon.spec.tsx.snap create mode 100644 packages/lucide-solid/tests/testIconNodes.ts create mode 100644 packages/lucide-svelte/tests/Icon.spec.ts create mode 100644 packages/lucide-svelte/tests/__snapshots__/Icon.spec.ts.snap create mode 100644 packages/lucide-svelte/tests/testIconNodes.ts create mode 100644 packages/lucide-vue-next/src/Icon.ts create mode 100644 packages/lucide-vue-next/src/types.ts create mode 100644 packages/lucide-vue-next/tests/Icon.spec.ts create mode 100644 packages/lucide-vue-next/tests/__snapshots__/Icon.spec.ts.snap create mode 100644 packages/lucide-vue-next/tests/testIconNodes.ts create mode 100644 packages/lucide/src/createIcons.ts create mode 100644 packages/shared/src/utility-types.ts rename tools/build-icons/{main.mjs => cli.mjs} (100%) diff --git a/.prettierignore b/.prettierignore index 4a40c2a72e..c150f271bb 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,6 +2,10 @@ pnpm-lock.yaml # docs examples docs/**/examples/ +docs/.vitepress/.temp +docs/.vitepress/cache +docs/.vitepress/data +docs/.nitro # lucide-angular packages/lucide-angular/.angular/cache diff --git a/docs/guide/packages/lucide-angular.md b/docs/guide/packages/lucide-angular.md index aba4524502..4999f3368d 100644 --- a/docs/guide/packages/lucide-angular.md +++ b/docs/guide/packages/lucide-angular.md @@ -115,3 +115,20 @@ import { icons } from 'lucide-angular'; LucideAngularModule.pick(icons) ``` + +## With Lucide lab or custom icons + +[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library. +They can be used in the same way as the official icons. + +```js +import { LucideAngularModule } from 'lucide-angular'; +import { burger } from '@lucide/lab'; + +@NgModule({ + imports: [ + LucideAngularModule.pick({ burger }) + ] +}) +export class AppModule { } +``` diff --git a/docs/guide/packages/lucide-preact.md b/docs/guide/packages/lucide-preact.md index 6fd69b9af4..7ebb879e2c 100644 --- a/docs/guide/packages/lucide-preact.md +++ b/docs/guide/packages/lucide-preact.md @@ -67,6 +67,26 @@ const App = () => { > SVG attributes in Preact aren't transformed, so if you want to change for example the `stroke-linejoin` you need to pass it in kebabcase. Basically how the SVG spec want you to write it. See this topic in the [Preact documentation](https://preactjs.com/guide/v10/differences-to-react/#svg-inside-jsx). +## With Lucide lab or custom icons + +[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library. + +They can be used by using the `Icon` component. +All props like regular lucide icons can be passed to adjust the icon appearance. + +### Using the `Icon` component + +This creates a single icon based on the iconNode passed and renders a Lucide icon component. + +```jsx +import { Icon } from 'lucide-preact'; +import { burger } from '@lucide/lab'; + +const App = () => ( + +); +``` + ## One generic icon component It is possible to create one generic icon component to load icons, but it is not recommended. diff --git a/docs/guide/packages/lucide-react-native.md b/docs/guide/packages/lucide-react-native.md index 112e33230e..c5dacbe00d 100644 --- a/docs/guide/packages/lucide-react-native.md +++ b/docs/guide/packages/lucide-react-native.md @@ -61,6 +61,26 @@ const App = () => { }; ``` +## With Lucide lab or custom icons + +[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library. + +They can be used by using the `Icon` component. +All props like regular lucide icons can be passed to adjust the icon appearance. + +### Using the `Icon` component + +This creates a single icon based on the iconNode passed and renders a Lucide icon component. + +```jsx +import { Icon } from 'lucide-react-native'; +import { burger } from '@lucide/lab'; + +const App = () => ( + +); +``` + ## One generic icon component It is possible to create one generic icon component to load icons, but it is not recommended. diff --git a/docs/guide/packages/lucide-react.md b/docs/guide/packages/lucide-react.md index 87f78f3b98..4c8a0c303a 100644 --- a/docs/guide/packages/lucide-react.md +++ b/docs/guide/packages/lucide-react.md @@ -61,6 +61,26 @@ const App = () => { }; ``` +## With Lucide lab or custom icons + +[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library. + +They can be used by using the `Icon` component. +All props like regular lucide icons can be passed to adjust the icon appearance. + +### Using the `Icon` component + +This creates a single icon based on the iconNode passed and renders a Lucide icon component. + +```jsx +import { Icon } from 'lucide-react'; +import { burger } from '@lucide/lab'; + +const App = () => ( + +); +``` + ## One generic icon component It is possible to create one generic icon component to load icons, but it is not recommended. diff --git a/docs/guide/packages/lucide-solid.md b/docs/guide/packages/lucide-solid.md index 94087df819..119f51d620 100644 --- a/docs/guide/packages/lucide-solid.md +++ b/docs/guide/packages/lucide-solid.md @@ -61,6 +61,26 @@ const App = () => { }; ``` +## With Lucide lab or custom icons + +[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library. + +They can be used by using the `Icon` component. +All props like the regular Lucide icons can be passed to adjust the icon appearance. + +### Using the `Icon` component + +This creates a single icon based on the iconNode passed and renders a Lucide icon component. + +```jsx +import { Icon } from 'lucide-solid'; +import { burger, sausage } from '@lucide/lab'; + +const App = () => ( + +); +``` + ## One generic icon component It is possible to create one generic icon component to load icons. It's not recommended. diff --git a/docs/guide/packages/lucide-svelte.md b/docs/guide/packages/lucide-svelte.md index 184aa2076c..2077a12a86 100644 --- a/docs/guide/packages/lucide-svelte.md +++ b/docs/guide/packages/lucide-svelte.md @@ -166,6 +166,27 @@ The package includes type definitions for all icons. This is useful if you want For more details about typing the `svelte:component` directive, see the [Svelte documentation](https://svelte.dev/docs/typescript#types-componenttype). +## With Lucide lab or custom icons + +[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library. + +They can be used by using the `Icon` component. +All props like the regular Lucide icons can be passed to adjust the icon appearance. + +### Using the `Icon` component + +This creates a single icon based on the iconNode passed and renders a Lucide icon component. + +```svelte + + + + +``` + ## One generic icon component It is possible to create one generic icon component to load icons, but it is not recommended. diff --git a/docs/guide/packages/lucide-vue-next.md b/docs/guide/packages/lucide-vue-next.md index acf1c2448b..367a4aafd4 100644 --- a/docs/guide/packages/lucide-vue-next.md +++ b/docs/guide/packages/lucide-vue-next.md @@ -37,16 +37,16 @@ Each icon can be imported as a Vue component, which renders an inline SVG Elemen You can pass additional props to adjust the icon. ```vue + + - - ``` ## Props @@ -69,6 +69,28 @@ To customize the appearance of an icon, you can pass custom properties as props ``` +## With Lucide lab or custom icons + +[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library. + +They can be used by using the `Icon` component. +All props like regular lucide icons can be passed to adjust the icon appearance. + +### Using the `Icon` component + +This creates a single icon based on the iconNode passed and renders a Lucide icon component. + +```vue + + + +``` + ## One generic icon component It is possible to create one generic icon component to load icons, but it is not recommended. diff --git a/docs/guide/packages/lucide.md b/docs/guide/packages/lucide.md index 068917ce8c..c42b228ac9 100644 --- a/docs/guide/packages/lucide.md +++ b/docs/guide/packages/lucide.md @@ -130,3 +130,18 @@ menuIcon.classList.add('my-icon-class'); const myApp = document.getElementById('app'); myApp.appendChild(menuIcon); ``` + +### With Lucide lab or custom icons + +[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library. +They can be used in the same way as the official icons. + +```js +import { burger } from '@lucide/lab'; + +createIcons({ + icons: { + burger + } +}); +``` diff --git a/packages/lucide-preact/src/Icon.ts b/packages/lucide-preact/src/Icon.ts new file mode 100644 index 0000000000..bfbda22977 --- /dev/null +++ b/packages/lucide-preact/src/Icon.ts @@ -0,0 +1,50 @@ +import { h, toChildArray } from 'preact'; +import defaultAttributes from './defaultAttributes'; +import type { IconNode, LucideProps } from './types'; + +interface IconComponentProps extends LucideProps { + iconNode: IconNode; +} + +/** + * Lucide icon component + * + * @component Icon + * @param {object} props + * @param {string} props.color - The color of the icon + * @param {number} props.size - The size of the icon + * @param {number} props.strokeWidth - The stroke width of the icon + * @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width + * @param {string} props.class - The class name of the icon + * @param {IconNode} props.children - The children of the icon + * @param {IconNode} props.iconNode - The icon node of the icon + * + * @returns {ForwardRefExoticComponent} LucideIcon + */ +const Icon = ({ + color = 'currentColor', + size = 24, + strokeWidth = 2, + absoluteStrokeWidth, + children, + iconNode, + class: classes = '', + ...rest +}: IconComponentProps) => + h( + 'svg', + { + ...defaultAttributes, + width: String(size), + height: size, + stroke: color, + ['stroke-width' as 'strokeWidth']: absoluteStrokeWidth + ? (Number(strokeWidth) * 24) / Number(size) + : strokeWidth, + class: ['lucide', classes].join(' '), + ...rest, + }, + [...iconNode.map(([tag, attrs]) => h(tag, attrs)), ...toChildArray(children)], + ); + +export default Icon; diff --git a/packages/lucide-preact/src/createLucideIcon.ts b/packages/lucide-preact/src/createLucideIcon.ts index e4eb95f3b6..2ba13086f3 100644 --- a/packages/lucide-preact/src/createLucideIcon.ts +++ b/packages/lucide-preact/src/createLucideIcon.ts @@ -1,17 +1,7 @@ -import { type FunctionComponent, h, type JSX, toChildArray } from 'preact'; -import defaultAttributes from './defaultAttributes'; -import { toKebabCase } from '@lucide/shared'; - -export type IconNode = [elementName: keyof JSX.IntrinsicElements, attrs: Record][]; - -export interface LucideProps extends Partial> { - color?: string; - size?: string | number; - strokeWidth?: string | number; - absoluteStrokeWidth?: boolean; -} - -export type LucideIcon = FunctionComponent; +import { h, type JSX } from 'preact'; +import { mergeClasses, toKebabCase } from '@lucide/shared'; +import Icon from './Icon'; +import type { IconNode, LucideIcon, LucideProps } from './types'; /** * Create a Lucide icon component @@ -20,29 +10,18 @@ export type LucideIcon = FunctionComponent; * @returns {FunctionComponent} LucideIcon */ const createLucideIcon = (iconName: string, iconNode: IconNode): LucideIcon => { - const Component = ({ - color = 'currentColor', - size = 24, - strokeWidth = 2, - absoluteStrokeWidth, - children, - class: classes = '', - ...rest - }: LucideProps) => + const Component = ({ class: classes = '', children, ...props }: LucideProps) => h( - 'svg', + Icon, { - ...defaultAttributes, - width: String(size), - height: size, - stroke: color, - ['stroke-width' as 'strokeWidth']: absoluteStrokeWidth - ? (Number(strokeWidth) * 24) / Number(size) - : strokeWidth, - class: ['lucide', `lucide-${toKebabCase(iconName)}`, classes].join(' '), - ...rest, + ...props, + iconNode, + class: mergeClasses>( + `lucide-${toKebabCase(iconName)}`, + classes, + ), }, - [...iconNode.map(([tag, attrs]) => h(tag, attrs)), ...toChildArray(children)], + children, ); Component.displayName = `${iconName}`; diff --git a/packages/lucide-preact/src/lucide-preact.ts b/packages/lucide-preact/src/lucide-preact.ts index 2ddd5eb314..6636c22592 100644 --- a/packages/lucide-preact/src/lucide-preact.ts +++ b/packages/lucide-preact/src/lucide-preact.ts @@ -1,4 +1,7 @@ export * from './icons'; export * as icons from './icons'; export * from './aliases'; +export * from './types'; + export { default as createLucideIcon } from './createLucideIcon'; +export { default as Icon } from './Icon'; diff --git a/packages/lucide-preact/src/types.ts b/packages/lucide-preact/src/types.ts new file mode 100644 index 0000000000..03604e9606 --- /dev/null +++ b/packages/lucide-preact/src/types.ts @@ -0,0 +1,12 @@ +import { type FunctionComponent, type JSX } from 'preact'; + +export type IconNode = [elementName: keyof JSX.IntrinsicElements, attrs: Record][]; + +export interface LucideProps extends Partial> { + color?: string; + size?: string | number; + strokeWidth?: string | number; + absoluteStrokeWidth?: boolean; +} + +export type LucideIcon = FunctionComponent; diff --git a/packages/lucide-preact/tests/Icon.spec.tsx b/packages/lucide-preact/tests/Icon.spec.tsx new file mode 100644 index 0000000000..d43760ba93 --- /dev/null +++ b/packages/lucide-preact/tests/Icon.spec.tsx @@ -0,0 +1,33 @@ +import { describe, it, expect } from 'vitest'; +import { render } from '@testing-library/preact'; + +import { airVent } from './testIconNodes'; +import { Icon } from '../src/lucide-preact'; + +describe('Using Icon Component', () => { + it('should render icon based on a iconNode', async () => { + const { container } = render( + , + ); + + expect(container.firstChild).toBeDefined(); + }); + + it('should render icon and match snapshot', async () => { + const { container } = render( + , + ); + + expect(container.firstChild).toMatchSnapshot(); + }); +}); diff --git a/packages/lucide-preact/tests/__snapshots__/Icon.spec.tsx.snap b/packages/lucide-preact/tests/__snapshots__/Icon.spec.tsx.snap new file mode 100644 index 0000000000..2e30bf9a62 --- /dev/null +++ b/packages/lucide-preact/tests/__snapshots__/Icon.spec.tsx.snap @@ -0,0 +1,29 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Using Icon Component > should render icon and match snapshot 1`] = ` + + + + + + +`; diff --git a/packages/lucide-preact/tests/__snapshots__/createLucideIcon.spec.tsx.snap b/packages/lucide-preact/tests/__snapshots__/createLucideIcon.spec.tsx.snap new file mode 100644 index 0000000000..acf4f97390 --- /dev/null +++ b/packages/lucide-preact/tests/__snapshots__/createLucideIcon.spec.tsx.snap @@ -0,0 +1,29 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Using createLucideIcon > should create a component from an iconNode 1`] = ` + + + + + + +`; diff --git a/packages/lucide-preact/tests/__snapshots__/lucide-preact.spec.tsx.snap b/packages/lucide-preact/tests/__snapshots__/lucide-preact.spec.tsx.snap index 6df3af2c0f..a3cc086577 100644 --- a/packages/lucide-preact/tests/__snapshots__/lucide-preact.spec.tsx.snap +++ b/packages/lucide-preact/tests/__snapshots__/lucide-preact.spec.tsx.snap @@ -10,8 +10,7 @@ exports[`Using lucide icon components > should adjust the size, stroke color and stroke-width="4" stroke-linecap="round" stroke-linejoin="round" - class="lucide lucide-grid3x3 " - data-testid="grid-icon" + class="lucide lucide-grid3x3" > should not scale the strokeWidth when ab stroke-width="1" stroke-linecap="round" stroke-linejoin="round" - class="lucide lucide-grid3x3 " - data-testid="grid-icon" + class="lucide lucide-grid3x3" > should render an component 1`] = ` stroke-width="2" stroke-linecap="round" stroke-linejoin="round" - class="lucide lucide-grid3x3 " + class="lucide lucide-grid3x3" > { + it('should create a component from an iconNode', () => { + const AirVent = createLucideIcon('AirVent', airVent); + + const { container } = render(); + + expect(container.firstChild).toMatchSnapshot(); + expect(container.firstChild).toBeDefined(); + }); +}); diff --git a/packages/lucide-preact/tests/lucide-preact.spec.tsx b/packages/lucide-preact/tests/lucide-preact.spec.tsx index c0e6d06eb9..819ebfe728 100644 --- a/packages/lucide-preact/tests/lucide-preact.spec.tsx +++ b/packages/lucide-preact/tests/lucide-preact.spec.tsx @@ -1,6 +1,7 @@ import { describe, it, expect } from 'vitest'; import { render, cleanup } from '@testing-library/preact'; import { Pen, Edit2, Grid, Droplet } from '../src/lucide-preact'; +import defaultAttributes from '../src/defaultAttributes'; type AttributesAssertion = { attributes: Record }; @@ -11,30 +12,43 @@ describe('Using lucide icon components', () => { expect(container.innerHTML).toMatchSnapshot(); }); + it('should render the icon with the default attributes', () => { + const { container } = render(); + + const SVGElement = container.firstElementChild; + + expect(SVGElement).toHaveAttribute('xmlns', defaultAttributes.xmlns); + expect(SVGElement).toHaveAttribute('width', String(defaultAttributes.width)); + expect(SVGElement).toHaveAttribute('height', String(defaultAttributes.height)); + expect(SVGElement).toHaveAttribute('viewBox', defaultAttributes.viewBox); + expect(SVGElement).toHaveAttribute('fill', defaultAttributes.fill); + expect(SVGElement).toHaveAttribute('stroke', defaultAttributes.stroke); + expect(SVGElement).toHaveAttribute('stroke-width', String(defaultAttributes['stroke-width'])); + expect(SVGElement).toHaveAttribute('stroke-linecap', defaultAttributes['stroke-linecap']); + expect(SVGElement).toHaveAttribute('stroke-linejoin', defaultAttributes['stroke-linejoin']); + }); + it('should adjust the size, stroke color and stroke width', () => { - const testId = 'grid-icon'; - const { container, getByTestId } = render( + const { container } = render( , ); - const { attributes } = getByTestId(testId) as unknown as AttributesAssertion; - expect(attributes.stroke.value).toBe('red'); - expect(attributes.width.value).toBe('48'); - expect(attributes.height.value).toBe('48'); - expect(attributes['stroke-width'].value).toBe('4'); + const SVGElement = container.firstElementChild; + + expect(SVGElement).toHaveAttribute('stroke', 'red'); + expect(SVGElement).toHaveAttribute('width', '48'); + expect(SVGElement).toHaveAttribute('height', '48'); + expect(SVGElement).toHaveAttribute('stroke-width', '4'); expect(container.innerHTML).toMatchSnapshot(); }); it('should render the alias icon', () => { - const testId = 'pen-icon'; const { container } = render( { const { container: Edit2Container } = render( { }); it('should not scale the strokeWidth when absoluteStrokeWidth is set', () => { - const testId = 'grid-icon'; - const { container, getByTestId } = render( + const { container } = render( , ); - const { attributes } = getByTestId(testId) as unknown as AttributesAssertion; + const SVGElement = container.firstElementChild; + + expect(SVGElement).toHaveAttribute('stroke', 'red'); + expect(SVGElement).toHaveAttribute('width', '48'); + expect(SVGElement).toHaveAttribute('height', '48'); + expect(SVGElement).toHaveAttribute('stroke-width', '1'); - expect(attributes.stroke.value).toBe('red'); - expect(attributes.width.value).toBe('48'); - expect(attributes.height.value).toBe('48'); - expect(attributes['stroke-width'].value).toBe('1'); expect(container.innerHTML).toMatchSnapshot(); }); diff --git a/packages/lucide-preact/tests/setupVitest.js b/packages/lucide-preact/tests/setupVitest.js index ccd53195bb..4e0ce2a49d 100644 --- a/packages/lucide-preact/tests/setupVitest.js +++ b/packages/lucide-preact/tests/setupVitest.js @@ -1,5 +1,10 @@ -import { expect } from 'vitest'; -import '@testing-library/jest-dom'; +import { expect, afterEach } from 'vitest'; +import { cleanup } from '@testing-library/preact'; +import '@testing-library/jest-dom/vitest'; import htmlSerializer from 'jest-serializer-html'; expect.addSnapshotSerializer(htmlSerializer); + +afterEach(() => { + cleanup(); +}); diff --git a/packages/lucide-preact/tests/testIconNodes.ts b/packages/lucide-preact/tests/testIconNodes.ts new file mode 100644 index 0000000000..8c593572d5 --- /dev/null +++ b/packages/lucide-preact/tests/testIconNodes.ts @@ -0,0 +1,22 @@ +import { IconNode } from '../src/createLucideIcon'; + +export const airVent: IconNode = [ + [ + 'path', + { + d: 'M6 12H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2', + key: 'larmp2', + }, + ], + ['path', { d: 'M6 8h12', key: '6g4wlu' }], + ['path', { d: 'M18.3 17.7a2.5 2.5 0 0 1-3.16 3.83 2.53 2.53 0 0 1-1.14-2V12', key: '1bo8pg' }], + ['path', { d: 'M6.6 15.6A2 2 0 1 0 10 17v-5', key: 't9h90c' }], +]; + +export const coffee: IconNode = [ + ['path', { d: 'M17 8h1a4 4 0 1 1 0 8h-1', key: 'jx4kbh' }], + ['path', { d: 'M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4Z', key: '1bxrl0' }], + ['line', { x1: '6', x2: '6', y1: '2', y2: '4', key: '1cr9l3' }], + ['line', { x1: '10', x2: '10', y1: '2', y2: '4', key: '170wym' }], + ['line', { x1: '14', x2: '14', y1: '2', y2: '4', key: '1c5f70' }], +]; diff --git a/packages/lucide-react-native/package.json b/packages/lucide-react-native/package.json index 2e3605b234..0fe54ddc9a 100644 --- a/packages/lucide-react-native/package.json +++ b/packages/lucide-react-native/package.json @@ -45,6 +45,7 @@ "devDependencies": { "@lucide/rollup-plugins": "workspace:*", "@lucide/build-icons": "workspace:*", + "@lucide/shared": "workspace:*", "@testing-library/jest-dom": "^6.1.6", "@testing-library/react": "^14.1.2", "@types/prop-types": "^15.7.5", diff --git a/packages/lucide-react-native/src/Icon.ts b/packages/lucide-react-native/src/Icon.ts new file mode 100644 index 0000000000..ee43a1b0d7 --- /dev/null +++ b/packages/lucide-react-native/src/Icon.ts @@ -0,0 +1,69 @@ +import { createElement, forwardRef, type FunctionComponent } from 'react'; +import * as NativeSvg from 'react-native-svg'; +import defaultAttributes, { childDefaultAttributes } from './defaultAttributes'; +import { IconNode, LucideProps } from './types'; + +interface IconComponentProps extends LucideProps { + iconNode: IconNode; +} + +/** + * Lucide icon component + * + * @component Icon + * @param {object} props + * @param {string} props.color - The color of the icon + * @param {number} props.size - The size of the icon + * @param {number} props.strokeWidth - The stroke width of the icon + * @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width + * @param {string} props.className - The class name of the icon + * @param {IconNode} props.children - The children of the icon + * @param {IconNode} props.iconNode - The icon node of the icon + * + * @returns {ForwardRefExoticComponent} LucideIcon + */ +const Icon = forwardRef( + ( + { + color = 'currentColor', + size = 24, + strokeWidth = 2, + absoluteStrokeWidth, + children, + iconNode, + ...rest + }, + ref, + ) => { + const customAttrs = { + stroke: color, + strokeWidth: absoluteStrokeWidth ? (Number(strokeWidth) * 24) / Number(size) : strokeWidth, + ...rest, + }; + + return createElement( + NativeSvg.Svg as unknown as string, + { + ref, + ...defaultAttributes, + width: size, + height: size, + ...customAttrs, + }, + [ + ...iconNode.map(([tag, attrs]) => { + const upperCasedTag = (tag.charAt(0).toUpperCase() + + tag.slice(1)) as keyof typeof NativeSvg; + // duplicating the attributes here because generating the OTA update bundles don't inherit the SVG properties from parent (codepush, expo-updates) + return createElement( + NativeSvg[upperCasedTag] as FunctionComponent, + { ...childDefaultAttributes, ...customAttrs, ...attrs } as LucideProps, + ); + }), + ...((Array.isArray(children) ? children : [children]) || []), + ], + ); + }, +); + +export default Icon; diff --git a/packages/lucide-react-native/src/createLucideIcon.ts b/packages/lucide-react-native/src/createLucideIcon.ts index e824659bde..9eb27bd972 100644 --- a/packages/lucide-react-native/src/createLucideIcon.ts +++ b/packages/lucide-react-native/src/createLucideIcon.ts @@ -7,17 +7,7 @@ import { } from 'react'; import * as NativeSvg from 'react-native-svg'; import defaultAttributes, { childDefaultAttributes } from './defaultAttributes'; -import type { SvgProps } from 'react-native-svg'; - -export type IconNode = [elementName: keyof ReactSVG, attrs: Record][]; - -export interface LucideProps extends SvgProps { - size?: string | number; - absoluteStrokeWidth?: boolean; - 'data-testid'?: string; -} - -export type LucideIcon = ForwardRefExoticComponent; +import { IconNode, LucideIcon, LucideProps } from './types'; const createLucideIcon = (iconName: string, iconNode: IconNode): LucideIcon => { const Component = forwardRef( diff --git a/packages/lucide-react-native/src/lucide-react-native.ts b/packages/lucide-react-native/src/lucide-react-native.ts index a024114981..6636c22592 100644 --- a/packages/lucide-react-native/src/lucide-react-native.ts +++ b/packages/lucide-react-native/src/lucide-react-native.ts @@ -1,9 +1,7 @@ export * from './icons'; export * as icons from './icons'; export * from './aliases'; -export { - default as createLucideIcon, - type IconNode, - type LucideProps, - type LucideIcon, -} from './createLucideIcon'; +export * from './types'; + +export { default as createLucideIcon } from './createLucideIcon'; +export { default as Icon } from './Icon'; diff --git a/packages/lucide-react-native/src/types.ts b/packages/lucide-react-native/src/types.ts new file mode 100644 index 0000000000..fd534414ac --- /dev/null +++ b/packages/lucide-react-native/src/types.ts @@ -0,0 +1,12 @@ +import type { ForwardRefExoticComponent, ReactSVG } from 'react'; +import type { SvgProps } from 'react-native-svg'; + +export type IconNode = [elementName: keyof ReactSVG, attrs: Record][]; + +export interface LucideProps extends SvgProps { + size?: string | number; + absoluteStrokeWidth?: boolean; + 'data-testid'?: string; +} + +export type LucideIcon = ForwardRefExoticComponent; diff --git a/packages/lucide-react-native/tests/Icon.spec.tsx b/packages/lucide-react-native/tests/Icon.spec.tsx new file mode 100644 index 0000000000..0bf4e886ad --- /dev/null +++ b/packages/lucide-react-native/tests/Icon.spec.tsx @@ -0,0 +1,35 @@ +import { describe, it, expect, vi } from 'vitest'; +import { render } from '@testing-library/react'; + +import { airVent } from './testIconNodes'; +import { Icon } from '../src/lucide-react-native'; + +vi.mock('react-native-svg'); + +describe('Using Icon Component', () => { + it('should render icon based on a iconNode', async () => { + const { container } = render( + , + ); + + expect(container.firstChild).toBeDefined(); + }); + + it('should render icon and match snapshot', async () => { + const { container } = render( + , + ); + + expect(container.firstChild).toMatchSnapshot(); + }); +}); diff --git a/packages/lucide-react-native/tests/__snapshots__/Icon.spec.tsx.snap b/packages/lucide-react-native/tests/__snapshots__/Icon.spec.tsx.snap new file mode 100644 index 0000000000..fd704741d4 --- /dev/null +++ b/packages/lucide-react-native/tests/__snapshots__/Icon.spec.tsx.snap @@ -0,0 +1,48 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Using Icon Component > should render icon and match snapshot 1`] = ` + + + + + + +`; diff --git a/packages/lucide-react-native/tests/__snapshots__/lucide-react-native.spec.tsx.snap b/packages/lucide-react-native/tests/__snapshots__/lucide-react-native.spec.tsx.snap index 90dca01ac4..14af0d45ef 100644 --- a/packages/lucide-react-native/tests/__snapshots__/lucide-react-native.spec.tsx.snap +++ b/packages/lucide-react-native/tests/__snapshots__/lucide-react-native.spec.tsx.snap @@ -10,7 +10,6 @@ exports[`Using lucide icon components > should adjust the size, stroke color and stroke-width="4" stroke-linecap="round" stroke-linejoin="round" - data-testid="grid-icon" > should not scale the strokeWidth when ab stroke-width="1" stroke-linecap="round" stroke-linejoin="round" - data-testid="grid-icon" > { }); it('should adjust the size, stroke color and stroke width', () => { - const testId = 'grid-icon'; - const { container, getByTestId } = render( + const { container } = render( , ); - const { attributes } = getByTestId(testId); - expect((attributes as unknown as Attributes).stroke.value).toBe('red'); - expect((attributes as unknown as Attributes).width.value).toBe('48'); - expect((attributes as unknown as Attributes).height.value).toBe('48'); - expect((attributes as unknown as Attributes)['stroke-width'].value).toBe('4'); + const SVGElement = container.firstElementChild; + + expect(SVGElement).toHaveAttribute('stroke', 'red'); + expect(SVGElement).toHaveAttribute('width', '48'); + expect(SVGElement).toHaveAttribute('height', '48'); + expect(SVGElement).toHaveAttribute('stroke-width', '4'); expect(container.innerHTML).toMatchSnapshot(); }); @@ -61,23 +60,20 @@ describe('Using lucide icon components', () => { }); it('should not scale the strokeWidth when absoluteStrokeWidth is set', () => { - const testId = 'grid-icon'; - const { container, getByTestId } = render( + const { container } = render( , ); - const { attributes } = getByTestId(testId) as unknown as { - attributes: Record; - }; - expect(attributes.stroke.value).toBe('red'); - expect(attributes.width.value).toBe('48'); - expect(attributes.height.value).toBe('48'); - expect(attributes['stroke-width'].value).toBe('1'); + const SVGElement = container.firstElementChild; + + expect(SVGElement).toHaveAttribute('stroke', 'red'); + expect(SVGElement).toHaveAttribute('width', '48'); + expect(SVGElement).toHaveAttribute('height', '48'); + expect(SVGElement).toHaveAttribute('stroke-width', '1'); expect(container.innerHTML).toMatchSnapshot(); }); @@ -91,8 +87,8 @@ describe('Using lucide icon components', () => { , ); - const { children } = getByTestId(testId) as unknown as { children: HTMLCollection }; - const lastChild = children[children.length - 1]; + const { children } = container.firstElementChild ?? {}; + const lastChild = children?.[children.length - 1]; expect(lastChild).toEqual(getByTestId(childId)); expect(container.innerHTML).toMatchSnapshot(); diff --git a/packages/lucide-react-native/tests/testIconNodes.ts b/packages/lucide-react-native/tests/testIconNodes.ts new file mode 100644 index 0000000000..c93721961c --- /dev/null +++ b/packages/lucide-react-native/tests/testIconNodes.ts @@ -0,0 +1,22 @@ +import { IconNode } from '../src/types'; + +export const airVent: IconNode = [ + [ + 'path', + { + d: 'M6 12H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2', + key: 'larmp2', + }, + ], + ['path', { d: 'M6 8h12', key: '6g4wlu' }], + ['path', { d: 'M18.3 17.7a2.5 2.5 0 0 1-3.16 3.83 2.53 2.53 0 0 1-1.14-2V12', key: '1bo8pg' }], + ['path', { d: 'M6.6 15.6A2 2 0 1 0 10 17v-5', key: 't9h90c' }], +]; + +export const coffee: IconNode = [ + ['path', { d: 'M17 8h1a4 4 0 1 1 0 8h-1', key: 'jx4kbh' }], + ['path', { d: 'M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4Z', key: '1bxrl0' }], + ['line', { x1: '6', x2: '6', y1: '2', y2: '4', key: '1cr9l3' }], + ['line', { x1: '10', x2: '10', y1: '2', y2: '4', key: '170wym' }], + ['line', { x1: '14', x2: '14', y1: '2', y2: '4', key: '1c5f70' }], +]; diff --git a/packages/lucide-react/src/Icon.ts b/packages/lucide-react/src/Icon.ts new file mode 100644 index 0000000000..c623c0e3e5 --- /dev/null +++ b/packages/lucide-react/src/Icon.ts @@ -0,0 +1,59 @@ +import { createElement, forwardRef } from 'react'; +import defaultAttributes from './defaultAttributes'; +import { IconNode, LucideProps } from './types'; +import { mergeClasses } from '@lucide/shared'; + +interface IconComponentProps extends LucideProps { + iconNode: IconNode; +} + +/** + * Lucide icon component + * + * @component Icon + * @param {object} props + * @param {string} props.color - The color of the icon + * @param {number} props.size - The size of the icon + * @param {number} props.strokeWidth - The stroke width of the icon + * @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width + * @param {string} props.className - The class name of the icon + * @param {IconNode} props.children - The children of the icon + * @param {IconNode} props.iconNode - The icon node of the icon + * + * @returns {ForwardRefExoticComponent} LucideIcon + */ +const Icon = forwardRef( + ( + { + color = 'currentColor', + size = 24, + strokeWidth = 2, + absoluteStrokeWidth, + className = '', + children, + iconNode, + ...rest + }, + ref, + ) => { + return createElement( + 'svg', + { + ref, + ...defaultAttributes, + width: size, + height: size, + stroke: color, + strokeWidth: absoluteStrokeWidth ? (Number(strokeWidth) * 24) / Number(size) : strokeWidth, + className: mergeClasses('lucide', className), + ...rest, + }, + [ + ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)), + ...(Array.isArray(children) ? children : [children]), + ], + ); + }, +); + +export default Icon; diff --git a/packages/lucide-react/src/createLucideIcon.ts b/packages/lucide-react/src/createLucideIcon.ts index 5207168afc..b209293824 100644 --- a/packages/lucide-react/src/createLucideIcon.ts +++ b/packages/lucide-react/src/createLucideIcon.ts @@ -1,60 +1,22 @@ -import { - forwardRef, - createElement, - ReactSVG, - SVGProps, - ForwardRefExoticComponent, - RefAttributes, -} from 'react'; -import defaultAttributes from './defaultAttributes'; -import { toKebabCase } from '@lucide/shared'; - -export type IconNode = [elementName: keyof ReactSVG, attrs: Record][]; - -export type SVGAttributes = Partial>; -type ComponentAttributes = RefAttributes & SVGAttributes; - -export interface LucideProps extends ComponentAttributes { - size?: string | number; - absoluteStrokeWidth?: boolean; -} - -export type LucideIcon = ForwardRefExoticComponent; - -const createLucideIcon = (iconName: string, iconNode: IconNode): LucideIcon => { - const Component = forwardRef( - ( - { - color = 'currentColor', - size = 24, - strokeWidth = 2, - absoluteStrokeWidth, - className = '', - children, - ...rest - }, +import { createElement, forwardRef } from 'react'; +import { mergeClasses, toKebabCase } from '@lucide/shared'; +import { IconNode, LucideProps } from './types'; +import Icon from './Icon'; + +/** + * Create a Lucide icon component + * @param {string} iconName + * @param {array} iconNode + * @returns {ForwardRefExoticComponent} LucideIcon + */ +const createLucideIcon = (iconName: string, iconNode: IconNode) => { + const Component = forwardRef(({ className, ...props }, ref) => + createElement(Icon, { ref, - ) => { - return createElement( - 'svg', - { - ref, - ...defaultAttributes, - width: size, - height: size, - stroke: color, - strokeWidth: absoluteStrokeWidth - ? (Number(strokeWidth) * 24) / Number(size) - : strokeWidth, - className: ['lucide', `lucide-${toKebabCase(iconName)}`, className].join(' '), - ...rest, - }, - [ - ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)), - ...(Array.isArray(children) ? children : [children]), - ], - ); - }, + iconNode, + className: mergeClasses(`lucide-${toKebabCase(iconName)}`, className), + ...props, + }), ); Component.displayName = `${iconName}`; diff --git a/packages/lucide-react/src/lucide-react.ts b/packages/lucide-react/src/lucide-react.ts index a024114981..6636c22592 100644 --- a/packages/lucide-react/src/lucide-react.ts +++ b/packages/lucide-react/src/lucide-react.ts @@ -1,9 +1,7 @@ export * from './icons'; export * as icons from './icons'; export * from './aliases'; -export { - default as createLucideIcon, - type IconNode, - type LucideProps, - type LucideIcon, -} from './createLucideIcon'; +export * from './types'; + +export { default as createLucideIcon } from './createLucideIcon'; +export { default as Icon } from './Icon'; diff --git a/packages/lucide-react/src/types.ts b/packages/lucide-react/src/types.ts new file mode 100644 index 0000000000..ed686b315b --- /dev/null +++ b/packages/lucide-react/src/types.ts @@ -0,0 +1,15 @@ +import { ReactSVG, SVGProps, ForwardRefExoticComponent, RefAttributes } from 'react'; + +export type IconNode = [elementName: keyof ReactSVG, attrs: Record][]; + +export type SVGAttributes = Partial>; +type ElementAttributes = RefAttributes & SVGAttributes; + +export interface LucideProps extends ElementAttributes { + size?: string | number; + absoluteStrokeWidth?: boolean; +} + +export type LucideIcon = ForwardRefExoticComponent< + Omit & RefAttributes +>; diff --git a/packages/lucide-react/tests/Icon.spec.tsx b/packages/lucide-react/tests/Icon.spec.tsx new file mode 100644 index 0000000000..906f0c3117 --- /dev/null +++ b/packages/lucide-react/tests/Icon.spec.tsx @@ -0,0 +1,33 @@ +import { describe, it, expect } from 'vitest'; +import { render } from '@testing-library/react'; + +import { airVent } from './testIconNodes'; +import { Icon } from '../src/lucide-react'; + +describe('Using Icon Component', () => { + it('should render icon based on a iconNode', async () => { + const { container } = render( + , + ); + + expect(container.firstChild).toBeDefined(); + }); + + it('should render icon and match snapshot', async () => { + const { container } = render( + , + ); + + expect(container.firstChild).toMatchSnapshot(); + }); +}); diff --git a/packages/lucide-react/tests/__snapshots__/Icon.spec.tsx.snap b/packages/lucide-react/tests/__snapshots__/Icon.spec.tsx.snap new file mode 100644 index 0000000000..635ca428ad --- /dev/null +++ b/packages/lucide-react/tests/__snapshots__/Icon.spec.tsx.snap @@ -0,0 +1,29 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Using Icon Component > should render icon and match snapshot 1`] = ` + + + + + + +`; diff --git a/packages/lucide-react/tests/__snapshots__/createLucideIcon.spec.tsx.snap b/packages/lucide-react/tests/__snapshots__/createLucideIcon.spec.tsx.snap new file mode 100644 index 0000000000..acf4f97390 --- /dev/null +++ b/packages/lucide-react/tests/__snapshots__/createLucideIcon.spec.tsx.snap @@ -0,0 +1,29 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Using createLucideIcon > should create a component from an iconNode 1`] = ` + + + + + + +`; diff --git a/packages/lucide-react/tests/__snapshots__/dynamicImports.spec.tsx.snap b/packages/lucide-react/tests/__snapshots__/dynamicImports.spec.tsx.snap new file mode 100644 index 0000000000..81acb42979 --- /dev/null +++ b/packages/lucide-react/tests/__snapshots__/dynamicImports.spec.tsx.snap @@ -0,0 +1,36 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Using dynamicImports > should render icons dynamically by using the dynamicIconImports module 1`] = ` + + + + + + + + + + +`; diff --git a/packages/lucide-react/tests/__snapshots__/lucide-react.spec.tsx.snap b/packages/lucide-react/tests/__snapshots__/lucide-react.spec.tsx.snap index 31ab33829f..a3cc086577 100644 --- a/packages/lucide-react/tests/__snapshots__/lucide-react.spec.tsx.snap +++ b/packages/lucide-react/tests/__snapshots__/lucide-react.spec.tsx.snap @@ -10,8 +10,7 @@ exports[`Using lucide icon components > should adjust the size, stroke color and stroke-width="4" stroke-linecap="round" stroke-linejoin="round" - class="lucide lucide-grid3x3 " - data-testid="grid-icon" + class="lucide lucide-grid3x3" > should not scale the strokeWidth when ab stroke-width="1" stroke-linecap="round" stroke-linejoin="round" - class="lucide lucide-grid3x3 " - data-testid="grid-icon" + class="lucide lucide-grid3x3" > should render an component 1`] = ` stroke-width="2" stroke-linecap="round" stroke-linejoin="round" - class="lucide lucide-grid3x3 " + class="lucide lucide-grid3x3" > should render an component 1`] = ` `; - -exports[`Using lucide icon components > should render icons dynamically by using the dynamicIconImports module 1`] = ` - - - - - - - - - - -`; diff --git a/packages/lucide-react/tests/createLucideIcon.spec.tsx b/packages/lucide-react/tests/createLucideIcon.spec.tsx new file mode 100644 index 0000000000..7c1b5e475b --- /dev/null +++ b/packages/lucide-react/tests/createLucideIcon.spec.tsx @@ -0,0 +1,15 @@ +import { describe, it, expect } from 'vitest'; +import { createLucideIcon } from '../src/lucide-react'; +import { airVent } from './testIconNodes'; +import { render } from '@testing-library/react'; + +describe('Using createLucideIcon', () => { + it('should create a component from an iconNode', () => { + const AirVent = createLucideIcon('AirVent', airVent); + + const { container } = render(); + + expect(container.firstChild).toMatchSnapshot(); + expect(container.firstChild).toBeDefined(); + }); +}); diff --git a/packages/lucide-react/tests/dynamicImports.spec.tsx b/packages/lucide-react/tests/dynamicImports.spec.tsx new file mode 100644 index 0000000000..00f1eab8e4 --- /dev/null +++ b/packages/lucide-react/tests/dynamicImports.spec.tsx @@ -0,0 +1,38 @@ +import { describe, it, expect } from 'vitest'; +import { Suspense, lazy } from 'react'; +import { render, waitFor } from '@testing-library/react'; + +import dynamicIconImports from '../src/dynamicIconImports'; +import { LucideProps } from '../src/types'; + +describe('Using dynamicImports', () => { + it('should render icons dynamically by using the dynamicIconImports module', async () => { + interface IconProps extends Omit { + name: keyof typeof dynamicIconImports; + } + + const Icon = ({ name, ...props }: IconProps) => { + const LucideIcon = lazy(dynamicIconImports[name]); + + return ( + + + + ); + }; + + const { container, getByLabelText } = render( + , + ); + + await waitFor(() => getByLabelText('smile')); + + expect(container.innerHTML).toMatchSnapshot(); + }); +}); diff --git a/packages/lucide-react/tests/lucide-react.spec.tsx b/packages/lucide-react/tests/lucide-react.spec.tsx index 5d282290a9..8365d96f4a 100644 --- a/packages/lucide-react/tests/lucide-react.spec.tsx +++ b/packages/lucide-react/tests/lucide-react.spec.tsx @@ -1,8 +1,7 @@ import { describe, it, expect } from 'vitest'; -import { render, cleanup, waitFor } from '@testing-library/react'; -import { Pen, Edit2, Grid, LucideProps, Droplet } from '../src/lucide-react'; -import { Suspense, lazy } from 'react'; -import dynamicIconImports from '../src/dynamicIconImports'; +import { render, cleanup } from '@testing-library/react'; +import { Pen, Edit2, Grid, Droplet } from '../src/lucide-react'; +import defaultAttributes from '../src/defaultAttributes'; describe('Using lucide icon components', () => { it('should render an component', () => { @@ -11,24 +10,37 @@ describe('Using lucide icon components', () => { expect(container.innerHTML).toMatchSnapshot(); }); + it('should render the icon with default attributes', () => { + const { container } = render(); + + const SVGElement = container.firstElementChild; + + expect(SVGElement).toHaveAttribute('xmlns', defaultAttributes.xmlns); + expect(SVGElement).toHaveAttribute('width', String(defaultAttributes.width)); + expect(SVGElement).toHaveAttribute('height', String(defaultAttributes.height)); + expect(SVGElement).toHaveAttribute('viewBox', defaultAttributes.viewBox); + expect(SVGElement).toHaveAttribute('fill', defaultAttributes.fill); + expect(SVGElement).toHaveAttribute('stroke', defaultAttributes.stroke); + expect(SVGElement).toHaveAttribute('stroke-width', String(defaultAttributes.strokeWidth)); + expect(SVGElement).toHaveAttribute('stroke-linecap', defaultAttributes.strokeLinecap); + expect(SVGElement).toHaveAttribute('stroke-linejoin', defaultAttributes.strokeLinejoin); + }); + it('should adjust the size, stroke color and stroke width', () => { - const testId = 'grid-icon'; - const { container, getByTestId } = render( + const { container } = render( , ); - const { attributes } = getByTestId(testId) as unknown as { - attributes: Record; - }; - expect(attributes.stroke.value).toBe('red'); - expect(attributes.width.value).toBe('48'); - expect(attributes.height.value).toBe('48'); - expect(attributes['stroke-width'].value).toBe('4'); + const SVGElement = container.firstElementChild; + + expect(SVGElement).toHaveAttribute('stroke', 'red'); + expect(SVGElement).toHaveAttribute('width', '48'); + expect(SVGElement).toHaveAttribute('height', '48'); + expect(SVGElement).toHaveAttribute('stroke-width', '4'); expect(container.innerHTML).toMatchSnapshot(); }); @@ -58,23 +70,20 @@ describe('Using lucide icon components', () => { }); it('should not scale the strokeWidth when absoluteStrokeWidth is set', () => { - const testId = 'grid-icon'; const { container, getByTestId } = render( , ); - const { attributes } = getByTestId(testId) as unknown as { - attributes: Record; - }; - expect(attributes.stroke.value).toBe('red'); - expect(attributes.width.value).toBe('48'); - expect(attributes.height.value).toBe('48'); - expect(attributes['stroke-width'].value).toBe('1'); + const SVGElement = container.firstElementChild; + + expect(SVGElement).toHaveAttribute('stroke', 'red'); + expect(SVGElement).toHaveAttribute('width', '48'); + expect(SVGElement).toHaveAttribute('height', '48'); + expect(SVGElement).toHaveAttribute('stroke-width', '1'); expect(container.innerHTML).toMatchSnapshot(); }); @@ -87,34 +96,4 @@ describe('Using lucide icon components', () => { expect(container.firstChild).toHaveClass('lucide'); expect(container.firstChild).toHaveClass('lucide-droplet'); }); - - it('should render icons dynamically by using the dynamicIconImports module', async () => { - interface IconProps extends Omit { - name: keyof typeof dynamicIconImports; - } - - const Icon = ({ name, ...props }: IconProps) => { - const LucideIcon = lazy(dynamicIconImports[name]); - - return ( - - - - ); - }; - - const { container, getByLabelText } = render( - , - ); - - await waitFor(() => getByLabelText('smile')); - - expect(container.innerHTML).toMatchSnapshot(); - }); }); diff --git a/packages/lucide-react/tests/testIconNodes.ts b/packages/lucide-react/tests/testIconNodes.ts new file mode 100644 index 0000000000..c93721961c --- /dev/null +++ b/packages/lucide-react/tests/testIconNodes.ts @@ -0,0 +1,22 @@ +import { IconNode } from '../src/types'; + +export const airVent: IconNode = [ + [ + 'path', + { + d: 'M6 12H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2', + key: 'larmp2', + }, + ], + ['path', { d: 'M6 8h12', key: '6g4wlu' }], + ['path', { d: 'M18.3 17.7a2.5 2.5 0 0 1-3.16 3.83 2.53 2.53 0 0 1-1.14-2V12', key: '1bo8pg' }], + ['path', { d: 'M6.6 15.6A2 2 0 1 0 10 17v-5', key: 't9h90c' }], +]; + +export const coffee: IconNode = [ + ['path', { d: 'M17 8h1a4 4 0 1 1 0 8h-1', key: 'jx4kbh' }], + ['path', { d: 'M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4Z', key: '1bxrl0' }], + ['line', { x1: '6', x2: '6', y1: '2', y2: '4', key: '1cr9l3' }], + ['line', { x1: '10', x2: '10', y1: '2', y2: '4', key: '170wym' }], + ['line', { x1: '14', x2: '14', y1: '2', y2: '4', key: '1c5f70' }], +]; diff --git a/packages/lucide-solid/src/Icon.tsx b/packages/lucide-solid/src/Icon.tsx index 5e92bd4a16..d805f72ca4 100644 --- a/packages/lucide-solid/src/Icon.tsx +++ b/packages/lucide-solid/src/Icon.tsx @@ -2,10 +2,10 @@ import { For, splitProps } from 'solid-js'; import { Dynamic } from 'solid-js/web'; import defaultAttributes from './defaultAttributes'; import { IconNode, LucideProps } from './types'; -import { toKebabCase } from '@lucide/shared'; +import { mergeClasses, toKebabCase } from '@lucide/shared'; interface IconProps { - name: string; + name?: string; iconNode: IconNode; } @@ -33,9 +33,12 @@ const Icon = (props: LucideProps & IconProps) => { Number(localProps.size) : Number(localProps.strokeWidth ?? defaultAttributes['stroke-width']) } - class={`lucide lucide-${toKebabCase(localProps?.name ?? 'icon')} ${ - localProps.class != null ? localProps.class : '' - }`} + class={mergeClasses( + 'lucide', + 'lucide-icon', + localProps.name != null ? `lucide-${toKebabCase(localProps?.name)}` : undefined, + localProps.class != null ? localProps.class : '', + )} {...rest} > diff --git a/packages/lucide-solid/src/lucide-solid.ts b/packages/lucide-solid/src/lucide-solid.ts index 2e28382436..3bfeb70ea9 100644 --- a/packages/lucide-solid/src/lucide-solid.ts +++ b/packages/lucide-solid/src/lucide-solid.ts @@ -1,3 +1,6 @@ export * from './icons'; export * as icons from './icons'; export * from './aliases'; +export * from './types'; + +export { default as Icon } from './Icon'; diff --git a/packages/lucide-solid/src/types.ts b/packages/lucide-solid/src/types.ts index 80ad93fe76..cea277310d 100644 --- a/packages/lucide-solid/src/types.ts +++ b/packages/lucide-solid/src/types.ts @@ -11,3 +11,5 @@ export interface LucideProps extends SVGAttributes { class?: string; absoluteStrokeWidth?: boolean; } + +export type LucideIcon = (props: LucideProps) => JSX.Element; diff --git a/packages/lucide-solid/tests/Icon.spec.tsx b/packages/lucide-solid/tests/Icon.spec.tsx new file mode 100644 index 0000000000..74c3936abb --- /dev/null +++ b/packages/lucide-solid/tests/Icon.spec.tsx @@ -0,0 +1,33 @@ +import { describe, it, expect } from 'vitest'; +import { render } from '@solidjs/testing-library'; + +import { airVent } from './testIconNodes'; +import { Icon } from '../src/lucide-solid'; + +describe('Using Icon Component', () => { + it('should render icon based on a iconNode', async () => { + const { container } = render(() => ( + + )); + + expect(container.firstChild).toBeDefined(); + }); + + it('should render icon and match snapshot', async () => { + const { container } = render(() => ( + + )); + + expect(container.firstChild).toMatchSnapshot(); + }); +}); diff --git a/packages/lucide-solid/tests/__snapshots__/Icon.spec.tsx.snap b/packages/lucide-solid/tests/__snapshots__/Icon.spec.tsx.snap new file mode 100644 index 0000000000..3ec6f852d3 --- /dev/null +++ b/packages/lucide-solid/tests/__snapshots__/Icon.spec.tsx.snap @@ -0,0 +1,33 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Using Icon Component > should render icon and match snapshot 1`] = ` + + + + + + +`; diff --git a/packages/lucide-solid/tests/__snapshots__/lucide-solid.spec.tsx.snap b/packages/lucide-solid/tests/__snapshots__/lucide-solid.spec.tsx.snap index 0b1d5289a7..47ba999bfa 100644 --- a/packages/lucide-solid/tests/__snapshots__/lucide-solid.spec.tsx.snap +++ b/packages/lucide-solid/tests/__snapshots__/lucide-solid.spec.tsx.snap @@ -10,7 +10,7 @@ exports[`Using lucide icon components > should adjust the size, stroke color and height="48" stroke="red" stroke-width="4" - class="lucide lucide-grid3x3 " + class="lucide lucide-icon lucide-grid3x3" data-testid="grid-icon" > should not scale the strokeWidth when ab height="48" stroke="red" stroke-width="1" - class="lucide lucide-grid3x3 " + class="lucide lucide-icon lucide-grid3x3" data-testid="grid-icon" > should render a component 1`] = ` height="24" stroke="currentColor" stroke-width="2" - class="lucide lucide-grid3x3 " + class="lucide lucide-icon lucide-grid3x3" > + import { mergeClasses } from '@lucide/shared' import defaultAttributes from './defaultAttributes' import type { IconNode } from './types'; - export let name: string + export let name: string | undefined = undefined export let color = 'currentColor' export let size: number | string = 24 export let strokeWidth: number | string = 2 @@ -21,7 +22,14 @@ ? Number(strokeWidth) * 24 / Number(size) : strokeWidth } - class={`lucide-icon lucide lucide-${name} ${$$props.class ?? ''}`} + class={ + mergeClasses( + 'lucide-icon', + 'lucide', + name ? `lucide-${name}`: '', + $$props.class + ) + } > {#each iconNode as [tag, attrs]} diff --git a/packages/lucide-svelte/src/lucide-svelte.ts b/packages/lucide-svelte/src/lucide-svelte.ts index 77e474d300..c1567a365b 100644 --- a/packages/lucide-svelte/src/lucide-svelte.ts +++ b/packages/lucide-svelte/src/lucide-svelte.ts @@ -3,3 +3,4 @@ export * as icons from './icons/index.js'; export * from './aliases.js'; export { default as defaultAttributes } from './defaultAttributes.js'; export * from './types.js'; +export { default as Icon } from './Icon.svelte'; diff --git a/packages/lucide-svelte/tests/Icon.spec.ts b/packages/lucide-svelte/tests/Icon.spec.ts new file mode 100644 index 0000000000..e5f0eb3244 --- /dev/null +++ b/packages/lucide-svelte/tests/Icon.spec.ts @@ -0,0 +1,33 @@ +import { describe, it, expect } from 'vitest'; +import { render } from '@testing-library/svelte'; +import { Icon } from '../src/lucide-svelte'; + +import { airVent } from './testIconNodes'; + +describe('Using Icon Component', () => { + it('should render icon based on a iconNode', async () => { + const { container } = render(Icon, { + props: { + iconNode: airVent, + size: 48, + color: 'red', + absoluteStrokeWidth: true, + }, + }); + + expect(container.firstChild).toBeDefined(); + }); + + it('should render icon and match snapshot', async () => { + const { container } = render(Icon, { + props: { + iconNode: airVent, + size: 48, + color: 'red', + absoluteStrokeWidth: true, + }, + }); + + expect(container.firstChild).toMatchSnapshot(); + }); +}); diff --git a/packages/lucide-svelte/tests/__snapshots__/Icon.spec.ts.snap b/packages/lucide-svelte/tests/__snapshots__/Icon.spec.ts.snap new file mode 100644 index 0000000000..bd3dddc7f1 --- /dev/null +++ b/packages/lucide-svelte/tests/__snapshots__/Icon.spec.ts.snap @@ -0,0 +1,36 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Using Icon Component > should render icon and match snapshot 1`] = ` +
+ + + + + + + + + + + +
+`; diff --git a/packages/lucide-svelte/tests/__snapshots__/lucide-svelte.spec.ts.snap b/packages/lucide-svelte/tests/__snapshots__/lucide-svelte.spec.ts.snap index 5c44a60e5b..620513a6bc 100644 --- a/packages/lucide-svelte/tests/__snapshots__/lucide-svelte.spec.ts.snap +++ b/packages/lucide-svelte/tests/__snapshots__/lucide-svelte.spec.ts.snap @@ -45,7 +45,7 @@ exports[`Using lucide icon components > should adjust the size, stroke color and
should not scale the strokeWidth when ab stroke-linecap="round" stroke-linejoin="round" data-testid="smile-icon" - class="lucide-icon lucide lucide-smile " + class="lucide-icon lucide lucide-smile" > should render an component 1`] = `
should render an icon slot 1`] = `
=3.0.1" diff --git a/packages/lucide-vue-next/src/Icon.ts b/packages/lucide-vue-next/src/Icon.ts new file mode 100644 index 0000000000..d37973b7b7 --- /dev/null +++ b/packages/lucide-vue-next/src/Icon.ts @@ -0,0 +1,30 @@ +import { type FunctionalComponent, h } from 'vue'; +import { mergeClasses, toKebabCase } from '@lucide/shared'; +import defaultAttributes from './defaultAttributes'; +import { IconNode, LucideProps } from './types'; + +interface IconProps { + iconNode: IconNode; + name: string; +} + +const Icon: FunctionalComponent = ( + { size, strokeWidth = 2, absoluteStrokeWidth, color, iconNode, name, class: classes, ...props }, + { slots }, +) => { + return h( + 'svg', + { + ...defaultAttributes, + width: size || defaultAttributes.width, + height: size || defaultAttributes.height, + stroke: color || defaultAttributes.stroke, + 'stroke-width': absoluteStrokeWidth ? (Number(strokeWidth) * 24) / Number(size) : strokeWidth, + class: ['lucide', `lucide-${toKebabCase(name ?? 'icon')}`], + ...props, + }, + [...iconNode.map((child) => h(...child)), ...(slots.default ? [slots.default()] : [])], + ); +}; + +export default Icon; diff --git a/packages/lucide-vue-next/src/createLucideIcon.ts b/packages/lucide-vue-next/src/createLucideIcon.ts index 7f15fb3389..27c0904f98 100644 --- a/packages/lucide-vue-next/src/createLucideIcon.ts +++ b/packages/lucide-vue-next/src/createLucideIcon.ts @@ -1,17 +1,9 @@ import { h } from 'vue'; -import type { SVGAttributes, FunctionalComponent } from 'vue'; -import defaultAttributes from './defaultAttributes'; -import { toKebabCase } from '@lucide/shared'; +import type { FunctionalComponent } from 'vue'; +import { IconNode, LucideProps } from './types'; +import Icon from './Icon'; // Create interface extending SVGAttributes -export interface SVGProps extends Partial { - size?: 24 | number; - strokeWidth?: number | string; - absoluteStrokeWidth?: boolean; -} - -export type IconNode = [elementName: string, attrs: Record][]; -export type Icon = FunctionalComponent; /** * Create a Lucide icon component @@ -20,27 +12,16 @@ export type Icon = FunctionalComponent; * @returns {FunctionalComponent} LucideIcon */ const createLucideIcon = - (iconName: string, iconNode: IconNode): Icon => - ( - { size, strokeWidth = 2, absoluteStrokeWidth, color, class: classes, ...props }, // props - { attrs, slots }, // context - ) => { - return h( - 'svg', + (iconName: string, iconNode: IconNode): FunctionalComponent => + (props, { slots }) => + h( + Icon, { - ...defaultAttributes, - width: size || defaultAttributes.width, - height: size || defaultAttributes.height, - stroke: color || defaultAttributes.stroke, - 'stroke-width': absoluteStrokeWidth - ? (Number(strokeWidth) * 24) / Number(size) - : strokeWidth, - ...attrs, - class: ['lucide', `lucide-${toKebabCase(iconName)}`], ...props, + iconNode, + name: iconName, }, - [...iconNode.map((child) => h(...child)), ...(slots.default ? [slots.default()] : [])], + slots, ); - }; export default createLucideIcon; diff --git a/packages/lucide-vue-next/src/lucide-vue-next.ts b/packages/lucide-vue-next/src/lucide-vue-next.ts index 2e28382436..6636c22592 100644 --- a/packages/lucide-vue-next/src/lucide-vue-next.ts +++ b/packages/lucide-vue-next/src/lucide-vue-next.ts @@ -1,3 +1,7 @@ export * from './icons'; export * as icons from './icons'; export * from './aliases'; +export * from './types'; + +export { default as createLucideIcon } from './createLucideIcon'; +export { default as Icon } from './Icon'; diff --git a/packages/lucide-vue-next/src/types.ts b/packages/lucide-vue-next/src/types.ts new file mode 100644 index 0000000000..638af5b7fe --- /dev/null +++ b/packages/lucide-vue-next/src/types.ts @@ -0,0 +1,13 @@ +import type { FunctionalComponent, SVGAttributes } from 'vue'; + +export interface LucideProps extends Partial { + size?: 24 | number; + strokeWidth?: number | string; + absoluteStrokeWidth?: boolean; +} + +export type IconNode = [elementName: string, attrs: Record][]; +export type LucideIcon = FunctionalComponent; + +// Legacy exports +export type SVGProps = LucideProps; diff --git a/packages/lucide-vue-next/tests/Icon.spec.ts b/packages/lucide-vue-next/tests/Icon.spec.ts new file mode 100644 index 0000000000..6546744ad0 --- /dev/null +++ b/packages/lucide-vue-next/tests/Icon.spec.ts @@ -0,0 +1,33 @@ +import { describe, it, expect } from 'vitest'; +import { render } from '@testing-library/vue'; + +import { airVent } from './testIconNodes'; +import { Icon } from '../src/lucide-vue-next'; + +describe('Using Icon Component', () => { + it('should render icon based on a iconNode', async () => { + const { container } = render(Icon, { + props: { + iconNode: airVent, + size: 48, + color: 'red', + absoluteStrokeWidth: true, + }, + }); + + expect(container.firstChild).toBeDefined(); + }); + + it('should render icon and match snapshot', async () => { + const { container } = render(Icon, { + props: { + iconNode: airVent, + size: 48, + color: 'red', + absoluteStrokeWidth: true, + }, + }); + + expect(container.firstChild).toMatchSnapshot(); + }); +}); diff --git a/packages/lucide-vue-next/tests/__snapshots__/Icon.spec.ts.snap b/packages/lucide-vue-next/tests/__snapshots__/Icon.spec.ts.snap new file mode 100644 index 0000000000..5e38eec073 --- /dev/null +++ b/packages/lucide-vue-next/tests/__snapshots__/Icon.spec.ts.snap @@ -0,0 +1,29 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Using Icon Component > should render icon and match snapshot 1`] = ` + + + + + + +`; diff --git a/packages/lucide-vue-next/tests/__snapshots__/lucide-vue-next.spec.ts.snap b/packages/lucide-vue-next/tests/__snapshots__/lucide-vue-next.spec.ts.snap index 9a609fb1d6..c9e6de1970 100644 --- a/packages/lucide-vue-next/tests/__snapshots__/lucide-vue-next.spec.ts.snap +++ b/packages/lucide-vue-next/tests/__snapshots__/lucide-vue-next.spec.ts.snap @@ -81,10 +81,8 @@ exports[`Using lucide icon components > should adjust the size, stroke color and
{ afterEach(() => cleanup()); @@ -10,6 +11,22 @@ describe('Using lucide icon components', () => { expect(container).toMatchSnapshot(); }); + it('should render the icon with the default attributes', () => { + const { container } = render(Smile); + + const SVGElement = container.firstElementChild; + + expect(SVGElement).toHaveAttribute('xmlns', defaultAttributes.xmlns); + expect(SVGElement).toHaveAttribute('width', String(defaultAttributes.width)); + expect(SVGElement).toHaveAttribute('height', String(defaultAttributes.height)); + expect(SVGElement).toHaveAttribute('viewBox', defaultAttributes.viewBox); + expect(SVGElement).toHaveAttribute('fill', defaultAttributes.fill); + expect(SVGElement).toHaveAttribute('stroke', defaultAttributes.stroke); + expect(SVGElement).toHaveAttribute('stroke-width', String(defaultAttributes['stroke-width'])); + expect(SVGElement).toHaveAttribute('stroke-linecap', defaultAttributes['stroke-linecap']); + expect(SVGElement).toHaveAttribute('stroke-linejoin', defaultAttributes['stroke-linejoin']); + }); + it('should adjust the size, stroke color and stroke width', () => { const { container } = render(Smile, { props: { @@ -19,11 +36,11 @@ describe('Using lucide icon components', () => { }, }); - const [icon] = document.getElementsByClassName('lucide'); + const SVGElement = container.firstElementChild; - expect(icon.getAttribute('width')).toBe('48'); - expect(icon.getAttribute('stroke')).toBe('red'); - expect(icon.getAttribute('stroke-width')).toBe('4'); + expect(SVGElement).toHaveAttribute('width', '48'); + expect(SVGElement).toHaveAttribute('stroke', 'red'); + expect(SVGElement).toHaveAttribute('stroke-width', '4'); expect(container).toMatchSnapshot(); }); @@ -37,7 +54,7 @@ describe('Using lucide icon components', () => { expect(container).toMatchSnapshot(); - const [icon] = document.getElementsByClassName('my-icon'); + const icon = container.firstElementChild; expect(icon).toHaveClass('my-icon'); expect(icon).toHaveClass('lucide'); @@ -53,20 +70,20 @@ describe('Using lucide icon components', () => { expect(container).toMatchSnapshot(); - const [icon] = document.getElementsByClassName('lucide'); + const icon = container.firstElementChild; expect(icon).toHaveStyle({ position: 'absolute' }); }); it('should call the onClick event', async () => { const onClick = vi.fn(); - render(Smile, { + const { container } = render(Smile, { attrs: { onClick, }, }); - const [icon] = document.getElementsByClassName('lucide'); + const icon = container.firstElementChild; await fireEvent.click(icon); @@ -116,7 +133,7 @@ describe('Using lucide icon components', () => { }); it('should not scale the strokeWidth when absoluteStrokeWidth is set', () => { - render(Pen, { + const { container } = render(Pen, { props: { size: 48, color: 'red', @@ -124,10 +141,10 @@ describe('Using lucide icon components', () => { }, }); - const [icon] = document.getElementsByClassName('lucide'); + const icon = container.firstElementChild; - expect(icon.getAttribute('width')).toBe('48'); - expect(icon.getAttribute('stroke')).toBe('red'); - expect(icon.getAttribute('stroke-width')).toBe('1'); + expect(icon).toHaveAttribute('width', '48'); + expect(icon).toHaveAttribute('stroke', 'red'); + expect(icon).toHaveAttribute('stroke-width', '1'); }); }); diff --git a/packages/lucide-vue-next/tests/setupVitest.js b/packages/lucide-vue-next/tests/setupVitest.js index 7b0828bfa8..bb02c60cd0 100644 --- a/packages/lucide-vue-next/tests/setupVitest.js +++ b/packages/lucide-vue-next/tests/setupVitest.js @@ -1 +1 @@ -import '@testing-library/jest-dom'; +import '@testing-library/jest-dom/vitest'; diff --git a/packages/lucide-vue-next/tests/testIconNodes.ts b/packages/lucide-vue-next/tests/testIconNodes.ts new file mode 100644 index 0000000000..8c593572d5 --- /dev/null +++ b/packages/lucide-vue-next/tests/testIconNodes.ts @@ -0,0 +1,22 @@ +import { IconNode } from '../src/createLucideIcon'; + +export const airVent: IconNode = [ + [ + 'path', + { + d: 'M6 12H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2', + key: 'larmp2', + }, + ], + ['path', { d: 'M6 8h12', key: '6g4wlu' }], + ['path', { d: 'M18.3 17.7a2.5 2.5 0 0 1-3.16 3.83 2.53 2.53 0 0 1-1.14-2V12', key: '1bo8pg' }], + ['path', { d: 'M6.6 15.6A2 2 0 1 0 10 17v-5', key: 't9h90c' }], +]; + +export const coffee: IconNode = [ + ['path', { d: 'M17 8h1a4 4 0 1 1 0 8h-1', key: 'jx4kbh' }], + ['path', { d: 'M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4Z', key: '1bxrl0' }], + ['line', { x1: '6', x2: '6', y1: '2', y2: '4', key: '1cr9l3' }], + ['line', { x1: '10', x2: '10', y1: '2', y2: '4', key: '170wym' }], + ['line', { x1: '14', x2: '14', y1: '2', y2: '4', key: '1c5f70' }], +]; diff --git a/packages/lucide/src/createIcons.ts b/packages/lucide/src/createIcons.ts new file mode 100644 index 0000000000..aff458e891 --- /dev/null +++ b/packages/lucide/src/createIcons.ts @@ -0,0 +1,37 @@ +import replaceElement from './replaceElement'; + +/** + * Replaces all elements with matching nameAttr with the defined icons + * @param {{ icons?: object, nameAttr?: string, attrs?: object }} options + */ +const createIcons = ({ icons = {}, nameAttr = 'data-lucide', attrs = {} } = {}) => { + if (!Object.values(icons).length) { + throw new Error( + "Please provide an icons object.\nIf you want to use all the icons you can import it like:\n `import { createIcons, icons } from 'lucide';\nlucide.createIcons({icons});`", + ); + } + + if (typeof document === 'undefined') { + throw new Error('`createIcons()` only works in a browser environment.'); + } + + const elementsToReplace = document.querySelectorAll(`[${nameAttr}]`); + Array.from(elementsToReplace).forEach((element) => + replaceElement(element, { nameAttr, icons, attrs }), + ); + + /** @todo: remove this block in v1.0 */ + if (nameAttr === 'data-lucide') { + const deprecatedElements = document.querySelectorAll('[icon-name]'); + if (deprecatedElements.length > 0) { + console.warn( + '[Lucide] Some icons were found with the now deprecated icon-name attribute. These will still be replaced for backwards compatibility, but will no longer be supported in v1.0 and you should switch to data-lucide', + ); + Array.from(deprecatedElements).forEach((element) => + replaceElement(element, { nameAttr: 'icon-name', icons, attrs }), + ); + } + } +}; + +export default createIcons; diff --git a/packages/lucide/src/lucide.ts b/packages/lucide/src/lucide.ts index ab7e4a4afa..38a2ab6ecf 100644 --- a/packages/lucide/src/lucide.ts +++ b/packages/lucide/src/lucide.ts @@ -1,41 +1,9 @@ -import replaceElement from './replaceElement'; import * as iconAndAliases from './iconsAndAliases'; -/** - * Replaces all elements with matching nameAttr with the defined icons - * @param {{ icons?: object, nameAttr?: string, attrs?: object }} options - */ -const createIcons = ({ icons = {}, nameAttr = 'data-lucide', attrs = {} } = {}) => { - if (!Object.values(icons).length) { - throw new Error( - "Please provide an icons object.\nIf you want to use all the icons you can import it like:\n `import { createIcons, icons } from 'lucide';\nlucide.createIcons({icons});`", - ); - } - - if (typeof document === 'undefined') { - throw new Error('`createIcons()` only works in a browser environment.'); - } - - const elementsToReplace = document.querySelectorAll(`[${nameAttr}]`); - Array.from(elementsToReplace).forEach((element) => - replaceElement(element, { nameAttr, icons, attrs }), - ); - - /** @todo: remove this block in v1.0 */ - if (nameAttr === 'data-lucide') { - const deprecatedElements = document.querySelectorAll('[icon-name]'); - if (deprecatedElements.length > 0) { - console.warn( - '[Lucide] Some icons were found with the now deprecated icon-name attribute. These will still be replaced for backwards compatibility, but will no longer be supported in v1.0 and you should switch to data-lucide', - ); - Array.from(deprecatedElements).forEach((element) => - replaceElement(element, { nameAttr: 'icon-name', icons, attrs }), - ); - } - } -}; - -export { createIcons }; +/* + Create Icons function export. +*/ +export { default as createIcons } from './createIcons'; /* Create Element function export. diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 04bca77e0d..e1a8199185 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -1 +1,2 @@ export * from './utils'; +export * from './utility-types'; diff --git a/packages/shared/src/utility-types.ts b/packages/shared/src/utility-types.ts new file mode 100644 index 0000000000..892014723d --- /dev/null +++ b/packages/shared/src/utility-types.ts @@ -0,0 +1,16 @@ +/** + * Convert a type string from camelCase to PascalCase + * + * @example + * type Test = CamelToPascal<'fooBar'> // 'FooBar' + */ +export type CamelToPascal = T extends `${infer FirstChar}${infer Rest}` + ? `${Capitalize}${Rest}` + : never; + +/** + * Creates a list of components from a list of component names and a component type + */ +export type ComponentList = { + [Prop in keyof ComponentNames as CamelToPascal]: ComponentType; +}; diff --git a/packages/shared/src/utils.ts b/packages/shared/src/utils.ts index 9e45977f2e..f068a5714e 100644 --- a/packages/shared/src/utils.ts +++ b/packages/shared/src/utils.ts @@ -1,8 +1,37 @@ +import { CamelToPascal } from './utility-types'; + /** - * Converts string to KebabCase + * Converts string to kebab case * * @param {string} string * @returns {string} A kebabized string */ export const toKebabCase = (string: string) => string.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase(); + +/** + * Converts string to pascal case + * + * @param {string} string + * @returns {string} A pascalized string + */ +export const toPascalCase = (string: T): CamelToPascal => { + const camelCase = string.replace(/^([A-Z])|[\s-_]+(\w)/g, (match, p1, p2) => + p2 ? p2.toUpperCase() : p1.toLowerCase(), + ); + + return (camelCase.charAt(0).toUpperCase() + camelCase.slice(1)) as CamelToPascal; +}; + +/** + * Merges classes into a single string + * + * @param {array} classes + * @returns {string} A string of classes + */ +export const mergeClasses = (...classes: ClassType[]) => + classes + .filter((className, index, array) => { + return Boolean(className) && array.indexOf(className) === index; + }) + .join(' '); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a0dd975a19..04f8027cb3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -457,6 +457,9 @@ importers: '@lucide/rollup-plugins': specifier: workspace:* version: link:../../tools/rollup-plugins + '@lucide/shared': + specifier: workspace:* + version: link:../shared '@testing-library/jest-dom': specifier: ^6.1.6 version: 6.4.2(vitest@1.2.2) @@ -586,6 +589,9 @@ importers: '@lucide/build-icons': specifier: workspace:* version: link:../../tools/build-icons + '@lucide/shared': + specifier: workspace:* + version: link:../shared '@sveltejs/package': specifier: ^2.2.3 version: 2.2.6(svelte@4.1.2)(typescript@5.1.6) @@ -681,16 +687,16 @@ importers: version: link:../shared '@testing-library/jest-dom': specifier: ^6.1.6 - version: 6.4.2(vitest@1.2.2) + version: 6.4.2(vitest@1.4.0) '@testing-library/vue': - specifier: ^8.0.1 - version: 8.0.2(vue@3.4.18) + specifier: ^8.0.3 + version: 8.0.3(vue@3.4.21) '@vitejs/plugin-vue': specifier: ^4.6.2 - version: 4.6.2(vite@5.0.13)(vue@3.4.18) + version: 4.6.2(vite@5.0.13)(vue@3.4.21) '@vue/test-utils': - specifier: 2.4.3 - version: 2.4.3(vue@3.4.18) + specifier: 2.4.5 + version: 2.4.5 rollup: specifier: ^4.9.2 version: 4.9.6 @@ -701,11 +707,11 @@ importers: specifier: 5.0.13 version: 5.0.13 vitest: - specifier: ^1.1.1 - version: 1.2.2(jsdom@20.0.3) + specifier: ^1.4.0 + version: 1.4.0 vue: - specifier: ^3.0.1 - version: 3.4.18(typescript@4.9.5) + specifier: ^3.4.21 + version: 3.4.21(typescript@4.9.5) packages/shared: {} @@ -7452,6 +7458,38 @@ packages: vitest: 1.2.2(jsdom@20.0.3) dev: true + /@testing-library/jest-dom@6.4.2(vitest@1.4.0): + resolution: {integrity: sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + peerDependencies: + '@jest/globals': '>= 28' + '@types/bun': latest + '@types/jest': '>= 28' + jest: '>= 28' + vitest: '>= 0.32' + peerDependenciesMeta: + '@jest/globals': + optional: true + '@types/bun': + optional: true + '@types/jest': + optional: true + jest: + optional: true + vitest: + optional: true + dependencies: + '@adobe/css-tools': 4.3.3 + '@babel/runtime': 7.23.9 + aria-query: 5.3.0 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + lodash: 4.17.21 + redent: 3.0.0 + vitest: 1.4.0 + dev: true + /@testing-library/preact@3.2.3(preact@10.19.4): resolution: {integrity: sha512-y6Kklp1XK3f1X2fWCbujmJyzkf+1BgLYXNgAx21j9+D4CoqMTz5qC4SQufb1L6q/jxLGACzrQ90ewVOTBvHOfg==} engines: {node: '>= 12'} @@ -7500,8 +7538,8 @@ packages: vue-template-compiler: 2.7.14(vue@2.7.14) dev: true - /@testing-library/vue@8.0.2(vue@3.4.18): - resolution: {integrity: sha512-A8wWX+qQn0o0izpQWnGCpwQt8wAdpsVP8vPP2h5Q/jcGhZ5yKXz9PPUqhQv+45LTFaWlyRf8bArTVaB/KFFd5A==} + /@testing-library/vue@8.0.3(vue@3.4.21): + resolution: {integrity: sha512-wSsbNlZ69ZFQgVlHMtc/ZC/g9BHO7MhyDrd4nHyfEubtMr3kToN/w4/BsSBknGIF8w9UmPbsgbIuq/CbdBHzCA==} engines: {node: '>=14'} peerDependencies: '@vue/compiler-sfc': '>= 3' @@ -7512,10 +7550,8 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@testing-library/dom': 9.3.4 - '@vue/test-utils': 2.4.3(vue@3.4.18) - vue: 3.4.18(typescript@4.9.5) - transitivePeerDependencies: - - '@vue/server-renderer' + '@vue/test-utils': 2.4.5 + vue: 3.4.21(typescript@4.9.5) dev: true /@tokenizer/token@0.3.0: @@ -8378,7 +8414,7 @@ packages: vue: 2.7.14 dev: true - /@vitejs/plugin-vue@4.6.2(vite@5.0.13)(vue@3.4.18): + /@vitejs/plugin-vue@4.6.2(vite@5.0.13)(vue@3.4.21): resolution: {integrity: sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -8386,7 +8422,7 @@ packages: vue: ^3.2.25 dependencies: vite: 5.0.13 - vue: 3.4.18(typescript@4.9.5) + vue: 3.4.21(typescript@4.9.5) dev: true /@vitejs/plugin-vue@5.0.3(vite@5.0.12)(vue@3.4.18): @@ -8416,6 +8452,14 @@ packages: chai: 4.4.1 dev: true + /@vitest/expect@1.4.0: + resolution: {integrity: sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==} + dependencies: + '@vitest/spy': 1.4.0 + '@vitest/utils': 1.4.0 + chai: 4.4.1 + dev: true + /@vitest/runner@0.32.4: resolution: {integrity: sha512-cHOVCkiRazobgdKLnczmz2oaKK9GJOw6ZyRcaPdssO1ej+wzHVIkWiCiNacb3TTYPdzMddYkCgMjZ4r8C0JFCw==} dependencies: @@ -8432,6 +8476,14 @@ packages: pathe: 1.1.2 dev: true + /@vitest/runner@1.4.0: + resolution: {integrity: sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==} + dependencies: + '@vitest/utils': 1.4.0 + p-limit: 5.0.0 + pathe: 1.1.2 + dev: true + /@vitest/snapshot@0.32.4: resolution: {integrity: sha512-IRpyqn9t14uqsFlVI2d7DFMImGMs1Q9218of40bdQQgMePwVdmix33yMNnebXcTzDU5eiV3eUsoxxH5v0x/IQA==} dependencies: @@ -8448,6 +8500,14 @@ packages: pretty-format: 29.7.0 dev: true + /@vitest/snapshot@1.4.0: + resolution: {integrity: sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==} + dependencies: + magic-string: 0.30.7 + pathe: 1.1.2 + pretty-format: 29.7.0 + dev: true + /@vitest/spy@0.32.4: resolution: {integrity: sha512-oA7rCOqVOOpE6rEoXuCOADX7Lla1LIa4hljI2MSccbpec54q+oifhziZIJXxlE/CvI2E+ElhBHzVu0VEvJGQKQ==} dependencies: @@ -8460,6 +8520,12 @@ packages: tinyspy: 2.2.1 dev: true + /@vitest/spy@1.4.0: + resolution: {integrity: sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==} + dependencies: + tinyspy: 2.2.1 + dev: true + /@vitest/utils@0.32.4: resolution: {integrity: sha512-Gwnl8dhd1uJ+HXrYyV0eRqfmk9ek1ASE/LWfTCuWMw+d07ogHqp4hEAV28NiecimK6UY9DpSEPh+pXBA5gtTBg==} dependencies: @@ -8477,6 +8543,15 @@ packages: pretty-format: 29.7.0 dev: true + /@vitest/utils@1.4.0: + resolution: {integrity: sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==} + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + dev: true + /@vue/compiler-core@3.4.18: resolution: {integrity: sha512-F7YK8lMK0iv6b9/Gdk15A67wM0KKZvxDxed0RR60C1z9tIJTKta+urs4j0RTN5XqHISzI3etN3mX0uHhjmoqjQ==} dependencies: @@ -8486,12 +8561,29 @@ packages: estree-walker: 2.0.2 source-map-js: 1.0.2 + /@vue/compiler-core@3.4.21: + resolution: {integrity: sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==} + dependencies: + '@babel/parser': 7.23.9 + '@vue/shared': 3.4.21 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.0.2 + dev: true + /@vue/compiler-dom@3.4.18: resolution: {integrity: sha512-24Eb8lcMfInefvQ6YlEVS18w5Q66f4+uXWVA+yb7praKbyjHRNuKVWGuinfSSjM0ZIiPi++QWukhkgznBaqpEA==} dependencies: '@vue/compiler-core': 3.4.18 '@vue/shared': 3.4.18 + /@vue/compiler-dom@3.4.21: + resolution: {integrity: sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==} + dependencies: + '@vue/compiler-core': 3.4.21 + '@vue/shared': 3.4.21 + dev: true + /@vue/compiler-sfc@2.7.14: resolution: {integrity: sha512-aNmNHyLPsw+sVvlQFQ2/8sjNuLtK54TC6cuKnVzAY93ks4ZBrvwQSnkkIh7bsbNhum5hJBS00wSDipQ937f5DA==} dependencies: @@ -8513,12 +8605,33 @@ packages: postcss: 8.4.35 source-map-js: 1.0.2 + /@vue/compiler-sfc@3.4.21: + resolution: {integrity: sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==} + dependencies: + '@babel/parser': 7.23.9 + '@vue/compiler-core': 3.4.21 + '@vue/compiler-dom': 3.4.21 + '@vue/compiler-ssr': 3.4.21 + '@vue/shared': 3.4.21 + estree-walker: 2.0.2 + magic-string: 0.30.7 + postcss: 8.4.35 + source-map-js: 1.0.2 + dev: true + /@vue/compiler-ssr@3.4.18: resolution: {integrity: sha512-hSlv20oUhPxo2UYUacHgGaxtqP0tvFo6ixxxD6JlXIkwzwoZ9eKK6PFQN4hNK/R13JlNyldwWt/fqGBKgWJ6nQ==} dependencies: '@vue/compiler-dom': 3.4.18 '@vue/shared': 3.4.18 + /@vue/compiler-ssr@3.4.21: + resolution: {integrity: sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==} + dependencies: + '@vue/compiler-dom': 3.4.21 + '@vue/shared': 3.4.21 + dev: true + /@vue/devtools-api@6.5.1: resolution: {integrity: sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==} dev: true @@ -8528,12 +8641,25 @@ packages: dependencies: '@vue/shared': 3.4.18 + /@vue/reactivity@3.4.21: + resolution: {integrity: sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==} + dependencies: + '@vue/shared': 3.4.21 + dev: true + /@vue/runtime-core@3.4.18: resolution: {integrity: sha512-7mU9diCa+4e+8/wZ7Udw5pwTH10A11sZ1nldmHOUKJnzCwvZxfJqAtw31mIf4T5H2FsLCSBQT3xgioA9vIjyDQ==} dependencies: '@vue/reactivity': 3.4.18 '@vue/shared': 3.4.18 + /@vue/runtime-core@3.4.21: + resolution: {integrity: sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==} + dependencies: + '@vue/reactivity': 3.4.21 + '@vue/shared': 3.4.21 + dev: true + /@vue/runtime-dom@3.4.18: resolution: {integrity: sha512-2y1Mkzcw1niSfG7z3Qx+2ir9Gb4hdTkZe5p/I8x1aTIKQE0vY0tPAEUPhZm5tx6183gG3D/KwHG728UR0sIufA==} dependencies: @@ -8541,6 +8667,14 @@ packages: '@vue/shared': 3.4.18 csstype: 3.1.3 + /@vue/runtime-dom@3.4.21: + resolution: {integrity: sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==} + dependencies: + '@vue/runtime-core': 3.4.21 + '@vue/shared': 3.4.21 + csstype: 3.1.3 + dev: true + /@vue/server-renderer@3.4.18(vue@3.4.18): resolution: {integrity: sha512-YJd1wa7mzUN3NRqLEsrwEYWyO+PUBSROIGlCc3J/cvn7Zu6CxhNLgXa8Z4zZ5ja5/nviYO79J1InoPeXgwBTZA==} peerDependencies: @@ -8550,9 +8684,23 @@ packages: '@vue/shared': 3.4.18 vue: 3.4.18(typescript@4.9.5) + /@vue/server-renderer@3.4.21(vue@3.4.21): + resolution: {integrity: sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==} + peerDependencies: + vue: 3.4.21 + dependencies: + '@vue/compiler-ssr': 3.4.21 + '@vue/shared': 3.4.21 + vue: 3.4.21(typescript@4.9.5) + dev: true + /@vue/shared@3.4.18: resolution: {integrity: sha512-CxouGFxxaW5r1WbrSmWwck3No58rApXgRSBxrqgnY1K+jk20F6DrXJkHdH9n4HVT+/B6G2CAn213Uq3npWiy8Q==} + /@vue/shared@3.4.21: + resolution: {integrity: sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==} + dev: true + /@vue/test-utils@1.3.0(vue-template-compiler@2.7.14)(vue@2.7.14): resolution: {integrity: sha512-Xk2Xiyj2k5dFb8eYUKkcN9PzqZSppTlx7LaQWBbdA8tqh3jHr/KHX2/YLhNFc/xwDrgeLybqd+4ZCPJSGPIqeA==} peerDependencies: @@ -8566,18 +8714,11 @@ packages: vue-template-compiler: 2.7.14(vue@2.7.14) dev: true - /@vue/test-utils@2.4.3(vue@3.4.18): - resolution: {integrity: sha512-F4K7mF+ad++VlTrxMJVRnenKSJmO6fkQt2wpRDiKDesQMkfpniGWsqEi/JevxGBo2qEkwwjvTUAoiGJLNx++CA==} - peerDependencies: - '@vue/server-renderer': ^3.0.1 - vue: ^3.0.1 - peerDependenciesMeta: - '@vue/server-renderer': - optional: true + /@vue/test-utils@2.4.5: + resolution: {integrity: sha512-oo2u7vktOyKUked36R93NB7mg2B+N7Plr8lxp2JBGwr18ch6EggFjixSCdIVVLkT6Qr0z359Xvnafc9dcKyDUg==} dependencies: js-beautify: 1.14.9 - vue: 3.4.18(typescript@4.9.5) - vue-component-type-helpers: 1.8.27 + vue-component-type-helpers: 2.0.7 dev: true /@vueuse/components@10.7.2(vue@3.4.18): @@ -9211,13 +9352,6 @@ packages: engines: {node: '>=0.10.0'} dev: false - /array-buffer-byte-length@1.0.0: - resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} - dependencies: - call-bind: 1.0.6 - is-array-buffer: 3.0.4 - dev: true - /array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} @@ -11013,12 +11147,12 @@ packages: /deep-equal@2.2.2: resolution: {integrity: sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA==} dependencies: - array-buffer-byte-length: 1.0.0 + array-buffer-byte-length: 1.0.1 call-bind: 1.0.6 es-get-iterator: 1.1.3 get-intrinsic: 1.2.4 is-arguments: 1.1.1 - is-array-buffer: 3.0.2 + is-array-buffer: 3.0.4 is-date-object: 1.0.5 is-regex: 1.1.4 is-shared-array-buffer: 1.0.2 @@ -11026,11 +11160,11 @@ packages: object-is: 1.1.5 object-keys: 1.1.1 object.assign: 4.1.4 - regexp.prototype.flags: 1.5.0 + regexp.prototype.flags: 1.5.1 side-channel: 1.0.4 which-boxed-primitive: 1.0.2 which-collection: 1.0.1 - which-typed-array: 1.1.11 + which-typed-array: 1.1.14 dev: true /deep-is@0.1.4: @@ -14156,14 +14290,6 @@ packages: has-tostringtag: 1.0.2 dev: true - /is-array-buffer@3.0.2: - resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} - dependencies: - call-bind: 1.0.6 - get-intrinsic: 1.2.4 - is-typed-array: 1.1.12 - dev: true - /is-array-buffer@3.0.4: resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} engines: {node: '>= 0.4'} @@ -14763,6 +14889,10 @@ packages: /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + /js-tokens@8.0.3: + resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==} + dev: true + /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -18754,15 +18884,6 @@ packages: resolution: {integrity: sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==} dev: true - /regexp.prototype.flags@1.5.0: - resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.6 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - dev: true - /regexp.prototype.flags@1.5.1: resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} engines: {node: '>= 0.4'} @@ -20217,6 +20338,12 @@ packages: acorn: 8.11.3 dev: true + /strip-literal@2.0.0: + resolution: {integrity: sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==} + dependencies: + js-tokens: 8.0.3 + dev: true + /strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} dev: true @@ -21569,6 +21696,27 @@ packages: - terser dev: true + /vite-node@1.4.0: + resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + pathe: 1.1.2 + picocolors: 1.0.0 + vite: 5.0.12 + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vite-plugin-singlefile@0.5.1(vite@5.0.13): resolution: {integrity: sha512-yA9lWd6bSet0Br4/s34YPNnVBlDl2MbxlHDRrLrBCncD7q+HO5GGsw29Ymp+ydZ3eb4UU2GECgX2MJZW+qnoeQ==} peerDependencies: @@ -21909,6 +22057,61 @@ packages: - terser dev: true + /vitest@1.4.0: + resolution: {integrity: sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.4.0 + '@vitest/ui': 1.4.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@vitest/expect': 1.4.0 + '@vitest/runner': 1.4.0 + '@vitest/snapshot': 1.4.0 + '@vitest/spy': 1.4.0 + '@vitest/utils': 1.4.0 + acorn-walk: 8.3.2 + chai: 4.4.1 + debug: 4.3.4 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.7 + pathe: 1.1.2 + picocolors: 1.0.0 + std-env: 3.7.0 + strip-literal: 2.0.0 + tinybench: 2.6.0 + tinypool: 0.8.2 + vite: 5.0.12 + vite-node: 1.4.0 + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vlq@1.0.1: resolution: {integrity: sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==} dev: true @@ -21918,8 +22121,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /vue-component-type-helpers@1.8.27: - resolution: {integrity: sha512-0vOfAtI67UjeO1G6UiX5Kd76CqaQ67wrRZiOe7UAb9Jm6GzlUr/fC7CV90XfwapJRjpCMaZFhv1V0ajWRmE9Dg==} + /vue-component-type-helpers@2.0.7: + resolution: {integrity: sha512-7e12Evdll7JcTIocojgnCgwocX4WzIYStGClBQ+QuWPinZo/vQolv2EMq4a3lg16TKfwWafLimG77bxb56UauA==} dev: true /vue-demi@0.14.5(vue@3.4.18): @@ -21983,6 +22186,22 @@ packages: '@vue/shared': 3.4.18 typescript: 4.9.5 + /vue@3.4.21(typescript@4.9.5): + resolution: {integrity: sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@vue/compiler-dom': 3.4.21 + '@vue/compiler-sfc': 3.4.21 + '@vue/runtime-dom': 3.4.21 + '@vue/server-renderer': 3.4.21(vue@3.4.21) + '@vue/shared': 3.4.21 + typescript: 4.9.5 + dev: true + /w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} dev: false @@ -22243,17 +22462,6 @@ packages: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} dev: true - /which-typed-array@1.1.11: - resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} - engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.6 - call-bind: 1.0.6 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.2 - dev: true - /which-typed-array@1.1.14: resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} engines: {node: '>= 0.4'} diff --git a/tools/build-icons/main.mjs b/tools/build-icons/cli.mjs similarity index 100% rename from tools/build-icons/main.mjs rename to tools/build-icons/cli.mjs diff --git a/tools/build-icons/package.json b/tools/build-icons/package.json index 92beb4610e..866323ed0f 100644 --- a/tools/build-icons/package.json +++ b/tools/build-icons/package.json @@ -5,10 +5,10 @@ "main": "index.mjs", "type": "module", "scripts": { - "start": "node ./main.mjs" + "start": "node ./cli.mjs" }, "bin": { - "build-icons": "./main.mjs" + "build-icons": "./cli.mjs" }, "engines": { "node": ">= 16"