Compare commits
42 Commits
0.556.0
...
fix-stable
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c3b25202a | ||
|
|
4efc8e07a0 | ||
|
|
5be50c241c | ||
|
|
506f3652c3 | ||
|
|
6b4075b89b | ||
|
|
7a68e10b12 | ||
|
|
a4531a9985 | ||
|
|
23b85f7834 | ||
|
|
9392a8f84f | ||
|
|
115fb243af | ||
|
|
3edcd9e0c3 | ||
|
|
0b8f99326c | ||
|
|
7abb61630e | ||
|
|
3b0d158ea1 | ||
|
|
124572c83b | ||
|
|
5408bc1d69 | ||
|
|
4fcfb6a4d1 | ||
|
|
0f732b411d | ||
|
|
efa795aa4c | ||
|
|
ba46fcf4fc | ||
|
|
ce09c31f08 | ||
|
|
c2b059fb60 | ||
|
|
b3c80d027a | ||
|
|
20f30bb5ea | ||
|
|
c47ae67a3b | ||
|
|
7866a5a5c6 | ||
|
|
92bc88b001 | ||
|
|
e75fbcdec4 | ||
|
|
4cef8283a7 | ||
|
|
330f4b37db | ||
|
|
fd31cb44a8 | ||
|
|
790d30dbfa | ||
|
|
e7c075785f | ||
|
|
6d4c91707d | ||
|
|
c0ea92ebe7 | ||
|
|
42dc5508dd | ||
|
|
4dda432471 | ||
|
|
484984ad68 | ||
|
|
0775d8647e | ||
|
|
83ef8fc98d | ||
|
|
5b56ef705d | ||
|
|
dafe529892 |
57
.github/workflows/ci.yml
vendored
@@ -11,6 +11,9 @@ permissions:
|
||||
id-token: write # Required for OIDC
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
if: github.repository == 'lucide-icons/lucide' && startsWith(github.event.head_commit.message, 'feat(icons)')
|
||||
@@ -36,25 +39,19 @@ jobs:
|
||||
id: latest-tag
|
||||
run: echo "LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Log latest tag
|
||||
run: echo '${{ steps.latest-tag.outputs.LATEST_TAG }}'
|
||||
|
||||
- name: Check if we can patch
|
||||
run: .github/workflows/version-up.sh --minor
|
||||
run: pnpm semver $LATEST_TAG -i minor
|
||||
env:
|
||||
LATEST_TAG: ${{ steps.latest-tag.outputs.LATEST_TAG }}
|
||||
|
||||
- name: Create new version
|
||||
id: new-version
|
||||
run: echo "NEW_VERSION=$(.github/workflows/version-up.sh --minor)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create change log
|
||||
id: change-log
|
||||
run: |
|
||||
CHANGE_LOG=$(pnpm run generate:changelog --old-tag=${{ steps.latest-tag.outputs.LATEST_TAG }})
|
||||
CHANGE_LOG=$(tail -n +5 <<< $CHANGE_LOG)
|
||||
echo $CHANGE_LOG
|
||||
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
|
||||
echo "CHANGE_LOG<<$EOF" >> $GITHUB_OUTPUT
|
||||
echo "$CHANGE_LOG" >> $GITHUB_OUTPUT
|
||||
echo "$EOF" >> $GITHUB_OUTPUT
|
||||
run: echo "NEW_VERSION=$(pnpm semver $LATEST_TAG -i minor)" >> $GITHUB_OUTPUT
|
||||
env:
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_TOKEN }}
|
||||
LATEST_TAG: ${{ steps.latest-tag.outputs.LATEST_TAG }}
|
||||
|
||||
- name: Check output
|
||||
run: |
|
||||
@@ -68,38 +65,6 @@ jobs:
|
||||
name: Version ${{ steps.new-version.outputs.NEW_VERSION }}
|
||||
generate_release_notes: true
|
||||
|
||||
test-semantic-release:
|
||||
if: github.repository == 'lucide-icons/lucide'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Semantic Release
|
||||
id: semantic
|
||||
uses: cycjimmy/semantic-release-action@v4
|
||||
with:
|
||||
tag_format: ${version}
|
||||
branches: |
|
||||
['new-release-workflow']
|
||||
extends: |
|
||||
semantic-release-monorepo
|
||||
extra_plugins: |
|
||||
@semantic-release/github
|
||||
@semantic-release/git
|
||||
@semantic-release/release-notes-generator
|
||||
conventional-changelog-conventionalcommits
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Log output
|
||||
if: steps.semantic.outputs.new_release_published == 'true'
|
||||
run: |
|
||||
echo ${{ steps.semantic.outputs.new_release_version }}
|
||||
echo ${{ steps.semantic.outputs.new_release_major_version }}
|
||||
echo ${{ steps.semantic.outputs.new_release_minor_version }}
|
||||
echo ${{ steps.semantic.outputs.new_release_patch_version }}
|
||||
|
||||
start-release:
|
||||
if: github.repository == 'lucide-icons/lucide'
|
||||
needs: create-release
|
||||
|
||||
20
.github/workflows/release.yml
vendored
@@ -20,7 +20,10 @@ on:
|
||||
|
||||
permissions:
|
||||
id-token: write # Required for OIDC
|
||||
contents: read
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
jobs:
|
||||
pre-release:
|
||||
@@ -72,9 +75,6 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Set Auth Token
|
||||
run: npm config set //registry.npmjs.org/:_authToken ${{ inputs.NPM_TOKEN || secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Set new version
|
||||
run: pnpm --filter ${{ matrix.package }} version --new-version ${{ needs.pre-release.outputs.VERSION }} --no-git-tag-version
|
||||
|
||||
@@ -109,9 +109,6 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Set Auth Token
|
||||
run: npm config set //registry.npmjs.org/:_authToken ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Set new version
|
||||
run: pnpm --filter lucide-static version --new-version ${{ needs.pre-release.outputs.VERSION }} --no-git-tag-version
|
||||
|
||||
@@ -141,11 +138,8 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Outline svg Icons
|
||||
run: pnpm build:outline-icons
|
||||
|
||||
- name: Create font in ./lucide-font
|
||||
run: pnpm build:font
|
||||
run: pnpm build:font --saveCodePoints
|
||||
|
||||
- name: 'Upload to Artifacts'
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -157,7 +151,9 @@ jobs:
|
||||
if: github.repository == 'lucide-icons/lucide'
|
||||
runs-on: ubuntu-latest
|
||||
needs: [pre-release, lucide-font]
|
||||
|
||||
permissions:
|
||||
id-token: write # Required for OIDC
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/download-artifact@v4
|
||||
|
||||
284
.github/workflows/version-up.sh
vendored
@@ -1,284 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
## Copyright (C) 2017, Oleksandr Kucherenko
|
||||
## Last revisit: 2017-09-29
|
||||
|
||||
## get highest version tag for all branches
|
||||
function highest_tag(){
|
||||
local TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
|
||||
echo "$TAG"
|
||||
}
|
||||
|
||||
## extract current branch name
|
||||
function current_branch(){
|
||||
## expected: heads/{branch_name}
|
||||
## expected: {branch_name}
|
||||
local BRANCH=$(git rev-parse --abbrev-ref HEAD | cut -d"/" -f2)
|
||||
echo "$BRANCH"
|
||||
}
|
||||
|
||||
## get latest/head commit hash number
|
||||
function head_hash(){
|
||||
local COMMIT_HASH=$(git rev-parse --verify HEAD)
|
||||
echo "$COMMIT_HASH"
|
||||
}
|
||||
|
||||
## extract tag commit hash code, tag name provided by argument
|
||||
function tag_hash(){
|
||||
local TAG_HASH=$(git log -1 --format=format:"%H" $1 2>/dev/null | tail -n1)
|
||||
echo "$TAG_HASH"
|
||||
}
|
||||
|
||||
## get latest revision number
|
||||
function latest_revision(){
|
||||
local REV=$(git rev-list --count HEAD 2>/dev/null)
|
||||
echo "$REV"
|
||||
}
|
||||
|
||||
## parse last found tag, extract it PARTS
|
||||
function parse_last(){
|
||||
local position=$(($1-1))
|
||||
|
||||
# two parts found only
|
||||
local SUBS=( ${PARTS[$position]//-/ } )
|
||||
#echo ${SUBS[@]}, size: ${#SUBS}
|
||||
|
||||
# found NUMBER
|
||||
PARTS[$position]=${SUBS[0]}
|
||||
#echo ${PARTS[@]}
|
||||
|
||||
# found SUFFIX
|
||||
if [[ ${#SUBS} -ge 1 ]]; then
|
||||
PARTS[4]=${SUBS[1],,} #lowercase
|
||||
#echo ${PARTS[@]}, ${SUBS[@]}
|
||||
fi
|
||||
}
|
||||
|
||||
## increment REVISION part, don't touch STAGE
|
||||
function increment_revision(){
|
||||
PARTS[3]=$(( PARTS[3] + 1 ))
|
||||
IS_DIRTY=1
|
||||
}
|
||||
|
||||
## increment PATCH part, reset all other lower PARTS, don't touch STAGE
|
||||
function increment_patch(){
|
||||
PARTS[2]=$(( PARTS[2] + 1 ))
|
||||
PARTS[3]=0
|
||||
IS_DIRTY=1
|
||||
}
|
||||
|
||||
## increment MINOR part, reset all other lower PARTS, don't touch STAGE
|
||||
function increment_minor(){
|
||||
PARTS[1]=$(( PARTS[1] + 1 ))
|
||||
PARTS[2]=0
|
||||
PARTS[3]=0
|
||||
IS_DIRTY=1
|
||||
}
|
||||
|
||||
## increment MAJOR part, reset all other lower PARTS, don't touch STAGE
|
||||
function incremet_major(){
|
||||
PARTS[0]="v$(( PARTS[0] + 1 ))"
|
||||
PARTS[1]=0
|
||||
PARTS[2]=0
|
||||
PARTS[3]=0
|
||||
IS_DIRTY=1
|
||||
}
|
||||
|
||||
## increment the number only of last found PART: REVISION --> PATCH --> MINOR. don't touch STAGE
|
||||
function increment_last_found(){
|
||||
if [[ "${#PARTS[3]}" == 0 || "${PARTS[3]}" == "0" ]]; then
|
||||
if [[ "${#PARTS[2]}" == 0 || "${PARTS[2]}" == "0" ]]; then
|
||||
increment_minor
|
||||
else
|
||||
increment_patch
|
||||
fi
|
||||
else
|
||||
increment_revision
|
||||
fi
|
||||
|
||||
# stage part is not EMPTY
|
||||
if [[ "${#PARTS[4]}" != 0 ]]; then
|
||||
IS_SHIFT=1
|
||||
fi
|
||||
}
|
||||
|
||||
## compose version from PARTS
|
||||
function compose(){
|
||||
MAJOR="${PARTS[0]}"
|
||||
MINOR=".${PARTS[1]}"
|
||||
PATCH=".${PARTS[2]}"
|
||||
REVISION=".${PARTS[3]}"
|
||||
SUFFIX="-${PARTS[4]}"
|
||||
|
||||
if [[ "${#PATCH}" == 1 ]]; then # if empty {PATCH}
|
||||
PATCH=""
|
||||
fi
|
||||
|
||||
if [[ "${#REVISION}" == 1 ]]; then # if empty {REVISION}
|
||||
REVISION=""
|
||||
fi
|
||||
|
||||
if [[ "${PARTS[3]}" == "0" ]]; then # if revision is ZERO
|
||||
REVISION=""
|
||||
fi
|
||||
|
||||
# shrink patch and revision
|
||||
if [[ -z "${REVISION// }" ]]; then
|
||||
if [[ "${PARTS[2]}" == "0" ]]; then
|
||||
PATCH=".0"
|
||||
fi
|
||||
else # revision is not EMPTY
|
||||
if [[ "${#PATCH}" == 0 ]]; then
|
||||
PATCH=".0"
|
||||
fi
|
||||
fi
|
||||
|
||||
# remove suffix if we don't have a alpha/beta/rc
|
||||
if [[ "${#SUFFIX}" == 1 ]]; then
|
||||
SUFFIX=""
|
||||
fi
|
||||
|
||||
|
||||
echo "${MAJOR}${MINOR}${PATCH}${REVISION}${SUFFIX}" #full format
|
||||
}
|
||||
|
||||
# initial version used for repository without tags
|
||||
INIT_VERSION=0.0.0.0-alpha
|
||||
|
||||
# do GIT data extracting
|
||||
TAG=$(highest_tag)
|
||||
REVISION=$(latest_revision)
|
||||
BRANCH=$(current_branch)
|
||||
TAG_HASH=$(tag_hash $TAG)
|
||||
HEAD_HASH=$(head_hash)
|
||||
|
||||
# if tag and branch commit hashes are different, than print info about that
|
||||
#echo $HEAD_HASH vs $TAG_HASH
|
||||
if [[ "$@" == "" ]]; then
|
||||
if [[ "$TAG_HASH" == "$HEAD_HASH" ]]; then
|
||||
echo "Tag $TAG and HEAD are aligned. We will stay on the TAG version."
|
||||
echo ""
|
||||
NO_ARGS_VALUE='--stay'
|
||||
else
|
||||
PATTERN="^[0-9]+.[0-9]+(.[0-9]+)*(-(alpha|beta|rc))*$"
|
||||
|
||||
if [[ "$BRANCH" =~ $PATTERN ]]; then
|
||||
echo "Detected version branch '$BRANCH'. We will auto-increment the last version PART."
|
||||
echo ""
|
||||
NO_ARGS_VALUE='--default'
|
||||
else
|
||||
echo "Detected branch name '$BRANCH' than does not match version pattern. We will increase MINOR."
|
||||
echo ""
|
||||
NO_ARGS_VALUE='--minor'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# {MAJOR}.{MINOR}[.{PATCH}[.{REVISION}][-(.*)]
|
||||
#
|
||||
# Suffix: alpha, beta, rc
|
||||
# No Suffix --> {NEW_VERSION}-alpha
|
||||
# alpha --> beta
|
||||
# beta --> rc
|
||||
# rc --> {VERSION}
|
||||
#
|
||||
PARTS=( ${TAG//./ } )
|
||||
parse_last ${#PARTS[@]} # array size as argument
|
||||
#echo ${PARTS[@]}
|
||||
|
||||
# if no parameters than emulate --default parameter
|
||||
if [[ "$@" == "" ]]; then
|
||||
set -- $NO_ARGS_VALUE
|
||||
fi
|
||||
|
||||
# parse input parameters
|
||||
for i in "$@"
|
||||
do
|
||||
key="$i"
|
||||
|
||||
case $key in
|
||||
-a|--alpha) # switched to ALPHA
|
||||
PARTS[4]="alpha"
|
||||
IS_SHIFT=1
|
||||
;;
|
||||
-b|--beta) # switched to BETA
|
||||
PARTS[4]="beta"
|
||||
IS_SHIFT=1
|
||||
;;
|
||||
-c|--release-candidate) # switched to RC
|
||||
PARTS[4]="rc"
|
||||
IS_SHIFT=1
|
||||
;;
|
||||
-r|--release) # switched to RELEASE
|
||||
PARTS[4]=""
|
||||
IS_SHIFT=1
|
||||
;;
|
||||
-p|--patch) # increment of PATCH
|
||||
increment_patch
|
||||
;;
|
||||
-e|--revision) # increment of REVISION
|
||||
increment_revision
|
||||
;;
|
||||
-g|--git-revision) # use git revision number as a revision part§
|
||||
PARTS[3]=$(( REVISION ))
|
||||
IS_DIRTY=1
|
||||
;;
|
||||
-i|--minor) # increment of MINOR by default
|
||||
increment_minor
|
||||
;;
|
||||
--default) # stay on the same stage, but increment only last found PART of version code
|
||||
increment_last_found
|
||||
;;
|
||||
-m|--major) # increment of MAJOR
|
||||
incremet_major
|
||||
;;
|
||||
-s|--stay) # extract version info
|
||||
IS_DIRTY=1
|
||||
NO_APPLY_MSG=1
|
||||
;;
|
||||
-t|--tag-only) # extract version info
|
||||
TAG_ONLY=1
|
||||
;;
|
||||
--apply)
|
||||
DO_APPLY=1
|
||||
;;
|
||||
-h|--help)
|
||||
help
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# detected shift, but no increment
|
||||
if [[ "$IS_SHIFT" == "1" ]]; then
|
||||
# temporary disable stage shift
|
||||
stage=${PARTS[4]}
|
||||
PARTS[4]=''
|
||||
|
||||
# detect first run on repository, INIT_VERSION was used
|
||||
if [[ "$(compose)" == "0.0" ]]; then
|
||||
increment_minor
|
||||
fi
|
||||
|
||||
PARTS[4]=$stage
|
||||
fi
|
||||
|
||||
# no increment applied yet and no shift of state, do minor increase
|
||||
if [[ "$IS_DIRTY$IS_SHIFT" == "" ]]; then
|
||||
increment_minor
|
||||
fi
|
||||
|
||||
compose
|
||||
|
||||
# is proposed tag in conflict with any other TAG
|
||||
PROPOSED_HASH=$(tag_hash $(compose))
|
||||
if [[ "${#PROPOSED_HASH}" -gt 0 && "$NO_APPLY_MSG" == "" ]]; then
|
||||
echo -e "\033[31mERROR:\033[0m "
|
||||
echo -e "\033[31mERROR:\033[0m Found conflict with existing tag \033[32m$(compose)\033[0m / $PROPOSED_HASH"
|
||||
echo -e "\033[31mERROR:\033[0m Only manual resolving is possible now."
|
||||
echo -e "\033[31mERROR:\033[0m "
|
||||
echo -e "\033[31mERROR:\033[0m To Resolve try to add --revision or --patch modifier."
|
||||
echo -e "\033[31mERROR:\033[0m "
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
1
.gitignore
vendored
@@ -14,6 +14,7 @@ coverage
|
||||
stats
|
||||
*.log
|
||||
outlined
|
||||
lucide-font
|
||||
packages/**/src/icons/*.js
|
||||
packages/**/src/icons/*.ts
|
||||
packages/**/src/icons/*.tsx
|
||||
|
||||
@@ -9,14 +9,20 @@ type CodeExampleType = {
|
||||
const getIconCodes = (): CodeExampleType => {
|
||||
return [
|
||||
{
|
||||
language: 'js',
|
||||
language: 'html',
|
||||
title: 'Vanilla',
|
||||
code: `\
|
||||
import { createIcons, icons } from 'lucide';
|
||||
<script>
|
||||
import { createIcons, $CamelCase } from 'lucide';
|
||||
|
||||
createIcons({ icons });
|
||||
createIcons({
|
||||
icons: {
|
||||
$CamelCase
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
document.body.append('<i data-lucide="$Name"></i>');\
|
||||
<i data-lucide="$Name"></i>\
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -10,10 +10,11 @@ type CodeExampleType = {
|
||||
const getIconCodes = (): CodeExampleType => {
|
||||
return [
|
||||
{
|
||||
language: 'js',
|
||||
language: 'html',
|
||||
title: 'Vanilla',
|
||||
code: `\
|
||||
import { createIcons, icons } from 'lucide';
|
||||
<script>
|
||||
import { createIcons } from 'lucide';
|
||||
import { $CamelCase } from '@lucide/lab';
|
||||
|
||||
createIcons({
|
||||
@@ -21,8 +22,9 @@ createIcons({
|
||||
$CamelCase
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
document.body.append('<i data-lucide="$Name"></i>');\
|
||||
<i data-lucide="$Name"></i>\
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createLucideIcon } from 'lucide-react/src/lucide-react';
|
||||
import { type LucideProps, type IconNode } from 'lucide-react/src/createLucideIcon';
|
||||
import { type LucideProps, type IconNode } from 'lucide-react/src/types';
|
||||
import { IconEntity } from '../theme/types';
|
||||
import { renderToStaticMarkup } from 'react-dom/server';
|
||||
import { IconContent } from './generateZip';
|
||||
|
||||
@@ -1,23 +1,31 @@
|
||||
<script setup lang="ts">
|
||||
import { useData } from 'vitepress';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: string
|
||||
id: string
|
||||
}>()
|
||||
modelValue: string;
|
||||
id: string;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const { isDark } = useData();
|
||||
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const value = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emit('update:modelValue', val)
|
||||
})
|
||||
get: () => {
|
||||
if (props.modelValue == null || props.modelValue === 'currentColor') {
|
||||
return isDark.value ? '#ffffff' : '#000000';
|
||||
}
|
||||
|
||||
return props.modelValue;
|
||||
},
|
||||
set: (val) => emit('update:modelValue', val),
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="color-picker">
|
||||
<div class="color-input-wrapper">
|
||||
<!-- TODO: Add currentColor div if value is currentColor -->
|
||||
<input
|
||||
type="color"
|
||||
:id="id"
|
||||
@@ -33,6 +41,7 @@ const value = computed({
|
||||
class="color-input-text"
|
||||
aria-label="Color picker input"
|
||||
v-model="value"
|
||||
placeholder="[default]"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -45,27 +54,33 @@ const value = computed({
|
||||
top: -5px;
|
||||
left: -5px;
|
||||
}
|
||||
|
||||
.color-input-wrapper {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
border-radius: 12px;
|
||||
border-radius: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.color-picker {
|
||||
background: var(--color-picker-bg, var(--vp-c-bg-alt));
|
||||
border-radius: 8px;
|
||||
color: var(--vp-c-text-2);
|
||||
padding: 4px 8px;
|
||||
padding: 3px 8px 3px 3px;
|
||||
height: auto;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
border: 1px solid transparent;
|
||||
cursor: text;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
transition:
|
||||
color 0.25s,
|
||||
border-color 0.25s,
|
||||
background-color 0.25s;
|
||||
}
|
||||
|
||||
.color-input-text {
|
||||
@@ -75,19 +90,22 @@ const value = computed({
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--vp-c-text-1);
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
border-radius: 8px;
|
||||
cursor: text;
|
||||
transition: border-color 0.25s, background 0.4s ease;
|
||||
transition:
|
||||
border-color 0.25s,
|
||||
background 0.4s ease;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.color-picker:hover, .color-picker:focus {
|
||||
.color-picker:hover,
|
||||
.color-picker:focus {
|
||||
border-color: var(--vp-c-brand);
|
||||
background: var(--vp-c-bg-alt);
|
||||
}
|
||||
|
||||
.color-input[value="currentColor"] {
|
||||
|
||||
.color-input[value='currentColor'] {
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
<script setup>
|
||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon'
|
||||
import { search } from '../../../data/iconNodes'
|
||||
|
||||
const SearchIcon = createLucideIcon('search', search)
|
||||
import Icon from 'lucide-vue-next/src/Icon';
|
||||
import { search } from '../../../data/iconNodes';
|
||||
|
||||
defineProps({
|
||||
shortcut: {
|
||||
type: String,
|
||||
required: false
|
||||
}
|
||||
})
|
||||
required: false,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button class="fake-input">
|
||||
<component :is="SearchIcon" class="search-icon"/>
|
||||
<slot/>
|
||||
<kbd v-if="shortcut" class="shortcut">{{ shortcut }}</kbd>
|
||||
<Icon
|
||||
:iconNode="search"
|
||||
class="search-icon"
|
||||
/>
|
||||
<slot />
|
||||
<kbd
|
||||
v-if="shortcut"
|
||||
class="shortcut"
|
||||
>{{ shortcut }}</kbd
|
||||
>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
@@ -34,10 +39,14 @@ defineProps({
|
||||
cursor: text;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
transition: color 0.25s, border-color 0.25s, background-color 0.25s;
|
||||
transition:
|
||||
color 0.25s,
|
||||
border-color 0.25s,
|
||||
background-color 0.25s;
|
||||
}
|
||||
|
||||
.fake-input:hover, .fake-input:focus {
|
||||
.fake-input:hover,
|
||||
.fake-input:focus {
|
||||
border-color: var(--vp-c-brand);
|
||||
background: var(--vp-c-bg-alt);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.icon-button {
|
||||
display: inline-flex;
|
||||
border: 1px solid transparent;
|
||||
@@ -30,9 +29,9 @@
|
||||
}
|
||||
|
||||
.icon-button:active {
|
||||
border-color: var(--vp-button-alt-active-border);
|
||||
color: var(--vp-button-alt-active-text);
|
||||
background-color: var(--vp-button-alt-active-bg);
|
||||
border-color: var(--vp-button-alt-active-border);
|
||||
color: var(--vp-button-alt-active-text);
|
||||
background-color: var(--vp-button-alt-active-bg);
|
||||
}
|
||||
|
||||
.icon-button.active {
|
||||
|
||||
@@ -1,60 +1,90 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
inheritAttrs: false,
|
||||
}
|
||||
};
|
||||
|
||||
export interface InputProps {
|
||||
type: string
|
||||
modelValue: string
|
||||
shortcut?: string
|
||||
type: string;
|
||||
modelValue: string;
|
||||
shortcut?: string;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, nextTick, watch } from 'vue'
|
||||
import { ref, onMounted, nextTick, watch } from 'vue';
|
||||
import Icon from 'lucide-vue-next/src/Icon';
|
||||
import { x } from '../../../data/iconNodes';
|
||||
import IconButton from './IconButton.vue';
|
||||
|
||||
const props = withDefaults(defineProps<InputProps>(), {
|
||||
type: 'text'
|
||||
})
|
||||
type: 'text',
|
||||
});
|
||||
|
||||
const input = ref()
|
||||
const wrapperEl = ref()
|
||||
const shortcutEl = ref()
|
||||
const input = ref();
|
||||
const wrapperEl = ref();
|
||||
const shortcutEl = ref();
|
||||
|
||||
defineEmits(['change', 'input', 'update:modelValue'])
|
||||
const emit = defineEmits(['change', 'input', 'update:modelValue']);
|
||||
|
||||
const updateShortcutSpacing = () => {
|
||||
nextTick(() => {
|
||||
if (shortcutEl.value && wrapperEl.value) {
|
||||
const shortcutWidth = shortcutEl.value.offsetWidth
|
||||
wrapperEl.value.style.setProperty('--shortcut-width', `${shortcutWidth}px`)
|
||||
const shortcutWidth = shortcutEl.value.offsetWidth;
|
||||
wrapperEl.value.style.setProperty('--shortcut-width', `${shortcutWidth}px`);
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(updateShortcutSpacing)
|
||||
watch(() => props.shortcut, updateShortcutSpacing)
|
||||
onMounted(updateShortcutSpacing);
|
||||
watch(() => props.shortcut, updateShortcutSpacing);
|
||||
|
||||
function onClear() {
|
||||
emit('update:modelValue', '');
|
||||
input.value.focus();
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
focus: () => {
|
||||
input.value.focus()
|
||||
}
|
||||
})
|
||||
input.value.focus();
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="input-wrapper" ref="wrapperEl">
|
||||
<slot name="icon" class="icon" />
|
||||
<div
|
||||
class="input-wrapper"
|
||||
ref="wrapperEl"
|
||||
>
|
||||
<slot
|
||||
name="icon"
|
||||
class="icon"
|
||||
/>
|
||||
<input
|
||||
:type="type"
|
||||
class="input"
|
||||
:class="{'has-icon': $slots.icon, 'has-shortcut': shortcut}"
|
||||
:class="{ 'has-icon': $slots.icon, 'has-shortcut': shortcut }"
|
||||
ref="input"
|
||||
:value="modelValue"
|
||||
v-bind="$attrs"
|
||||
@input="$emit('update:modelValue', $event.target.value)"
|
||||
/>
|
||||
<kbd v-if="shortcut" class="shortcut" ref="shortcutEl">{{ shortcut }}</kbd>
|
||||
<IconButton
|
||||
@click="onClear"
|
||||
v-if="type === 'search' && modelValue"
|
||||
class="clear-button"
|
||||
aria-label="Clear input"
|
||||
>
|
||||
<Icon
|
||||
:iconNode="x"
|
||||
:size="20"
|
||||
/>
|
||||
</IconButton>
|
||||
<kbd
|
||||
v-if="shortcut"
|
||||
class="shortcut"
|
||||
ref="shortcutEl"
|
||||
>{{ shortcut }}</kbd
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -62,6 +92,7 @@ defineExpose({
|
||||
.input-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.input {
|
||||
justify-content: flex-start;
|
||||
border: 1px solid transparent;
|
||||
@@ -71,13 +102,18 @@ defineExpose({
|
||||
height: 40px;
|
||||
background-color: var(--vp-c-bg-alt);
|
||||
font-size: 14px;
|
||||
transition:
|
||||
color 0.25s,
|
||||
border-color 0.25s,
|
||||
background-color 0.25s;
|
||||
}
|
||||
|
||||
.input.has-shortcut {
|
||||
padding-right: calc(var(--shortcut-width, 40px) + 22px);
|
||||
}
|
||||
|
||||
.input:hover, .input:focus {
|
||||
.input:hover,
|
||||
.input:focus {
|
||||
border-color: var(--vp-c-brand);
|
||||
background: var(--vp-c-bg-alt);
|
||||
}
|
||||
@@ -86,6 +122,14 @@ defineExpose({
|
||||
padding-left: 52px;
|
||||
}
|
||||
|
||||
.clear-button {
|
||||
position: absolute;
|
||||
right: 56px;
|
||||
top: 9px;
|
||||
padding: 4px;
|
||||
transition: background-color .25s;
|
||||
}
|
||||
|
||||
.shortcut {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
@@ -111,7 +155,7 @@ defineExpose({
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.input-wrapper svg {
|
||||
.input-wrapper > svg {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
top: 12px;
|
||||
|
||||
@@ -1,38 +1,36 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
inheritAttrs: false,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import Input from './Input.vue'
|
||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon'
|
||||
import { search } from '../../../data/iconNodes'
|
||||
|
||||
const SearchIcon = createLucideIcon('search', search)
|
||||
import { computed, ref } from 'vue';
|
||||
import Input from './Input.vue';
|
||||
import Icon from 'lucide-vue-next/src/Icon';
|
||||
import { search } from '../../../data/iconNodes';
|
||||
|
||||
interface Props {
|
||||
modelValue: string
|
||||
shortcut?: string
|
||||
modelValue: string;
|
||||
shortcut?: string;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const input = ref()
|
||||
const input = ref();
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
defineExpose({
|
||||
focus: () => {
|
||||
input.value.focus()
|
||||
}
|
||||
})
|
||||
input.value.focus();
|
||||
},
|
||||
});
|
||||
|
||||
const value = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emit('update:modelValue', val)
|
||||
})
|
||||
set: (val) => emit('update:modelValue', val),
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -46,7 +44,10 @@ const value = computed({
|
||||
class="input-wrapper"
|
||||
>
|
||||
<template #icon>
|
||||
<component :is="SearchIcon" class="search-icon" />
|
||||
<Icon
|
||||
:iconNode="search"
|
||||
class="search-icon"
|
||||
/>
|
||||
</template>
|
||||
</Input>
|
||||
</template>
|
||||
@@ -62,7 +63,8 @@ const value = computed({
|
||||
background-color: var(--vp-c-bg-alt);
|
||||
}
|
||||
|
||||
.input:hover, .input:focus {
|
||||
.input:hover,
|
||||
.input:focus {
|
||||
border-color: var(--vp-c-brand);
|
||||
background: var(--vp-c-bg-alt);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { rotateCw } from '../../../data/iconNodes'
|
||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon'
|
||||
import IconButton from "./IconButton.vue";
|
||||
|
||||
const RotateIcon = createLucideIcon('RotateIcon', rotateCw)
|
||||
import { rotateCw } from '../../../data/iconNodes';
|
||||
import Icon from 'lucide-vue-next/src/Icon';
|
||||
import IconButton from './IconButton.vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<IconButton class="reset-button">
|
||||
<RotateIcon :size="20"/>
|
||||
<Icon
|
||||
:size="20"
|
||||
:iconNode="rotateCw"
|
||||
/>
|
||||
</IconButton>
|
||||
</template>
|
||||
|
||||
@@ -32,6 +33,7 @@ const RotateIcon = createLucideIcon('RotateIcon', rotateCw)
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
|
||||
@@ -22,16 +22,16 @@ export default {
|
||||
logo: '/framework-logos/svelte.svg',
|
||||
label: 'Lucide documentation for Svelte',
|
||||
},
|
||||
{
|
||||
name: 'lucide-preact',
|
||||
logo: '/framework-logos/preact.svg',
|
||||
label: 'Lucide documentation for Preact',
|
||||
},
|
||||
{
|
||||
name: 'lucide-solid',
|
||||
logo: '/framework-logos/solid.svg',
|
||||
label: 'Lucide documentation for Solid',
|
||||
},
|
||||
{
|
||||
name: 'lucide-preact',
|
||||
logo: '/framework-logos/preact.svg',
|
||||
label: 'Lucide documentation for Preact',
|
||||
},
|
||||
{
|
||||
name: 'lucide-angular',
|
||||
logo: '/framework-logos/angular.svg',
|
||||
@@ -48,11 +48,6 @@ export default {
|
||||
logo: '/framework-logos/react-native.svg',
|
||||
label: 'Lucide documentation for React Native',
|
||||
},
|
||||
{
|
||||
name: 'lucide-flutter',
|
||||
logo: '/framework-logos/flutter.svg',
|
||||
label: 'Lucide documentation for Flutter',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
@@ -2,45 +2,48 @@
|
||||
import { useData } from 'vitepress';
|
||||
import { useSessionStorage } from '@vueuse/core';
|
||||
import IconButton from '../base/IconButton.vue';
|
||||
import VPDocAsideCarbonAds from 'vitepress/dist/client/theme-default/components/VPDocAsideCarbonAds.vue'
|
||||
import { x } from '../../../data/iconNodes'
|
||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon';
|
||||
import VPDocAsideCarbonAds from 'vitepress/dist/client/theme-default/components/VPDocAsideCarbonAds.vue';
|
||||
import { x } from '../../../data/iconNodes';
|
||||
import Icon from 'lucide-vue-next/src/Icon';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
const { theme } = useData()
|
||||
const showAd = useSessionStorage('show-carbon-ads', true)
|
||||
const carbonLoaded = ref(true)
|
||||
const { theme } = useData();
|
||||
const showAd = useSessionStorage('show-carbon-ads', true);
|
||||
const carbonLoaded = ref(true);
|
||||
|
||||
defineProps<{
|
||||
drawerOpen: boolean
|
||||
}>()
|
||||
|
||||
const CloseIcon = createLucideIcon('Close', x)
|
||||
drawerOpen: boolean;
|
||||
}>();
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
if (window?._carbonads == null) {
|
||||
carbonLoaded.value = false
|
||||
carbonLoaded.value = false;
|
||||
}
|
||||
}, 5000)
|
||||
})
|
||||
}, 5000);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'drawer-open': drawerOpen,
|
||||
'hide-ad': !(showAd && carbonLoaded)
|
||||
'hide-ad': !(showAd && carbonLoaded),
|
||||
}"
|
||||
class="floating-ad"
|
||||
v-if="theme.carbonAds"
|
||||
>
|
||||
<IconButton @click="showAd = false" class="hide-button">
|
||||
<component :is="CloseIcon" :size="20" absoluteStrokeWidth />
|
||||
<IconButton
|
||||
@click="showAd = false"
|
||||
class="hide-button"
|
||||
>
|
||||
<Icon
|
||||
:iconNode="x"
|
||||
:size="20"
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
</IconButton>
|
||||
<VPDocAsideCarbonAds
|
||||
:carbon-ads="theme.carbonAds"
|
||||
/>
|
||||
<VPDocAsideCarbonAds :carbon-ads="theme.carbonAds" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -51,7 +54,9 @@ onMounted(() => {
|
||||
bottom: 32px;
|
||||
width: 224px;
|
||||
right: 32px;
|
||||
transition: opacity 0.5s, transform 0.25s ease;
|
||||
transition:
|
||||
opacity 0.5s,
|
||||
transform 0.25s ease;
|
||||
}
|
||||
|
||||
.floating-ad.drawer-open {
|
||||
@@ -67,8 +72,11 @@ onMounted(() => {
|
||||
transform: translateY(-288px) translateX(224px);
|
||||
}
|
||||
|
||||
.floating-ad.drawer-open, .floating-ad.hide-ad {
|
||||
transition: opacity 0.25s, transform 0.5s cubic-bezier(0.19, 1, 0.22, 1);
|
||||
.floating-ad.drawer-open,
|
||||
.floating-ad.hide-ad {
|
||||
transition:
|
||||
opacity 0.25s,
|
||||
transform 0.5s cubic-bezier(0.19, 1, 0.22, 1);
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
|
||||
@@ -1,70 +1,68 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import ButtonMenu from '../base/ButtonMenu.vue'
|
||||
import ButtonMenu from '../base/ButtonMenu.vue';
|
||||
import { useIconStyleContext } from '../../composables/useIconStyle';
|
||||
import useConfetti from '../../composables/useConfetti';
|
||||
import getSVGIcon from '../../utils/getSVGIcon';
|
||||
import downloadData from '../../utils/downloadData';
|
||||
|
||||
const downloadText = 'Download!'
|
||||
const copiedText = 'Copied!'
|
||||
const confettiText = ref(copiedText)
|
||||
const downloadText = 'Download!';
|
||||
const copiedText = 'Copied!';
|
||||
const confettiText = ref(copiedText);
|
||||
const props = defineProps<{
|
||||
name: string
|
||||
popoverPosition?: 'top' | 'bottom'
|
||||
}>()
|
||||
name: string;
|
||||
popoverPosition?: 'top' | 'bottom';
|
||||
}>();
|
||||
|
||||
const { size } = useIconStyleContext()
|
||||
const { size } = useIconStyleContext();
|
||||
|
||||
const { animate, confetti } = useConfetti()
|
||||
const { animate, confetti } = useConfetti();
|
||||
|
||||
function copySVG() {
|
||||
confettiText.value = copiedText
|
||||
const svgString = getSVGIcon()
|
||||
confettiText.value = copiedText;
|
||||
const svgString = getSVGIcon();
|
||||
|
||||
navigator.clipboard.writeText(svgString)
|
||||
navigator.clipboard.writeText(svgString);
|
||||
|
||||
confetti()
|
||||
confetti();
|
||||
}
|
||||
|
||||
function copyDataUrl() {
|
||||
confettiText.value = copiedText
|
||||
const svgString = getSVGIcon()
|
||||
confettiText.value = copiedText;
|
||||
const svgString = getSVGIcon();
|
||||
|
||||
// Create SVG data url
|
||||
const dataUrl = `data:image/svg+xml;base64,${btoa(svgString)}`
|
||||
navigator.clipboard.writeText(dataUrl)
|
||||
const dataUrl = `data:image/svg+xml;base64,${btoa(svgString)}`;
|
||||
navigator.clipboard.writeText(dataUrl);
|
||||
|
||||
confetti()
|
||||
confetti();
|
||||
}
|
||||
|
||||
function downloadSVG() {
|
||||
confettiText.value = downloadText
|
||||
const svgString = getSVGIcon()
|
||||
confettiText.value = downloadText;
|
||||
const svgString = getSVGIcon();
|
||||
|
||||
downloadData(`${props.name}.svg`, `data:image/svg+xml;base64,${btoa(svgString)}`)
|
||||
confetti()
|
||||
downloadData(`${props.name}.svg`, `data:image/svg+xml;base64,${btoa(svgString)}`);
|
||||
confetti();
|
||||
}
|
||||
|
||||
function downloadPNG() {
|
||||
confettiText.value = downloadText
|
||||
const svgString = getSVGIcon()
|
||||
confettiText.value = downloadText;
|
||||
const svgString = getSVGIcon();
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = size.value;
|
||||
canvas.height = size.value;
|
||||
const ctx = canvas.getContext("2d");
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
const image = new Image();
|
||||
image.src = `data:image/svg+xml;base64,${btoa(svgString)}`;
|
||||
image.onload = function() {
|
||||
image.onload = function () {
|
||||
ctx.drawImage(image, 0, 0);
|
||||
downloadData(`${props.name}.png`, canvas.toDataURL('image/png'))
|
||||
confetti()
|
||||
}
|
||||
downloadData(`${props.name}.png`, canvas.toDataURL('image/png'));
|
||||
confetti();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -75,10 +73,10 @@ function downloadPNG() {
|
||||
:data-confetti-text="confettiText"
|
||||
:popoverPosition="popoverPosition"
|
||||
:options="[
|
||||
{ text: 'Copy SVG' , onClick: copySVG },
|
||||
{ text: 'Copy Data URL' , onClick: copyDataUrl },
|
||||
{ text: 'Download SVG' , onClick: downloadSVG },
|
||||
{ text: 'Download PNG' , onClick: downloadPNG },
|
||||
{ text: 'Copy SVG', onClick: copySVG },
|
||||
{ text: 'Copy Data URL', onClick: copyDataUrl },
|
||||
{ text: 'Download SVG', onClick: downloadSVG },
|
||||
{ text: 'Download PNG', onClick: downloadPNG },
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,41 +1,44 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, useSlots } from 'vue';
|
||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon'
|
||||
import { copy } from '../../../data/iconNodes'
|
||||
import { copy } from '../../../data/iconNodes';
|
||||
import useConfetti from '../../composables/useConfetti';
|
||||
const { animate, confetti } = useConfetti()
|
||||
const slots = useSlots()
|
||||
import Icon from 'lucide-vue-next/src/Icon';
|
||||
const { animate, confetti } = useConfetti();
|
||||
const slots = useSlots();
|
||||
|
||||
const copiedText = computed(() => slots.default?.()[0].children)
|
||||
const copiedText = computed(() => slots.default?.()[0].children);
|
||||
|
||||
function copyText() {
|
||||
navigator.clipboard.writeText(copiedText.value)
|
||||
navigator.clipboard.writeText(copiedText.value);
|
||||
|
||||
confetti()
|
||||
confetti();
|
||||
}
|
||||
|
||||
const Copy = createLucideIcon('ChevronUp', copy)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1
|
||||
class="icon-name confetti-button"
|
||||
:class="{animate}"
|
||||
:class="{ animate }"
|
||||
data-confetti-text="Copied!"
|
||||
@click="copyText"
|
||||
>
|
||||
<slot />
|
||||
<Copy :size="20" class="copy-icon"/>
|
||||
<Icon
|
||||
:iconNode="copy"
|
||||
:size="20"
|
||||
class="copy-icon"
|
||||
/>
|
||||
</h1>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@import './confetti.css';
|
||||
|
||||
.icon-name {
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
line-height: 32px;
|
||||
transition: background ease-in .15s;;
|
||||
transition: background ease-in 0.15s;
|
||||
padding: 2px 8px;
|
||||
border-radius: 8px;
|
||||
width: auto;
|
||||
@@ -48,7 +51,7 @@ const Copy = createLucideIcon('ChevronUp', copy)
|
||||
}
|
||||
|
||||
.icon-name:hover .copy-icon {
|
||||
opacity: .9;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.icon-name:before,
|
||||
@@ -65,10 +68,10 @@ const Copy = createLucideIcon('ChevronUp', copy)
|
||||
opacity: 0;
|
||||
margin-left: 12px;
|
||||
margin-top: 6px;
|
||||
transition:ease .3s opacity;
|
||||
transition: ease 0.3s opacity;
|
||||
}
|
||||
|
||||
.icon-name:hover .copy-icon:hover {
|
||||
opacity: .6;
|
||||
opacity: 0.6;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,75 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import { shallowRef, type Ref, watch, computed } from 'vue'
|
||||
import { useCssVar, syncRef } from '@vueuse/core'
|
||||
import { STYLE_DEFAULTS, useIconStyleContext } from '../../composables/useIconStyle'
|
||||
import RangeSlider from '../base/RangeSlider.vue'
|
||||
import InputField from '../base/InputField.vue'
|
||||
import ColorPicker from '../base/ColorPicker.vue'
|
||||
import ResetButton from '../base/ResetButton.vue'
|
||||
import Switch from '../base/Switch.vue'
|
||||
import { shallowRef, type Ref, watch, computed } from 'vue';
|
||||
import { useCssVar, syncRef } from '@vueuse/core';
|
||||
import { STYLE_DEFAULTS, useIconStyleContext } from '../../composables/useIconStyle';
|
||||
import RangeSlider from '../base/RangeSlider.vue';
|
||||
import InputField from '../base/InputField.vue';
|
||||
import ColorPicker from '../base/ColorPicker.vue';
|
||||
import ResetButton from '../base/ResetButton.vue';
|
||||
import Switch from '../base/Switch.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
rootEl?: Ref<HTMLElement>
|
||||
}>()
|
||||
rootEl?: Ref<HTMLElement>;
|
||||
}>();
|
||||
|
||||
const { color, strokeWidth, size, absoluteStrokeWidth } = useIconStyleContext()
|
||||
const documentRef = shallowRef<HTMLElement | undefined>(typeof document !== 'undefined' ? document?.documentElement : undefined)
|
||||
const { color, strokeWidth, size, absoluteStrokeWidth } = useIconStyleContext();
|
||||
const documentRef = shallowRef<HTMLElement | undefined>(
|
||||
typeof document !== 'undefined' ? document?.documentElement : undefined,
|
||||
);
|
||||
|
||||
const colorCssVar = useCssVar(
|
||||
'--customize-color',
|
||||
props.rootEl?.value ?? documentRef.value,
|
||||
{
|
||||
initialValue: `${STYLE_DEFAULTS.color}`
|
||||
}
|
||||
)
|
||||
const colorCssVar = useCssVar('--customize-color', props.rootEl?.value ?? documentRef.value, {
|
||||
initialValue: `${STYLE_DEFAULTS.color}`,
|
||||
});
|
||||
|
||||
const strokeWidthCssVar = useCssVar(
|
||||
'--customize-strokeWidth',
|
||||
props.rootEl?.value ?? documentRef.value,
|
||||
{
|
||||
initialValue: `${STYLE_DEFAULTS.strokeWidth}`
|
||||
}
|
||||
)
|
||||
initialValue: `${STYLE_DEFAULTS.strokeWidth}`,
|
||||
},
|
||||
);
|
||||
|
||||
const sizeCssVar = useCssVar(
|
||||
'--customize-size',
|
||||
props.rootEl?.value ?? documentRef.value,
|
||||
{
|
||||
initialValue: `${STYLE_DEFAULTS.size}`
|
||||
}
|
||||
)
|
||||
const sizeCssVar = useCssVar('--customize-size', props.rootEl?.value ?? documentRef.value, {
|
||||
initialValue: `${STYLE_DEFAULTS.size}`,
|
||||
});
|
||||
|
||||
syncRef(color, colorCssVar, { direction: 'ltr' })
|
||||
syncRef(strokeWidth, strokeWidthCssVar, { direction: 'ltr' })
|
||||
syncRef(size, sizeCssVar, { direction: 'ltr' })
|
||||
syncRef(color, colorCssVar, { direction: 'ltr' });
|
||||
syncRef(strokeWidth, strokeWidthCssVar, { direction: 'ltr' });
|
||||
syncRef(size, sizeCssVar, { direction: 'ltr' });
|
||||
|
||||
function resetStyle () {
|
||||
color.value = STYLE_DEFAULTS.color
|
||||
strokeWidth.value = STYLE_DEFAULTS.strokeWidth
|
||||
size.value = STYLE_DEFAULTS.size
|
||||
absoluteStrokeWidth.value = STYLE_DEFAULTS.absoluteStrokeWidth
|
||||
function resetStyle() {
|
||||
color.value = STYLE_DEFAULTS.color;
|
||||
strokeWidth.value = STYLE_DEFAULTS.strokeWidth;
|
||||
size.value = STYLE_DEFAULTS.size;
|
||||
absoluteStrokeWidth.value = STYLE_DEFAULTS.absoluteStrokeWidth;
|
||||
}
|
||||
|
||||
watch(absoluteStrokeWidth, (enabled) => {
|
||||
const htmlEl = document.documentElement
|
||||
const htmlEl = document.documentElement;
|
||||
|
||||
htmlEl.classList.toggle('absolute-stroke-width', enabled)
|
||||
})
|
||||
htmlEl.classList.toggle('absolute-stroke-width', enabled);
|
||||
});
|
||||
|
||||
const customizingActive = computed(() => {
|
||||
return color.value !== STYLE_DEFAULTS.color
|
||||
|| strokeWidth.value !== STYLE_DEFAULTS.strokeWidth
|
||||
|| size.value !== STYLE_DEFAULTS.size
|
||||
|| absoluteStrokeWidth.value !== STYLE_DEFAULTS.absoluteStrokeWidth
|
||||
})
|
||||
return (
|
||||
color.value !== STYLE_DEFAULTS.color ||
|
||||
strokeWidth.value !== STYLE_DEFAULTS.strokeWidth ||
|
||||
size.value !== STYLE_DEFAULTS.size ||
|
||||
absoluteStrokeWidth.value !== STYLE_DEFAULTS.absoluteStrokeWidth
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="customizer-card" :class="{ customized: customizingActive }">
|
||||
<div
|
||||
class="customizer-card"
|
||||
:class="{ customized: customizingActive }"
|
||||
>
|
||||
<div class="card-header">
|
||||
<h2 class="card-title">
|
||||
Customizer
|
||||
</h2>
|
||||
<h2 class="card-title">Customizer</h2>
|
||||
<ResetButton @click="resetStyle"></ResetButton>
|
||||
</div>
|
||||
<InputField
|
||||
@@ -77,7 +74,11 @@ const customizingActive = computed(() => {
|
||||
label="Color"
|
||||
>
|
||||
<template #display>
|
||||
<ColorPicker v-model="color" id="icon-color" class="color-picker"/>
|
||||
<ColorPicker
|
||||
v-model="color"
|
||||
id="icon-color"
|
||||
class="color-picker"
|
||||
/>
|
||||
</template>
|
||||
</InputField>
|
||||
|
||||
@@ -117,7 +118,7 @@ const customizingActive = computed(() => {
|
||||
|
||||
<InputField
|
||||
id="absolute-stroke-width"
|
||||
label="Absolute Stroke width"
|
||||
label="Absolute stroke width"
|
||||
>
|
||||
<Switch
|
||||
id="absolute-stroke-width"
|
||||
@@ -143,6 +144,7 @@ const customizingActive = computed(() => {
|
||||
font-size: 16px;
|
||||
/* margin-bottom: 12px; */
|
||||
}
|
||||
|
||||
.customizer-card {
|
||||
background: var(--vp-c-bg);
|
||||
padding: 12px 24px 24px;
|
||||
@@ -151,7 +153,7 @@ const customizingActive = computed(() => {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
border: 1px solid transparent;
|
||||
transition: border-color .4s ease-in-out;
|
||||
transition: border-color 0.4s ease-in-out;
|
||||
}
|
||||
|
||||
.customizer-card.customized {
|
||||
|
||||
@@ -29,7 +29,7 @@ export default function useSearchPlaceholder(
|
||||
}
|
||||
}
|
||||
state.value = {
|
||||
isNoResults: query in BRAND_STOPWORDS || (searchResults.length === 0 && query !== ''),
|
||||
isNoResults: query in BRAND_STOPWORDS && searchResults.length === 0 && query !== '',
|
||||
isBrand: query in BRAND_STOPWORDS,
|
||||
query: BRAND_STOPWORDS[query] ?? query,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IconNode } from 'lucide-vue-next/src/createLucideIcon';
|
||||
import { type IconNode } from 'lucide-vue-next/src/types';
|
||||
import Vue from 'vue';
|
||||
|
||||
declare module '*.vue' {
|
||||
@@ -20,5 +20,6 @@ declare module 'node:module' {
|
||||
}
|
||||
|
||||
declare module '*.node.json' {
|
||||
export default IconNode;
|
||||
const value: IconNode;
|
||||
export default value;
|
||||
}
|
||||
@@ -102,10 +102,16 @@ The example below imports all ES Modules, so exercise caution when using it. Imp
|
||||
|
||||
### Icon Component Example
|
||||
|
||||
```jsx
|
||||
import { icons } from 'lucide-react-native';
|
||||
```tsx
|
||||
import * as icons from 'lucide-react-native/icons';
|
||||
|
||||
const Icon = ({ name, color, size }) => {
|
||||
interface IconProps {
|
||||
name: keyof typeof icons;
|
||||
color?: string;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
const Icon = ({ name, color, size }: IconProps) => {
|
||||
const LucideIcon = icons[name];
|
||||
|
||||
return <LucideIcon color={color} size={size} />;
|
||||
@@ -116,11 +122,11 @@ export default Icon;
|
||||
|
||||
#### Using the Icon Component
|
||||
|
||||
```jsx
|
||||
```tsx
|
||||
import Icon from './Icon';
|
||||
|
||||
const App = () => {
|
||||
return <Icon name="house" />;
|
||||
return <Icon name="House" />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
"docs:build": "pnpm run /^prebuild:.*/ && vitepress build",
|
||||
"docs:preview": "vitepress preview",
|
||||
"build:docs": "vitepress build",
|
||||
"prebuild:iconNodes": "node --experimental-strip-types ./scripts/writeIconNodes.mjs",
|
||||
"prebuild:metaJson": "node --experimental-strip-types ./scripts/writeIconMetaIndex.mjs",
|
||||
"prebuild:releaseJson": "node --experimental-strip-types ./scripts/writeReleaseMetadata.mjs",
|
||||
"prebuild:categoriesJson": "node --experimental-strip-types ./scripts/writeCategoriesMetadata.mjs",
|
||||
"prebuild:relatedIcons": "node --experimental-strip-types ./scripts/writeIconRelatedIcons.mjs",
|
||||
"prebuild:iconDetails": "node --experimental-strip-types ./scripts/writeIconDetails.mjs",
|
||||
"prebuild:brandStopwords": "node --experimental-strip-types ./scripts/writeBrandStopwords.mjs",
|
||||
"postbuild:vercelJson": "node --experimental-strip-types ./scripts/writeVercelOutput.mjs",
|
||||
"prebuild:iconNodes": "node ./scripts/writeIconNodes.mjs",
|
||||
"prebuild:metaJson": "node ./scripts/writeIconMetaIndex.mjs",
|
||||
"prebuild:releaseJson": "node ./scripts/writeReleaseMetadata.mjs",
|
||||
"prebuild:categoriesJson": "node ./scripts/writeCategoriesMetadata.mjs",
|
||||
"prebuild:relatedIcons": "node ./scripts/writeIconRelatedIcons.mjs",
|
||||
"prebuild:iconDetails": "node ./scripts/writeIconDetails.mjs",
|
||||
"prebuild:brandStopwords": "node ./scripts/writeBrandStopwords.mjs",
|
||||
"postbuild:vercelJson": "node ./scripts/writeVercelOutput.mjs",
|
||||
"dev": "npx nitropack dev",
|
||||
"prebuild:api": "npx nitropack prepare",
|
||||
"build:api": "npx nitropack build",
|
||||
|
||||
22
icons/balloon.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"peteruithoven"
|
||||
],
|
||||
"tags": [
|
||||
"party",
|
||||
"festival",
|
||||
"congratulations",
|
||||
"celebration",
|
||||
"decoration",
|
||||
"colorful",
|
||||
"floating",
|
||||
"fun",
|
||||
"birthday",
|
||||
"event",
|
||||
"entertainment"
|
||||
],
|
||||
"categories": [
|
||||
"emoji"
|
||||
]
|
||||
}
|
||||
15
icons/balloon.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 16v1a2 2 0 0 0 2 2h1a2 2 0 0 1 2 2v1" />
|
||||
<path d="M12 6a2 2 0 0 1 2 2" />
|
||||
<path d="M18 8c0 4-3.5 8-6 8s-6-4-6-8a6 6 0 0 1 12 0" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 358 B |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"karsa-mistmere"
|
||||
"karsa-mistmere",
|
||||
"jguddas"
|
||||
],
|
||||
"tags": [
|
||||
"cleaning",
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m16 22-1-4" />
|
||||
<path d="M19 13.99a1 1 0 0 0 1-1V12a2 2 0 0 0-2-2h-3a1 1 0 0 1-1-1V4a2 2 0 0 0-4 0v5a1 1 0 0 1-1 1H6a2 2 0 0 0-2 2v.99a1 1 0 0 0 1 1" />
|
||||
<path d="M5 14h14l1.973 6.767A1 1 0 0 1 20 22H4a1 1 0 0 1-.973-1.233z" />
|
||||
<path d="M19 14a1 1 0 0 0 1-1v-1a2 2 0 0 0-2-2h-3a1 1 0 0 1-1-1V4a2 2 0 0 0-4 0v5a1 1 0 0 1-1 1H6a2 2 0 0 0-2 2v1a1 1 0 0 0 1 1" />
|
||||
<path d="M19 14H5l-1.973 6.767A1 1 0 0 0 4 22h16a1 1 0 0 0 .973-1.233z" />
|
||||
<path d="m8 22 1-4" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 474 B After Width: | Height: | Size: 470 B |
14
icons/cannabis-off.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"nickveles"
|
||||
],
|
||||
"tags": [
|
||||
"cannabis",
|
||||
"weed",
|
||||
"leaf"
|
||||
],
|
||||
"categories": [
|
||||
"nature"
|
||||
]
|
||||
}
|
||||
18
icons/cannabis-off.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22v-4c1.5 1.5 3.5 3 6 3 0-1.5-.5-3.5-2-5" />
|
||||
<path d="M13.988 8.327C13.902 6.054 13.365 3.82 12 2a9.3 9.3 0 0 0-1.445 2.9" />
|
||||
<path d="M17.375 11.725C18.882 10.53 21 7.841 21 6c-2.324 0-5.08 1.296-6.662 2.684" />
|
||||
<path d="m2 2 20 20" />
|
||||
<path d="M21.024 15.378A15 15 0 0 0 22 15c-.426-1.279-2.67-2.557-4.25-2.907" />
|
||||
<path d="M6.995 6.992C5.714 6.4 4.29 6 3 6c0 2 2.5 5 4 6-1.5 0-4.5 1.5-5 3 3.5 1.5 6 1 6 1-1.5 1.5-2 3.5-2 5 2.5 0 4.5-1.5 6-3" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 681 B |
29
icons/circle-pile.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"nathan-de-pachtere"
|
||||
],
|
||||
"tags": [
|
||||
"off",
|
||||
"zero",
|
||||
"record",
|
||||
"shape",
|
||||
"circle-pile",
|
||||
"circle",
|
||||
"pile",
|
||||
"stack",
|
||||
"layer",
|
||||
"structure",
|
||||
"form",
|
||||
"group",
|
||||
"collection",
|
||||
"stock",
|
||||
"inventory",
|
||||
"materials",
|
||||
"warehouse"
|
||||
],
|
||||
"categories": [
|
||||
"shapes"
|
||||
]
|
||||
}
|
||||
9
icons/circle-pile.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<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">
|
||||
<circle cx="12" cy="19" r="2" />
|
||||
<circle cx="12" cy="5" r="2" />
|
||||
<circle cx="16" cy="12" r="2" />
|
||||
<circle cx="20" cy="19" r="2" />
|
||||
<circle cx="4" cy="19" r="2" />
|
||||
<circle cx="8" cy="12" r="2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 397 B |
33
icons/cloud-backup.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"ericfennis",
|
||||
"jguddas",
|
||||
"danielbayley",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"storage",
|
||||
"memory",
|
||||
"bytes",
|
||||
"servers",
|
||||
"backup",
|
||||
"timemachine",
|
||||
"rotate",
|
||||
"synchronize",
|
||||
"synchronise",
|
||||
"refresh",
|
||||
"reconnect",
|
||||
"transfer",
|
||||
"data",
|
||||
"security",
|
||||
"upload",
|
||||
"save",
|
||||
"remote",
|
||||
"safety"
|
||||
],
|
||||
"categories": [
|
||||
"arrows",
|
||||
"files"
|
||||
]
|
||||
}
|
||||
15
icons/cloud-backup.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M21 15.251A4.5 4.5 0 0 0 17.5 8h-1.79A7 7 0 1 0 3 13.607" />
|
||||
<path d="M7 11v4h4" />
|
||||
<path d="M8 19a5 5 0 0 0 9-3 4.5 4.5 0 0 0-4.5-4.5 4.82 4.82 0 0 0-3.41 1.41L7 15" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 393 B |
27
icons/cloud-sync.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"csandman",
|
||||
"ericfennis",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"synchronize",
|
||||
"synchronise",
|
||||
"refresh",
|
||||
"reconnect",
|
||||
"transfer",
|
||||
"backup",
|
||||
"storage",
|
||||
"upload",
|
||||
"download",
|
||||
"connection",
|
||||
"network",
|
||||
"data"
|
||||
],
|
||||
"categories": [
|
||||
"arrows",
|
||||
"files"
|
||||
]
|
||||
}
|
||||
17
icons/cloud-sync.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m17 18-1.535 1.605a5 5 0 0 1-8-1.5" />
|
||||
<path d="M17 22v-4h-4" />
|
||||
<path d="M20.996 15.251A4.5 4.5 0 0 0 17.495 8h-1.79a7 7 0 1 0-12.709 5.607" />
|
||||
<path d="M7 10v4h4" />
|
||||
<path d="m7 14 1.535-1.605a5 5 0 0 1 8 1.5" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 442 B |
28
icons/fishing-hook.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"7ender",
|
||||
"jguddas",
|
||||
"karsa-mistmere",
|
||||
"jamiemlaw"
|
||||
],
|
||||
"tags": [
|
||||
"sea",
|
||||
"boating",
|
||||
"angler",
|
||||
"bait",
|
||||
"reel",
|
||||
"tackle",
|
||||
"marine",
|
||||
"outdoors",
|
||||
"fish",
|
||||
"fishing",
|
||||
"hook",
|
||||
"sports",
|
||||
"travel"
|
||||
],
|
||||
"categories": [
|
||||
"sports",
|
||||
"travel"
|
||||
]
|
||||
}
|
||||
15
icons/fishing-hook.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m17.586 11.414-5.93 5.93a1 1 0 0 1-8-8l3.137-3.137a.707.707 0 0 1 1.207.5V10" />
|
||||
<path d="M20.414 8.586 22 7" />
|
||||
<circle cx="19" cy="10" r="2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 369 B |
21
icons/hd.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"ahtohbi4",
|
||||
"jamiemlaw",
|
||||
"karsa-mistmere",
|
||||
"jguddas"
|
||||
],
|
||||
"tags": [
|
||||
"tv",
|
||||
"resolution",
|
||||
"video",
|
||||
"high definition",
|
||||
"720p",
|
||||
"1080p"
|
||||
],
|
||||
"categories": [
|
||||
"devices",
|
||||
"multimedia"
|
||||
]
|
||||
}
|
||||
17
icons/hd.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M10 12H6" />
|
||||
<path d="M10 15V9" />
|
||||
<path d="M14 14.5a.5.5 0 0 0 .5.5h1a2.5 2.5 0 0 0 2.5-2.5v-1A2.5 2.5 0 0 0 15.5 9h-1a.5.5 0 0 0-.5.5z" />
|
||||
<path d="M6 15V9" />
|
||||
<rect x="2" y="5" width="20" height="14" rx="2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 440 B |
22
icons/layers-plus.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"juanisidoro",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"stack",
|
||||
"layers",
|
||||
"add",
|
||||
"new",
|
||||
"increase",
|
||||
"create",
|
||||
"positive",
|
||||
"copy",
|
||||
"upgrade"
|
||||
],
|
||||
"categories": [
|
||||
"design",
|
||||
"layout"
|
||||
]
|
||||
}
|
||||
17
icons/layers-plus.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 .83.18 2 2 0 0 0 .83-.18l8.58-3.9a1 1 0 0 0 0-1.831z" />
|
||||
<path d="M16 17h6" />
|
||||
<path d="M19 14v6" />
|
||||
<path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 .825.178" />
|
||||
<path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l2.116-.962" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 539 B |
@@ -9,13 +9,15 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M6 19v-3" />
|
||||
<path d="M10 19v-3" />
|
||||
<path d="M14 19v-3" />
|
||||
<path d="M18 19v-3" />
|
||||
<path d="M8 11V9" />
|
||||
<path d="M16 11V9" />
|
||||
<path d="M12 11V9" />
|
||||
<path d="M2 15h20" />
|
||||
<path d="M2 7a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v1.1a2 2 0 0 0 0 3.837V17a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-5.1a2 2 0 0 0 0-3.837Z" />
|
||||
<path d="M12 12v-2" />
|
||||
<path d="M12 18v-2" />
|
||||
<path d="M16 12v-2" />
|
||||
<path d="M16 18v-2" />
|
||||
<path d="M2 11h1.5" />
|
||||
<path d="M20 18v-2" />
|
||||
<path d="M20.5 11H22" />
|
||||
<path d="M4 18v-2" />
|
||||
<path d="M8 12v-2" />
|
||||
<path d="M8 18v-2" />
|
||||
<rect x="2" y="6" width="20" height="10" rx="2" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 532 B After Width: | Height: | Size: 510 B |
@@ -9,15 +9,14 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M10 12h4" />
|
||||
<path d="M10 17h4" />
|
||||
<path d="M10 7h4" />
|
||||
<path d="M18 12h2" />
|
||||
<path d="M18 16h2" />
|
||||
<path d="M18 20h2" />
|
||||
<path d="M18 4h2" />
|
||||
<path d="M18 8h2" />
|
||||
<path d="M18 18h2" />
|
||||
<path d="M18 6h2" />
|
||||
<path d="M4 12h2" />
|
||||
<path d="M4 16h2" />
|
||||
<path d="M4 20h2" />
|
||||
<path d="M4 4h2" />
|
||||
<path d="M4 8h2" />
|
||||
<path d="M8 2a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2h-1.5c-.276 0-.494.227-.562.495a2 2 0 0 1-3.876 0C9.994 2.227 9.776 2 9.5 2z" />
|
||||
<path d="M4 18h2" />
|
||||
<path d="M4 6h2" />
|
||||
<rect x="6" y="2" width="12" height="20" rx="2" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 598 B After Width: | Height: | Size: 471 B |
@@ -9,8 +9,8 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m19 11-8-8-8.6 8.6a2 2 0 0 0 0 2.8l5.2 5.2c.8.8 2 .8 2.8 0L19 11Z" />
|
||||
<path d="m5 2 5 5" />
|
||||
<path d="M2 13h15" />
|
||||
<path d="M22 20a2 2 0 1 1-4 0c0-1.6 1.7-2.4 2-4 .3 1.6 2 2.4 2 4Z" />
|
||||
<path d="M11 7 6 2" />
|
||||
<path d="M18.992 12H2.041" />
|
||||
<path d="M21.145 18.38A3.34 3.34 0 0 1 20 16.5a3.3 3.3 0 0 1-1.145 1.88c-.575.46-.855 1.02-.855 1.595A2 2 0 0 0 20 22a2 2 0 0 0 2-2.025c0-.58-.285-1.13-.855-1.595" />
|
||||
<path d="m8.5 4.5 2.148-2.148a1.205 1.205 0 0 1 1.704 0l7.296 7.296a1.205 1.205 0 0 1 0 1.704l-7.592 7.592a3.615 3.615 0 0 1-5.112 0l-3.888-3.888a3.615 3.615 0 0 1 0-5.112L5.67 7.33" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 409 B After Width: | Height: | Size: 622 B |
25
icons/search-alert.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"ericfennis",
|
||||
"jguddas",
|
||||
"Veatec22"
|
||||
],
|
||||
"tags": [
|
||||
"find",
|
||||
"scan",
|
||||
"magnifier",
|
||||
"magnifying glass",
|
||||
"stop",
|
||||
"warning",
|
||||
"alert",
|
||||
"error",
|
||||
"anomaly",
|
||||
"lens"
|
||||
],
|
||||
"categories": [
|
||||
"text",
|
||||
"social"
|
||||
]
|
||||
}
|
||||
16
icons/search-alert.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<circle cx="11" cy="11" r="8" />
|
||||
<path d="m21 21-4.3-4.3" />
|
||||
<path d="M11 7v4" />
|
||||
<path d="M11 15h.01" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 321 B |
24
icons/stone.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"Alportan",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"mineral",
|
||||
"geology",
|
||||
"nature",
|
||||
"solid",
|
||||
"pebble",
|
||||
"crystal",
|
||||
"ore",
|
||||
"hard",
|
||||
"coal",
|
||||
"stone",
|
||||
"rock",
|
||||
"boulder"
|
||||
],
|
||||
"categories": [
|
||||
"nature"
|
||||
]
|
||||
}
|
||||
15
icons/stone.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M11.264 2.205A4 4 0 0 0 6.42 4.211l-4 8a4 4 0 0 0 1.359 5.117l6 4a4 4 0 0 0 4.438 0l6-4a4 4 0 0 0 1.576-4.592l-2-6a4 4 0 0 0-2.53-2.53z" />
|
||||
<path d="M11.99 22 14 12l7.822 3.184" />
|
||||
<path d="M14 12 8.47 2.302" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 435 B |
@@ -9,6 +9,6 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M17 14V2" />
|
||||
<path d="M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z" />
|
||||
<path d="M17 14V2" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 399 B After Width: | Height: | Size: 399 B |
@@ -9,6 +9,6 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M7 10v12" />
|
||||
<path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z" />
|
||||
<path d="M7 10v12" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 400 B After Width: | Height: | Size: 400 B |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"jguddas"
|
||||
"jguddas",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"plane",
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
>
|
||||
<path d="M10.5 17h1.227a2 2 0 0 0 1.345-.52L18 12" />
|
||||
<path d="m12 13.5 3.75.5" />
|
||||
<path d="m4.5 8 10.58-5.06a1 1 0 0 1 1.342.488L18.5 8" />
|
||||
<path d="m3.173 8.18 11-5a2 2 0 0 1 2.647.993L18.56 8" />
|
||||
<path d="M6 10V8" />
|
||||
<path d="M6 14v1" />
|
||||
<path d="M6 19v2" />
|
||||
|
||||
|
Before Width: | Height: | Size: 477 B After Width: | Height: | Size: 477 B |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"jguddas"
|
||||
"jguddas",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"trip",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m4.5 8 10.58-5.06a1 1 0 0 1 1.342.488L18.5 8" />
|
||||
<path d="m3.173 8.18 11-5a2 2 0 0 1 2.647.993L18.56 8" />
|
||||
<path d="M6 10V8" />
|
||||
<path d="M6 14v1" />
|
||||
<path d="M6 19v2" />
|
||||
|
||||
|
Before Width: | Height: | Size: 390 B After Width: | Height: | Size: 390 B |
37
icons/toolbox.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"toolkit",
|
||||
"tools",
|
||||
"trunk",
|
||||
"chest",
|
||||
"box",
|
||||
"storage",
|
||||
"utility",
|
||||
"utilities",
|
||||
"container",
|
||||
"kit",
|
||||
"set",
|
||||
"repair",
|
||||
"fix",
|
||||
"service",
|
||||
"maintenance",
|
||||
"mechanic",
|
||||
"workshop",
|
||||
"construction",
|
||||
"hardware",
|
||||
"equipment",
|
||||
"gear",
|
||||
"handyman",
|
||||
"engineering",
|
||||
"craft",
|
||||
"diy"
|
||||
],
|
||||
"categories": [
|
||||
"tools",
|
||||
"home"
|
||||
]
|
||||
}
|
||||
17
icons/toolbox.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M16 12v4" />
|
||||
<path d="M16 6a2 2 0 0 1 1.414.586l4 4A2 2 0 0 1 22 12v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 .586-1.414l4-4A2 2 0 0 1 8 6z" />
|
||||
<path d="M16 6V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2" />
|
||||
<path d="M2 14h20" />
|
||||
<path d="M8 12v4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 471 B |
@@ -7,8 +7,8 @@ const filenamesToAjvOption = (filenames) => filenames.map((filename) => `-d ${fi
|
||||
/** @satisfies {import('lint-staged').Config} */
|
||||
const config = {
|
||||
'icons/*.svg': [
|
||||
'node ./scripts/optimizeStagedSvgs.mjs',
|
||||
'node ./scripts/generateNextJSAliases.mjs',
|
||||
'node ./scripts/optimizeStagedSvgs.mts',
|
||||
'node ./scripts/generateNextJSAliases.mts',
|
||||
],
|
||||
'icons/*.json': (filenames) => [
|
||||
`ajv --spec=draft2020 -s icon.schema.json ${filenamesToAjvOption(filenames)}`,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"lucide-svelte": "pnpm --filter lucide-svelte",
|
||||
"lucide-static": "pnpm --filter lucide-static",
|
||||
"build:outline-icons": "pnpm --filter outline-svg start",
|
||||
"build:font": "pnpm --filter docs prebuild:releaseJson && pnpm --filter build-font start",
|
||||
"build:font": "pnpm --filter build-font start",
|
||||
"optimize": "node ./scripts/optimizeSvgs.mts",
|
||||
"addjsons": "node ./scripts/addMissingIconJsonFiles.mts",
|
||||
"checkIcons": "node ./scripts/checkIconsAndCategories.mts",
|
||||
@@ -73,9 +73,9 @@
|
||||
"zod": "^3.25.67"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=23.0.0"
|
||||
"node": ">=24.11.1"
|
||||
},
|
||||
"packageManager": "pnpm@10.23.0+sha512.21c4e5698002ade97e4efe8b8b4a89a8de3c85a37919f957e7a0f30f38fbc5bbdd05980ffe29179b2fb6e6e691242e098d945d1601772cad0fef5fb6411e2a4b",
|
||||
"packageManager": "pnpm@10.24.0+sha512.01ff8ae71b4419903b65c60fb2dc9d34cf8bb6e06d03bde112ef38f7a34d6904c424ba66bea5cdcf12890230bf39f9580473140ed9c946fef328b6e5238a345a",
|
||||
"pnpm": {
|
||||
"packageExtensions": {
|
||||
"vue-template-compiler": {
|
||||
|
||||
@@ -24,11 +24,23 @@
|
||||
"author": "Eric Fennis",
|
||||
"amdName": "lucide-react-native",
|
||||
"main": "dist/cjs/lucide-react-native.js",
|
||||
"main:umd": "dist/umd/lucide-react-native.js",
|
||||
"module": "dist/esm/lucide-react-native.js",
|
||||
"unpkg": "dist/umd/lucide-react-native.min.js",
|
||||
"typings": "dist/lucide-react-native.d.ts",
|
||||
"react-native": "dist/esm/lucide-react-native.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/lucide-react-native.d.ts",
|
||||
"import": "./dist/esm/lucide-react-native.js",
|
||||
"browser": "./dist/esm/lucide-react-native.js",
|
||||
"require": "./dist/cjs/lucide-react-native.js"
|
||||
},
|
||||
"./icons": {
|
||||
"types": "./dist/icons.d.ts",
|
||||
"import": "./dist/esm/icons/index.js",
|
||||
"browser": "./dist/esm/icons/index.js",
|
||||
"require": "./dist/cjs/icons/index.js"
|
||||
}
|
||||
},
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"dist"
|
||||
|
||||
@@ -5,7 +5,7 @@ import pkg from './package.json' with { type: 'json' };
|
||||
const packageName = 'LucideReact';
|
||||
const outputFileName = 'lucide-react-native';
|
||||
const outputDir = 'dist';
|
||||
const inputs = ['src/lucide-react-native.ts'];
|
||||
const inputs = ['src/lucide-react-native.ts', 'src/icons/index.ts'];
|
||||
const bundles = [
|
||||
{
|
||||
format: 'cjs',
|
||||
@@ -60,6 +60,16 @@ export default [
|
||||
],
|
||||
plugins: [dts()],
|
||||
},
|
||||
{
|
||||
input: inputs[1],
|
||||
output: [
|
||||
{
|
||||
file: `dist/icons.d.ts`,
|
||||
format: 'es',
|
||||
},
|
||||
],
|
||||
plugins: [dts()],
|
||||
},
|
||||
{
|
||||
input: `src/${outputFileName}.suffixed.ts`,
|
||||
output: [
|
||||
|
||||
@@ -31,6 +31,7 @@ const Icon = forwardRef<SVGSVGElement, IconComponentProps>(
|
||||
absoluteStrokeWidth,
|
||||
children,
|
||||
iconNode,
|
||||
className,
|
||||
...rest
|
||||
},
|
||||
ref,
|
||||
@@ -46,6 +47,7 @@ const Icon = forwardRef<SVGSVGElement, IconComponentProps>(
|
||||
{
|
||||
ref,
|
||||
...defaultAttributes,
|
||||
className,
|
||||
width: size,
|
||||
height: size,
|
||||
...customAttrs,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export * from './icons';
|
||||
export * as icons from './icons';
|
||||
export * from './aliases/prefixed';
|
||||
export * from './types';
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export * from './icons';
|
||||
export * as icons from './icons';
|
||||
export * from './aliases/suffixed';
|
||||
export * from './types';
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export * from './icons';
|
||||
export * as icons from './icons';
|
||||
export * from './aliases';
|
||||
export * from './types';
|
||||
|
||||
|
||||
143
pnpm-lock.yaml
generated
@@ -199,7 +199,7 @@ importers:
|
||||
version: 7.7.1
|
||||
nitropack:
|
||||
specifier: 2.8.1
|
||||
version: 2.8.1(db0@0.3.4)(encoding@0.1.13)(ioredis@5.8.2)(xml2js@0.6.2)
|
||||
version: 2.8.1(@vercel/blob@2.0.0)(db0@0.3.4)(encoding@0.1.13)(ioredis@5.8.2)(xml2js@0.6.2)
|
||||
rollup-plugin-copy:
|
||||
specifier: ^3.5.0
|
||||
version: 3.5.0
|
||||
@@ -226,7 +226,7 @@ importers:
|
||||
version: 6.9.1
|
||||
astro:
|
||||
specifier: ^5.16.0
|
||||
version: 5.16.0(@types/node@24.10.1)(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(less@4.2.0)(rollup@4.53.3)(sass@1.77.8)(stylus@0.56.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.0)
|
||||
version: 5.16.0(@types/node@24.10.1)(@vercel/blob@2.0.0)(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(less@4.2.0)(rollup@4.53.3)(sass@1.77.8)(stylus@0.56.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.0)
|
||||
jest-serializer-html:
|
||||
specifier: ^7.1.0
|
||||
version: 7.1.0
|
||||
@@ -813,10 +813,16 @@ importers:
|
||||
minimist:
|
||||
specifier: ^1.2.8
|
||||
version: 1.2.8
|
||||
oslllo-svg-fixer:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0(encoding@0.1.13)
|
||||
svgtofont:
|
||||
specifier: ^6.5.0
|
||||
version: 6.5.0(@types/svg2ttf@5.0.1)(chokidar@3.6.0)
|
||||
devDependencies:
|
||||
'@lucide/helpers':
|
||||
specifier: workspace:*
|
||||
version: link:../build-helpers
|
||||
'@types/fs-extra':
|
||||
specifier: ^11.0.4
|
||||
version: 11.0.4
|
||||
@@ -858,15 +864,6 @@ importers:
|
||||
specifier: ^22
|
||||
version: 22.19.1
|
||||
|
||||
tools/outline-svg:
|
||||
dependencies:
|
||||
minimist:
|
||||
specifier: ^1.2.8
|
||||
version: 1.2.8
|
||||
oslllo-svg-fixer:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0(encoding@0.1.13)
|
||||
|
||||
tools/rollup-plugins:
|
||||
dependencies:
|
||||
'@rollup/plugin-node-resolve':
|
||||
@@ -5612,6 +5609,10 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@vercel/blob@2.0.0':
|
||||
resolution: {integrity: sha512-oAj7Pdy83YKSwIaMFoM7zFeLYWRc+qUpW3PiDSblxQMnGFb43qs4bmfq7dr/+JIfwhs6PTwe1o2YBwKhyjWxXw==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@vercel/nft@0.24.4':
|
||||
resolution: {integrity: sha512-KjYAZty7boH5fi5udp6p+lNu6nawgs++pHW+3koErMgbRkkHuToGX/FwjN5clV1FcaM3udfd4zW/sUapkMgpZw==}
|
||||
engines: {node: '>=16'}
|
||||
@@ -6167,6 +6168,9 @@ packages:
|
||||
async-limiter@1.0.1:
|
||||
resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==}
|
||||
|
||||
async-retry@1.3.3:
|
||||
resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==}
|
||||
|
||||
async-sema@3.1.1:
|
||||
resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==}
|
||||
|
||||
@@ -8112,10 +8116,6 @@ packages:
|
||||
resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
fast-glob@3.3.2:
|
||||
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
|
||||
fast-glob@3.3.3:
|
||||
resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
@@ -8880,6 +8880,10 @@ packages:
|
||||
is-buffer@1.1.6:
|
||||
resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
|
||||
|
||||
is-buffer@2.0.5:
|
||||
resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
is-builtin-module@3.2.1:
|
||||
resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -8978,6 +8982,9 @@ packages:
|
||||
resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-node-process@1.2.0:
|
||||
resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==}
|
||||
|
||||
is-number-object@1.0.7:
|
||||
resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -12382,6 +12389,10 @@ packages:
|
||||
throat@5.0.0:
|
||||
resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==}
|
||||
|
||||
throttleit@2.1.0:
|
||||
resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
through2@2.0.5:
|
||||
resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==}
|
||||
|
||||
@@ -16704,14 +16715,14 @@ snapshots:
|
||||
dependencies:
|
||||
'@jest/fake-timers': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
jest-mock: 29.7.0
|
||||
|
||||
'@jest/fake-timers@29.7.0':
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@sinonjs/fake-timers': 10.3.0
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
jest-message-util: 29.7.0
|
||||
jest-mock: 29.7.0
|
||||
jest-util: 29.7.0
|
||||
@@ -16745,7 +16756,7 @@ snapshots:
|
||||
'@jest/schemas': 29.6.3
|
||||
'@types/istanbul-lib-coverage': 2.0.4
|
||||
'@types/istanbul-reports': 3.0.1
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
'@types/yargs': 17.0.35
|
||||
chalk: 4.1.2
|
||||
|
||||
@@ -18452,11 +18463,11 @@ snapshots:
|
||||
'@types/body-parser@1.19.5':
|
||||
dependencies:
|
||||
'@types/connect': 3.4.38
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/bonjour@3.5.13':
|
||||
dependencies:
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/chai@5.2.2':
|
||||
dependencies:
|
||||
@@ -18465,17 +18476,17 @@ snapshots:
|
||||
'@types/connect-history-api-fallback@1.5.4':
|
||||
dependencies:
|
||||
'@types/express-serve-static-core': 4.19.5
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/connect@3.4.38':
|
||||
dependencies:
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/cookie@0.4.1': {}
|
||||
|
||||
'@types/cors@2.8.17':
|
||||
dependencies:
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/debug@4.1.12':
|
||||
dependencies:
|
||||
@@ -18503,7 +18514,7 @@ snapshots:
|
||||
|
||||
'@types/express-serve-static-core@4.19.5':
|
||||
dependencies:
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
'@types/qs': 6.9.15
|
||||
'@types/range-parser': 1.2.7
|
||||
'@types/send': 0.17.4
|
||||
@@ -18517,7 +18528,7 @@ snapshots:
|
||||
|
||||
'@types/fontkit@2.0.8':
|
||||
dependencies:
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/fs-extra@11.0.4':
|
||||
dependencies:
|
||||
@@ -18531,11 +18542,11 @@ snapshots:
|
||||
'@types/glob@7.2.0':
|
||||
dependencies:
|
||||
'@types/minimatch': 6.0.0
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/graceful-fs@4.1.9':
|
||||
dependencies:
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/hast@3.0.4':
|
||||
dependencies:
|
||||
@@ -18596,7 +18607,7 @@ snapshots:
|
||||
|
||||
'@types/node-forge@1.3.11':
|
||||
dependencies:
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/node@12.20.55': {}
|
||||
|
||||
@@ -18635,7 +18646,7 @@ snapshots:
|
||||
|
||||
'@types/resolve@1.17.1':
|
||||
dependencies:
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/resolve@1.20.2': {}
|
||||
|
||||
@@ -18650,7 +18661,7 @@ snapshots:
|
||||
'@types/send@0.17.4':
|
||||
dependencies:
|
||||
'@types/mime': 1.3.5
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/serve-index@1.9.4':
|
||||
dependencies:
|
||||
@@ -18659,12 +18670,12 @@ snapshots:
|
||||
'@types/serve-static@1.15.7':
|
||||
dependencies:
|
||||
'@types/http-errors': 2.0.4
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
'@types/send': 0.17.4
|
||||
|
||||
'@types/sockjs@0.3.36':
|
||||
dependencies:
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/stack-utils@2.0.1': {}
|
||||
|
||||
@@ -18677,7 +18688,7 @@ snapshots:
|
||||
|
||||
'@types/ws@8.5.12':
|
||||
dependencies:
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
|
||||
'@types/yargs-parser@21.0.3': {}
|
||||
|
||||
@@ -18947,6 +18958,15 @@ snapshots:
|
||||
'@unrs/resolver-binding-win32-x64-msvc@1.6.2':
|
||||
optional: true
|
||||
|
||||
'@vercel/blob@2.0.0':
|
||||
dependencies:
|
||||
async-retry: 1.3.3
|
||||
is-buffer: 2.0.5
|
||||
is-node-process: 1.2.0
|
||||
throttleit: 2.1.0
|
||||
undici: 5.28.5
|
||||
optional: true
|
||||
|
||||
'@vercel/nft@0.24.4(encoding@0.1.13)':
|
||||
dependencies:
|
||||
'@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13)
|
||||
@@ -19591,7 +19611,7 @@ snapshots:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
astro@5.16.0(@types/node@24.10.1)(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(less@4.2.0)(rollup@4.53.3)(sass@1.77.8)(stylus@0.56.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.0):
|
||||
astro@5.16.0(@types/node@24.10.1)(@vercel/blob@2.0.0)(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(less@4.2.0)(rollup@4.53.3)(sass@1.77.8)(stylus@0.56.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.0):
|
||||
dependencies:
|
||||
'@astrojs/compiler': 2.13.0
|
||||
'@astrojs/internal-helpers': 0.7.5
|
||||
@@ -19646,7 +19666,7 @@ snapshots:
|
||||
ultrahtml: 1.6.0
|
||||
unifont: 0.6.0
|
||||
unist-util-visit: 5.0.0
|
||||
unstorage: 1.17.3(db0@0.3.4)(ioredis@5.8.2)
|
||||
unstorage: 1.17.3(@vercel/blob@2.0.0)(db0@0.3.4)(ioredis@5.8.2)
|
||||
vfile: 6.0.3
|
||||
vite: 6.4.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(sass@1.77.8)(stylus@0.56.0)(terser@5.44.1)(yaml@2.8.0)
|
||||
vitefu: 1.1.1(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(sass@1.77.8)(stylus@0.56.0)(terser@5.44.1)(yaml@2.8.0))
|
||||
@@ -19697,6 +19717,11 @@ snapshots:
|
||||
|
||||
async-limiter@1.0.1: {}
|
||||
|
||||
async-retry@1.3.3:
|
||||
dependencies:
|
||||
retry: 0.13.1
|
||||
optional: true
|
||||
|
||||
async-sema@3.1.1: {}
|
||||
|
||||
async@2.6.4:
|
||||
@@ -20260,7 +20285,7 @@ snapshots:
|
||||
|
||||
chrome-launcher@0.15.2:
|
||||
dependencies:
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
escape-string-regexp: 4.0.0
|
||||
is-wsl: 2.2.0
|
||||
lighthouse-logger: 1.4.2
|
||||
@@ -20271,7 +20296,7 @@ snapshots:
|
||||
|
||||
chromium-edge-launcher@0.2.0:
|
||||
dependencies:
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
escape-string-regexp: 4.0.0
|
||||
is-wsl: 2.2.0
|
||||
lighthouse-logger: 1.4.2
|
||||
@@ -20503,7 +20528,7 @@ snapshots:
|
||||
|
||||
copy-webpack-plugin@10.2.1(webpack@5.76.1(@swc/core@1.7.23(@swc/helpers@0.5.17))(esbuild@0.14.22)):
|
||||
dependencies:
|
||||
fast-glob: 3.3.2
|
||||
fast-glob: 3.3.3
|
||||
glob-parent: 6.0.2
|
||||
globby: 12.2.0
|
||||
normalize-path: 3.0.0
|
||||
@@ -21072,7 +21097,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/cookie': 0.4.1
|
||||
'@types/cors': 2.8.17
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
accepts: 1.3.8
|
||||
base64id: 2.0.0
|
||||
cookie: 0.4.2
|
||||
@@ -21937,14 +21962,6 @@ snapshots:
|
||||
merge2: 1.4.1
|
||||
micromatch: 4.0.8
|
||||
|
||||
fast-glob@3.3.2:
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
'@nodelib/fs.walk': 1.2.8
|
||||
glob-parent: 5.1.2
|
||||
merge2: 1.4.1
|
||||
micromatch: 4.0.8
|
||||
|
||||
fast-glob@3.3.3:
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
@@ -22380,7 +22397,7 @@ snapshots:
|
||||
dependencies:
|
||||
array-union: 3.0.1
|
||||
dir-glob: 3.0.1
|
||||
fast-glob: 3.3.2
|
||||
fast-glob: 3.3.3
|
||||
ignore: 5.3.2
|
||||
merge2: 1.4.1
|
||||
slash: 4.0.0
|
||||
@@ -22884,6 +22901,9 @@ snapshots:
|
||||
|
||||
is-buffer@1.1.6: {}
|
||||
|
||||
is-buffer@2.0.5:
|
||||
optional: true
|
||||
|
||||
is-builtin-module@3.2.1:
|
||||
dependencies:
|
||||
builtin-modules: 3.3.0
|
||||
@@ -22960,6 +22980,9 @@ snapshots:
|
||||
|
||||
is-negative-zero@2.0.3: {}
|
||||
|
||||
is-node-process@1.2.0:
|
||||
optional: true
|
||||
|
||||
is-number-object@1.0.7:
|
||||
dependencies:
|
||||
has-tostringtag: 1.0.2
|
||||
@@ -23170,7 +23193,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@types/graceful-fs': 4.1.9
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
anymatch: 3.1.3
|
||||
fb-watchman: 2.0.2
|
||||
graceful-fs: 4.2.11
|
||||
@@ -23197,7 +23220,7 @@ snapshots:
|
||||
jest-mock@29.7.0:
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
jest-util: 29.7.0
|
||||
|
||||
jest-regex-util@29.6.3: {}
|
||||
@@ -23209,7 +23232,7 @@ snapshots:
|
||||
jest-util@29.7.0:
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.8.0
|
||||
graceful-fs: 4.2.11
|
||||
@@ -23226,13 +23249,13 @@ snapshots:
|
||||
|
||||
jest-worker@27.5.1:
|
||||
dependencies:
|
||||
'@types/node': 12.20.55
|
||||
'@types/node': 22.19.1
|
||||
merge-stream: 2.0.0
|
||||
supports-color: 8.1.1
|
||||
|
||||
jest-worker@29.7.0:
|
||||
dependencies:
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 22.19.1
|
||||
jest-util: 29.7.0
|
||||
merge-stream: 2.0.0
|
||||
supports-color: 8.1.1
|
||||
@@ -24637,7 +24660,7 @@ snapshots:
|
||||
node-gyp-build: 4.8.4
|
||||
optional: true
|
||||
|
||||
nitropack@2.8.1(db0@0.3.4)(encoding@0.1.13)(ioredis@5.8.2)(xml2js@0.6.2):
|
||||
nitropack@2.8.1(@vercel/blob@2.0.0)(db0@0.3.4)(encoding@0.1.13)(ioredis@5.8.2)(xml2js@0.6.2):
|
||||
dependencies:
|
||||
'@cloudflare/kv-asset-handler': 0.3.4
|
||||
'@netlify/functions': 2.8.2
|
||||
@@ -24702,7 +24725,7 @@ snapshots:
|
||||
unctx: 2.4.1
|
||||
unenv: 1.10.0
|
||||
unimport: 3.14.6(rollup@4.53.3)
|
||||
unstorage: 1.17.3(db0@0.3.4)(ioredis@5.8.2)
|
||||
unstorage: 1.17.3(@vercel/blob@2.0.0)(db0@0.3.4)(ioredis@5.8.2)
|
||||
optionalDependencies:
|
||||
xml2js: 0.6.2
|
||||
transitivePeerDependencies:
|
||||
@@ -25147,7 +25170,7 @@ snapshots:
|
||||
dependencies:
|
||||
ansi-colors: 4.1.3
|
||||
cli-progress: 3.12.0
|
||||
fast-glob: 3.3.2
|
||||
fast-glob: 3.3.3
|
||||
oslllo-potrace: 3.0.0(encoding@0.1.13)
|
||||
oslllo-svg2: 3.0.0(encoding@0.1.13)
|
||||
oslllo-validator: 3.1.0
|
||||
@@ -27289,7 +27312,7 @@ snapshots:
|
||||
|
||||
stylus-loader@6.2.0(stylus@0.56.0)(webpack@5.76.1(@swc/core@1.7.23(@swc/helpers@0.5.17))(esbuild@0.14.22)):
|
||||
dependencies:
|
||||
fast-glob: 3.3.2
|
||||
fast-glob: 3.3.3
|
||||
klona: 2.0.6
|
||||
normalize-path: 3.0.0
|
||||
stylus: 0.56.0
|
||||
@@ -27621,6 +27644,9 @@ snapshots:
|
||||
|
||||
throat@5.0.0: {}
|
||||
|
||||
throttleit@2.1.0:
|
||||
optional: true
|
||||
|
||||
through2@2.0.5:
|
||||
dependencies:
|
||||
readable-stream: 2.3.8
|
||||
@@ -28082,7 +28108,7 @@ snapshots:
|
||||
'@unrs/resolver-binding-win32-ia32-msvc': 1.6.2
|
||||
'@unrs/resolver-binding-win32-x64-msvc': 1.6.2
|
||||
|
||||
unstorage@1.17.3(db0@0.3.4)(ioredis@5.8.2):
|
||||
unstorage@1.17.3(@vercel/blob@2.0.0)(db0@0.3.4)(ioredis@5.8.2):
|
||||
dependencies:
|
||||
anymatch: 3.1.3
|
||||
chokidar: 4.0.3
|
||||
@@ -28093,6 +28119,7 @@ snapshots:
|
||||
ofetch: 1.5.1
|
||||
ufo: 1.6.1
|
||||
optionalDependencies:
|
||||
'@vercel/blob': 2.0.0
|
||||
db0: 0.3.4
|
||||
ioredis: 5.8.2
|
||||
|
||||
|
||||
1914
tools/build-font/codepoints.json
Normal file
@@ -1,149 +0,0 @@
|
||||
import { readJson } from 'fs-extra/esm';
|
||||
import svgtofont from 'svgtofont';
|
||||
import getArgumentOptions from 'minimist';
|
||||
import path from 'path';
|
||||
|
||||
const fontName = 'lucide';
|
||||
const classNamePrefix = 'icon';
|
||||
const startUnicode = 57400;
|
||||
|
||||
const inputDir = path.join(process.cwd(), '../../', 'outlined');
|
||||
const cliArguments = getArgumentOptions(process.argv.slice(2));
|
||||
const { outputDir = 'lucide-font' } = cliArguments;
|
||||
const targetDir = path.join(process.cwd(), '../../', outputDir);
|
||||
const releaseMetaDataDir = path.join(process.cwd(), '../../', 'docs/.vitepress/data');
|
||||
const releaseMetaDataPath = path.resolve(releaseMetaDataDir, 'releaseMetaData.json');
|
||||
|
||||
const releaseMetaData = convertReleaseMetaData(await getReleaseMetaData());
|
||||
|
||||
async function getReleaseMetaData() {
|
||||
let releaseMetaData = {};
|
||||
try {
|
||||
releaseMetaData = await readJson(releaseMetaDataPath);
|
||||
} catch (err) {
|
||||
throw new Error('Execution stopped because no release information was found.');
|
||||
}
|
||||
return releaseMetaData;
|
||||
}
|
||||
|
||||
type Releases = Record<string, ReleaseMetaData>;
|
||||
|
||||
type ReleaseMetaData = {
|
||||
createdRelease: {
|
||||
version: string;
|
||||
date: string;
|
||||
};
|
||||
changedRelease: {
|
||||
version: string;
|
||||
date: string;
|
||||
};
|
||||
};
|
||||
|
||||
type ReleaseMetaDataWithName = ReleaseMetaData & {
|
||||
name: string;
|
||||
};
|
||||
|
||||
function convertReleaseMetaData(releases: Releases) {
|
||||
return Object.entries(releases)
|
||||
.map(([key, data]) => ({
|
||||
...data,
|
||||
name: key,
|
||||
}))
|
||||
.sort((a, b) => sortMultiple(a, b, [sortByCreatedReleaseDate, sortByName]))
|
||||
.map((value, index) => ({ ...value, index }))
|
||||
.map((value, index) => ({
|
||||
...value,
|
||||
unicode: index + startUnicode,
|
||||
}));
|
||||
}
|
||||
|
||||
type CollatorFunction = (a: ReleaseMetaDataWithName, b: ReleaseMetaDataWithName) => number;
|
||||
|
||||
function sortMultiple(
|
||||
a: ReleaseMetaDataWithName,
|
||||
b: ReleaseMetaDataWithName,
|
||||
collators: CollatorFunction[] = [],
|
||||
) {
|
||||
const comparison = collators?.shift?.()?.(a, b) ?? 0;
|
||||
if (comparison === 0 && collators.length > 0) return sortMultiple(a, b, collators);
|
||||
return comparison;
|
||||
}
|
||||
|
||||
function sortByCreatedReleaseDate(a: ReleaseMetaDataWithName, b: ReleaseMetaDataWithName) {
|
||||
const [dateA, dateB] = [a, b].map((value) => new Date(value.createdRelease.date).valueOf());
|
||||
return Number(dateA > dateB) - Number(dateA < dateB);
|
||||
}
|
||||
|
||||
function sortByName(a: ReleaseMetaDataWithName, b: ReleaseMetaDataWithName) {
|
||||
return new Intl.Collator('en-US').compare(a.name, b.name);
|
||||
}
|
||||
|
||||
function getIconUnicode(name: string): [string, number] {
|
||||
const { unicode } = releaseMetaData.find(({ name: iconName }) => iconName === name) ?? {
|
||||
unicode: startUnicode,
|
||||
};
|
||||
return [String.fromCharCode(unicode), startUnicode];
|
||||
}
|
||||
|
||||
async function init() {
|
||||
console.time('Font generation');
|
||||
try {
|
||||
await svgtofont({
|
||||
src: path.resolve(process.cwd(), inputDir),
|
||||
dist: path.resolve(process.cwd(), targetDir),
|
||||
// styleTemplates: path.resolve(process.cwd(), 'styles'), // Add different templates if needed
|
||||
fontName,
|
||||
classNamePrefix,
|
||||
css: {
|
||||
fontSize: 'inherit',
|
||||
},
|
||||
emptyDist: true,
|
||||
useCSSVars: false,
|
||||
outSVGReact: false,
|
||||
outSVGPath: false,
|
||||
svgicons2svgfont: {
|
||||
fontHeight: 1000, // At least 1000 is recommended
|
||||
normalize: false,
|
||||
},
|
||||
generateInfoData: true,
|
||||
website: {
|
||||
title: 'Lucide',
|
||||
logo: undefined,
|
||||
meta: {
|
||||
description: 'Lucide icons as TTF/EOT/WOFF/WOFF2/SVG.',
|
||||
keywords: 'Lucide,TTF,EOT,WOFF,WOFF2,SVG',
|
||||
},
|
||||
corners: {
|
||||
url: 'https://github.com/lucide-icons/lucide',
|
||||
width: 62, // default: 60
|
||||
height: 62, // default: 60
|
||||
bgColor: '#dc3545', // default: '#151513'
|
||||
},
|
||||
links: [
|
||||
{
|
||||
title: 'GitHub',
|
||||
url: 'https://github.com/lucide-icons/lucide',
|
||||
},
|
||||
{
|
||||
title: 'Feedback',
|
||||
url: 'https://github.com/lucide-icons/lucide/issues',
|
||||
},
|
||||
{
|
||||
title: 'Font Class',
|
||||
url: 'index.html',
|
||||
},
|
||||
{
|
||||
title: 'Unicode',
|
||||
url: 'unicode.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
getIconUnicode,
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
console.timeEnd('Font generation');
|
||||
}
|
||||
|
||||
init();
|
||||
@@ -6,7 +6,7 @@
|
||||
"main": "main.ts",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node ./main.ts"
|
||||
"start": "node ./src/main.ts"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
@@ -14,9 +14,11 @@
|
||||
"dependencies": {
|
||||
"fs-extra": "^11.2.0",
|
||||
"minimist": "^1.2.8",
|
||||
"oslllo-svg-fixer": "^5.0.0",
|
||||
"svgtofont": "^6.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lucide/helpers": "workspace:*",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/minimist": "^1.2.5",
|
||||
"@types/node": "^22"
|
||||
|
||||
60
tools/build-font/src/allocateCodepoints.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { type IconAliases } from "@lucide/helpers";
|
||||
import path from "path";
|
||||
import { promises as fs } from 'fs';
|
||||
import { cwd } from "process";
|
||||
|
||||
export type CodePoints = Record<string, number>;
|
||||
|
||||
async function getLatestCodePoints(): Promise<CodePoints> {
|
||||
// This is for the first release where no codepoints.json exists yet
|
||||
const codepointsContents = await fs.readFile(path.join(cwd(), 'codepoints.json'), 'utf-8')
|
||||
|
||||
return JSON.parse(codepointsContents) as CodePoints
|
||||
|
||||
// Next releases will use the codepoints.json from latest release in lucide-static.
|
||||
// const codepointsContents = await fetch('https://unpkg.com/lucide-static@latest/font/codepoints.json')
|
||||
// return codepointsContents.json() as Promise<CodePoints>
|
||||
}
|
||||
|
||||
interface AllocateCodePointsOptions {
|
||||
saveCodePoints?: boolean;
|
||||
iconsWithAliases: IconAliases
|
||||
}
|
||||
|
||||
export async function allocateCodePoints({
|
||||
saveCodePoints = false,
|
||||
iconsWithAliases
|
||||
}: AllocateCodePointsOptions): Promise<CodePoints> {
|
||||
const baseCodePoints = await getLatestCodePoints()
|
||||
|
||||
const endCodePoint = Math.max(...Object.values(baseCodePoints))
|
||||
|
||||
await Promise.all(
|
||||
iconsWithAliases.map(async ([iconName, aliases]) => {
|
||||
if(!baseCodePoints[iconName]) {
|
||||
console.log('Code point not found creating new one for', iconName);
|
||||
baseCodePoints[iconName] = endCodePoint + 1;
|
||||
}
|
||||
|
||||
aliases.forEach((alias, index) => {
|
||||
if (baseCodePoints[alias]) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Code point not found creating new one for');
|
||||
|
||||
baseCodePoints[alias] = endCodePoint + index + 1;
|
||||
});
|
||||
})
|
||||
)
|
||||
|
||||
if (saveCodePoints) {
|
||||
await fs.writeFile(
|
||||
path.join(cwd(), 'codepoints.json'),
|
||||
JSON.stringify(baseCodePoints, null, 2),
|
||||
'utf-8'
|
||||
);
|
||||
}
|
||||
|
||||
return baseCodePoints;
|
||||
}
|
||||
86
tools/build-font/src/buildFont.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import svgtofont from 'svgtofont';
|
||||
import { type CodePoints } from './allocateCodepoints.ts';
|
||||
|
||||
interface BuildFontOptions {
|
||||
inputDir: string;
|
||||
targetDir: string;
|
||||
fontName: string;
|
||||
classNamePrefix: string;
|
||||
codePoints: CodePoints
|
||||
startUnicode: number;
|
||||
}
|
||||
|
||||
export async function buildFont({
|
||||
inputDir,
|
||||
targetDir,
|
||||
fontName,
|
||||
classNamePrefix,
|
||||
codePoints,
|
||||
startUnicode
|
||||
}: BuildFontOptions) {
|
||||
console.time('Font generation');
|
||||
try {
|
||||
await svgtofont({
|
||||
src: inputDir,
|
||||
dist: targetDir,
|
||||
fontName,
|
||||
classNamePrefix,
|
||||
css: {
|
||||
fontSize: 'inherit',
|
||||
},
|
||||
emptyDist: true,
|
||||
useCSSVars: false,
|
||||
outSVGReact: false,
|
||||
outSVGPath: false,
|
||||
addLigatures: true,
|
||||
svgicons2svgfont: {
|
||||
fontHeight: 1000, // At least 1000 is recommended
|
||||
normalize: false,
|
||||
},
|
||||
generateInfoData: true,
|
||||
website: {
|
||||
title: 'Lucide',
|
||||
logo: undefined,
|
||||
meta: {
|
||||
description: 'Lucide icons as TTF/EOT/WOFF/WOFF2/SVG.',
|
||||
keywords: 'Lucide,TTF,EOT,WOFF,WOFF2,SVG',
|
||||
},
|
||||
corners: {
|
||||
url: 'https://github.com/lucide-icons/lucide',
|
||||
width: 62, // default: 60
|
||||
height: 62, // default: 60
|
||||
bgColor: '#dc3545', // default: '#151513'
|
||||
},
|
||||
links: [
|
||||
{
|
||||
title: 'GitHub',
|
||||
url: 'https://github.com/lucide-icons/lucide',
|
||||
},
|
||||
{
|
||||
title: 'Feedback',
|
||||
url: 'https://github.com/lucide-icons/lucide/issues',
|
||||
},
|
||||
{
|
||||
title: 'Font Class',
|
||||
url: 'index.html',
|
||||
},
|
||||
{
|
||||
title: 'Unicode',
|
||||
url: 'unicode.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
getIconUnicode: (name: string) => {
|
||||
if (!codePoints[name]) {
|
||||
throw new Error(`No codepoint found for icon: ${name}`);
|
||||
}
|
||||
|
||||
const unicode = codePoints[name];
|
||||
return [String.fromCharCode(unicode), startUnicode];
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
console.timeEnd('Font generation');
|
||||
}
|
||||
15
tools/build-font/src/helpers.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { type IconAliases } from "@lucide/helpers";
|
||||
import { type CodePoints } from "./allocateCodepoints.ts";
|
||||
|
||||
export function hasMissingCodePoints(iconsWithAliases: IconAliases, codePoints: CodePoints): boolean {
|
||||
return iconsWithAliases.map(([iconName, aliases]) => ([iconName, ...aliases]))
|
||||
.flat()
|
||||
.some(name => {
|
||||
if (!codePoints?.[name]) {
|
||||
console.log(`Missing code point for icon/alias: ${name}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
52
tools/build-font/src/main.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import getArgumentOptions from 'minimist';
|
||||
import path from 'path';
|
||||
import { promises as fs } from 'fs';
|
||||
|
||||
import { getAllIconAliases } from '@lucide/helpers';
|
||||
import { outlineSVG } from './outlineSVGs.ts';
|
||||
import { allocateCodePoints } from './allocateCodepoints.ts';
|
||||
import { buildFont } from './buildFont.ts';
|
||||
import { hasMissingCodePoints } from './helpers.ts';
|
||||
|
||||
const fontName = 'lucide';
|
||||
const classNamePrefix = 'icon';
|
||||
const startUnicode = 57400;
|
||||
const outputDir = 'lucide-font';
|
||||
|
||||
const {
|
||||
saveCodePoints = false,
|
||||
} = getArgumentOptions(process.argv.slice(2)) ?? {}
|
||||
|
||||
const repoRoot = path.join(process.cwd(), '../../')
|
||||
const iconsDir = path.join(repoRoot, 'icons');
|
||||
const outlinedDir = path.join(repoRoot, 'outlined');
|
||||
const targetDir = path.join(repoRoot, outputDir);
|
||||
|
||||
const iconsWithAliases = await getAllIconAliases(iconsDir)
|
||||
|
||||
await outlineSVG({
|
||||
iconsDir,
|
||||
outlinedDir,
|
||||
iconsWithAliases
|
||||
});
|
||||
|
||||
const codePoints = await allocateCodePoints({
|
||||
saveCodePoints,
|
||||
iconsWithAliases
|
||||
});
|
||||
|
||||
|
||||
if (hasMissingCodePoints(iconsWithAliases, codePoints)) {
|
||||
throw new Error('Some icons or aliases are missing code points. See log for details.');
|
||||
}
|
||||
|
||||
await buildFont({
|
||||
inputDir: outlinedDir,
|
||||
targetDir,
|
||||
fontName,
|
||||
classNamePrefix,
|
||||
codePoints,
|
||||
startUnicode,
|
||||
});
|
||||
|
||||
await fs.copyFile(path.join(process.cwd(), 'codepoints.json'), path.join(targetDir, 'codepoints.json'));
|
||||
49
tools/build-font/src/outlineSVGs.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { promises as fs } from 'fs';
|
||||
import SVGFixer from 'oslllo-svg-fixer';
|
||||
import { getAllIconAliases, type IconAliases } from '@lucide/helpers';
|
||||
import path from 'path';
|
||||
|
||||
interface OutlineSVGOptions {
|
||||
iconsDir: string;
|
||||
outlinedDir: string;
|
||||
iconsWithAliases: IconAliases
|
||||
}
|
||||
|
||||
export async function outlineSVG({
|
||||
iconsDir,
|
||||
outlinedDir,
|
||||
iconsWithAliases
|
||||
}: OutlineSVGOptions) {
|
||||
console.time('icon outliner');
|
||||
try {
|
||||
try {
|
||||
await fs.mkdir(outlinedDir);
|
||||
} catch (error) { } // eslint-disable-line no-empty
|
||||
|
||||
await SVGFixer(iconsDir, outlinedDir, {
|
||||
showProgressBar: true,
|
||||
traceResolution: 800,
|
||||
}).fix();
|
||||
|
||||
console.log('Duplicate icons with aliases..');
|
||||
|
||||
await Promise.all(iconsWithAliases.map(async ([iconName, aliases]) => {
|
||||
const sourcePath = path.join(outlinedDir, `${iconName}.svg`);
|
||||
|
||||
await Promise.all(aliases.map(async (aliasName) => {
|
||||
const destinationPath = path.join(outlinedDir, `${aliasName}.svg`);
|
||||
|
||||
try {
|
||||
await fs.copyFile(sourcePath, destinationPath);
|
||||
console.log(`Copied ${iconName}.svg to ${aliasName}.svg`);
|
||||
} catch (err) {
|
||||
console.log(`Failed to copy ${sourcePath} to ${destinationPath}:`, err);
|
||||
}
|
||||
}));
|
||||
}));
|
||||
|
||||
console.timeEnd('icon outliner');
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ export * from './src/appendFile.ts';
|
||||
export * from './src/writeFile.ts';
|
||||
export * from './src/writeFileIfNotExists.ts';
|
||||
export * from './src/readAllMetadata.ts';
|
||||
export * from './src/getAllIconAliases.ts';
|
||||
export * from './src/readMetadata.ts';
|
||||
export * from './src/readSvgDirectory.ts';
|
||||
export * from './src/readSvg.ts';
|
||||
|
||||
20
tools/build-helpers/src/getAllIconAliases.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { readAllMetadata } from "./readAllMetadata.ts";
|
||||
|
||||
export type IconAliases = [iconName: string, aliases: string[]][];
|
||||
|
||||
export const getAllIconAliases = async (iconsDir: string): Promise<IconAliases> => {
|
||||
const metaDataFiles = await readAllMetadata(iconsDir)
|
||||
|
||||
return Object.entries(metaDataFiles).map(([iconName, metadata]) => {
|
||||
const { aliases } = metadata;
|
||||
|
||||
if (!aliases?.length) return [iconName, []];
|
||||
|
||||
const aliasesNames = aliases.map(alias =>
|
||||
typeof alias === 'string' ? alias : alias.name,
|
||||
);
|
||||
|
||||
return [iconName, aliasesNames]
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { readMetadata } from './readMetadata.ts';
|
||||
import { type IconMetadata } from '../../build-icons/types.ts';
|
||||
|
||||
/**
|
||||
* Reads metadata from the icons/categories directories
|
||||
@@ -8,7 +9,7 @@ import { readMetadata } from './readMetadata.ts';
|
||||
* @param {string} directory
|
||||
* @returns {object} A map of icon or category metadata
|
||||
*/
|
||||
export const readAllMetadata = async (directory: string): Promise<Record<string, unknown>> => {
|
||||
export const readAllMetadata = async (directory: string): Promise<Record<string, IconMetadata>> => {
|
||||
const directoryContent = await fs.readdir(directory);
|
||||
|
||||
const metaDataPromises = directoryContent
|
||||
@@ -16,6 +17,7 @@ export const readAllMetadata = async (directory: string): Promise<Record<string,
|
||||
.map(async (file) => [path.basename(file, '.json'), await readMetadata(file, directory)]);
|
||||
|
||||
const metadata = await Promise.all(metaDataPromises);
|
||||
|
||||
if (metadata.length === 0) {
|
||||
throw new Error(`No metadata files found in directory: ${directory}`);
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# @lucide/outline-svg
|
||||
|
||||
A internal used package to outline SVGs.
|
||||
@@ -1,29 +0,0 @@
|
||||
import { promises as fs } from 'fs';
|
||||
import SVGFixer from 'oslllo-svg-fixer';
|
||||
import getArgumentOptions from 'minimist';
|
||||
import path from 'path';
|
||||
|
||||
const inputDir = path.join(process.cwd(), '../../icons');
|
||||
const cliArguments = getArgumentOptions(process.argv.slice(2));
|
||||
const { outputDir = 'outlined' } = cliArguments;
|
||||
const targetDir = path.join(process.cwd(), '../../', outputDir);
|
||||
|
||||
async function init() {
|
||||
console.time('icon outliner');
|
||||
try {
|
||||
try {
|
||||
await fs.mkdir(targetDir);
|
||||
} catch (error) {} // eslint-disable-line no-empty
|
||||
|
||||
await SVGFixer(inputDir, targetDir, {
|
||||
showProgressBar: true,
|
||||
traceResolution: 800,
|
||||
}).fix();
|
||||
|
||||
console.timeEnd('icon outliner');
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "@lucide/outline-svg",
|
||||
"description": "A internal used package to outline SVGs.",
|
||||
"private": true,
|
||||
"version": "2.0.0",
|
||||
"main": "main.ts",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node ./main.ts"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.8",
|
||||
"oslllo-svg-fixer": "^5.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"declaration": true,
|
||||
"noEmitOnError": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"moduleResolution": "node",
|
||||
"module": "ESNext",
|
||||
"target": "ESNext",
|
||||
"esModuleInterop": true,
|
||||
"lib": ["esnext"],
|
||||
"resolveJsonModule": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"noEmit": true,
|
||||
"sourceMap": true,
|
||||
"outDir": "./dist",
|
||||
},
|
||||
}
|
||||