Merge branch 'main' into more

This commit is contained in:
Eric Fennis
2024-01-07 17:27:11 +01:00
committed by GitHub
77 changed files with 953 additions and 268 deletions
+34 -154
View File
@@ -6,8 +6,29 @@ on:
- 'icons/*.svg'
branches:
- main
- fix-icon-preview
jobs:
lint-filenames:
if: github.repository == 'lucide-icons/lucide'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v41
with:
files: icons/*
- name: Generate annotations
run: node ./scripts/lintFilenames.mjs
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
lint-contributors:
if: github.repository == 'lucide-icons/lucide'
runs-on: ubuntu-latest
@@ -46,184 +67,43 @@ jobs:
# Example for the previous substitution
# input: +++ b/icons/accessibility.json%0A@@ -2,0 +3 @@%0A+ "contributors": ["hi"],%0A@@ -13 +14 @@%0A+}%0A
# output: ::$ANNOTATION_SEVERITY file=icons/accessibility.json,line=2,endLine=3,title=$ANNOTATION_TITLE::$ANNOTATION_DESCRIPTION%0A%0A+ "contributors": ["hi"],%0A@@ -13 +14 @@%0A+}%0A
# - name: Fail if contributors have changed
# run: git diff --exit-code -- icons/*.json
generate-changed-icons-comment-data:
if: github.repository == 'lucide-icons/lucide'
generate-changed-icons-comment:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
generate-1px-stroke-width: ${{ steps.generate-1px-stroke-width.outputs.body }}
generate-2px-stroke-width: ${{ steps.generate-2px-stroke-width.outputs.body }}
generate-3px-stroke-width: ${{ steps.generate-3px-stroke-width.outputs.body }}
generate-24px-dpi-preview: ${{ steps.generate-24px-dpi-preview.outputs.body }}
generate-cohesion-check-random: ${{ steps.generate-cohesion-check-random.outputs.body }}
generate-cohesion-check-squares: ${{ steps.generate-cohesion-check-squares.outputs.body }}
generate-x-rays: ${{ steps.generate-x-rays.outputs.body }}
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v41
with:
files: icons/*.svg
- name: Generate 24px dpi preview
id: generate-24px-dpi-preview
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
while IFS= read -r file; do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/dpi/24/&.svg\"/> |"
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Generate cohesion check random
id: generate-cohesion-check-random
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
for file in $(printf "%s\\n" icons/*.svg | shuf | head -n$(awk -F' ' '{print NF}' <<< '${{ steps.changed-files.outputs.all_changed_files }}')); do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/2/&.svg\"/> |"
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Generate cohesion check squares
id: generate-cohesion-check-squares
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
for file in $(printf "%s\\n" icons/*square*.svg | shuf | head -n$(awk -F' ' '{print NF}' <<< '${{ steps.changed-files.outputs.all_changed_files }}')); do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/2/&.svg\"/> |"
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Generate 1px stroke-width
id: generate-1px-stroke-width
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
while IFS= read -r file; do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/1/&.svg\"/> |"
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Generate 2px stroke-width
id: generate-2px-stroke-width
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
while IFS= read -r file; do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/2/&.svg\"/> |"
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Generate 3px stroke-width
id: generate-3px-stroke-width
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
while IFS= read -r file; do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/3/&.svg\"/> |"
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Generate X-rays
id: generate-x-rays
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
while IFS= read -r file; do
cat "$file" | # get file content
tr '\n' ' ' | # remove line breaks
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
base64 -w 0 | # encode svg
sed "s|.*|<img width=\"400\" title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/$(basename ${file//\.svg/})/&.svg\"/> |"
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
echo >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
add-changed-icons-comment:
if: github.repository == 'lucide-icons/lucide'
runs-on: ubuntu-latest
permissions:
pull-requests: write
needs: [generate-changed-icons-comment-data]
steps:
- name: Find Comment
uses: peter-evans/find-comment@v2
id: fc
id: pr-comment
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: Added or changed icons
- name: Generate comment markup
run: node ./scripts/generateChangedIconsCommentMarkup.mjs >> comment-markup.md
id: comment-markup
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
- name: Create or update comment
uses: peter-evans/create-or-update-comment@v3
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
comment-id: ${{ steps.pr-comment.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body: |
### Added or changed icons
${{ needs.generate-changed-icons-comment-data.outputs.generate-2px-stroke-width }}<br/>
<details>
<summary>Preview cohesion</summary>
${{ needs.generate-changed-icons-comment-data.outputs.generate-cohesion-check-squares }}<br/>
${{ needs.generate-changed-icons-comment-data.outputs.generate-2px-stroke-width }}<br/>
${{ needs.generate-changed-icons-comment-data.outputs.generate-cohesion-check-random }}<br/>
</details>
<details>
<summary>Preview stroke widths</summary>
${{ needs.generate-changed-icons-comment-data.outputs.generate-1px-stroke-width }}<br/>
${{ needs.generate-changed-icons-comment-data.outputs.generate-2px-stroke-width }}<br/>
${{ needs.generate-changed-icons-comment-data.outputs.generate-3px-stroke-width }}<br/>
</details>
<details>
<summary>DPI Preview (24px)</summary>
${{ needs.generate-changed-icons-comment-data.outputs.generate-24px-dpi-preview }}
</details>
<details>
<summary>Icon X-rays</summary>
${{ needs.generate-changed-icons-comment-data.outputs.generate-x-rays }}
</details>
body-path: ./comment-markup.md
edit-mode: replace
+4
View File
@@ -47,6 +47,10 @@
},
"minItems": 1,
"uniqueItems": true
},
"deprecated": {
"type": "boolean",
"default": false
}
},
"description": "A JSON Schema for icons defined by Lucide Icons."
@@ -31,5 +31,8 @@
"design",
"tools",
"account"
],
"aliases": [
"between-horizonal-end"
]
}

Before

Width:  |  Height:  |  Size: 343 B

After

Width:  |  Height:  |  Size: 343 B

@@ -31,5 +31,8 @@
"design",
"tools",
"account"
],
"aliases": [
"between-horizonal-start"
]
}

Before

Width:  |  Height:  |  Size: 341 B

After

Width:  |  Height:  |  Size: 341 B

+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"ericfennis"
@@ -11,4 +12,4 @@
"categories": [
"brands"
]
}
}
@@ -5,11 +5,13 @@
"ericfennis"
],
"tags": [
"paste",
"signature"
"paste"
],
"categories": [
"text",
"account"
],
"aliases": [
"clipboard-signature"
]
}
@@ -9,9 +9,9 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<rect width="8" height="4" x="8" y="2" rx="1" ry="1" />
<rect width="8" height="4" x="8" y="2" rx="1" />
<path d="M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-.5" />
<path d="M16 4h2a2 2 0 0 1 1.73 1" />
<path d="M18.42 9.61a2.1 2.1 0 1 1 2.97 2.97L16.95 17 13 18l.99-3.95 4.43-4.44Z" />
<path d="M8 18h1" />
<path d="M18.4 9.6a2 2 0 0 1 3 3L17 17l-4 1 1-4Z" />
</svg>

Before

Width:  |  Height:  |  Size: 489 B

After

Width:  |  Height:  |  Size: 451 B

@@ -5,11 +5,13 @@
"ericfennis"
],
"tags": [
"edit",
"paste",
"signature"
],
"categories": [
"text"
],
"aliases": [
"clipboard-edit"
]
}
@@ -9,8 +9,8 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<rect width="8" height="4" x="8" y="2" rx="1" ry="1" />
<path d="M10.42 12.61a2.1 2.1 0 1 1 2.97 2.97L7.95 21 4 22l.99-3.95 5.43-5.44Z" />
<rect width="8" height="4" x="8" y="2" rx="1" />
<path d="M10.4 12.6a2 2 0 0 1 3 3L8 21l-4 1 1-4Z" />
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-5.5" />
<path d="M4 13.5V6a2 2 0 0 1 2-2h2" />
</svg>

Before

Width:  |  Height:  |  Size: 451 B

After

Width:  |  Height:  |  Size: 414 B

+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"ericfennis"
@@ -11,4 +12,4 @@
"brands",
"development"
]
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"csandman",
@@ -12,4 +13,4 @@
"brands",
"development"
]
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"ahtohbi4",
"karsa-mistmere"
@@ -13,4 +14,4 @@
"social",
"design"
]
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"csandman",
@@ -14,4 +15,4 @@
"social",
"brands"
]
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"csandman",
@@ -15,4 +16,4 @@
"brands",
"design"
]
}
}
@@ -5,10 +5,12 @@
"jguddas"
],
"tags": [
"edit",
"signature"
"edit"
],
"categories": [
"files"
],
"aliases": [
"file-signature"
]
}
@@ -11,5 +11,5 @@
>
<path d="M20 19.5v.5a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8.5L18 5.5" />
<path d="M8 18h1" />
<path d="M18.42 9.61a2.1 2.1 0 1 1 2.97 2.97L16.95 17 13 18l.99-3.95 4.43-4.44Z" />
<path d="M18.4 9.6a2 2 0 0 1 3 3L17 17l-4 1 1-4Z" />
</svg>

Before

Width:  |  Height:  |  Size: 401 B

After

Width:  |  Height:  |  Size: 370 B

+3 -1
View File
@@ -4,10 +4,12 @@
"karsa-mistmere"
],
"tags": [
"edit",
"signature"
],
"categories": [
"files"
],
"aliases": [
"file-edit"
]
}
+2 -2
View File
@@ -10,6 +10,6 @@
stroke-linejoin="round"
>
<path d="M4 13.5V4a2 2 0 0 1 2-2h8.5L20 7.5V20a2 2 0 0 1-2 2h-5.5" />
<polyline points="14 2 14 8 20 8" />
<path d="M10.42 12.61a2.1 2.1 0 1 1 2.97 2.97L7.95 21 4 22l.99-3.95 5.43-5.44Z" />
<path d="M14 2v6h6" />
<path d="M10.4 12.6a2 2 0 0 1 3 3L8 21l-4 1 1-4Z" />
</svg>

Before

Width:  |  Height:  |  Size: 404 B

After

Width:  |  Height:  |  Size: 360 B

@@ -5,10 +5,12 @@
],
"tags": [
"directory",
"edit",
"rename"
],
"categories": [
"files"
],
"aliases": [
"folder-edit"
]
}
@@ -9,6 +9,6 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M8.4 10.6a2.1 2.1 0 1 1 2.99 2.98L6 19l-4 1 1-3.9Z" />
<path d="M2 11.5V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-9.5" />
<path d="M8.4 10.6a2 2 0 0 1 3 3L6 19l-4 1 1-4Z" />
<path d="M2 11.5V5a2 2 0 0 1 2-2h3.9c.7 0 1.3.3 1.7.9l.8 1.2c.4.6 1 .9 1.7.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-9.5" />
</svg>

Before

Width:  |  Height:  |  Size: 398 B

After

Width:  |  Height:  |  Size: 384 B

+3 -2
View File
@@ -1,7 +1,8 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"danielbayley"
"danielbayley",
"jguddas"
],
"tags": [
"directory",
@@ -16,4 +17,4 @@
"files",
"arrows"
]
}
}
+3 -3
View File
@@ -9,9 +9,9 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M9 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v1" />
<path d="M9 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v.5" />
<path d="M12 10v4h4" />
<path d="m12 14 1.5-1.5c.9-.9 2.2-1.5 3.5-1.5s2.6.6 3.5 1.5c.4.4.8 1 1 1.5" />
<path d="m12 14 1.535-1.605a5 5 0 0 1 8 1.5" />
<path d="M22 22v-4h-4" />
<path d="m22 18-1.5 1.5c-.9.9-2.1 1.5-3.5 1.5s-2.6-.6-3.5-1.5c-.4-.4-.8-1-1-1.5" />
<path d="m22 18-1.535 1.605a5 5 0 0 1-8-1.5" />
</svg>

Before

Width:  |  Height:  |  Size: 547 B

After

Width:  |  Height:  |  Size: 481 B

+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"csandman",
@@ -15,4 +16,4 @@
"brands",
"design"
]
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"csandman",
@@ -14,4 +15,4 @@
"brands",
"development"
]
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"csandman",
@@ -14,4 +15,4 @@
"brands",
"development"
]
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"csandman",
@@ -15,4 +16,4 @@
"social",
"photography"
]
}
}
+37
View File
@@ -0,0 +1,37 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"danielbayley"
],
"tags": [
"pencil",
"notepad",
"notes",
"noted",
"stationery",
"sketchbook",
"organizer",
"organiser",
"planner",
"diary",
"journal",
"writing",
"write",
"written",
"reading",
"high school",
"university",
"college",
"academy",
"student",
"study",
"research",
"homework",
"eraser",
"rubber"
],
"categories": [
"text",
"social"
]
}
+18
View File
@@ -0,0 +1,18 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4" />
<path d="M2 6h4" />
<path d="M2 10h4" />
<path d="M2 14h4" />
<path d="M2 18h4" />
<path d="M18.4 2.6a2.17 2.17 0 0 1 3 3L16 11l-4 1 1-4Z" />
</svg>

After

Width:  |  Height:  |  Size: 438 B

+34
View File
@@ -0,0 +1,34 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"danielbayley"
],
"tags": [
"notepad",
"notes",
"people",
"family",
"friends",
"acquaintances",
"contacts",
"details",
"addresses",
"phone numbers",
"directory",
"listing",
"networking",
"alphabetical",
"a-z",
"organizer",
"organiser",
"planner",
"diary",
"stationery"
],
"categories": [
"account",
"connectivity",
"communication",
"social"
]
}
+21
View File
@@ -0,0 +1,21 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M2 6h4" />
<path d="M2 10h4" />
<path d="M2 14h4" />
<path d="M2 18h4" />
<rect width="16" height="20" x="4" y="2" rx="2" />
<path d="M15 2v20" />
<path d="M15 7h5" />
<path d="M15 12h5" />
<path d="M15 17h5" />
</svg>

After

Width:  |  Height:  |  Size: 447 B

+37
View File
@@ -0,0 +1,37 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"danielbayley"
],
"tags": [
"notepad",
"notes",
"pages",
"paper",
"stationery",
"sketchbook",
"organizer",
"organiser",
"planner",
"diary",
"journal",
"writing",
"write",
"written",
"reading",
"high school",
"university",
"college",
"academy",
"student",
"study",
"research",
"homework",
"lines",
"opened"
],
"categories": [
"text",
"social"
]
}
+20
View File
@@ -0,0 +1,20 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M2 6h4" />
<path d="M2 10h4" />
<path d="M2 14h4" />
<path d="M2 18h4" />
<rect width="16" height="20" x="4" y="2" rx="2" />
<path d="M9.5 8h5" />
<path d="M9.5 12H16" />
<path d="M9.5 16H14" />
</svg>

After

Width:  |  Height:  |  Size: 428 B

+40
View File
@@ -0,0 +1,40 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"danielbayley"
],
"tags": [
"notepad",
"notes",
"stationery",
"sketchbook",
"moleskine",
"closure",
"strap",
"band",
"elastic",
"organizer",
"organiser",
"planner",
"diary",
"journal",
"writing",
"written",
"writer",
"reading",
"high school",
"university",
"college",
"academy",
"student",
"study",
"homework",
"research"
],
"categories": [
"text",
"communication",
"social",
"design"
]
}
+18
View File
@@ -0,0 +1,18 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M2 6h4" />
<path d="M2 10h4" />
<path d="M2 14h4" />
<path d="M2 18h4" />
<rect width="16" height="20" x="4" y="2" rx="2" />
<path d="M16 2v20" />
</svg>

After

Width:  |  Height:  |  Size: 376 B

+25
View File
@@ -0,0 +1,25 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"danielbayley"
],
"tags": [
"notebook",
"notes",
"pages",
"paper",
"stationery",
"diary",
"journal",
"writing",
"write",
"written",
"draft",
"template",
"lines"
],
"categories": [
"text",
"social"
]
}
+25
View File
@@ -0,0 +1,25 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M8 2v4" />
<path d="M12 2v4" />
<path d="M16 2v4" />
<path d="M16 4h2a2 2 0 0 1 2 2v2" />
<path d="M20 12v2" />
<path d="M20 18v2a2 2 0 0 1-2 2h-1" />
<path d="M13 22h-2" />
<path d="M7 22H6a2 2 0 0 1-2-2v-2" />
<path d="M4 14v-2" />
<path d="M4 8V6a2 2 0 0 1 2-2h2" />
<path d="M8 10h6" />
<path d="M8 14h8" />
<path d="M8 18h5" />
</svg>

After

Width:  |  Height:  |  Size: 576 B

+37
View File
@@ -0,0 +1,37 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"danielbayley"
],
"tags": [
"notebook",
"notes",
"pages",
"paper",
"stationery",
"sketchbook",
"organizer",
"organiser",
"planner",
"diary",
"journal",
"writing",
"write",
"written",
"reading",
"high school",
"university",
"college",
"academy",
"student",
"study",
"homework",
"research",
"lines",
"opened"
],
"categories": [
"text",
"social"
]
}
+19
View File
@@ -0,0 +1,19 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M8 2v4" />
<path d="M12 2v4" />
<path d="M16 2v4" />
<rect width="16" height="18" x="4" y="4" rx="2" />
<path d="M8 10h6" />
<path d="M8 14h8" />
<path d="M8 18h5" />
</svg>

After

Width:  |  Height:  |  Size: 398 B

+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"csandman",
@@ -13,4 +14,4 @@
"brands",
"development"
]
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"ashygee",
@@ -17,4 +18,4 @@
"brands",
"development"
]
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"bdbch",
"csandman",
@@ -15,4 +16,4 @@
"brands",
"development"
]
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"ahtohbi4",
"johnletey"
@@ -14,4 +15,4 @@
"account",
"gaming"
]
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"csandman",
@@ -15,4 +16,4 @@
"social",
"account"
]
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
{
"$schema": "../icon.schema.json",
"deprecated": true,
"contributors": [
"colebemis",
"csandman",
@@ -20,4 +21,4 @@
"text",
"brands"
]
}
}
@@ -1,8 +1,26 @@
export default ({ componentName, children }) => `
/* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
export default ({ componentName, iconName, children, getSvg, deprecated }) => {
const svgContents = getSvg();
const svgBase64 = base64SVG(svgContents);
return `\
import { LucideIconData } from './types';
/* eslint-disable no-shadow-restricted-names */
const ${componentName}: LucideIconData = ${JSON.stringify(children)};
/**
* @component @name ${componentName}
* @description Lucide SVG icon component, renders SVG Element with children.
*
* @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName}
* @see https://lucide.dev/guide/packages/lucide-vue-next - Documentation
*
* @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {FunctionalComponent} Vue component
* ${deprecated ? '@deprecated' : ''}
*/
const ${componentName}: LucideIconData = ${JSON.stringify(children)}; //eslint-disable-line no-shadow-restricted-names
export default ${componentName};
`;
`
};
@@ -1,7 +1,26 @@
export default ({ componentName, children }) => `
/* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
export default ({ componentName, iconName, children, getSvg, deprecated }) => {
const svgContents = getSvg();
const svgBase64 = base64SVG(svgContents);
return `
import createLucideIcon from '../createLucideIcon';
/**
* @component @name ${componentName}
* @description Lucide SVG icon component, renders SVG Element with children.
*
* @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName}
* @see https://lucide.dev/guide/packages/lucide-preact - Documentation
*
* @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {JSX.Element} JSX Element
* ${deprecated ? '@deprecated' : ''}
*/
const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)});
export default ${componentName};
`;
};
@@ -1,7 +1,26 @@
export default ({ componentName, children }) => `
/* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
export default ({ componentName, iconName, children, getSvg, deprecated }) => {
const svgContents = getSvg();
const svgBase64 = base64SVG(svgContents);
return `
import createLucideIcon from '../createLucideIcon';
/**
* @component @name ${componentName}
* @description Lucide SVG icon component, renders SVG Element with children.
*
* @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName}
* @see https://lucide.dev/guide/packages/lucide-react-native - Documentation
*
* @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {JSX.Element} JSX Element
* ${deprecated ? '@deprecated' : ''}
*/
const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)});
export default ${componentName};
`;
};
@@ -1,16 +1,9 @@
export default ({ componentName, iconName, children, getSvg }) => {
/* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
export default ({ componentName, iconName, children, getSvg, deprecated }) => {
const svgContents = getSvg();
const svgBase64 = Buffer.from(
svgContents
.replace('\n', '')
.replace(
'stroke="currentColor"',
'stroke="#000" style="background-color: #fff; border-radius: 2px"',
),
).toString('base64');
// declarationFileContent += `\
const svgBase64 = base64SVG(svgContents);
return `
import createLucideIcon from '../createLucideIcon';
@@ -24,7 +17,7 @@ import createLucideIcon from '../createLucideIcon';
*
* @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {JSX.Element} JSX Element
*
* ${deprecated ? '@deprecated' : ''}
*/
const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)});
@@ -1,11 +1,11 @@
import path from 'path';
// eslint-disable-next-line import/no-extraneous-dependencies
import getAliases from '@lucide/build-icons/utils/getAliases.mjs';
import getIconMetaData from '@lucide/build-icons/utils/getIconMetaData.mjs';
const ICONS_DIR = path.resolve(process.cwd(), '../../icons');
export default async function getAliasesEntryNames() {
const metaJsonFiles = await getAliases(ICONS_DIR);
const metaJsonFiles = await getIconMetaData(ICONS_DIR);
const iconWithAliases = Object.values(metaJsonFiles).filter(({ aliases }) => aliases != null);
@@ -35,8 +35,9 @@ export const toKebabCase = (string: string) =>
const createLucideIcon = (iconName: string, iconNode: IconNode): LucideIcon => {
const Component = forwardRef<SVGSVGElement, LucideProps>(
({ color = 'currentColor', size = 24, strokeWidth = 2, absoluteStrokeWidth, className = '', children, ...rest }, ref) =>
createElement(
({ color = 'currentColor', size = 24, strokeWidth = 2, absoluteStrokeWidth, className = '', children, ...rest }, ref) =>{
return createElement(
'svg',
{
ref,
@@ -53,6 +54,7 @@ const createLucideIcon = (iconName: string, iconNode: IconNode): LucideIcon => {
...(Array.isArray(children) ? children : [children]),
]
)
}
);
Component.displayName = `${iconName}`;
@@ -1,12 +1,31 @@
export default ({ componentName, children }) => `
/* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
export default ({ componentName, iconName, children, getSvg, deprecated }) => {
const svgContents = getSvg();
const svgBase64 = base64SVG(svgContents);
return `
import Icon from '../Icon';
import type { IconNode, LucideProps } from '../types';
const iconNode: IconNode = ${JSON.stringify(children)};
/**
* @component @name ${componentName}
* @description Lucide SVG icon component, renders SVG Element with children.
*
* @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName}
* @see https://lucide.dev/guide/packages/lucide-solid - Documentation
*
* @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {JSX.Element} JSX Element
* ${deprecated ? '@deprecated' : ''}
*/
const ${componentName} = (props: LucideProps) => (
<Icon {...props} name="${componentName}" iconNode={iconNode} />
)
export default ${componentName};
`;
};
+13 -3
View File
@@ -22,17 +22,27 @@
"Fontawesome",
"Font Awesome"
],
"main": "lib/index.js",
"source": "src/lucide-static.js",
"main": "dist/cjs/lucide-static.js",
"module": "dist/esm/lucide-static.js",
"typings": "dist/lucide-static.d.ts",
"sideEffects": false,
"scripts": {
"copy:license": "cp ../../LICENSE ./LICENSE",
"build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:bundles && pnpm build:lib && pnpm build:tags",
"build:tags": "node ../../scripts/migrateIconsToTags.mjs",
"build": "pnpm clean && pnpm copy:license && pnpm build:lib && pnpm build:tags",
"build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --iconFileExtension=.ts --withAliases --aliasNamesOnly --aliasesFileExtension=.ts --exportFileName=index.ts",
"build:lib": "node ./scripts/buildLib.mjs",
"build:bundles": "rollup -c rollup.config.mjs",
"clean": "rm -rf lib && rm -rf build && rm -rf icons && rm -f sprite.svg",
"version": "pnpm version --git-tag-version=false"
},
"devDependencies": {
"prettier": "^2.3.2",
"svgson": "^5.2.1"
"svgson": "^5.2.1",
"@lucide/build-icons": "workspace:*",
"@lucide/rollup-plugins": "workspace:*",
"rollup": "^4.9.2",
"rollup-plugin-dts": "^6.1.0"
}
}
+59
View File
@@ -0,0 +1,59 @@
import plugins from '@lucide/rollup-plugins';
import dts from 'rollup-plugin-dts';
import pkg from './package.json' assert { type: 'json' };
const outputFileName = pkg.name;
const outputDir = 'dist';
const inputs = ['src/lucide-static.ts'];
const bundles = [
{
format: 'cjs',
inputs,
outputDir,
},
{
format: 'esm',
inputs,
outputDir,
preserveModules: true,
},
];
const configs = bundles
.map(({ inputs, outputDir, format, minify, preserveModules }) =>
inputs.map(input => ({
input,
plugins: plugins(pkg, minify),
output: {
name: outputFileName,
...(preserveModules
? {
dir: `${outputDir}/${format}`,
}
: {
file: `${outputDir}/${format}/${outputFileName}${minify ? '.min' : ''}.js`,
}),
format,
sourcemap: true,
preserveModules,
},
})),
)
.flat();
const typesFileConfig = {
input: inputs[0],
output: [
{
file: `${outputDir}/${outputFileName}.d.ts`,
format: 'esm',
},
],
plugins: [
dts({
include: ['src'],
}),
],
};
export default [...configs, typesFileConfig];
@@ -5,9 +5,7 @@ import getArgumentOptions from 'minimist';
import { parseSync } from 'svgson';
import {
appendFile,
readSvgDirectory,
toCamelCase,
getCurrentDirPath,
} from '../../../scripts/helpers.mjs';
import readSvgs from './readSvgs.mjs';
@@ -39,22 +37,6 @@ createDirectory(ICON_MODULE_DIR);
const svgFiles = readSvgDirectory(ICONS_DIR);
const svgs = readSvgs(svgFiles, ICONS_DIR);
const jsLicense = `/**\n * ${license}\n */\n`;
appendFile(jsLicense, `index.js`, LIB_DIR);
svgs.forEach(({ name, contents }) => {
const componentName = toCamelCase(name);
const importString = `module.exports.${componentName} = require('./icons/${name}');\n`;
appendFile(importString, `index.js`, LIB_DIR);
const svgContent = contents.replace('<svg', `<svg
class="lucide lucide-${name}"`);
const exportString = `${jsLicense}module.exports = \`${svgContent}\`;\n`;
appendFile(exportString, `${name}.js`, ICON_MODULE_DIR);
});
const parsedSvgs = svgs.map(({ name, contents }) => ({
name,
contents,
@@ -0,0 +1,32 @@
/* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
export default ({ componentName, iconName, children, getSvg, deprecated }) => {
let svgContents = getSvg();
const svgBase64 = base64SVG(svgContents);
svgContents = svgContents.replace(
'<svg',
`
<svg
class="lucide lucide-${iconName}"`,
);
return `
/**
* @name ${iconName}
* @description Lucide SVG string.
*
* @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName}
* @see https://lucide.dev/guide/packages/lucide-static - Documentation
*
* @returns {String}
* ${deprecated ? '@deprecated' : ''}
*/
const ${componentName}: string = \`\
${svgContents}\
\`
export default ${componentName};
`;
};
@@ -0,0 +1,2 @@
export * from './icons'
export * from './aliases';
+17
View File
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"strict": true,
"declaration": true,
"noEmitOnError": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"module": "ESNext",
"target": "ESNext",
"esModuleInterop": true,
"allowJs": true,
"lib": ["esnext", "dom"],
"resolveJsonModule": true,
"sourceMap": true,
"outDir": "./dist",
}
}
+28 -3
View File
@@ -24,6 +24,7 @@ for (const file of files) {
if (filestat.isFile() === false || filestat.isDirectory()) continue;
const contents = await readFile(filepath, { encoding: 'utf-8' });
let newContents = contents;
const ext = path.extname(filepath);
let license;
@@ -36,7 +37,31 @@ for (const file of files) {
}
if (license) {
await writeFile(filepath, license + contents, { encoding: 'utf-8' });
newContents = license + contents;
}
// Places icon block comment at the top of the Svelte component class
if(/icons\/(.*?)\.svelte\.d\.ts/.test(filepath)) {
const svelteFilepath = filepath.replace('.d.ts', '')
let svelteFileContents = await readFile(svelteFilepath, { encoding: 'utf-8' });
const blockCommentRegex = /\/\*\*[\s\S]*?\*\//;
const blockCommentMatch = blockCommentRegex.exec(svelteFileContents);
if (blockCommentMatch !== null) {
const blockComment = blockCommentMatch[0];
const exportClassRegex = /export default class (\w+) extends SvelteComponentTyped<(.*?)> {/;
if (exportClassRegex.test(newContents)) {
newContents = newContents.replace(exportClassRegex, `${blockComment}\nexport default class $1 extends SvelteComponentTyped<$2> {`);
}
}
}
if(newContents !== contents) {
await writeFile(filepath, newContents, { encoding: 'utf-8' });
}
}
@@ -48,8 +73,8 @@ function getJSBanner() {
}
function getSvelteBanner() {
return `<!--
${BANNER}
return `<!--
${BANNER}
-->
\n`;
}
@@ -1,6 +1,11 @@
// eslint-disable-next-line import/no-extraneous-dependencies
export default ({ iconName, children }) =>
`\
/* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
export default ({ iconName, children, componentName, getSvg, deprecated }) => {
const svgContents = getSvg();
const svgBase64 = base64SVG(svgContents);
return `\
<script lang="ts">
import Icon from '../Icon.svelte';
import type { IconNode, IconProps } from '../types.js';
@@ -8,9 +13,22 @@ import type { IconNode, IconProps } from '../types.js';
type $$Props = IconProps;
const iconNode: IconNode = ${JSON.stringify(children)};
/**
* @component @name ${componentName}
* @description Lucide SVG icon component, renders SVG Element with children.
*
* @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName}
* @see https://lucide.dev/guide/packages/lucide-svelte - Documentation
*
* @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {FunctionalComponent} Vue component
* ${deprecated ? '@deprecated' : ''}
*/
</script>
<Icon name="${iconName}" {...$$props} iconNode={iconNode}>
<slot/>
</Icon>
`;
};
+1 -1
View File
@@ -2,4 +2,4 @@ export * from './icons/index.js';
export * as icons from './icons/index.js';
export * from './aliases.js';
export { default as defaultAttributes } from './defaultAttributes.js';
export type { Icon } from './types.js';
export * from './types.js';
+2 -2
View File
@@ -13,11 +13,11 @@ export interface IconProps extends Attrs {
class?: string;
}
type IconEvents = {
export type IconEvents = {
[evt: string]: CustomEvent<any>;
};
type IconSlots = {
export type IconSlots = {
default: {};
};
@@ -1,7 +1,26 @@
export default ({ componentName, children }) => `
/* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
export default ({ componentName, iconName, children, getSvg, deprecated }) => {
const svgContents = getSvg();
const svgBase64 = base64SVG(svgContents);
return `
import createLucideIcon from '../createLucideIcon';
/**
* @component @name ${componentName}
* @description Lucide SVG icon component, renders SVG Element with children.
*
* @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName}
* @see https://lucide.dev/guide/packages/lucide-vue-next - Documentation
*
* @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {FunctionalComponent} Vue component
* ${deprecated ? '@deprecated' : ''}
*/
const ${componentName} = createLucideIcon('${componentName}Icon', ${JSON.stringify(children)});
export default ${componentName};
`;
};
+22 -3
View File
@@ -1,7 +1,26 @@
export default ({ componentName, children }) => `
import createVueComponent from '../createVueComponent';
/* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
const ${componentName} = createVueComponent('${componentName}Icon', ${JSON.stringify(children)});
export default ({ componentName, iconName, children, getSvg, deprecated }) => {
const svgContents = getSvg();
const svgBase64 = base64SVG(svgContents);
return `
import createLucideIcon from '../createLucideIcon';
/**
* @component @name ${componentName}
* @description Lucide SVG icon component, renders SVG Element with children.
*
* @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName}
* @see https://lucide.dev/guide/packages/lucide-vue - Documentation
*
* @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {Component} Vue Component
* ${deprecated ? '@deprecated' : ''}
*/
const ${componentName} = createLucideIcon('${componentName}Icon', ${JSON.stringify(children)});
export default ${componentName};
`;
};
+19 -1
View File
@@ -1,7 +1,24 @@
export default ({ componentName, children }) => `
/* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
export default ({ componentName, iconName, children, getSvg, deprecated }) => {
const svgContents = getSvg();
const svgBase64 = base64SVG(svgContents);
return `
import defaultAttributes from '../defaultAttributes';
import type { IconNode } from '../types';
/**
* @name ${iconName}
* @description Lucide SVG icon node.
*
* @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName}
* @see https://lucide.dev/guide/packages/lucide - Documentation
*
* @returns {Array}
* ${deprecated ? '@deprecated' : ''}
*/
const ${componentName}: IconNode = [
'svg',
defaultAttributes,
@@ -10,3 +27,4 @@ const ${componentName}: IconNode = [
export default ${componentName};
`;
};
+15 -3
View File
@@ -547,9 +547,21 @@ importers:
packages/lucide-static:
devDependencies:
'@lucide/build-icons':
specifier: workspace:*
version: link:../../tools/build-icons
'@lucide/rollup-plugins':
specifier: workspace:*
version: link:../../tools/rollup-plugins
prettier:
specifier: ^2.3.2
version: 2.8.8
rollup:
specifier: ^4.9.2
version: 4.9.2
rollup-plugin-dts:
specifier: ^6.1.0
version: 6.1.0(rollup@4.9.2)(typescript@4.9.5)
svgson:
specifier: ^5.2.1
version: 5.3.1
@@ -13790,8 +13802,8 @@ packages:
duplexer: 0.1.2
dev: true
/h3-nightly@1.10.0-1701948668.39f9434:
resolution: {integrity: sha512-ZgDOpzAr8BO/sFzWYvLZLhg3d/NRbDeff+rA6vnoog0530NPEVfO3nIzCwY3nT+Z0faROooaiCyKaAPYbo7b9A==}
/h3-nightly@1.10.1-1704400265.ae91fc8:
resolution: {integrity: sha512-R2kWa+PpzYWLel4wSyJxS3DH8GSOs515uf72bW10uo5rbR0qvLw3esTnSYQLgDiOaqiFRP56kFFK7ClTfqko0g==}
dependencies:
cookie-es: 1.0.0
defu: 6.1.3
@@ -16817,7 +16829,7 @@ packages:
fs-extra: 11.2.0
globby: 13.2.2
gzip-size: 7.0.0
h3: /h3-nightly@1.10.0-1701948668.39f9434
h3: /h3-nightly@1.10.1-1704400265.ae91fc8
hookable: 5.5.3
httpxy: 0.1.5
is-primitive: 3.0.1
@@ -0,0 +1,98 @@
import fs from 'fs';
import path from 'path';
import { shuffle, readSvgDirectory, getCurrentDirPath } from './helpers.mjs';
const currentDir = getCurrentDirPath(import.meta.url);
const ICONS_DIR = path.resolve(currentDir, '../icons');
const BASE_URL = 'https://lucide.dev/api/gh-icon';
const changedFilesPathString = process.env.CHANGED_FILES;
const changedFiles = changedFilesPathString
.split(' ')
.map((file) => file.replace('.json', '.svg'))
.filter((file, idx, arr) => arr.indexOf(file) === idx);
const getImageTagsByFiles = (files, getBaseUrl, width) =>
files
.map((file) => {
const svgContent = fs.readFileSync(path.join(process.cwd(), file), 'utf-8');
const strippedAttrsSVG = svgContent
.replace(/<svg[^>]*>/, '<svg>')
.replaceAll(/\n| {2}|\t/g, '');
const base64 = Buffer.from(strippedAttrsSVG).toString('base64');
const url = getBaseUrl(file);
const widthAttr = width ? `width="${width}"` : '';
return `<img title="${file}" alt="${file}" ${widthAttr} src="${url}/${base64}.svg"/>`;
})
.join('');
const svgFiles = readSvgDirectory(ICONS_DIR).map((file) => `icons/${file}`);
const iconsFilteredByName = (search) => svgFiles.filter((file) => file.includes(search));
const cohesionRandomImageTags = getImageTagsByFiles(
shuffle(svgFiles).slice(0, changedFiles.length),
() => `${BASE_URL}/stroke-width/2`,
);
const cohesionSquaresImageTags = getImageTagsByFiles(
shuffle(iconsFilteredByName('square')).slice(0, changedFiles.length),
() => `${BASE_URL}/stroke-width/2`,
);
const changeFiles1pxStrokeImageTags = getImageTagsByFiles(
changedFiles,
() => `${BASE_URL}/stroke-width/1`,
);
const changeFiles2pxStrokeImageTags = getImageTagsByFiles(
changedFiles,
() => `${BASE_URL}/stroke-width/2`,
);
const changeFiles3pxStrokeImageTags = getImageTagsByFiles(
changedFiles,
() => `${BASE_URL}/stroke-width/3`,
);
const changeFilesLowDPIImageTags = getImageTagsByFiles(changedFiles, () => `${BASE_URL}/dpi/24`);
const changeFilesXRayImageTags = getImageTagsByFiles(
changedFiles,
(file) => {
const iconName = path.basename(file, '.svg');
return `${BASE_URL}/${iconName}`;
},
400,
);
const commentMarkup = `\
### Added or changed icons
${changeFiles2pxStrokeImageTags}
<details>
<summary>Preview cohesion</summary>
${cohesionSquaresImageTags}<br/>
${changeFiles2pxStrokeImageTags}<br/>
${cohesionRandomImageTags}<br/>
</details>
<details>
<summary>Preview stroke widths</summary>
${changeFiles1pxStrokeImageTags}<br/>
${changeFiles2pxStrokeImageTags}<br/>
${changeFiles3pxStrokeImageTags}<br/>
</details>
<details>
<summary>DPI Preview (24px)</summary>
${changeFilesLowDPIImageTags}<br/>
</details>
<details>
<summary>Icon X-rays</summary>
${changeFilesXRayImageTags}
</details>
`;
console.log(commentMarkup);
+23 -5
View File
@@ -90,12 +90,13 @@ export const writeFileIfNotExists = (content, fileName, outputDirectory) => {
* @returns {object} A map of icon or category metadata
*/
export const readAllMetadata = (directory) =>
fs.readdirSync(directory).filter((file) => path.extname(file) === '.json').reduce(
(acc, fileName, i) => {
fs
.readdirSync(directory)
.filter((file) => path.extname(file) === '.json')
.reduce((acc, fileName, i) => {
acc[path.basename(fileName, '.json')] = readMetadata(fileName, directory);
return acc;
}, {}
);
}, {});
/**
* Reads metadata for an icon or category
@@ -111,7 +112,7 @@ export const readMetadata = (fileName, directory) =>
* reads the icon directory
*
* @param {string} directory
* @returns {array} An array of file paths containig svgs
* @returns {array} An array of file paths containing svgs
*/
export const readSvgDirectory = (directory, fileExtension = '.svg') =>
fs.readdirSync(directory).filter((file) => path.extname(file) === fileExtension);
@@ -189,4 +190,21 @@ export const mergeArrays = (a, b) => {
return a;
};
/**
* @param {string} currentPath
* @returns {string}
*/
export const getCurrentDirPath = (currentPath) => path.dirname(fileURLToPath(currentPath));
/**
* @param {array} array
* @returns {array}
*/
export const shuffle = (array) => {
// eslint-disable-next-line no-plusplus
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
};
+24
View File
@@ -0,0 +1,24 @@
import { spawn } from 'child_process';
const regex = /(?<file>[^:]+):(?<line>\d+):(?<column>\d+)\s-\s+(?<message>.+)/;
const fileList = (process.env.CHANGED_FILES || '').split(' ');
const cspell = spawn('npx', ['cspell', 'stdin'], { stdio: ['pipe', 'pipe', 'inherit'] });
cspell.stdin.write(fileList.join('\n'));
cspell.stdin.end();
cspell.stdout.on('data', (data) => {
console.log(data.toString());
data
.toString()
.split('\n')
.forEach((line) => {
const match = line.match(regex);
if (match) {
const { line, message } = match.groups;
console.log(`::error file=${fileList[line - 1]},line=1,column=1::${message}`);
}
});
});
cspell.on('exit', process.exit);
@@ -10,7 +10,7 @@ export default async function generateAliasesFile({
outputDirectory,
fileExtension,
iconFileExtension = '.js',
aliases,
iconMetaData,
aliasImportFileExtension,
aliasNamesOnly = false,
separateAliasesFile = false,
@@ -27,7 +27,7 @@ export default async function generateAliasesFile({
await Promise.all(
icons.map(async (iconName, index) => {
const componentName = toPascalCase(iconName);
const iconAliases = aliases[iconName]?.aliases;
const iconAliases = iconMetaData[iconName]?.aliases;
let importString = '';
@@ -11,6 +11,7 @@ export default ({
iconFileExtension = '.js',
pretty = true,
iconsDir,
iconMetaData,
}) => {
const icons = Object.keys(iconNodes);
const iconsDistDirectory = path.join(outputDirectory, `icons`);
@@ -27,8 +28,9 @@ export default ({
children = children.map(({ name, attributes }) => [name, attributes]);
const getSvg = () => readSvg(`${iconName}.svg`, iconsDir);
const { deprecated = false } = iconMetaData[iconName];
const elementTemplate = template({ componentName, iconName, children, getSvg });
const elementTemplate = template({ componentName, iconName, children, getSvg, deprecated });
const output = pretty
? prettier.format(elementTemplate, {
singleQuote: true,
+1 -1
View File
@@ -1,2 +1,2 @@
// eslint-disable-next-line import/prefer-default-export
export { default as getAliases } from './utils/getAliases.mjs';
export { default as getIconMetaData } from './utils/getIconMetaData.mjs';
+5 -4
View File
@@ -9,7 +9,7 @@ import generateExportsFile from './building/generateExportsFile.mjs';
import { readSvgDirectory, getCurrentDirPath } from '../../scripts/helpers.mjs';
import generateAliasesFile from './building/generateAliasesFile.mjs';
import getAliases from './utils/getAliases.mjs';
import getIconMetaData from './utils/getIconMetaData.mjs';
import generateDynamicImports from './building/generateDynamicImports.mjs';
const cliArguments = getArgumentOptions(process.argv.slice(2));
@@ -50,6 +50,8 @@ async function buildIcons() {
const { default: iconFileTemplate } = await import(path.resolve(process.cwd(), templateSrc));
const iconMetaData = await getIconMetaData(ICONS_DIR);
// Generates iconsNodes files for each icon
generateIconFiles({
iconNodes: icons,
@@ -59,14 +61,13 @@ async function buildIcons() {
iconFileExtension,
pretty: JSON.parse(pretty),
iconsDir: ICONS_DIR,
iconMetaData,
});
if (withAliases) {
const aliases = await getAliases(ICONS_DIR);
await generateAliasesFile({
iconNodes: icons,
aliases,
iconMetaData,
aliasNamesOnly,
iconFileExtension,
outputDirectory: OUTPUT_DIR,
+11
View File
@@ -0,0 +1,11 @@
const base64SVG = (svgContents) =>
Buffer.from(
svgContents
.replace('\n', '')
.replace(
'stroke="currentColor"',
'stroke="#000" style="background-color: #fff; border-radius: 2px"',
),
).toString('base64');
export default base64SVG;
@@ -1,7 +1,7 @@
import path from 'path';
import { readSvgDirectory } from '../../../scripts/helpers.mjs';
async function getAliases(iconDirectory) {
async function getIconMetaData(iconDirectory) {
const iconJsons = readSvgDirectory(iconDirectory, '.json');
const aliasesEntries = await Promise.all(
iconJsons.map(async (jsonFile) => {
@@ -13,4 +13,4 @@ async function getAliases(iconDirectory) {
return Object.fromEntries(aliasesEntries);
}
export default getAliases
export default getIconMetaData