Compare commits
98 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
494f7953c8 | ||
|
|
a5ea3a5368 | ||
|
|
6486f76c55 | ||
|
|
e32db96f1f | ||
|
|
73f70c885a | ||
|
|
14c7ea8e13 | ||
|
|
9fc7653dc1 | ||
|
|
2b007e7962 | ||
|
|
bb1e470f3a | ||
|
|
4a1e6bbfa5 | ||
|
|
e5ee997566 | ||
|
|
27c0a136cd | ||
|
|
84b3c46b65 | ||
|
|
1a09e7fb39 | ||
|
|
75e9724072 | ||
|
|
fbaccc7d9f | ||
|
|
c24bc4d7ef | ||
|
|
5c8c8f4362 | ||
|
|
ffd2a62941 | ||
|
|
e77959e1a6 | ||
|
|
149ee36e61 | ||
|
|
88bf60b5d7 | ||
|
|
1e5df716a4 | ||
|
|
fc0ea760e5 | ||
|
|
c85275899a | ||
|
|
288edde1ea | ||
|
|
207ff6c487 | ||
|
|
a1a9a4d839 | ||
|
|
c5804ad9a5 | ||
|
|
c72fb4a28b | ||
|
|
da5ad547b5 | ||
|
|
66cfe527b3 | ||
|
|
d1866225ba | ||
|
|
372735999f | ||
|
|
f3a33346dd | ||
|
|
3373acf596 | ||
|
|
73d5bfc318 | ||
|
|
ddbc074aa3 | ||
|
|
8f4d6b1651 | ||
|
|
d8b08f8fda | ||
|
|
fddacb6260 | ||
|
|
3d0c8691c9 | ||
|
|
47998b05aa | ||
|
|
9a9e051343 | ||
|
|
6c6c8448fa | ||
|
|
49445aad3a | ||
|
|
70656eb4f0 | ||
|
|
930f862547 | ||
|
|
931b7f5376 | ||
|
|
81e44bdc40 | ||
|
|
e6e90944b9 | ||
|
|
f6fd369bfe | ||
|
|
bbf183fe48 | ||
|
|
4f5642b872 | ||
|
|
1dce6a141a | ||
|
|
dbfce919fc | ||
|
|
52adb78df8 | ||
|
|
c5cfbed28c | ||
|
|
1e4fd13852 | ||
|
|
0a0fd1cf6c | ||
|
|
487d03fc4d | ||
|
|
950160ad5a | ||
|
|
b6f5898aee | ||
|
|
a9c1dca801 | ||
|
|
c05c7e333f | ||
|
|
dff42fe326 | ||
|
|
c1f642e20f | ||
|
|
cf9565b69c | ||
|
|
4cc4468d2f | ||
|
|
fd9ab8f17a | ||
|
|
c9101f0f39 | ||
|
|
614ef1a1d5 | ||
|
|
1a441812ac | ||
|
|
4a33e90c65 | ||
|
|
062a64a078 | ||
|
|
95a1ea7255 | ||
|
|
a0a5bc8fc2 | ||
|
|
698eded89b | ||
|
|
a70b713572 | ||
|
|
34530ad805 | ||
|
|
f73aed151a | ||
|
|
2bd7748562 | ||
|
|
da8a6c5a1b | ||
|
|
5736028dfa | ||
|
|
45d2063340 | ||
|
|
f71d3ffd1d | ||
|
|
b8c3a5fa0b | ||
|
|
a4076db69b | ||
|
|
55cb681461 | ||
|
|
09d9bb747d | ||
|
|
42f9cdceca | ||
|
|
c652723b32 | ||
|
|
a44328d8be | ||
|
|
376568239f | ||
|
|
92d05b5fca | ||
|
|
27b5b7eaad | ||
|
|
4de1355e54 | ||
|
|
c8d94bf3e1 |
@@ -4,3 +4,7 @@ coverage
|
||||
lib
|
||||
tests
|
||||
node_modules
|
||||
.eslintrc.js
|
||||
docs/images
|
||||
docs/guide/basics/examples
|
||||
packages/lucide-react/dynamicIconImports.js
|
||||
|
||||
41
.eslintrc.js
@@ -1,10 +1,13 @@
|
||||
const DEFAULT_ATTRS = require('./scripts/render/default-attrs.json');
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
extends: ['airbnb-base', 'prettier'],
|
||||
plugins: ['import', 'prettier'],
|
||||
plugins: ['import', 'prettier', '@html-eslint'],
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
'no-param-reassign': 'off',
|
||||
@@ -15,6 +18,7 @@ module.exports = {
|
||||
{
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
printWidth: 100
|
||||
},
|
||||
],
|
||||
'import/no-extraneous-dependencies': [
|
||||
@@ -37,4 +41,39 @@ module.exports = {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['./icons/*.svg'],
|
||||
parser: '@html-eslint/parser',
|
||||
rules: {
|
||||
'prettier/prettier': 'off',
|
||||
'@html-eslint/require-doctype': 'off',
|
||||
'@html-eslint/no-duplicate-attrs': 'error',
|
||||
'@html-eslint/no-inline-styles': 'error',
|
||||
'@html-eslint/require-attrs': [
|
||||
'error',
|
||||
...Object.entries(DEFAULT_ATTRS)
|
||||
.map(([attr, value]) => ({ tag: 'svg', attr, value: String(value) }))
|
||||
],
|
||||
'@html-eslint/indent': ['error', 2],
|
||||
"@html-eslint/no-multiple-empty-lines": ["error", { "max": 0 }],
|
||||
'@html-eslint/no-extra-spacing-attrs': [
|
||||
'error',
|
||||
{
|
||||
enforceBeforeSelfClose: true,
|
||||
},
|
||||
],
|
||||
'@html-eslint/require-closing-tags': [
|
||||
'error',
|
||||
{
|
||||
selfClosing: 'always',
|
||||
allowSelfClosingCustom: true,
|
||||
},
|
||||
],
|
||||
'@html-eslint/element-newline': 'error',
|
||||
'@html-eslint/no-trailing-spaces': 'error',
|
||||
'@html-eslint/quotes': 'error',
|
||||
}
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
31
.github/workflows/ci.yml
vendored
@@ -16,32 +16,16 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Fetch tags
|
||||
run: git fetch --all --tags
|
||||
@@ -50,9 +34,6 @@ jobs:
|
||||
id: latest-tag
|
||||
run: echo "LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Check if we can patch
|
||||
run: .github/workflows/version-up.sh --minor
|
||||
|
||||
|
||||
25
.github/workflows/linting.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: Linting
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- icons/**
|
||||
|
||||
jobs:
|
||||
linting:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Run Linter
|
||||
run: pnpm lint
|
||||
28
.github/workflows/lucide-angular.yml
vendored
@@ -12,32 +12,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter lucide-angular build
|
||||
|
||||
36
.github/workflows/lucide-font.yml
vendored
@@ -10,44 +10,24 @@ on:
|
||||
jobs:
|
||||
lucide-font:
|
||||
runs-on: ubuntu-latest
|
||||
container: ericfennis/lucide-font:latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3.4.1
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --filter outline-svg
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Outline svg Icons
|
||||
run: pnpm build:outline-icons
|
||||
|
||||
- name: Create directory
|
||||
run: mkdir lucide-font
|
||||
|
||||
- name: Build font
|
||||
run: fontcustom compile "./outlined" -h -n "lucide" -o ./lucide-font -F
|
||||
- name: Create font in ./lucide-font
|
||||
run: pnpm build:font
|
||||
|
||||
- name: "Upload to Artifacts"
|
||||
uses: actions/upload-artifact@v1
|
||||
|
||||
29
.github/workflows/lucide-preact.yml
vendored
@@ -5,6 +5,7 @@ on:
|
||||
paths:
|
||||
- packages/lucide-preact/**
|
||||
- tools/build-icons/**
|
||||
- tools/rollup-plugins/**
|
||||
- pnpm-lock.yaml
|
||||
|
||||
jobs:
|
||||
@@ -12,32 +13,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter lucide-preact build
|
||||
|
||||
29
.github/workflows/lucide-react-native.yml
vendored
@@ -5,6 +5,7 @@ on:
|
||||
paths:
|
||||
- packages/lucide-react-native/**
|
||||
- tools/build-icons/**
|
||||
- tools/rollup-plugins/**
|
||||
- pnpm-lock.yaml
|
||||
|
||||
jobs:
|
||||
@@ -12,32 +13,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter lucide-react-native build
|
||||
|
||||
30
.github/workflows/lucide-react.yml
vendored
@@ -5,6 +5,8 @@ on:
|
||||
paths:
|
||||
- packages/lucide-react/**
|
||||
- tools/build-icons/**
|
||||
- tools/rollup-plugins/**
|
||||
- scripts/generateNextJSAliases.mjs
|
||||
- pnpm-lock.yaml
|
||||
|
||||
jobs:
|
||||
@@ -12,32 +14,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter lucide-react build
|
||||
|
||||
29
.github/workflows/lucide-solid.yml
vendored
@@ -5,6 +5,7 @@ on:
|
||||
paths:
|
||||
- packages/lucide-solid/**
|
||||
- tools/build-icons/**
|
||||
- tools/rollup-plugins/**
|
||||
- pnpm-lock.yaml
|
||||
|
||||
jobs:
|
||||
@@ -12,32 +13,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter lucide-solid build
|
||||
|
||||
28
.github/workflows/lucide-static.yml
vendored
@@ -12,32 +12,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter lucide-static build
|
||||
|
||||
29
.github/workflows/lucide-svelte.yml
vendored
@@ -5,6 +5,7 @@ on:
|
||||
paths:
|
||||
- packages/lucide-svelte/**
|
||||
- tools/build-icons/**
|
||||
- tools/rollup-plugins/**
|
||||
- pnpm-lock.yaml
|
||||
|
||||
jobs:
|
||||
@@ -12,32 +13,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter lucide-svelte build
|
||||
|
||||
29
.github/workflows/lucide-vue-next.yml
vendored
@@ -5,6 +5,7 @@ on:
|
||||
paths:
|
||||
- packages/lucide-vue-next/**
|
||||
- tools/build-icons/**
|
||||
- tools/rollup-plugins/**
|
||||
- pnpm-lock.yaml
|
||||
|
||||
jobs:
|
||||
@@ -12,32 +13,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter lucide-vue-next build
|
||||
|
||||
29
.github/workflows/lucide-vue.yml
vendored
@@ -5,6 +5,7 @@ on:
|
||||
paths:
|
||||
- packages/lucide-vue/**
|
||||
- tools/build-icons/**
|
||||
- tools/rollup-plugins/**
|
||||
- pnpm-lock.yaml
|
||||
|
||||
jobs:
|
||||
@@ -12,32 +13,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter lucide-vue build
|
||||
|
||||
29
.github/workflows/lucide.yml
vendored
@@ -5,6 +5,7 @@ on:
|
||||
paths:
|
||||
- packages/lucide/**
|
||||
- tools/build-icons/**
|
||||
- tools/rollup-plugins/**
|
||||
- pnpm-lock.yaml
|
||||
|
||||
jobs:
|
||||
@@ -12,32 +13,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter lucide build
|
||||
|
||||
76
.github/workflows/pull-request.yml
vendored
@@ -5,13 +5,53 @@ on:
|
||||
paths:
|
||||
- 'icons/*.svg'
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
add-changed-icons-comment:
|
||||
lint-contributors:
|
||||
if: github.repository == 'lucide-icons/lucide'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v35
|
||||
with:
|
||||
files: icons/*
|
||||
- uses: actions/setup-node@v3.8.1
|
||||
- name: Install simple-git (safer and faster than installing all deps)
|
||||
run: npm install simple-git
|
||||
- env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
FETCH_DEPTH: ${{ github.event.pull_request.commits }}
|
||||
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||
run: node ./scripts/updateContributors.mjs
|
||||
- name: Generate annotations
|
||||
env:
|
||||
ANNOTATION_SEVERITY: notice
|
||||
ANNOTATION_TITLE: Contributors have changed!
|
||||
ANNOTATION_DESCRIPTION: Don't add people who have only performed automatic optimizations.
|
||||
run: |
|
||||
git diff --unified=0 -- icons/*.json | # diff icon metadata (unified=0 gives the correct chunk line number)
|
||||
perl -ne '/^(\+|- |@)/ && print' | # get chunks (lines that start with "+++", "@@", "+ ", "- ")
|
||||
perl -pe 's/\n/%0A/' | # url encode line breaks (\n -> %0A)
|
||||
perl -pe 's/%0A(\+\+\+ b\/)/\n\1/g' | # split chunks(one chunk per line)
|
||||
perl -pe "s/\+\+\+ b\/([^@]*)%0A@@ -(\d+)[^\s]* \+(\d+)[^@]*@@(.*)/::$ANNOTATION_SEVERITY file=\1,line=\2,endLine=\3,title=$ANNOTATION_TITLE::$ANNOTATION_DESCRIPTION%0A\4/"
|
||||
# Example for the previous substitution
|
||||
# input: +++ b/icons/accessibility.json%0A@@ -2,0 +3 @@%0A+ "contributors": ["hi"],%0A@@ -13 +14 @@%0A+}%0A
|
||||
# output: ::$ANNOTATION_SEVERITY file=icons/accessibility.json,line=2,endLine=3,title=$ANNOTATION_TITLE::$ANNOTATION_DESCRIPTION%0A%0A+ "contributors": ["hi"],%0A@@ -13 +14 @@%0A+}%0A
|
||||
# - name: Fail if contributors have changed
|
||||
# run: git diff --exit-code -- icons/*.json
|
||||
|
||||
add-changed-icons-comment:
|
||||
if: github.repository == 'lucide-icons/lucide'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -24,16 +64,18 @@ jobs:
|
||||
files: icons/*.svg
|
||||
- name: Generate 24px dpi preview
|
||||
id: generate-24px-dpi-preview
|
||||
env:
|
||||
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||
run: |
|
||||
delimiter="$(openssl rand -hex 8)"
|
||||
echo "body<<$delimiter" >> $GITHUB_OUTPUT
|
||||
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
|
||||
while IFS= read -r file; do
|
||||
cat "$file" | # get file content
|
||||
tr '\n' ' ' | # remove line breaks
|
||||
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
|
||||
base64 -w 0 | # encode svg
|
||||
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/dpi/24/&.svg\"/> |"
|
||||
done | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
echo >> $GITHUB_OUTPUT
|
||||
echo "$delimiter" >> $GITHUB_OUTPUT
|
||||
- name: Generate cohesion check random
|
||||
@@ -47,7 +89,7 @@ jobs:
|
||||
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
|
||||
base64 -w 0 | # encode svg
|
||||
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/2/&.svg\"/> |"
|
||||
done | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
echo >> $GITHUB_OUTPUT
|
||||
echo "$delimiter" >> $GITHUB_OUTPUT
|
||||
- name: Generate cohesion check squares
|
||||
@@ -61,7 +103,7 @@ jobs:
|
||||
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
|
||||
base64 -w 0 | # encode svg
|
||||
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/2/&.svg\"/> |"
|
||||
done | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
echo >> $GITHUB_OUTPUT
|
||||
echo "$delimiter" >> $GITHUB_OUTPUT
|
||||
- name: Generate 1px stroke-width
|
||||
@@ -69,13 +111,13 @@ jobs:
|
||||
run: |
|
||||
delimiter="$(openssl rand -hex 8)"
|
||||
echo "body<<$delimiter" >> $GITHUB_OUTPUT
|
||||
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
|
||||
while IFS= read -r file; do
|
||||
cat "$file" | # get file content
|
||||
tr '\n' ' ' | # remove line breaks
|
||||
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
|
||||
base64 -w 0 | # encode svg
|
||||
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/1/&.svg\"/> |"
|
||||
done | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
echo >> $GITHUB_OUTPUT
|
||||
echo "$delimiter" >> $GITHUB_OUTPUT
|
||||
- name: Generate 2px stroke-width
|
||||
@@ -83,13 +125,13 @@ jobs:
|
||||
run: |
|
||||
delimiter="$(openssl rand -hex 8)"
|
||||
echo "body<<$delimiter" >> $GITHUB_OUTPUT
|
||||
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
|
||||
while IFS= read -r file; do
|
||||
cat "$file" | # get file content
|
||||
tr '\n' ' ' | # remove line breaks
|
||||
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
|
||||
base64 -w 0 | # encode svg
|
||||
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/2/&.svg\"/> |"
|
||||
done | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
echo >> $GITHUB_OUTPUT
|
||||
echo "$delimiter" >> $GITHUB_OUTPUT
|
||||
- name: Generate 3px stroke-width
|
||||
@@ -97,13 +139,13 @@ jobs:
|
||||
run: |
|
||||
delimiter="$(openssl rand -hex 8)"
|
||||
echo "body<<$delimiter" >> $GITHUB_OUTPUT
|
||||
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
|
||||
while IFS= read -r file; do
|
||||
cat "$file" | # get file content
|
||||
tr '\n' ' ' | # remove line breaks
|
||||
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
|
||||
base64 -w 0 | # encode svg
|
||||
sed "s|.*|<img title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/stroke-width/3/&.svg\"/> |"
|
||||
done | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
echo >> $GITHUB_OUTPUT
|
||||
echo "$delimiter" >> $GITHUB_OUTPUT
|
||||
- name: Generate X-rays
|
||||
@@ -111,13 +153,13 @@ jobs:
|
||||
run: |
|
||||
delimiter="$(openssl rand -hex 8)"
|
||||
echo "body<<$delimiter" >> $GITHUB_OUTPUT
|
||||
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
|
||||
while IFS= read -r file; do
|
||||
cat "$file" | # get file content
|
||||
tr '\n' ' ' | # remove line breaks
|
||||
sed -e 's/<svg[^>]*>/<svg>/g' | # remove attributes from svg element
|
||||
base64 -w 0 | # encode svg
|
||||
sed "s|.*|<img width=\"400\" title=\"$file\" alt=\"$file\" src=\"https://lucide.dev/api/gh-icon/$(basename ${file//\.svg/})/&.svg\"/> |"
|
||||
done | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
done <<< "$CHANGED_FILES" | tr '\n' ' ' >> $GITHUB_OUTPUT
|
||||
echo >> $GITHUB_OUTPUT
|
||||
echo "$delimiter" >> $GITHUB_OUTPUT
|
||||
- name: Find Comment
|
||||
|
||||
88
.github/workflows/release.yml
vendored
@@ -39,6 +39,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: pre-release
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
package: [
|
||||
'lucide',
|
||||
@@ -53,29 +54,13 @@ jobs:
|
||||
]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
@@ -102,30 +87,13 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/download-artifact@v2
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
@@ -149,44 +117,24 @@ jobs:
|
||||
if: github.repository == 'lucide-icons/lucide'
|
||||
runs-on: ubuntu-latest
|
||||
needs: pre-release
|
||||
container: ericfennis/lucide-font:latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3.4.1
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
node-version: 18
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --filter outline-svg
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Outline svg Icons
|
||||
run: pnpm build:outline-icons
|
||||
|
||||
- name: Create directory
|
||||
run: mkdir lucide-font
|
||||
|
||||
- name: Build font
|
||||
run: fontcustom compile "./outlined" -h -n "lucide" -o ./lucide-font -F
|
||||
- name: Create font in ./lucide-font
|
||||
run: pnpm build:font
|
||||
|
||||
- name: "Upload to Artifacts"
|
||||
uses: actions/upload-artifact@v1
|
||||
|
||||
8
.vscode/settings.json
vendored
@@ -3,5 +3,11 @@
|
||||
"devs",
|
||||
"preact",
|
||||
"Preact"
|
||||
]
|
||||
],
|
||||
"eslint.enable": true,
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"svg"
|
||||
],
|
||||
"svg.preview.background": "transparent"
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ Here you can find instructions on how to implement the guidelines with different
|
||||
|
||||
#### [Adobe Illustrator Guide](https://lucide.dev/docs/illustrator-guide)
|
||||
|
||||
You can also [download an Adobe Illustrator template](https://lucide.dev/templates/illustrator-template.ai).
|
||||
You can also [download an Adobe Illustrator template](https://github.com/lucide-icons/lucide/blob/main/docs/public/templates/illustrator_template.ai).
|
||||
|
||||
#### [Inkscape Guide](https://lucide.dev/docs/inkscape-guide)
|
||||
|
||||
|
||||
18
README.md
@@ -18,7 +18,7 @@ Lucide is trying to expand the icon set as much as possible while staying faithf
|
||||
### Why choose Lucide over Feather Icons
|
||||
|
||||
- More icons to work with: Lucide already has hundreds of icons more than Feather does.
|
||||
- Official librairies and integrations with popular frameworks and design tools.
|
||||
- Official libraries and integrations with popular frameworks and design tools.
|
||||
- Well maintained code base.
|
||||
- Active community, regularly growing and improving the set.
|
||||
|
||||
@@ -35,7 +35,6 @@ Lucide is trying to expand the icon set as much as possible while staying faithf
|
||||
- [Static (svg sprite, font, icons ..)](#static-svg-sprite-font-icons-)
|
||||
- [Figma](#figma)
|
||||
- [Laravel](#laravel)
|
||||
- [Flutter](#flutter)
|
||||
- [Svelte](#svelte)
|
||||
- [Solid](#solid)
|
||||
- [Hyva](#hyva)
|
||||
@@ -200,16 +199,6 @@ composer require mallardduck/blade-lucide-icons
|
||||
|
||||
For more details, see the [documentation](https://github.com/mallardduck/blade-lucide-icons/blob/main/README.md).
|
||||
|
||||
### Flutter
|
||||
|
||||
Implementation of Lucide icon library for Flutter applications.
|
||||
|
||||
```sh
|
||||
flutter pub add lucide_icons
|
||||
```
|
||||
|
||||
For more details, see the [pub.dev](https://pub.dev/packages/lucide_icons).
|
||||
|
||||
### Svelte
|
||||
|
||||
Implementation of the lucide icon library for Svelte applications.
|
||||
@@ -285,6 +274,9 @@ Thank you to all the people who contributed to Lucide!
|
||||
|
||||
## Sponsors
|
||||
|
||||
|
||||
<a href="https://vercel.com?utm_source=lucide&utm_campaign=oss">
|
||||
<img src="/docs/public/vercel.svg" alt="Powered by Vercel" width="200" />
|
||||
<img src="docs/public/vercel.svg" alt="Powered by Vercel" width="200" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.digitalocean.com/?refcode=b0877a2caebd&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge"><img src="docs/public/digitalocean.svg" width="200" alt="DigitalOcean Referral Badge" /></a>
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
},
|
||||
"title": "Lucide Icons category schema",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["$schema", "icon", "title"],
|
||||
"properties": {
|
||||
"title": {
|
||||
"$schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
@@ -22,13 +24,12 @@
|
||||
"icon": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"weight": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"title",
|
||||
"icon"
|
||||
],
|
||||
"description": "A JSON Schema for categories defined by Lucide Icons."
|
||||
}
|
||||
|
||||
@@ -1,41 +1,53 @@
|
||||
import { eventHandler, setResponseHeader, defaultContentType } from 'h3'
|
||||
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
|
||||
import { createElement } from 'react'
|
||||
import { eventHandler, setResponseHeader, defaultContentType } from 'h3';
|
||||
import { renderToString, renderToStaticMarkup } from 'react-dom/server';
|
||||
import { createElement } from 'react';
|
||||
import SvgPreview from '../../lib/SvgPreview/index.tsx';
|
||||
import iconNodes from '../../data/iconNodes'
|
||||
import createLucideIcon from 'lucide-react/src/createLucideIcon'
|
||||
import iconNodes from '../../data/iconNodes';
|
||||
import createLucideIcon from 'lucide-react/src/createLucideIcon';
|
||||
import Backdrop from '../../lib/SvgPreview/Backdrop.tsx';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
const { params } = event.context
|
||||
const { params } = event.context;
|
||||
|
||||
const [name, svgData] = params.data.split('/');
|
||||
const data = svgData.slice(0, -4);
|
||||
const pathData = params.data.split('/');
|
||||
const data = pathData.at(-1).slice(0, -4);
|
||||
const [name] = pathData;
|
||||
|
||||
const src = Buffer.from(data, 'base64').toString('utf8');
|
||||
|
||||
const children = []
|
||||
const children = [];
|
||||
|
||||
if (name in iconNodes) {
|
||||
const iconNode = iconNodes[name]
|
||||
// Finds the longest matching icon to be use as the backdrop.
|
||||
// For `square-dashed-bottom-code` it suggests `square-dashed-bottom-code`.
|
||||
// For `square-dashed-bottom-i-dont-exist` it suggests `square-dashed-bottom`.
|
||||
const backdropName = name
|
||||
.split('-')
|
||||
.map((_, idx, arr) => arr.slice(0, idx + 1).join('-'))
|
||||
.reverse()
|
||||
.find((groupName) => groupName in iconNodes);
|
||||
if (backdropName) {
|
||||
const iconNode = iconNodes[backdropName];
|
||||
|
||||
const LucideIcon = createLucideIcon(name, iconNode)
|
||||
const svg = renderToStaticMarkup(createElement(LucideIcon))
|
||||
const LucideIcon = createLucideIcon(backdropName, iconNode);
|
||||
const svg = renderToStaticMarkup(createElement(LucideIcon));
|
||||
const backdropString = svg.replace(/<svg[^>]*>|<\/svg>/g, '');
|
||||
|
||||
children.push(createElement(Backdrop, { backdropString, src }))
|
||||
children.push(
|
||||
createElement(Backdrop, {
|
||||
backdropString,
|
||||
src,
|
||||
color: name in iconNodes ? 'red' : '#777',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const svg = Buffer.from(
|
||||
// We can't use jsx here, is not supported here by nitro.
|
||||
renderToString(createElement(SvgPreview, {src, showGrid: true}, children)).replace(
|
||||
/>/,
|
||||
'><style>@media screen and (prefers-color-scheme: dark) { svg { stroke: #fff } }</style>'
|
||||
)
|
||||
renderToString(createElement(SvgPreview, { src, showGrid: true }, children))
|
||||
).toString('utf8');
|
||||
|
||||
defaultContentType(event, 'image/svg+xml')
|
||||
setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000')
|
||||
defaultContentType(event, 'image/svg+xml');
|
||||
setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000');
|
||||
|
||||
return svg
|
||||
})
|
||||
return svg;
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@ export default defineConfig({
|
||||
description,
|
||||
cleanUrls: true,
|
||||
outDir: '.vercel/output/static',
|
||||
srcExclude: ['**/README.md'],
|
||||
vite: {
|
||||
resolve: {
|
||||
alias: [
|
||||
@@ -103,6 +104,7 @@ export default defineConfig({
|
||||
{ text: 'Icons', link: '/icons/' },
|
||||
{ text: 'Guide', link: '/guide/' },
|
||||
{ text: 'Packages', link: '/packages' },
|
||||
{ text: 'Showcase', link: '/showcase' },
|
||||
{ text: 'License', link: '/license' },
|
||||
],
|
||||
sidebar,
|
||||
@@ -117,6 +119,10 @@ export default defineConfig({
|
||||
editLink: {
|
||||
pattern: 'https://github.com/lucide-icons/lucide/edit/main/docs/:path'
|
||||
},
|
||||
carbonAds: {
|
||||
code: 'CWYIC53U',
|
||||
placement: 'lucidedev'
|
||||
}
|
||||
},
|
||||
sitemap: {
|
||||
hostname: 'https://lucide.dev/'
|
||||
|
||||
50
docs/.vitepress/data/companiesData.json
Normal file
@@ -0,0 +1,50 @@
|
||||
[
|
||||
{
|
||||
"name": "Vercel",
|
||||
"url": "https://vercel.com",
|
||||
"image": {
|
||||
"light": "/company-logos/vercel-light.svg",
|
||||
"dark": "/company-logos/vercel-dark.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Supabase",
|
||||
"url": "https://supabase.com",
|
||||
"image": {
|
||||
"light": "/company-logos/supabase-light.svg",
|
||||
"dark": "/company-logos/supabase-dark.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Obsidian",
|
||||
"url": "https://obsidian.md",
|
||||
"image": {
|
||||
"light": "/company-logos/obsidian-light.svg",
|
||||
"dark": "/company-logos/obsidian-dark.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Open Collective",
|
||||
"url": "https://opencollective.com",
|
||||
"image": {
|
||||
"light": "/company-logos/open-collective-light.svg",
|
||||
"dark": "/company-logos/open-collective-dark.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Super",
|
||||
"url": "https://super.so",
|
||||
"image": {
|
||||
"light": "/company-logos/super-light.svg",
|
||||
"dark": "/company-logos/super-dark.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Noodle",
|
||||
"url": "https://noodle.run/",
|
||||
"image": {
|
||||
"light": "/company-logos/noodle-light.svg",
|
||||
"dark": "/company-logos/noodle-dark.svg"
|
||||
}
|
||||
}
|
||||
]
|
||||
18
docs/.vitepress/data/componentLibrariesData.json
Normal file
@@ -0,0 +1,18 @@
|
||||
[
|
||||
{
|
||||
"name": "Shadcn/ui",
|
||||
"url": "https://ui.shadcn.com/",
|
||||
"image": {
|
||||
"light": "/library-logos/shadcn-ui-light.svg",
|
||||
"dark": "/library-logos/shadcn-ui-dark.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Tamagui",
|
||||
"url": "https://tamagui.dev/",
|
||||
"image": {
|
||||
"light": "/library-logos/tamagui.svg",
|
||||
"dark": "/library-logos/tamagui.svg"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1,11 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
interface BackdropProps {
|
||||
src: string
|
||||
backdropString: string
|
||||
src: string;
|
||||
color?: string;
|
||||
backdropString: string;
|
||||
}
|
||||
|
||||
const Backdrop = ({ src, backdropString }: BackdropProps): JSX.Element => {
|
||||
const Backdrop = ({ src, color = 'red', backdropString }: BackdropProps): JSX.Element => {
|
||||
return (
|
||||
<>
|
||||
<defs xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -16,8 +17,8 @@ const Backdrop = ({ src, backdropString }: BackdropProps): JSX.Element => {
|
||||
patternUnits="userSpaceOnUse"
|
||||
patternTransform="rotate(45 50 50)"
|
||||
>
|
||||
<line stroke="red" strokeWidth={0.1} y2={1} />
|
||||
<line stroke="red" strokeWidth={0.1} y2={1} />
|
||||
<line stroke={color} strokeWidth={0.1} y2={1} />
|
||||
<line stroke={color} strokeWidth={0.1} y2={1} />
|
||||
</pattern>
|
||||
</defs>
|
||||
<mask id="svg-preview-backdrop-mask-outline" maskUnits="userSpaceOnUse">
|
||||
@@ -29,20 +30,8 @@ const Backdrop = ({ src, backdropString }: BackdropProps): JSX.Element => {
|
||||
<g dangerouslySetInnerHTML={{ __html: src }} strokeWidth={2.05} />
|
||||
<g strokeWidth={1.75} dangerouslySetInnerHTML={{ __html: backdropString }} />
|
||||
</mask>
|
||||
<g
|
||||
strokeWidth={2.25}
|
||||
stroke="url(#pattern)"
|
||||
mask={'url(#svg-preview-backdrop-mask-outline)'}
|
||||
>
|
||||
<rect
|
||||
x="0"
|
||||
y="0"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="url(#pattern)"
|
||||
opacity={0.5}
|
||||
stroke="none"
|
||||
/>
|
||||
<g strokeWidth={2.25} stroke="url(#pattern)" mask={'url(#svg-preview-backdrop-mask-outline)'}>
|
||||
<rect x="0" y="0" width="24" height="24" fill="url(#pattern)" opacity={0.5} stroke="none" />
|
||||
</g>
|
||||
<rect
|
||||
x="0"
|
||||
@@ -58,14 +47,13 @@ const Backdrop = ({ src, backdropString }: BackdropProps): JSX.Element => {
|
||||
y="0"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="red"
|
||||
fill={color}
|
||||
opacity={0.5}
|
||||
stroke="none"
|
||||
mask={'url(#svg-preview-backdrop-mask-fill)'}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
export default Backdrop;
|
||||
|
||||
@@ -199,6 +199,28 @@ const Radii = ({
|
||||
);
|
||||
};
|
||||
|
||||
const Handles = ({
|
||||
paths,
|
||||
...props
|
||||
}: { paths: Path[] } & PathProps<
|
||||
'strokeWidth' | 'stroke' | 'strokeDasharray' | 'strokeOpacity',
|
||||
any
|
||||
>) => {
|
||||
console.log(paths);
|
||||
return (
|
||||
<g className="svg-preview-handles-group" {...props}>
|
||||
{paths.map(({ c, prev, next, cp1, cp2 }) => (
|
||||
<>
|
||||
{cp1 && <path d={`M${prev.x} ${prev.y} ${cp1.x} ${cp1.y}`} />}
|
||||
{cp1 && <circle cy={cp1.y} cx={cp1.x} r={0.25} />}
|
||||
{cp2 && <path d={`M${next.x} ${next.y} ${cp2.x} ${cp2.y}`} />}
|
||||
{cp2 && <circle cy={cp2.y} cx={cp2.x} r={0.25} />}
|
||||
</>
|
||||
))}
|
||||
</g>
|
||||
);
|
||||
};
|
||||
|
||||
const SvgPreview = React.forwardRef<
|
||||
SVGSVGElement,
|
||||
{
|
||||
@@ -238,6 +260,7 @@ const SvgPreview = React.forwardRef<
|
||||
<style>{darkModeCss}</style>
|
||||
{showGrid && <Grid strokeWidth={0.1} stroke="#777" strokeOpacity={0.3} radius={1} />}
|
||||
<Shadow paths={paths} strokeWidth={4} stroke="#777" radius={1} strokeOpacity={0.15} />
|
||||
<Handles paths={paths} strokeWidth={0.12} stroke="#777" strokeOpacity={0.6} />
|
||||
<ColoredPath
|
||||
paths={paths}
|
||||
colors={[
|
||||
@@ -263,6 +286,7 @@ const SvgPreview = React.forwardRef<
|
||||
strokeOpacity={0.3}
|
||||
/>
|
||||
<ControlPath radius={1} paths={paths} pointSize={1} stroke="#fff" strokeWidth={0.125} />
|
||||
<Handles paths={paths} strokeWidth={0.12} stroke="#FFF" strokeOpacity={0.3} />
|
||||
{children}
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -8,7 +8,9 @@ export type Path = {
|
||||
prev: Point;
|
||||
next: Point;
|
||||
isStart: boolean;
|
||||
circle: { x: number; y: number; r: number };
|
||||
circle?: { x: number; y: number; r: number };
|
||||
cp1?: Point;
|
||||
cp2?: Point;
|
||||
c: ReturnType<typeof getCommands>[number];
|
||||
};
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ export const getPaths = (src: string) => {
|
||||
c: typeof commands[number],
|
||||
next: Point,
|
||||
d?: string,
|
||||
circle?: Path['circle']
|
||||
extras?: { circle?: Path['circle']; cp1?: Path['cp1']; cp2?: Path['cp2'] }
|
||||
) => {
|
||||
assert(prev);
|
||||
paths.push({
|
||||
@@ -71,7 +71,7 @@ export const getPaths = (src: string) => {
|
||||
d: d || `M ${prev.x} ${prev.y} L ${next.x} ${next.y}`,
|
||||
prev,
|
||||
next,
|
||||
circle,
|
||||
...extras,
|
||||
isStart: start === prev,
|
||||
});
|
||||
prev = next;
|
||||
@@ -110,7 +110,10 @@ export const getPaths = (src: string) => {
|
||||
}
|
||||
case SVGPathData.CURVE_TO: {
|
||||
assert(prev);
|
||||
addPath(c, c, `M ${prev.x} ${prev.y} ${encodeSVGPath(c)}`);
|
||||
addPath(c, c, `M ${prev.x} ${prev.y} ${encodeSVGPath(c)}`, {
|
||||
cp1: { x: c.x1, y: c.y1 },
|
||||
cp2: { x: c.x2, y: c.y2 },
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SVGPathData.SMOOTH_CURVE_TO: {
|
||||
@@ -146,13 +149,20 @@ export const getPaths = (src: string) => {
|
||||
y1: prev.y - reflectedCp1.y,
|
||||
x2: c.x2,
|
||||
y2: c.y2,
|
||||
})}`
|
||||
})}`,
|
||||
{
|
||||
cp1: reflectedCp1,
|
||||
cp2: { x: c.x2, y: c.y2 },
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
case SVGPathData.QUAD_TO: {
|
||||
assert(prev);
|
||||
addPath(c, c, `M ${prev.x} ${prev.y} ${encodeSVGPath(c)}`);
|
||||
addPath(c, c, `M ${prev.x} ${prev.y} ${encodeSVGPath(c)}`, {
|
||||
cp1: { x: c.x1, y: c.y1 },
|
||||
cp2: { x: c.x1, y: c.y1 },
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SVGPathData.SMOOTH_QUAD_TO: {
|
||||
@@ -197,7 +207,11 @@ export const getPaths = (src: string) => {
|
||||
y: c.y,
|
||||
x1: prevCP.x,
|
||||
y1: prevCP.y,
|
||||
})}`
|
||||
})}`,
|
||||
{
|
||||
cp1: { x: prevCP.x, y: prevCP.y },
|
||||
cp2: { x: prevCP.x, y: prevCP.y },
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -218,7 +232,7 @@ export const getPaths = (src: string) => {
|
||||
c,
|
||||
c,
|
||||
`M ${prev.x} ${prev.y} A${c.rX} ${c.rY} ${c.xRot} ${c.lArcFlag} ${c.sweepFlag} ${c.x} ${c.y}`,
|
||||
c.rX === c.rY ? { ...center, r: c.rX } : undefined
|
||||
{ circle: c.rX === c.rY ? { ...center, r: c.rX } : undefined }
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,41 +1,29 @@
|
||||
import {
|
||||
BUNDLED_LANGUAGES,
|
||||
type IThemeRegistration
|
||||
} from 'shiki'
|
||||
bundledLanguages,
|
||||
type ThemeRegistration
|
||||
} from 'shikiji'
|
||||
import {
|
||||
getHighlighter,
|
||||
} from 'shiki-processor'
|
||||
} from 'shikiji'
|
||||
|
||||
|
||||
type CodeExampleType = {
|
||||
title: string,
|
||||
lang: string,
|
||||
codes: {
|
||||
language?: string,
|
||||
code: string,
|
||||
metastring?: string,
|
||||
}[],
|
||||
language: string,
|
||||
code: string,
|
||||
}[]
|
||||
|
||||
const getIconCodes = (): CodeExampleType => {
|
||||
return [
|
||||
{
|
||||
lang: 'html',
|
||||
language: 'html',
|
||||
title: 'HTML',
|
||||
codes: [
|
||||
{
|
||||
language: 'html',
|
||||
code: `<i data-lucide-name="Name"></i>
|
||||
`,
|
||||
},
|
||||
],
|
||||
code: `<i data-lucide="Name"></i>`
|
||||
},
|
||||
{
|
||||
lang: 'tsx',
|
||||
language: 'tsx',
|
||||
title: 'React',
|
||||
codes: [
|
||||
{
|
||||
language: 'tsx',
|
||||
code: `import { PascalCase } from 'lucide-react';
|
||||
code: `import { PascalCase } from 'lucide-react';
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
@@ -45,17 +33,11 @@ const App = () => {
|
||||
|
||||
export default App;
|
||||
`,
|
||||
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
lang: 'vue',
|
||||
title: 'Vue 3',
|
||||
codes: [
|
||||
{
|
||||
language: 'vue',
|
||||
code: `<script setup>
|
||||
language: 'vue',
|
||||
title: 'Vue',
|
||||
code: `<script setup>
|
||||
import { PascalCase } from 'lucide-vue-next';
|
||||
</script>
|
||||
|
||||
@@ -63,33 +45,21 @@ export default App;
|
||||
<PascalCase />
|
||||
</template>
|
||||
`,
|
||||
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
lang: 'svelte',
|
||||
language: 'svelte',
|
||||
title: 'Svelte',
|
||||
codes: [
|
||||
{
|
||||
language: 'svelte',
|
||||
code: `<script>
|
||||
code: `<script>
|
||||
import { PascalCase } from 'lucide-svelte';
|
||||
</script>
|
||||
|
||||
<PascalCase />
|
||||
`,
|
||||
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
lang: 'preact',
|
||||
language: 'tsx',
|
||||
title: 'Preact',
|
||||
codes: [
|
||||
{
|
||||
language: 'tsx',
|
||||
code: `import { PascalCase } from 'lucide-preact';
|
||||
code: `import { PascalCase } from 'lucide-preact';
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
@@ -99,17 +69,11 @@ const App = () => {
|
||||
|
||||
export default App;
|
||||
`,
|
||||
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
lang: 'solid',
|
||||
language: 'tsx',
|
||||
title: 'Solid',
|
||||
codes: [
|
||||
{
|
||||
language: 'tsx',
|
||||
code: `import { PascalCase } from 'lucide-solid';
|
||||
code: `import { PascalCase } from 'lucide-solid';
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
@@ -119,17 +83,11 @@ const App = () => {
|
||||
|
||||
export default App;
|
||||
`,
|
||||
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
lang: 'angular',
|
||||
language: 'tsx',
|
||||
title: 'Angular',
|
||||
codes: [
|
||||
{
|
||||
language: 'tsx',
|
||||
code: `// app.module.ts
|
||||
code: `// app.module.ts
|
||||
import { LucideAngularModule, PascalCase } from 'lucide-angular';
|
||||
|
||||
@NgModule({
|
||||
@@ -141,54 +99,38 @@ import { LucideAngularModule, PascalCase } from 'lucide-angular';
|
||||
// app.component.html
|
||||
<lucide-icon name="Name"></lucide-icon>
|
||||
`,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
lang: 'html',
|
||||
language: 'html',
|
||||
title: 'Icon Font',
|
||||
codes: [
|
||||
{
|
||||
language: 'html',
|
||||
code: `<style>
|
||||
code: `<style>
|
||||
@import ('~lucide-static/font/Lucide.css');
|
||||
</style>
|
||||
|
||||
<div class="icon-Name"></div>
|
||||
`,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
lang: 'dart',
|
||||
title: 'Flutter',
|
||||
codes: [
|
||||
{
|
||||
language: 'dart',
|
||||
code: `Icon(LucideIcons.Name);
|
||||
`,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export type ThemeOptions =
|
||||
| IThemeRegistration
|
||||
| { light: IThemeRegistration; dark: IThemeRegistration }
|
||||
| ThemeRegistration
|
||||
| { light: ThemeRegistration; dark: ThemeRegistration }
|
||||
|
||||
const highLightCode = async (code: string, lang: string, active?: boolean) => {
|
||||
const highlighter = await getHighlighter({
|
||||
themes: ['material-theme-palenight'],
|
||||
langs: [...BUNDLED_LANGUAGES],
|
||||
processors: []
|
||||
themes: ['github-light', 'github-dark'],
|
||||
langs: Object.keys(bundledLanguages)
|
||||
})
|
||||
|
||||
const highlightedCode = highlighter.codeToHtml(code, {
|
||||
lang,
|
||||
// lineOptions,
|
||||
theme: 'material-theme-palenight'
|
||||
}).replace('background-color: #292D3E', '')
|
||||
themes: {
|
||||
light: 'github-light',
|
||||
dark: 'github-dark'
|
||||
},
|
||||
defaultColor: false
|
||||
}).replace('shiki-themes', 'shiki-themes vp-code')
|
||||
|
||||
return `<div class="language-${lang} ${active ? 'active' : ''}">
|
||||
<button title="Copy Code" class="copy"></button>
|
||||
@@ -201,16 +143,15 @@ const highLightCode = async (code: string, lang: string, active?: boolean) => {
|
||||
export default async function createCodeExamples() {
|
||||
const codes = getIconCodes();
|
||||
|
||||
const codeExamplePromises = codes.map(async (codeTemplate, index) => {
|
||||
const { title, lang, codes } = codeTemplate;
|
||||
const codeExamplePromises = codes.map(async ({ title, language, code }, index) => {
|
||||
const isFirst = index === 0;
|
||||
|
||||
const code = await highLightCode(codes[0].code, codes[0].language || lang, isFirst);
|
||||
const codeString = await highLightCode(code, language, isFirst);
|
||||
|
||||
return {
|
||||
title,
|
||||
language: codes[0].language || lang,
|
||||
code,
|
||||
language: language,
|
||||
code: codeString,
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
@@ -10,26 +10,49 @@ const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
|
||||
{ text: 'Comparison', link: '/guide/comparison' }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Basics',
|
||||
items: [
|
||||
{
|
||||
text: 'Color',
|
||||
link: '/guide/basics/color'
|
||||
},
|
||||
{
|
||||
text: 'Sizing',
|
||||
link: '/guide/basics/sizing'
|
||||
},
|
||||
{
|
||||
text: 'Stroke width',
|
||||
link: '/guide/basics/stroke-width'
|
||||
},
|
||||
]
|
||||
},
|
||||
// TODO: Add this section
|
||||
// {
|
||||
// text: 'Using Icons',
|
||||
// text: 'Advanced',
|
||||
// items: [
|
||||
// {
|
||||
// text: 'How to use icons',
|
||||
// link: 'how-to-use-icons'
|
||||
// },
|
||||
// {
|
||||
// text: 'Styling icons',
|
||||
// link: 'styling-icons'
|
||||
// },
|
||||
// {
|
||||
// text: 'Accessibility',
|
||||
// link: 'accessibility'
|
||||
// link: '/guide/advanced/accessibility'
|
||||
// },
|
||||
// {
|
||||
// text: 'What should I use',
|
||||
// link: 'what-should-i-use'
|
||||
// text: 'Global styling',
|
||||
// },
|
||||
|
||||
// {
|
||||
// text: 'Animations',
|
||||
// },
|
||||
// {
|
||||
// text: 'Filled icons',
|
||||
// },
|
||||
// {
|
||||
// text: 'Combining icons',
|
||||
// },
|
||||
// {
|
||||
// text: 'Dynamic imports'
|
||||
// },
|
||||
// // {
|
||||
// // text: 'Auto importing'
|
||||
// // },
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
@@ -103,15 +126,9 @@ const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
|
||||
]
|
||||
},
|
||||
],
|
||||
// This should be here to keep the sidebar shown on the icons page
|
||||
'icons': [
|
||||
{ text: '', link: '/' },
|
||||
// { text: 'Categorized', link: '/icons/categorized' },
|
||||
// {
|
||||
// text: 'Categories',
|
||||
// items: [
|
||||
// ...(getAllCategoryFiles().map((category) => ({ text: category, link: `/icons/category/${category}` })))
|
||||
// ]
|
||||
// }
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
<style scoped>
|
||||
.container {
|
||||
padding: 32px;
|
||||
padding-top: 33px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -36,6 +36,7 @@ const component = computed(() => props.href ? 'a' : 'div')
|
||||
border-radius: 6px;
|
||||
background-color: var(--vp-c-bg-alt);
|
||||
color: var(--vp-c-text-1);
|
||||
text-decoration: none;
|
||||
/* width: 56px;
|
||||
height: 56px; */
|
||||
font-size: 16px;
|
||||
|
||||
56
docs/.vitepress/theme/components/base/Card.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
href?: string;
|
||||
}>()
|
||||
|
||||
const isExternal = computed(() => {
|
||||
return props.href?.startsWith('http') ?? false
|
||||
})
|
||||
|
||||
const component = computed(() => {
|
||||
return props.href ? 'a' : 'div'
|
||||
})
|
||||
|
||||
const rel = computed(() => {
|
||||
return isExternal.value ? 'noreferrer noopener' : undefined
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="component"
|
||||
:href="href"
|
||||
:rel="rel"
|
||||
class="card"
|
||||
>
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.card {
|
||||
border: 1px solid var(--vp-c-bg-soft);
|
||||
border-radius: 12px;
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 24px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.card[href] {
|
||||
display: block;
|
||||
border: 1px solid var(--vp-c-bg-soft);
|
||||
border-radius: 12px;
|
||||
height: 100%;
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
transition: border-color .25s,background-color .25s;
|
||||
}
|
||||
|
||||
.card[href]:hover {
|
||||
border-color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
</style>
|
||||
36
docs/.vitepress/theme/components/base/CardGrid.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div class="grid">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
align-content: space-evenly;
|
||||
box-sizing: border-box;
|
||||
margin: -8px;
|
||||
}
|
||||
|
||||
.grid > * {
|
||||
flex-basis: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.grid > * {
|
||||
flex-basis: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.grid > * {
|
||||
flex-basis: 33.33%;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -54,7 +54,7 @@ const value = computed({
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.color-picker {
|
||||
background: var(--color-picker-bg, var(--vp-c-bg-soft));
|
||||
background: var(--color-picker-bg, var(--vp-c-bg-alt));
|
||||
border-radius: 8px;
|
||||
color: var(--vp-c-text-2);
|
||||
padding: 4px 8px;
|
||||
@@ -71,10 +71,10 @@ const value = computed({
|
||||
.color-input-text {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 8px;
|
||||
padding: 0 0 0 8px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--vp-c-text-2);
|
||||
color: var(--vp-c-text-1);
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
border-radius: 8px;
|
||||
|
||||
63
docs/.vitepress/theme/components/base/GridSection.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import CardGrid from './CardGrid.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
title: string,
|
||||
headingLevel: 1 | 2 | 3 | 4 | 5 | 6,
|
||||
}>()
|
||||
|
||||
const headingElement = computed(() => `h${props.headingLevel}`)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section>
|
||||
<component :is="headingElement" class="name">{{ title }}</component>
|
||||
<CardGrid>
|
||||
<slot />
|
||||
</CardGrid>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.name {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
section {
|
||||
margin-bottom: 96px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
align-content: space-evenly;
|
||||
box-sizing: border-box;
|
||||
margin: -8px;
|
||||
}
|
||||
|
||||
.grid > * {
|
||||
flex-basis: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.grid > * {
|
||||
flex-basis: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.grid > * {
|
||||
flex-basis: 33.33%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@@ -49,7 +49,7 @@ const percentage = computed<string>(() => `${((Number(props.modelValue) - props.
|
||||
width: 100%;
|
||||
line-height: 10px;
|
||||
height: 20px;
|
||||
--bar-color: var(--slider-bar-color, var(--vp-c-bg-soft));
|
||||
--bar-color: var(--slider-bar-color, var(--vp-input-switch-bg-color));
|
||||
}
|
||||
|
||||
.slider:hover input{
|
||||
|
||||
@@ -10,7 +10,7 @@ import { data } from './HomeHeroBefore.data'
|
||||
:href="`https://github.com/lucide-icons/lucide/releases/tag/${data.version}`"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>{{ data.version }}</Badge>
|
||||
>v{{ data.version }}</Badge>
|
||||
</HomeContainer>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -67,7 +67,10 @@ watch(absoluteStrokeWidth, (enabled) => {
|
||||
Lucide has a lot of customization options to match the icons with your UI.
|
||||
</p>
|
||||
|
||||
<div class="customizer">
|
||||
<div
|
||||
class="customizer"
|
||||
style="--color-picker-bg: var(--vp-input-switch-bg-color)"
|
||||
>
|
||||
<InputField
|
||||
id="icon-color"
|
||||
label="Color"
|
||||
|
||||
@@ -1,48 +1,50 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue'
|
||||
import { useCategoryView } from '../../composables/useCategoryView'
|
||||
import { onMounted } from 'vue';
|
||||
import { useCategoryView } from '../../composables/useCategoryView';
|
||||
|
||||
interface Header {
|
||||
level: number
|
||||
title: string
|
||||
slug: string
|
||||
iconCount: number
|
||||
link: string
|
||||
children: Header[]
|
||||
level: number;
|
||||
title: string;
|
||||
slug: string;
|
||||
iconCount: number;
|
||||
link: string;
|
||||
children: Header[];
|
||||
}
|
||||
|
||||
type MenuItem = Omit<Header, 'slug' | 'children'> & {
|
||||
children?: MenuItem[]
|
||||
}
|
||||
children?: MenuItem[];
|
||||
};
|
||||
|
||||
const props = defineProps<{
|
||||
headers: MenuItem[]
|
||||
root?: boolean
|
||||
}>()
|
||||
headers: MenuItem[];
|
||||
root?: boolean;
|
||||
}>();
|
||||
|
||||
const { selectedCategory } = useCategoryView()
|
||||
const { selectedCategory } = useCategoryView();
|
||||
|
||||
function onClick(event: Event) {
|
||||
const target = (event.target as HTMLElement).nodeName === 'span' ? (event.target as HTMLElement).parentNode : event.target as HTMLElement
|
||||
const id = '#' + (target as HTMLAnchorElement).href!.split('#')[1]
|
||||
const decodedId = decodeURIComponent(id)
|
||||
const target =
|
||||
(event.target as HTMLElement).nodeName === 'span'
|
||||
? (event.target as HTMLElement).parentNode
|
||||
: (event.target as HTMLElement);
|
||||
const href = (target as HTMLAnchorElement)?.href;
|
||||
|
||||
selectedCategory.value = decodedId.replace('#', '')
|
||||
if (href) {
|
||||
const id = '#' + href.split('#')[1];
|
||||
const decodedId = decodeURIComponent(id);
|
||||
|
||||
const heading = document.querySelector<HTMLAnchorElement>(decodedId)
|
||||
heading?.focus()
|
||||
selectedCategory.value = decodedId.replace('#', '');
|
||||
|
||||
const heading = document.querySelector<HTMLAnchorElement>(decodedId);
|
||||
heading?.focus();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ul :class="root ? 'root' : 'nested'">
|
||||
<li v-for="{ children, link, title, iconCount } in headers">
|
||||
<a
|
||||
class="outline-link"
|
||||
:href="link"
|
||||
@click="onClick"
|
||||
:title="title"
|
||||
>
|
||||
<a class="outline-link" :href="link" @click="onClick" :title="title">
|
||||
<span>
|
||||
{{ title }}
|
||||
</span>
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useRouter } from 'vitepress';
|
||||
import IconInfo from './IconInfo.vue';
|
||||
import Badge from '../base/Badge.vue';
|
||||
import { computedAsync } from '@vueuse/core';
|
||||
import { satisfies } from 'semver';
|
||||
|
||||
const props = defineProps<{
|
||||
iconName: string
|
||||
@@ -25,6 +26,12 @@ const icon = computedAsync<IconEntity | null>(async () => {
|
||||
const emit = defineEmits(['close'])
|
||||
const isOpen = computed(() => !!icon.value)
|
||||
|
||||
function releaseTagLink(version) {
|
||||
const shouldAddV = satisfies(version, `<0.266.0`)
|
||||
|
||||
return `https://github.com/lucide-icons/lucide/releases/tag/${shouldAddV ? 'v' : ''}${version}`
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
emit('close')
|
||||
}
|
||||
@@ -43,7 +50,7 @@ const Expand = createLucideIcon('Expand', expand)
|
||||
<Badge
|
||||
v-if="icon.createdRelease"
|
||||
class="version"
|
||||
:href="`https://github.com/lucide-icons/lucide/releases/tag/v${icon.createdRelease.version}`"
|
||||
:href="releaseTagLink(icon.createdRelease.version)"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>v{{ icon.createdRelease.version }}</Badge>
|
||||
|
||||
@@ -1,93 +1,92 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, defineAsyncComponent } from 'vue'
|
||||
import type { IconEntity, Category } from '../../types'
|
||||
import useSearch from '../../composables/useSearch'
|
||||
import InputSearch from '../base/InputSearch.vue'
|
||||
import useSearchInput from '../../composables/useSearchInput'
|
||||
import StickyBar from './StickyBar.vue'
|
||||
import IconsCategory from './IconsCategory.vue'
|
||||
import { useFetch } from '@vueuse/core'
|
||||
import useFetchTags from '../../composables/useFetchTags'
|
||||
import useFetchCategories from '../../composables/useFetchCategories'
|
||||
import { ref, computed, defineAsyncComponent } from 'vue';
|
||||
import type { IconEntity, Category } from '../../types';
|
||||
import useSearch from '../../composables/useSearch';
|
||||
import InputSearch from '../base/InputSearch.vue';
|
||||
import useSearchInput from '../../composables/useSearchInput';
|
||||
import StickyBar from './StickyBar.vue';
|
||||
import IconsCategory from './IconsCategory.vue';
|
||||
import { useFetch } from '@vueuse/core';
|
||||
import useFetchTags from '../../composables/useFetchTags';
|
||||
import useFetchCategories from '../../composables/useFetchCategories';
|
||||
|
||||
const props = defineProps<{
|
||||
icons: IconEntity[]
|
||||
categories: Category[]
|
||||
iconCategories: Record<string, string[]>
|
||||
}>()
|
||||
icons: IconEntity[];
|
||||
categories: Category[];
|
||||
iconCategories: Record<string, string[]>;
|
||||
}>();
|
||||
|
||||
const activeIconName = ref(null)
|
||||
const { searchInput, searchQuery, searchQueryThrottled } = useSearchInput()
|
||||
const activeIconName = ref(null);
|
||||
const { searchInput, searchQuery, searchQueryDebounced } = useSearchInput();
|
||||
|
||||
const isSearching = computed(() => !!searchQuery.value)
|
||||
const isSearching = computed(() => !!searchQuery.value);
|
||||
|
||||
function setActiveIconName(name: string) {
|
||||
activeIconName.value = name
|
||||
activeIconName.value = name;
|
||||
}
|
||||
|
||||
const { execute: fetchTags, data: tags } = useFetchTags()
|
||||
const { execute: fetchCategories, data: categoriesMap } = useFetchCategories()
|
||||
const { execute: fetchTags, data: tags } = useFetchTags();
|
||||
const { execute: fetchCategories, data: categoriesMap } = useFetchCategories();
|
||||
|
||||
const mappedIcons = computed(() => {
|
||||
if(tags.value == null) {
|
||||
return props.icons
|
||||
if (tags.value == null) {
|
||||
return props.icons;
|
||||
}
|
||||
return props.icons.map((icon) => {
|
||||
const iconTags = tags.value[icon.name]
|
||||
const iconCategories = categoriesMap.value?.[icon.name] ?? []
|
||||
const iconTags = tags.value[icon.name];
|
||||
const iconCategories = categoriesMap.value?.[icon.name] ?? [];
|
||||
|
||||
return {
|
||||
...icon,
|
||||
tags: iconTags,
|
||||
categories: iconCategories,
|
||||
}
|
||||
})
|
||||
})
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
const searchResults = useSearch(searchQuery, mappedIcons, [
|
||||
{ name: 'name', weight: 2 },
|
||||
{ name: 'tags', weight: 1 },
|
||||
])
|
||||
]);
|
||||
|
||||
const categories = computed(() => {
|
||||
if( !props.categories?.length || !props.icons?.length ) return []
|
||||
if (!props.categories?.length || !props.icons?.length) return [];
|
||||
|
||||
return props.categories.map(({ name, title }) => {
|
||||
const categoryIcons = props.icons.filter((icon) => {
|
||||
const iconCategories = props.iconCategories[icon.name]
|
||||
return props.categories
|
||||
.map(({ name, title }) => {
|
||||
const categoryIcons = props.icons.filter((icon) => {
|
||||
const iconCategories = props.iconCategories[icon.name];
|
||||
|
||||
return iconCategories?.includes(name)
|
||||
return iconCategories?.includes(name);
|
||||
});
|
||||
|
||||
const searchedCategoryIcons = isSearching
|
||||
? categoryIcons.filter((icon) =>
|
||||
searchResults.value.some((item) => item?.name === icon?.name)
|
||||
)
|
||||
: categoryIcons;
|
||||
|
||||
return {
|
||||
title,
|
||||
name,
|
||||
icons: searchedCategoryIcons,
|
||||
};
|
||||
})
|
||||
|
||||
const searchedCategoryIcons = isSearching
|
||||
? categoryIcons.filter(icon => searchResults.value.some((item) => item?.name === icon?.name))
|
||||
: categoryIcons;
|
||||
|
||||
return {
|
||||
title,
|
||||
name,
|
||||
icons: searchedCategoryIcons,
|
||||
};
|
||||
})
|
||||
.filter(({ icons }) => icons.length)
|
||||
})
|
||||
.filter(({ icons }) => icons.length);
|
||||
});
|
||||
|
||||
function onFocusSearchInput() {
|
||||
if (tags.value == null) {
|
||||
fetchTags()
|
||||
fetchTags();
|
||||
}
|
||||
if (categoriesMap.value == null) {
|
||||
fetchCategories()
|
||||
fetchCategories();
|
||||
}
|
||||
}
|
||||
|
||||
const NoResults = defineAsyncComponent(() =>
|
||||
import('./NoResults.vue')
|
||||
)
|
||||
const NoResults = defineAsyncComponent(() => import('./NoResults.vue'));
|
||||
|
||||
const IconDetailOverlay = defineAsyncComponent(() =>
|
||||
import('./IconDetailOverlay.vue')
|
||||
)
|
||||
const IconDetailOverlay = defineAsyncComponent(() => import('./IconDetailOverlay.vue'));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -100,11 +99,7 @@ const IconDetailOverlay = defineAsyncComponent(() =>
|
||||
@focus="onFocusSearchInput"
|
||||
/>
|
||||
</StickyBar>
|
||||
<NoResults
|
||||
v-if="categories.length === 0"
|
||||
:searchQuery="searchQuery"
|
||||
@clear="searchQuery = ''"
|
||||
/>
|
||||
<NoResults v-if="categories.length === 0" :searchQuery="searchQuery" @clear="searchQuery = ''" />
|
||||
<IconsCategory
|
||||
v-for="category in categories"
|
||||
:key="category.name"
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, defineAsyncComponent } from 'vue'
|
||||
import type { IconEntity } from '../../types'
|
||||
import { useMediaQuery, useOffsetPagination } from '@vueuse/core'
|
||||
import IconGrid from './IconGrid.vue'
|
||||
import InputSearch from '../base/InputSearch.vue'
|
||||
import useSearch from '../../composables/useSearch'
|
||||
import EndOfPage from '../base/EndOfPage.vue'
|
||||
import useSearchInput from '../../composables/useSearchInput'
|
||||
import StickyBar from './StickyBar.vue'
|
||||
import useFetchTags from '../../composables/useFetchTags'
|
||||
import useFetchCategories from '../../composables/useFetchCategories'
|
||||
import { ref, computed, watch, defineAsyncComponent } from 'vue';
|
||||
import type { IconEntity } from '../../types';
|
||||
import { useMediaQuery, useOffsetPagination } from '@vueuse/core';
|
||||
import IconGrid from './IconGrid.vue';
|
||||
import InputSearch from '../base/InputSearch.vue';
|
||||
import useSearch from '../../composables/useSearch';
|
||||
import EndOfPage from '../base/EndOfPage.vue';
|
||||
import useSearchInput from '../../composables/useSearchInput';
|
||||
import StickyBar from './StickyBar.vue';
|
||||
import useFetchTags from '../../composables/useFetchTags';
|
||||
import useFetchCategories from '../../composables/useFetchCategories';
|
||||
|
||||
const props = defineProps<{
|
||||
icons: IconEntity[]
|
||||
}>()
|
||||
icons: IconEntity[];
|
||||
}>();
|
||||
|
||||
const activeIconName = ref(null)
|
||||
const activeIconName = ref(null);
|
||||
|
||||
const isExtraLargeScreen = useMediaQuery('(min-width: 1440px)');
|
||||
const isLargeScreen = useMediaQuery('(min-width: 1280px)');
|
||||
@@ -23,84 +23,78 @@ const isMediumScreen = useMediaQuery('(min-width: 960px)');
|
||||
const isSmallScreen = useMediaQuery('(min-width: 640px)');
|
||||
|
||||
const pageSize = computed(() => {
|
||||
if(isExtraLargeScreen.value) {
|
||||
if (isExtraLargeScreen.value) {
|
||||
return 16 * 20;
|
||||
}
|
||||
if(isLargeScreen.value) {
|
||||
if (isLargeScreen.value) {
|
||||
return 16 * 12;
|
||||
}
|
||||
if(isMediumScreen.value) {
|
||||
if (isMediumScreen.value) {
|
||||
return 13 * 12;
|
||||
}
|
||||
|
||||
if(isSmallScreen.value) {
|
||||
if (isSmallScreen.value) {
|
||||
return 10 * 10;
|
||||
}
|
||||
|
||||
return 10 * 5;
|
||||
})
|
||||
});
|
||||
|
||||
const { execute: fetchTags, data: tags } = useFetchTags()
|
||||
const { execute: fetchCategories, data: categories } = useFetchCategories()
|
||||
const { execute: fetchTags, data: tags } = useFetchTags();
|
||||
const { execute: fetchCategories, data: categories } = useFetchCategories();
|
||||
|
||||
const mappedIcons = computed(() => {
|
||||
if(tags.value == null) {
|
||||
return props.icons
|
||||
if (tags.value == null) {
|
||||
return props.icons;
|
||||
}
|
||||
|
||||
return props.icons.map((icon) => {
|
||||
const iconTags = tags.value[icon.name]
|
||||
const iconCategories = categories.value?.[icon.name] ?? []
|
||||
const iconTags = tags.value[icon.name];
|
||||
const iconCategories = categories.value?.[icon.name] ?? [];
|
||||
|
||||
return {
|
||||
...icon,
|
||||
tags: iconTags,
|
||||
categories: iconCategories,
|
||||
}
|
||||
})
|
||||
})
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
const { searchInput, searchQuery, searchQueryThrottled } = useSearchInput()
|
||||
const searchResults = useSearch(searchQueryThrottled, mappedIcons, [
|
||||
const { searchInput, searchQuery, searchQueryDebounced } = useSearchInput();
|
||||
const searchResults = useSearch(searchQueryDebounced, mappedIcons, [
|
||||
{ name: 'name', weight: 3 },
|
||||
{ name: 'tags', weight: 2 },
|
||||
{ name: 'categories', weight: 1 },
|
||||
])
|
||||
|
||||
const { next, currentPage } = useOffsetPagination( { pageSize })
|
||||
]);
|
||||
|
||||
const { next, currentPage } = useOffsetPagination({ pageSize });
|
||||
|
||||
const paginatedIcons = computed(() => {
|
||||
const end = pageSize.value * currentPage.value
|
||||
const end = pageSize.value * currentPage.value;
|
||||
|
||||
return searchResults.value.slice(0, end)
|
||||
})
|
||||
return searchResults.value.slice(0, end);
|
||||
});
|
||||
|
||||
function setActiveIconName(name: string) {
|
||||
activeIconName.value = name
|
||||
activeIconName.value = name;
|
||||
}
|
||||
|
||||
watch(searchQueryThrottled, (searchString) => {
|
||||
currentPage.value = 1
|
||||
})
|
||||
watch(searchQueryDebounced, (searchString) => {
|
||||
currentPage.value = 1;
|
||||
});
|
||||
|
||||
function onFocusSearchInput() {
|
||||
if (tags.value == null) {
|
||||
fetchTags()
|
||||
fetchTags();
|
||||
}
|
||||
if (categories.value == null) {
|
||||
fetchCategories()
|
||||
fetchCategories();
|
||||
}
|
||||
}
|
||||
|
||||
const NoResults = defineAsyncComponent(() =>
|
||||
import('./NoResults.vue')
|
||||
)
|
||||
|
||||
const IconDetailOverlay = defineAsyncComponent(() =>
|
||||
import('./IconDetailOverlay.vue')
|
||||
)
|
||||
const NoResults = defineAsyncComponent(() => import('./NoResults.vue'));
|
||||
|
||||
const IconDetailOverlay = defineAsyncComponent(() => import('./IconDetailOverlay.vue'));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -124,7 +118,7 @@ const IconDetailOverlay = defineAsyncComponent(() =>
|
||||
:icons="paginatedIcons"
|
||||
@setActiveIcon="setActiveIconName"
|
||||
/>
|
||||
<EndOfPage @end-of-page="next" class="bottom-page"/>
|
||||
<EndOfPage @end-of-page="next" class="bottom-page" />
|
||||
<IconDetailOverlay
|
||||
v-if="activeIconName != null"
|
||||
:iconName="activeIconName"
|
||||
|
||||
@@ -36,15 +36,22 @@ const links = computed(() => [
|
||||
<template>
|
||||
<footer v-if="theme.footer" class="VPFooter" :class="{ 'has-sidebar': hasSidebar }">
|
||||
<div class="container">
|
||||
<p v-if="theme.footer.message" class="message" v-html="theme.footer.message"></p>
|
||||
<p v-if="theme.footer.copyright" class="copyright" v-html="theme.footer.copyright"></p>
|
||||
<div class="sponsors">
|
||||
<a href="https://vercel.com?utm_source=lucide&utm_campaign=oss" rel="noreferrer noopener">
|
||||
<img src="/vercel.svg" alt="Powered by Vercel" width="200" />
|
||||
</a>
|
||||
<a href="https://www.digitalocean.com/?refcode=b0877a2caebd&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge" rel="noreferrer noopener">
|
||||
<img src="/digitalocean.svg" alt="Digital Ocean" width="200" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="links">
|
||||
<VPLink v-for="link in links" :href="link.href" :key="link.text" :rel="link.href.startsWith('http') ? 'noreferrer noopener': undefined">
|
||||
{{ link.text }}
|
||||
</VPLink>
|
||||
<a href="https://vercel.com?utm_source=lucide&utm_campaign=oss" rel="noreferrer noopener">
|
||||
<img src="/vercel.svg" alt="Powered by Vercel" width="200" />
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<p v-if="theme.footer.message" class="message" v-html="theme.footer.message"></p>
|
||||
<p v-if="theme.footer.copyright" class="copyright" v-html="theme.footer.copyright"></p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -67,7 +74,7 @@ const links = computed(() => [
|
||||
|
||||
.container {
|
||||
margin: 0 auto;
|
||||
max-width: var(--vp-layout-max-width);
|
||||
max-width: calc(var(--vp-layout-max-width) - 64px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@@ -85,7 +92,7 @@ const links = computed(() => [
|
||||
.message { order: 2; }
|
||||
.copyright { order: 1; }
|
||||
|
||||
.links {
|
||||
.links, .sponsors {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
align-items: center;
|
||||
@@ -102,7 +109,7 @@ const links = computed(() => [
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.links {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,24 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
import {data} from './PackageList.data'
|
||||
import GridSection from '../base/GridSection.vue'
|
||||
import PackageListItem from "./PackageListItem.vue";</script>
|
||||
|
||||
<template>
|
||||
<section class="package-group">
|
||||
<h1 class="name">Packages</h1>
|
||||
<div class="grid package-list" ref="container">
|
||||
<div v-for="packageData in data.packages" class="item">
|
||||
<PackageListItem :packageData="packageData"/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="package-group">
|
||||
<h2 class="name">Third-party packages</h2>
|
||||
<div class="grid package-list" ref="container">
|
||||
<div v-for="packageData in data.thirdPartyPackages" class="item">
|
||||
<PackageListItem :packageData="packageData"/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<GridSection
|
||||
title="Packages"
|
||||
:headingLevel="1"
|
||||
class="package-group"
|
||||
>
|
||||
<PackageListItem
|
||||
v-for="packageData in data.packages"
|
||||
:packageData="packageData"
|
||||
/>
|
||||
</GridSection>
|
||||
|
||||
<GridSection
|
||||
title="Third-party packages"
|
||||
:headingLevel="2"
|
||||
class="package-group"
|
||||
>
|
||||
<PackageListItem
|
||||
v-for="packageData in data.thirdPartyPackages"
|
||||
:packageData="packageData"
|
||||
/>
|
||||
</GridSection>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@@ -26,7 +32,7 @@ import PackageListItem from "./PackageListItem.vue";</script>
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.package-group {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { useRouter } from 'vitepress';
|
||||
import {PackageItem} from "../../types";
|
||||
import VPButton from 'vitepress/dist/client/theme-default/components/VPButton.vue';
|
||||
import Card from '../base/Card.vue'
|
||||
|
||||
const { go } = useRouter()
|
||||
const props = defineProps<{
|
||||
@@ -10,48 +11,42 @@ const props = defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<article class="package">
|
||||
<header class="package-header">
|
||||
<div class="package-icon-well">
|
||||
<img :src="packageData.icon" alt="" class="package-icon" :class="{[packageData.iconClass]: true, light: packageData.iconDark}" />
|
||||
<img v-if="packageData.iconDark" :src="packageData.iconDark" alt="" class="package-icon dark" :class="packageData.iconClass" />
|
||||
<div>
|
||||
<Card class="package">
|
||||
<header class="package-header">
|
||||
<div class="package-icon-well">
|
||||
<img :src="packageData.icon" alt="" class="package-icon" :class="{[packageData.iconClass]: true, light: packageData.iconDark}" />
|
||||
<img v-if="packageData.iconDark" :src="packageData.iconDark" alt="" class="package-icon dark" :class="packageData.iconClass" />
|
||||
</div>
|
||||
<div class="package-title">
|
||||
<h2 class="title">{{ props.packageData.name }}</h2>
|
||||
<a v-for="shield in props.packageData.shields" :href="shield.href" class="package-shield" rel="noreferrer noopener">
|
||||
<img :src="shield.src" :alt="shield.href" />
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
<div class="package-details">
|
||||
{{ packageData.description }}
|
||||
</div>
|
||||
<div class="package-title">
|
||||
<h2 class="title">{{ props.packageData.name }}</h2>
|
||||
<a v-for="shield in props.packageData.shields" :href="shield.href" class="package-shield" rel="noreferrer noopener">
|
||||
<img :src="shield.src" :alt="shield.href" />
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
<div class="package-details">
|
||||
{{ packageData.description }}
|
||||
</div>
|
||||
<footer class="package-footer">
|
||||
<VPButton
|
||||
:href="packageData.documentation"
|
||||
text="Guide"
|
||||
theme="brand"
|
||||
@click="go(packageData.documentation)"
|
||||
/>
|
||||
<VPButton
|
||||
:href="packageData.source"
|
||||
text="Source"
|
||||
theme="alt"
|
||||
@click="go(packageData.source)"
|
||||
/>
|
||||
</footer>
|
||||
</article>
|
||||
<footer class="package-footer">
|
||||
<VPButton
|
||||
:href="packageData.documentation"
|
||||
text="Guide"
|
||||
theme="brand"
|
||||
@click="go(packageData.documentation)"
|
||||
/>
|
||||
<VPButton
|
||||
:href="packageData.source"
|
||||
text="Source"
|
||||
theme="alt"
|
||||
@click="go(packageData.source)"
|
||||
/>
|
||||
</footer>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.package {
|
||||
border: 1px solid var(--vp-c-bg-soft);
|
||||
border-radius: 12px;
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 24px;
|
||||
}
|
||||
.package {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
72
docs/.vitepress/theme/components/showcase/ShowcaseList.vue
Normal file
@@ -0,0 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import companies from '../../../data/companiesData.json'
|
||||
import componentLibraries from '../../../data/componentLibrariesData.json'
|
||||
import GridSection from '../base/GridSection.vue'
|
||||
import ShowcaseListItem from "./ShowcaseListItem.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<GridSection
|
||||
title="Used by"
|
||||
:headingLevel="1"
|
||||
class="package-group"
|
||||
>
|
||||
<ShowcaseListItem
|
||||
v-for="company in companies"
|
||||
:showcaseItem="company"
|
||||
/>
|
||||
</GridSection>
|
||||
|
||||
<GridSection
|
||||
title="Used in"
|
||||
:headingLevel="1"
|
||||
class="package-group"
|
||||
>
|
||||
<ShowcaseListItem
|
||||
v-for="componentLibrary in componentLibraries"
|
||||
:showcaseItem="componentLibrary"
|
||||
/>
|
||||
</GridSection>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.name {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.package-group {
|
||||
margin-bottom: 96px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
align-content: space-evenly;
|
||||
box-sizing: border-box;
|
||||
margin: -8px;
|
||||
}
|
||||
|
||||
.grid > * {
|
||||
flex-basis: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.grid > * {
|
||||
flex-basis: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.grid > * {
|
||||
flex-basis: 33.33%;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,52 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vitepress';
|
||||
import { ShowcaseItem } from "../../types";
|
||||
import Card from '../base/Card.vue'
|
||||
|
||||
const { go } = useRouter()
|
||||
defineProps<{
|
||||
showcaseItem: ShowcaseItem,
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Card
|
||||
class="company"
|
||||
:href="showcaseItem.url"
|
||||
:aria-label="showcaseItem.name"
|
||||
>
|
||||
<img
|
||||
:src="showcaseItem.image.light"
|
||||
class="logo light"
|
||||
:alt="`${showcaseItem.name} logo`"
|
||||
/>
|
||||
<img
|
||||
:src="showcaseItem.image.dark"
|
||||
class="logo dark"
|
||||
:alt="`${showcaseItem.name} logo`"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.company {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding: 48px 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height:64px;
|
||||
width: 240px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
html.dark .logo.dark {
|
||||
display: none;
|
||||
}
|
||||
html:not(.dark) .logo.light {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -1,43 +1,40 @@
|
||||
import { refThrottled } from '@vueuse/core';
|
||||
import { useDebounce } from '@vueuse/core';
|
||||
import { nextTick, onMounted, ref, watch } from 'vue';
|
||||
|
||||
const useSearchInput = () => {
|
||||
const searchInput = ref()
|
||||
const searchInput = ref();
|
||||
const searchQuery = ref(
|
||||
typeof window === 'undefined'
|
||||
? ''
|
||||
: (
|
||||
new URLSearchParams(window.location.search).get('search')
|
||||
|| ''
|
||||
)
|
||||
)
|
||||
const searchQueryThrottled = refThrottled(searchQuery, 400)
|
||||
? ''
|
||||
: new URLSearchParams(window.location.search).get('search') || ''
|
||||
);
|
||||
const searchQueryDebounced = useDebounce(searchQuery, 250);
|
||||
|
||||
watch(searchQueryThrottled, (searchString) => {
|
||||
watch(searchQueryDebounced, (searchString) => {
|
||||
const newUrl = new URL(window.location.href);
|
||||
|
||||
if(searchString === '') {
|
||||
if (searchString === '') {
|
||||
newUrl.searchParams.delete('search');
|
||||
} else {
|
||||
newUrl.searchParams.set('search', searchString);
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
window.history.replaceState({}, '', newUrl)
|
||||
})
|
||||
})
|
||||
window.history.replaceState({}, '', newUrl);
|
||||
});
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
if(searchParams.has('focus')) {
|
||||
searchInput.value.focus()
|
||||
if (searchParams.has('focus')) {
|
||||
searchInput.value.focus();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return {
|
||||
searchInput,
|
||||
searchQuery,
|
||||
searchQueryThrottled
|
||||
searchQueryDebounced,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
34
docs/.vitepress/theme/sandpackTheme.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"colors": {
|
||||
"surface1": "var(--vp-code-block-bg)",
|
||||
"surface2": "var(--vp-code-block-bg)",
|
||||
"surface3": "var(--vp-code-line-highlight-color)",
|
||||
"clickable": "var(--vp-c-text-2)",
|
||||
"base": "#323232",
|
||||
"disabled": "#C5C5C5",
|
||||
"hover": "var(--vp-c-brand)",
|
||||
"accent": "var(--vp-c-brand)",
|
||||
"error": "var(--vp-c-red)",
|
||||
"errorSurface": "#ffeceb"
|
||||
},
|
||||
"syntax": {
|
||||
"plain": "var(--vp-code-editor-plain)",
|
||||
"comment": {
|
||||
"color": "var(--vp-code-editor-comment)",
|
||||
"fontStyle": "italic"
|
||||
},
|
||||
"keyword": "var(--vp-code-editor-keyword)",
|
||||
"tag": "var(--vp-code-editor-tag)",
|
||||
"punctuation": "var(--vp-code-editor-punctuation)",
|
||||
"definition": "var(--vp-code-editor-definition)",
|
||||
"property": "var(--vp-code-editor-property)",
|
||||
"static": "var(--vp-code-editor-static)",
|
||||
"string": "var(--vp-code-editor-string)"
|
||||
},
|
||||
"font": {
|
||||
"body": "var(--vp-font-family-base)",
|
||||
"mono": "var(--vp-font-family-mono)",
|
||||
"size": "var(--vp-code-font-size)",
|
||||
"lineHeight": "var(--vp-code-line-height)"
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,39 @@
|
||||
--vp-c-brand-dark: #DC5A5A;
|
||||
--vp-c-brand-darker: #C45050;
|
||||
|
||||
--vp-c-brand-1: #F67373;
|
||||
--vp-c-brand-2: #FF7070;
|
||||
--vp-c-brand-3: #F56565;
|
||||
--vp-c-brand-4: #DC5A5A;
|
||||
--vp-c-brand-5: #C45050;
|
||||
|
||||
--vp-c-bg-alt-up: #fff;
|
||||
--vp-c-bg-alt-down: #fff;
|
||||
|
||||
--vp-code-editor-plain: #24292E;
|
||||
--vp-code-editor-comment: #6A737D;
|
||||
--vp-code-editor-keyword: #D73A49;
|
||||
--vp-code-editor-tag: #22863A;
|
||||
--vp-code-editor-punctuation: #24292E;
|
||||
--vp-code-editor-definition: #6F42C1;
|
||||
--vp-code-editor-property: #005CC5;
|
||||
--vp-code-editor-static: #F78C6C;
|
||||
--vp-code-editor-string: #032F62;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--vp-c-bg-alt-up: #1B1B1D;
|
||||
--vp-c-bg-alt-down: #0F0F10;
|
||||
|
||||
--vp-code-editor-plain: #E1E4E8;
|
||||
--vp-code-editor-comment: #6A737D;
|
||||
--vp-code-editor-keyword: #F97583;
|
||||
--vp-code-editor-tag: #85E89D;
|
||||
--vp-code-editor-punctuation: #9ECBFF;
|
||||
--vp-code-editor-definition: #B392F0;
|
||||
--vp-code-editor-property: #79B8FF;
|
||||
--vp-code-editor-static: #F78C6C;
|
||||
--vp-code-editor-string: #9ECBFF;
|
||||
}
|
||||
|
||||
.VPNavBarTitle .logo {
|
||||
@@ -126,3 +152,52 @@
|
||||
html:has(* .outline-link:target) {
|
||||
scroll-behavior: smooth;
|
||||
} */
|
||||
|
||||
.sp-wrapper .sp-layout {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.sp-wrapper .sp-tabs-scrollable-container {
|
||||
border-radius: 8px 8px 0 0;
|
||||
position: relative;
|
||||
|
||||
box-shadow: inset 0 -1px var(--vp-code-tab-divider);
|
||||
margin-bottom: 0px;
|
||||
margin-top: -1px;
|
||||
height: 48px;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
.sp-wrapper .sp-preview-container {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.sp-wrapper .sp-tabs .sp-tab-button {
|
||||
padding: 0 12px;
|
||||
line-height: 48px;
|
||||
height: 48px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
/* box-sizing: content-box; */
|
||||
}
|
||||
|
||||
.sp-wrapper .sp-tabs .sp-tab-button:after {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
left: 8px;
|
||||
bottom: 0px;
|
||||
z-index: 1;
|
||||
height: 1px;
|
||||
content: '';
|
||||
background-color: transparent;
|
||||
transition: background-color 0.25s;
|
||||
}
|
||||
|
||||
.sp-wrapper .sp-tabs .sp-tab-button[data-active="true"] {
|
||||
color: var(--vp-code-tab-active-text-color);
|
||||
}
|
||||
|
||||
.sp-wrapper .sp-tabs .sp-tab-button[data-active="true"]:after {
|
||||
background-color: var(--vp-code-tab-active-bar-color);
|
||||
}
|
||||
|
||||
@@ -44,3 +44,14 @@ export interface Release {
|
||||
version: string
|
||||
date: string
|
||||
}
|
||||
|
||||
interface ShowcaseItemImage {
|
||||
light: string
|
||||
dark: string
|
||||
}
|
||||
|
||||
export interface ShowcaseItem {
|
||||
name: string
|
||||
url: string
|
||||
image: ShowcaseItemImage
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
The Lucide docs website is built with Vitepress: https://vitepress.dev/
|
||||
This is Markdown-based documentation powered by Vue.
|
||||
|
||||
This is why this file is in txt format.
|
||||
|
||||
## Development
|
||||
|
||||
```sh
|
||||
4
docs/guide/advanced/accessibility.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# Accessibility
|
||||
|
||||
<!-- Description how you should use svg icons keeping web accessible -->
|
||||
<!-- See @JanTrichter comment about some information to write this: https://github.com/lucide-icons/lucide/pull/1521#discussion_r1332141390 -->
|
||||
13
docs/guide/advanced/filled-icons.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Filled Icons
|
||||
|
||||
Fills are officially not supported.
|
||||
However, all SVG properties are available on all icons.
|
||||
Fill can still be used and will work fine on certain icons.
|
||||
|
||||
Example with stars:
|
||||
|
||||
<!-- Code Example with stars -->
|
||||
|
||||
## Will Lucide have fills in the future?
|
||||
|
||||
This feature is requested several times and discussion is happening at: [#458](https://github.com/lucide-icons/lucide/discussions/458).
|
||||
52
docs/guide/basics/color.md
Normal file
@@ -0,0 +1,52 @@
|
||||
<script setup>
|
||||
import { Sandpack } from 'sandpack-vue3'
|
||||
import sandpackTheme from '../../.vitepress/theme/sandpackTheme.json'
|
||||
import buttonExampleFiles from './examples/button-example/files.ts'
|
||||
import iconColorExampleFiles from './examples/color-icon/files.ts'
|
||||
</script>
|
||||
|
||||
# Color
|
||||
|
||||
By default, all icons have the color value: `currentColor`. This keyword uses the element's computed text `color` value to represent the icon color.
|
||||
|
||||
Read more about [ `currentColor` on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword).
|
||||
|
||||
## Adjust the color using the `color` prop
|
||||
|
||||
The color can be adjusted by passing the color prop to the element.
|
||||
|
||||
<Sandpack
|
||||
template="react"
|
||||
:theme="sandpackTheme"
|
||||
:files="iconColorExampleFiles"
|
||||
:customSetup='{
|
||||
dependencies: {
|
||||
"lucide-react": "latest"
|
||||
}
|
||||
}'
|
||||
:options="{
|
||||
editorHeight: 295,
|
||||
editorWidthPercentage: 60,
|
||||
}"
|
||||
/>
|
||||
|
||||
## Using parent elements text color value
|
||||
|
||||
Because the color of lucide icons uses `currentColor`, the color of the icon depends on the computed `color` of the element, or it inherits it from its parent.
|
||||
|
||||
For example, if a parent element's color value is `#fff` and one of the children is a lucide icon, the color of the icon will be rendered as `#fff`. This is browser native behavior.
|
||||
|
||||
<Sandpack
|
||||
template="react"
|
||||
:theme="sandpackTheme"
|
||||
:files="buttonExampleFiles"
|
||||
:customSetup='{
|
||||
dependencies: {
|
||||
"lucide-react": "latest"
|
||||
}
|
||||
}'
|
||||
:options="{
|
||||
editorHeight: 320,
|
||||
editorWidthPercentage: 60,
|
||||
}"
|
||||
/>
|
||||
14
docs/guide/basics/examples/absolute-stroke-width-icon/App.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { RollerCoaster } from "lucide-react";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="app">
|
||||
<RollerCoaster
|
||||
size={96}
|
||||
absoluteStrokeWidth={true}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -0,0 +1,15 @@
|
||||
import App from './App.js?raw'
|
||||
import styles from '../styles.css?raw'
|
||||
|
||||
const files = {
|
||||
'App.js': {
|
||||
code: App,
|
||||
active: true,
|
||||
},
|
||||
'styles.css': {
|
||||
code:styles,
|
||||
hidden: true
|
||||
},
|
||||
}
|
||||
|
||||
export default files
|
||||
5
docs/guide/basics/examples/button-example/App.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import Button from "./Button";
|
||||
|
||||
export default function App() {
|
||||
return <Button />;
|
||||
}
|
||||
12
docs/guide/basics/examples/button-example/Button.jsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import { ThumbsUp } from "lucide-react";
|
||||
|
||||
function LikeButton() {
|
||||
return (
|
||||
<button style={{ color: "#fff" }}>
|
||||
<ThumbsUp />
|
||||
Like
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export default LikeButton;
|
||||
21
docs/guide/basics/examples/button-example/files.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import App from './App.js?raw'
|
||||
import Button from './Button.jsx?raw'
|
||||
import styles from '../styles.css?raw'
|
||||
|
||||
const files = {
|
||||
'App.js': {
|
||||
code: App,
|
||||
hidden: true
|
||||
},
|
||||
'Button.jsx': {
|
||||
code: Button,
|
||||
active: true,
|
||||
readOnly: false,
|
||||
},
|
||||
'styles.css': {
|
||||
code:styles,
|
||||
hidden: true
|
||||
},
|
||||
}
|
||||
|
||||
export default files
|
||||
11
docs/guide/basics/examples/color-icon/App.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Smile } from "lucide-react";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="app">
|
||||
<Smile color="#3e9392" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
15
docs/guide/basics/examples/color-icon/files.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import App from './App.js?raw'
|
||||
import styles from '../styles.css?raw'
|
||||
|
||||
const files = {
|
||||
'App.js': {
|
||||
code: App,
|
||||
active: true,
|
||||
},
|
||||
'styles.css': {
|
||||
code:styles,
|
||||
hidden: true
|
||||
},
|
||||
}
|
||||
|
||||
export default files
|
||||
12
docs/guide/basics/examples/size-icon-css-example/App.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Beer } from "lucide-react";
|
||||
import "./icon.css";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="app">
|
||||
<Beer className="my-beer-icon" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
21
docs/guide/basics/examples/size-icon-css-example/files.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import App from './App.js?raw'
|
||||
import styles from '../styles.css?raw'
|
||||
import IconCss from './icon.css?raw'
|
||||
|
||||
const files = {
|
||||
'icon.css': {
|
||||
code: IconCss,
|
||||
readOnly: false,
|
||||
active: true,
|
||||
},
|
||||
'App.js': {
|
||||
code: App,
|
||||
},
|
||||
'styles.css': {
|
||||
code:styles,
|
||||
hidden: true
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
export default files
|
||||
@@ -0,0 +1,5 @@
|
||||
.my-beer-icon {
|
||||
/* Change this! */
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
11
docs/guide/basics/examples/size-icon-example/App.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Landmark } from "lucide-react";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="app">
|
||||
<Landmark size={64} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
15
docs/guide/basics/examples/size-icon-example/files.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import App from './App.js?raw'
|
||||
import styles from '../styles.css?raw'
|
||||
|
||||
const files = {
|
||||
'App.js': {
|
||||
code: App,
|
||||
active: true,
|
||||
},
|
||||
'styles.css': {
|
||||
code:styles,
|
||||
hidden: true
|
||||
},
|
||||
}
|
||||
|
||||
export default files
|
||||
13
docs/guide/basics/examples/size-icon-font-example/App.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Star } from "lucide-react";
|
||||
import "./icon.css";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="text-wrapper">
|
||||
<Star class="my-icon" />
|
||||
<div>Yes</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
21
docs/guide/basics/examples/size-icon-font-example/files.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import App from './App.js?raw'
|
||||
import styles from '../styles.css?raw'
|
||||
import IconCss from './icon.css?raw'
|
||||
|
||||
const files = {
|
||||
'icon.css': {
|
||||
code: IconCss,
|
||||
readOnly: false,
|
||||
active: true,
|
||||
},
|
||||
'App.js': {
|
||||
code: App,
|
||||
},
|
||||
'styles.css': {
|
||||
code: styles,
|
||||
hidden: true
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
export default files
|
||||
15
docs/guide/basics/examples/size-icon-font-example/icon.css
Normal file
@@ -0,0 +1,15 @@
|
||||
.my-icon {
|
||||
/* Icon size will relative to font-size of .text-wrapper */
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.text-wrapper {
|
||||
/* Change this! */
|
||||
font-size: 96px;
|
||||
|
||||
/* layout stuff */
|
||||
display: flex;
|
||||
gap: 0.25em;
|
||||
align-items: center;
|
||||
}
|
||||
11
docs/guide/basics/examples/size-icon-tailwind-example/App.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import { PartyPopper } from "lucide-react";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div>
|
||||
<PartyPopper className="w-24 h-24" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -0,0 +1,15 @@
|
||||
import App from './App.js?raw'
|
||||
import styles from '../styles.css?raw'
|
||||
|
||||
const files = {
|
||||
'App.js': {
|
||||
code: App,
|
||||
active: true
|
||||
},
|
||||
'styles.css': {
|
||||
code:styles,
|
||||
hidden: true
|
||||
},
|
||||
}
|
||||
|
||||
export default files
|
||||
11
docs/guide/basics/examples/stroke-width-icon/App.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import { FolderLock } from "lucide-react";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="app">
|
||||
<FolderLock strokeWidth={1} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
15
docs/guide/basics/examples/stroke-width-icon/files.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import App from './App.js?raw'
|
||||
import styles from '../styles.css?raw'
|
||||
|
||||
const files = {
|
||||
'App.js': {
|
||||
code: App,
|
||||
active: true,
|
||||
},
|
||||
'styles.css': {
|
||||
code:styles,
|
||||
hidden: true
|
||||
},
|
||||
}
|
||||
|
||||
export default files
|
||||
50
docs/guide/basics/examples/styles.css
Normal file
@@ -0,0 +1,50 @@
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
-webkit-font-smoothing: auto;
|
||||
-moz-font-smoothing: auto;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-smoothing: auto;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-smooth: always;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-touch-callout: none;
|
||||
background: #202127;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 18px;
|
||||
padding: 10px 20px;
|
||||
line-height: 24px;
|
||||
gap: 8px;
|
||||
border-radius: 24px;
|
||||
outline: none;
|
||||
border: none;
|
||||
background: #111;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #F56565;
|
||||
}
|
||||
|
||||
.app {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 32px;
|
||||
}
|
||||
87
docs/guide/basics/sizing.md
Normal file
@@ -0,0 +1,87 @@
|
||||
<script setup>
|
||||
import { Sandpack } from 'sandpack-vue3'
|
||||
import sandpackTheme from '../../.vitepress/theme/sandpackTheme.json'
|
||||
import sizeIconExample from './examples/size-icon-example/files.ts'
|
||||
import sizeIconCssExample from './examples/size-icon-css-example/files.ts'
|
||||
import sizeIconFontExample from './examples/size-icon-font-example/files.ts'
|
||||
import sizeIconTailwind from './examples/size-icon-tailwind-example/files.ts'
|
||||
</script>
|
||||
|
||||
# Sizing
|
||||
|
||||
By default, the size of all icons is `24px` by `24px`. The size is adjustable using the `size` prop and CSS.
|
||||
|
||||
## Adjusting the icon size using the `size` prop
|
||||
|
||||
<Sandpack
|
||||
template="react"
|
||||
:theme="sandpackTheme"
|
||||
:files="sizeIconExample"
|
||||
:customSetup='{
|
||||
dependencies: {
|
||||
"lucide-react": "latest"
|
||||
}
|
||||
}'
|
||||
:options="{
|
||||
editorHeight: 300,
|
||||
editorWidthPercentage: 60,
|
||||
}"
|
||||
/>
|
||||
|
||||
## Adjusting the icon size via CSS
|
||||
|
||||
The CSS properties `width` and `height` can be used to adjust the icon size.
|
||||
|
||||
<Sandpack
|
||||
template="react"
|
||||
:theme="sandpackTheme"
|
||||
:files="sizeIconCssExample"
|
||||
:customSetup='{
|
||||
dependencies: {
|
||||
"lucide-react": "latest"
|
||||
}
|
||||
}'
|
||||
:options="{
|
||||
editorHeight: 300,
|
||||
}"
|
||||
/>
|
||||
|
||||
### Dynamically change the icon size based on the font size
|
||||
|
||||
It is possible to resize icons based on font size. This can be achieved using the `em` unit. See this [MDN article](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size#ems) for more information on the `em` unit.
|
||||
|
||||
<Sandpack
|
||||
template="react"
|
||||
:theme="sandpackTheme"
|
||||
:files="sizeIconFontExample"
|
||||
:customSetup='{
|
||||
dependencies: {
|
||||
"lucide-react": "latest"
|
||||
}
|
||||
}'
|
||||
:options="{
|
||||
editorHeight: 300,
|
||||
}"
|
||||
/>
|
||||
|
||||
### Resizing with Tailwind
|
||||
|
||||
`h-*` and `w-*` utilities can be used to adjust the size of the icon.
|
||||
|
||||
<Sandpack
|
||||
template="react"
|
||||
:theme="sandpackTheme"
|
||||
:files="sizeIconTailwind"
|
||||
:customSetup='{
|
||||
dependencies: {
|
||||
"lucide-react": "latest",
|
||||
}
|
||||
}'
|
||||
:options="{
|
||||
externalResources: ['https://cdn.tailwindcss.com'],
|
||||
editorHeight: 300,
|
||||
editorWidthPercentage: 60,
|
||||
}"
|
||||
/>
|
||||
|
||||
<!-- Code Example -->
|
||||
60
docs/guide/basics/stroke-width.md
Normal file
@@ -0,0 +1,60 @@
|
||||
<script setup>
|
||||
import { Sandpack } from 'sandpack-vue3'
|
||||
import sandpackTheme from '../../.vitepress/theme/sandpackTheme.json'
|
||||
import strokeWidth from './examples/stroke-width-icon/files.ts'
|
||||
import absoluteStrokeWidth from './examples/absolute-stroke-width-icon/files.ts'
|
||||
</script>
|
||||
|
||||
# Stroke width
|
||||
|
||||
All icons are designed with SVG elements using strokes.
|
||||
These have a default stroke width of `2px`.
|
||||
|
||||
The `strokeWidth` can be adjusted to create a different look of the icons.
|
||||
|
||||
## Adjusting stroke width with `strokeWidth` prop
|
||||
|
||||
|
||||
<Sandpack
|
||||
template="react"
|
||||
:theme="sandpackTheme"
|
||||
:files="strokeWidth"
|
||||
:customSetup='{
|
||||
dependencies: {
|
||||
"lucide-react": "latest"
|
||||
}
|
||||
}'
|
||||
:options="{
|
||||
editorHeight: 300,
|
||||
editorWidthPercentage: 60,
|
||||
}"
|
||||
/>
|
||||
|
||||
## Absolute stroke width
|
||||
|
||||
When adjusting the `size` prop the size of the stroke width will be relative to the size of the icon, this is the default SVG behavior. The `absoluteStrokeWidth` prop is introduced to adjust this behavior to make the stroke width constant no matter the size of the icon.
|
||||
|
||||
This means that when `absoluteStrokeWidth` is enabled and the `size` of the icons is set to `48px` the `strokeWidth` will still be `2px` on the screen.
|
||||
|
||||
Note `2px` is the default stroke width for a Lucide icon, this can be adjusted to all sizes.
|
||||
|
||||

|
||||
|
||||
### Adjusting stroke width with `absoluteStrokeWidth` prop
|
||||
|
||||
Setting `absoluteStrokeWidth` to `true` will make the stroke width absolute.
|
||||
|
||||
<Sandpack
|
||||
template="react"
|
||||
:theme="sandpackTheme"
|
||||
:files="absoluteStrokeWidth"
|
||||
:customSetup='{
|
||||
dependencies: {
|
||||
"lucide-react": "latest"
|
||||
}
|
||||
}'
|
||||
:options="{
|
||||
editorHeight: 320,
|
||||
editorWidthPercentage: 60,
|
||||
}"
|
||||
/>
|
||||
@@ -14,15 +14,15 @@ The Illustrator template is created following guidelines from the [Icon Design G
|
||||
|
||||
**Workflow:**
|
||||
|
||||
1. Download and open the [Illustrator template](https://github.com/lucide-icons/lucide/blob/main/docs/templates/illustrator_template.ai).
|
||||
1. Download and open the [Illustrator template](https://github.com/lucide-icons/lucide/blob/main/docs/public/templates/illustrator_template.ai).
|
||||
|
||||
2. You can now remove the content from the example logo layer ("Draw") and start creating.
|
||||
|
||||
3. Verify that you follow the [Icon Design Guidelines](icon-design-guide.md).
|
||||
|
||||
4. Before you export the file as an SVG make sure to check that you followed the guidelines and remove all unecessary layers (especially "Padding" and "Grid").
|
||||
4. Before you export the file as an SVG make sure to check that you followed the guidelines and remove all unnecessary layers (especially "Padding" and "Grid").
|
||||
|
||||
5. Export the file with the export menu under: `Export > Export As..` than safe the file as SVG. Select the following options in the SVG Options dialog:
|
||||
5. Export the file with the export menu under: `Export > Export As..` then save the file as SVG. Select the following options in the SVG Options dialog:
|
||||
|
||||

|
||||
|
||||
|
||||
1
docs/guide/how-to-use-icons.md
Normal file
@@ -0,0 +1 @@
|
||||
# How to use icons
|
||||
@@ -1,8 +0,0 @@
|
||||
# lucide_icons
|
||||
|
||||
Lucide Icons ([lucide.dev](https://lucide.dev)) for Flutter. Visit the website for the full list of icons
|
||||
|
||||
## Example
|
||||
```dart
|
||||
Icon(LucideIcons.activity);
|
||||
```
|
||||
@@ -26,9 +26,9 @@ npm install lucide-preact
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ES Modules so it's completely tree-shakable.
|
||||
Lucide is built with ES Modules, so it's completely tree-shakable.
|
||||
|
||||
Each icon can be imported as a Preact component, what renders a inline SVG Element. This way only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
Each icon can be imported as a Preact component, which renders an inline SVG element. This way, only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -56,7 +56,7 @@ export default App;
|
||||
|
||||
### Applying props
|
||||
|
||||
To apply custom props to change the look of the icon, this can be done by simply pass them as props to the component. All SVG attributes are available as props to style the SVGs. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
|
||||
```jsx
|
||||
// Usage
|
||||
@@ -69,10 +69,10 @@ const App = () => {
|
||||
|
||||
## One generic icon component
|
||||
|
||||
It is possible to create one generic icon component to load icons. It's not recommended.
|
||||
It is possible to create one generic icon component to load icons, but it is not recommended.
|
||||
|
||||
::: danger
|
||||
Example below importing all ES Modules, caution using this example. All icons will be imported. When using bundlers like: `Webpack`, `Rollup` or `Vite` the application build size will grow strongly and harming the performance the application.
|
||||
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important when using bundlers like `Webpack`, `Rollup`, or `Vite`.
|
||||
:::
|
||||
|
||||
### Icon Component Example
|
||||
|
||||
@@ -52,7 +52,7 @@ export default App;
|
||||
|
||||
### Applying props
|
||||
|
||||
To apply custom props to change the look of the icon, this can be done by simply pass them as props to the component.
|
||||
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements.
|
||||
|
||||
```jsx
|
||||
// Usage
|
||||
@@ -63,10 +63,10 @@ const App = () => {
|
||||
|
||||
## One generic icon component
|
||||
|
||||
It is possible to create one generic icon component to load icons.
|
||||
It is possible to create one generic icon component to load icons, but it is not recommended.
|
||||
|
||||
::: warning
|
||||
Example below importing all ES Modules, caution using this example. All icons will be imported. When using bundlers like: `Webpack`, `Rollup` or `Vite` the application build size will grow strongly and harming the performance the application.
|
||||
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important to keep in mind when using bundlers like `Webpack`, `Rollup`, or `Vite`.
|
||||
:::
|
||||
|
||||
### Icon Component Example
|
||||
|
||||
@@ -22,9 +22,9 @@ npm install lucide-react
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ES Modules so it's completely tree-shakable.
|
||||
Lucide is built with ES Modules, so it's completely tree-shakable.
|
||||
|
||||
Each icon can be imported as a React component, what renders a inline SVG Element. This way only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
Each icon can be imported as a React component, which renders an inline SVG element. This way, only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -52,7 +52,7 @@ export default App;
|
||||
|
||||
### Applying props
|
||||
|
||||
To apply custom props to change the look of the icon, this can be done by simply pass them as props to the component. All SVG attributes are available as props to style the SVGs. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
|
||||
```jsx
|
||||
// Usage
|
||||
@@ -63,10 +63,10 @@ const App = () => {
|
||||
|
||||
## One generic icon component
|
||||
|
||||
It is possible to create one generic icon component to load icons. It's not recommended.
|
||||
It is possible to create one generic icon component to load icons, but it is not recommended.
|
||||
|
||||
::: danger
|
||||
Example below importing all ES Modules, caution using this example. All icons will be imported. When using bundlers like: `Webpack`, `Rollup` or `Vite` the application build size will grow strongly and harming the performance the application.
|
||||
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important to keep in mind when using bundlers like `Webpack`, `Rollup`, or `Vite`.
|
||||
|
||||
This is not the case for the latest NextJS, because it uses server side rendering. The icons will be streamed to the client when needed. For NextJS with Dynamic Imports, see [dynamic imports](#nextjs-example) section for more information.
|
||||
:::
|
||||
@@ -99,9 +99,7 @@ export default App;
|
||||
|
||||
#### With Dynamic Imports
|
||||
|
||||
> :warning: This is experimental and only works with bundlers that support dynamic imports.
|
||||
|
||||
Lucide react exports a dynamic import map `dynamicIconImports`. Useful for applications that want to show icons dynamically by icon name. For example when using a content management system with where icon names are stored in a database.
|
||||
Lucide react exports a dynamic import map `dynamicIconImports`, which is useful for applications that want to show icons dynamically by icon name. For example, when using a content management system with where icon names are stored in a database.
|
||||
|
||||
When using client side rendering, it will fetch the icon component when it's needed. This will reduce the initial bundle size.
|
||||
|
||||
@@ -134,7 +132,21 @@ export default Icon
|
||||
|
||||
##### NextJS Example
|
||||
|
||||
In NextJS [the dynamic function](https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading#nextdynamic) can be used to load the icon component dynamically.
|
||||
In NextJS, [the dynamic function](https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading#nextdynamic) can be used to dynamically load the icon component.
|
||||
|
||||
To make dynamic imports work with NextJS, you need to add `lucide-react` to the [`transpilePackages`](https://nextjs.org/docs/app/api-reference/next-config-js/transpilePackages) option in your `next.config.js` like this:
|
||||
|
||||
```js
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
transpilePackages: ['lucide-react'] // add this
|
||||
}
|
||||
|
||||
module.exports = nextConfig
|
||||
|
||||
```
|
||||
|
||||
You can then start using it:
|
||||
|
||||
```tsx
|
||||
import dynamic from 'next/dynamic'
|
||||
|
||||
@@ -22,9 +22,9 @@ npm install lucide-solid
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ES Modules so it's completely tree-shakable.
|
||||
Lucide is built with ES Modules, so it's completely tree-shakable.
|
||||
|
||||
Each icon can be imported as a Solid component, what renders a inline SVG Element. This way only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
Each icon can be imported as a Solid component, which renders an inline SVG element. This way, only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -52,7 +52,7 @@ export default App;
|
||||
|
||||
### Applying props
|
||||
|
||||
To apply custom props to change the look of the icon, this can be done by simply pass them as props to the component. All SVG attributes are available as props to style the SVGs. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
|
||||
```jsx
|
||||
// Usage
|
||||
@@ -66,7 +66,7 @@ const App = () => {
|
||||
It is possible to create one generic icon component to load icons. It's not recommended.
|
||||
|
||||
::: danger
|
||||
Example below importing all ES Modules, caution using this example. All icons will be imported. When using bundlers like: `Webpack`, `Rollup` or `Vite` the application build size will grow strongly and harming the performance the application.
|
||||
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important to keep in mind when using bundlers like `Webpack`, `Rollup`, or `Vite`.
|
||||
:::
|
||||
|
||||
### Icon Component Example
|
||||
|
||||
@@ -22,9 +22,9 @@ npm install lucide-svelte
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ES Modules so it's completely tree-shakable.
|
||||
Lucide is built with ES Modules, so it's completely tree-shakable.
|
||||
|
||||
Each icon can be imported as a Svelte component, what renders a inline SVG Element. This way only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
Each icon can be imported as a Svelte component, which renders an inline SVG element. This way, only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -59,7 +59,7 @@ Additional props can be passed to adjust the icon:
|
||||
|
||||
### Applying props
|
||||
|
||||
To apply custom props to change the look of the icon, this can be done by simply pass them as props to the component. All SVG attributes are available as props to style the SVGs. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
|
||||
```svelte
|
||||
<script>
|
||||
@@ -73,10 +73,10 @@ This results a filled phone icon.
|
||||
|
||||
## One generic icon component
|
||||
|
||||
It is possible to create one generic icon component to load icons. It's not recommended.
|
||||
It is possible to create one generic icon component to load icons, but it is not recommended.
|
||||
|
||||
::: danger
|
||||
Example below importing all ES Modules, caution using this example. All icons will be imported. When using bundlers like: `Webpack`, `Rollup` or `Vite` the application build size will grow strongly and harming the performance the application.
|
||||
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important when using bundlers like `Webpack`, `Rollup`, or `Vite`.
|
||||
:::
|
||||
|
||||
### Icon Component Example
|
||||
|
||||
@@ -28,9 +28,9 @@ npm install lucide-vue-next
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ES Modules so it's completely tree-shakable.
|
||||
Lucide is built with ES Modules, so it's completely tree-shakable.
|
||||
|
||||
Each icon can be imported as a Vue component, what renders a inline SVG Element. This way only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
Each icon can be imported as a Vue component, which renders an inline SVG Element. This way only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -61,7 +61,7 @@ import { Camera } from 'lucide-vue-next';
|
||||
|
||||
### Applying props
|
||||
|
||||
To apply custom props to change the look of the icon, this can be done by simply pass them as props to the component. All SVG attributes are available as props to style the SVGs. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
|
||||
```vue
|
||||
<template>
|
||||
@@ -71,10 +71,10 @@ To apply custom props to change the look of the icon, this can be done by simply
|
||||
|
||||
## One generic icon component
|
||||
|
||||
It is possible to create one generic icon component to load icons. It's not recommended.
|
||||
It is possible to create one generic icon component to load icons, but it is not recommended.
|
||||
|
||||
::: danger
|
||||
Example below importing all ES Modules, caution using this example. All icons will be imported. When using bundlers like: `Webpack`, `Rollup` or `Vite` the application build size will grow strongly and harming the performance the application.
|
||||
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important when using bundlers like `Webpack`, `Rollup`, or `Vite`.
|
||||
:::
|
||||
|
||||
### Icon Component Example
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
Implementation of the lucide icon library for Vue applications.
|
||||
|
||||
::: warning
|
||||
This package will be deprecated end of 2023. Vue v2 will be EOF at the end of 2023 See [Announcement](https://v2.vuejs.org/lts/). We recommend to migrate to Vue 3.
|
||||
The Lucide Vue package will be only maintained for Vue 3 after the deprecation.
|
||||
:::
|
||||
|
||||
## Vue 2 or Vue 3
|
||||
|
||||
::: tip
|
||||
@@ -28,9 +33,9 @@ npm install lucide-vue
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ES Modules so it's completely tree-shakable.
|
||||
Lucide is built with ES Modules, so it's completely tree-shakable.
|
||||
|
||||
Each icon can be imported as a Vue component, what renders a inline SVG Element. This way only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
Each icon can be imported as a Vue component, which renders an inline SVG Element. This way only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -63,7 +68,7 @@ Additional props can be passed to adjust the icon:
|
||||
|
||||
### Applying props
|
||||
|
||||
To apply custom props to change the look of the icon, this can be done by simply pass them as props to the component. All SVG attributes are available as props to style the SVGs. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
|
||||
```vue
|
||||
<template>
|
||||
@@ -73,10 +78,10 @@ To apply custom props to change the look of the icon, this can be done by simply
|
||||
|
||||
## One generic icon component
|
||||
|
||||
It is possible to create one generic icon component to load icons. It's not recommended.
|
||||
It is possible to create one generic icon component to load icons, but it is not recommended.
|
||||
|
||||
::: danger
|
||||
Example below importing all ES Modules, caution using this example. All icons will be imported. When using bundlers like: `Webpack`, `Rollup` or `Vite` the application build size will grow strongly and harming the performance the application.
|
||||
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important when using bundlers like `Webpack`, `Rollup`, or `Vite`.
|
||||
:::
|
||||
|
||||
### Icon Component Example
|
||||
|
||||
@@ -21,6 +21,7 @@ import Label from '../.vitepress/theme/components/base/Label.vue'
|
||||
import VPButton from 'vitepress/dist/client/theme-default/components/VPButton.vue';
|
||||
import { data } from './codeExamples.data'
|
||||
import { camelCase, startCase } from 'lodash-es'
|
||||
import { satisfies } from 'semver'
|
||||
|
||||
const { params } = useData()
|
||||
|
||||
@@ -35,6 +36,12 @@ const codeExample = computed(() => data.codeExamples?.map(
|
||||
}
|
||||
).join('') ?? []
|
||||
)
|
||||
|
||||
function releaseTagLink(version) {
|
||||
const shouldAddV = satisfies(version, `<0.266.0`)
|
||||
|
||||
return `https://github.com/lucide-icons/lucide/releases/tag/${shouldAddV ? 'v' : ''}${version}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<div :class="$style.layout">
|
||||
@@ -61,7 +68,7 @@ const codeExample = computed(() => data.codeExamples?.map(
|
||||
>
|
||||
<Label>Created:</Label>
|
||||
<Badge
|
||||
:href="`https://github.com/lucide-icons/lucide/releases/tag/v${params.createdRelease.version}`"
|
||||
:href="releaseTagLink(params.createdRelease.version)"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
@@ -74,7 +81,7 @@ const codeExample = computed(() => data.codeExamples?.map(
|
||||
>
|
||||
<Label>Last changed:</Label>
|
||||
<Badge
|
||||
:href="`https://github.com/lucide-icons/lucide/releases/tag/v${params.changedRelease.version}`"
|
||||
:href="releaseTagLink(params.changedRelease.version)"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
|
||||
BIN
docs/images/absolute-stroke-width-compare.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 57 KiB |
@@ -25,11 +25,12 @@
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@types/semver": "^7.5.3",
|
||||
"h3": "^1.8.0",
|
||||
"nitropack": "npm:nitropack-edge@latest",
|
||||
"node-fetch": "2",
|
||||
"rollup-plugin-copy": "^3.4.0",
|
||||
"vitepress": "1.0.0-rc.4"
|
||||
"vitepress": "1.0.0-rc.30"
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/vue": "^1.0.1",
|
||||
@@ -47,9 +48,9 @@
|
||||
"lucide-vue-next": "workspace:*",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"sandpack-vue3": "^3.1.6",
|
||||
"semver": "^7.5.2",
|
||||
"shiki": "^0.14.2",
|
||||
"shiki-processor": "^0.1.3",
|
||||
"shikiji": "^0.7.4",
|
||||
"simple-git": "^3.18.0",
|
||||
"sitemap": "^7.1.1",
|
||||
"svg-pathdata": "^6.0.3",
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
layout: page
|
||||
outline: 2
|
||||
outlineTitle: Packages
|
||||
sidebar: true
|
||||
---
|
||||
<script setup>
|
||||
import PageContainer from '.vitepress/theme/components/PageContainer.vue'
|
||||
|
||||
28
docs/public/company-logos/noodle-dark.svg
Normal file
@@ -0,0 +1,28 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="10 -10 304 120">
|
||||
<g clip-path="url(#a)">
|
||||
<g clip-path="url(#b)">
|
||||
<path fill="url(#c)" d="M72 0H28A28 28 0 0 0 0 28v44a28 28 0 0 0 28 28h44a28 28 0 0 0 28-28V28A28 28 0 0 0 72 0Z"/>
|
||||
<path stroke="#161616" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="m47.81 54.34 26.63-6.66-19.73-19.1-26.63 6.67 19.73 19.1Z"/>
|
||||
<path stroke="#161616" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="m47.81 54.34 18.23-4.56c.67 5.86-.29 11.8-2.76 17.15a31.87 31.87 0 0 0-19.65 3.01 31.87 31.87 0 0 0-15.5-12.43 32.2 32.2 0 0 1 6.18-16.23l13.5 13.06Z"/>
|
||||
<path stroke="#161616" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="m33.37 67.04 5.17-19.32 11.84-2.96m-2.57 9.58 26.63-6.66-19.73-19.1-26.63 6.67 19.73 19.1Zm0 0 18.23-4.56c.67 5.86-.29 11.8-2.76 17.15a31.87 31.87 0 0 0-19.65 3.01 31.87 31.87 0 0 0-15.5-12.43 32.2 32.2 0 0 1 6.18-16.23l13.5 13.06Z"/>
|
||||
</g>
|
||||
<path fill="#161616" d="M281.5 67.51c-2.63 0-4.9-.54-6.8-1.64a11.08 11.08 0 0 1-4.39-4.67 15.64 15.64 0 0 1-1.53-7.14c0-2.7.51-5.05 1.53-7.09a11.6 11.6 0 0 1 4.33-4.77 12.14 12.14 0 0 1 6.53-1.72c1.62 0 3.14.26 4.57.78 1.44.51 2.72 1.3 3.82 2.39a11.18 11.18 0 0 1 2.62 4.12c.64 1.66.96 3.64.96 5.93v1.9h-21.46v-4.16h15.54a6.63 6.63 0 0 0-.76-3.16 5.58 5.58 0 0 0-2.1-2.2 5.9 5.9 0 0 0-3.1-.8c-1.26 0-2.37.31-3.33.92-.95.6-1.7 1.4-2.23 2.4a6.88 6.88 0 0 0-.8 3.21v3.63c0 1.53.28 2.83.83 3.92a5.96 5.96 0 0 0 2.34 2.5c1 .56 2.17.84 3.51.84.9 0 1.71-.12 2.44-.37a5.4 5.4 0 0 0 1.89-1.14c.53-.5.94-1.12 1.21-1.86l5.76.65a9 9 0 0 1-2.08 3.99c-1 1.12-2.3 2-3.88 2.62-1.58.61-3.39.92-5.42.92Z"/>
|
||||
<path fill="#161616" d="M263.56 32.1V67h-6.17V32.1h6.17Z"/>
|
||||
<path fill="#161616" d="M236.87 67.46a9.9 9.9 0 0 1-5.52-1.58 10.77 10.77 0 0 1-3.85-4.6 17.18 17.18 0 0 1-1.42-7.34c0-2.9.48-5.36 1.43-7.36a10.6 10.6 0 0 1 3.9-4.55 10.03 10.03 0 0 1 5.48-1.55c1.53 0 2.8.26 3.78.78a7.13 7.13 0 0 1 2.35 1.86c.58.72 1.03 1.4 1.35 2.03h.26V32.09h6.18V67h-6.06v-4.13h-.38c-.32.64-.78 1.32-1.38 2.03a7.6 7.6 0 0 1-6.12 2.56Zm1.72-5.06c1.3 0 2.42-.35 3.34-1.06a6.6 6.6 0 0 0 2.1-2.98c.48-1.27.72-2.76.72-4.45 0-1.7-.24-3.17-.72-4.42a6.28 6.28 0 0 0-2.08-2.91 5.38 5.38 0 0 0-3.36-1.04c-1.37 0-2.52.36-3.44 1.07a6.5 6.5 0 0 0-2.08 2.97c-.47 1.26-.7 2.7-.7 4.33 0 1.64.23 3.1.7 4.38a6.84 6.84 0 0 0 2.1 3.02 5.4 5.4 0 0 0 3.42 1.09Z"/>
|
||||
<path fill="#161616" d="M209.37 67.51c-2.56 0-4.77-.56-6.65-1.69a11.46 11.46 0 0 1-4.36-4.72 15.52 15.52 0 0 1-1.53-7.09c0-2.7.5-5.07 1.53-7.1a11.43 11.43 0 0 1 4.36-4.75 12.68 12.68 0 0 1 6.65-1.68c2.56 0 4.78.56 6.65 1.68a11.32 11.32 0 0 1 4.35 4.74 15.47 15.47 0 0 1 1.55 7.11c0 2.7-.52 5.07-1.55 7.1a11.34 11.34 0 0 1-4.35 4.71 12.68 12.68 0 0 1-6.65 1.7Zm.04-4.94c1.38 0 2.54-.38 3.47-1.14a6.89 6.89 0 0 0 2.08-3.1c.47-1.3.7-2.74.7-4.34 0-1.6-.23-3.05-.7-4.34a6.88 6.88 0 0 0-2.08-3.12 5.27 5.27 0 0 0-3.47-1.16c-1.42 0-2.6.39-3.55 1.16a7 7 0 0 0-2.1 3.12c-.45 1.3-.68 2.74-.68 4.34 0 1.6.23 3.04.68 4.33a7 7 0 0 0 2.1 3.1 5.46 5.46 0 0 0 3.55 1.15Z"/>
|
||||
<path fill="#161616" d="M180.17 67.51c-2.56 0-4.77-.56-6.65-1.69a11.46 11.46 0 0 1-4.36-4.72 15.52 15.52 0 0 1-1.54-7.09c0-2.7.51-5.07 1.54-7.1a11.43 11.43 0 0 1 4.36-4.75 12.68 12.68 0 0 1 6.65-1.68c2.56 0 4.77.56 6.65 1.68a11.32 11.32 0 0 1 4.34 4.74 15.49 15.49 0 0 1 1.55 7.11c0 2.7-.51 5.07-1.55 7.1a11.34 11.34 0 0 1-4.34 4.71 12.68 12.68 0 0 1-6.65 1.7Zm.03-4.94c1.39 0 2.55-.38 3.48-1.14a6.89 6.89 0 0 0 2.08-3.1c.47-1.3.7-2.74.7-4.34 0-1.6-.23-3.05-.7-4.34a6.88 6.88 0 0 0-2.08-3.12 5.26 5.26 0 0 0-3.48-1.16c-1.42 0-2.6.39-3.54 1.16a7 7 0 0 0-2.1 3.12c-.45 1.3-.68 2.74-.68 4.34 0 1.6.23 3.04.68 4.33a7 7 0 0 0 2.1 3.1 5.46 5.46 0 0 0 3.54 1.15Z"/>
|
||||
<path fill="#161616" d="M162.13 32.1V67h-5.62l-16.45-23.78h-.3V67h-6.32V32.1h5.66l16.43 23.79h.31v-23.8h6.3Z"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="a">
|
||||
<path fill="#161616" d="M0 0h293.14v100H0z"/>
|
||||
</clipPath>
|
||||
<clipPath id="b">
|
||||
<path fill="#161616" d="M0 0h100v100H0z"/>
|
||||
</clipPath>
|
||||
<linearGradient id="c" x1="0" x2="100" y1="50" y2="50" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F77062"/>
|
||||
<stop offset="1" stop-color="#FE5196"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
28
docs/public/company-logos/noodle-light.svg
Normal file
@@ -0,0 +1,28 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="10 -10 304 120">
|
||||
<g clip-path="url(#a)">
|
||||
<g clip-path="url(#b)">
|
||||
<path fill="url(#c)" d="M72 0H28A28 28 0 0 0 0 28v44a28 28 0 0 0 28 28h44a28 28 0 0 0 28-28V28A28 28 0 0 0 72 0Z"/>
|
||||
<path stroke="#161616" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="m47.81 54.34 26.63-6.66-19.73-19.1-26.63 6.67 19.73 19.1Z"/>
|
||||
<path stroke="#161616" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="m47.81 54.34 18.23-4.56c.67 5.86-.29 11.8-2.76 17.15a31.87 31.87 0 0 0-19.65 3.01 31.87 31.87 0 0 0-15.5-12.43 32.2 32.2 0 0 1 6.18-16.23l13.5 13.06Z"/>
|
||||
<path stroke="#161616" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="m33.37 67.04 5.17-19.32 11.84-2.96m-2.57 9.58 26.63-6.66-19.73-19.1-26.63 6.67 19.73 19.1Zm0 0 18.23-4.56c.67 5.86-.29 11.8-2.76 17.15a31.87 31.87 0 0 0-19.65 3.01 31.87 31.87 0 0 0-15.5-12.43 32.2 32.2 0 0 1 6.18-16.23l13.5 13.06Z"/>
|
||||
</g>
|
||||
<path fill="#fff" d="M281.5 67.51c-2.63 0-4.9-.54-6.8-1.64a11.08 11.08 0 0 1-4.39-4.67 15.64 15.64 0 0 1-1.53-7.14c0-2.7.51-5.05 1.53-7.09a11.6 11.6 0 0 1 4.33-4.77 12.14 12.14 0 0 1 6.53-1.72c1.62 0 3.14.26 4.57.78 1.44.51 2.72 1.3 3.82 2.39a11.18 11.18 0 0 1 2.62 4.12c.64 1.66.96 3.64.96 5.93v1.9h-21.46v-4.16h15.54a6.63 6.63 0 0 0-.76-3.16 5.58 5.58 0 0 0-2.1-2.2 5.9 5.9 0 0 0-3.1-.8c-1.26 0-2.37.31-3.33.92-.95.6-1.7 1.4-2.23 2.4a6.88 6.88 0 0 0-.8 3.21v3.63c0 1.53.28 2.83.83 3.92a5.96 5.96 0 0 0 2.34 2.5c1 .56 2.17.84 3.51.84.9 0 1.71-.12 2.44-.37a5.4 5.4 0 0 0 1.89-1.14c.53-.5.94-1.12 1.21-1.86l5.76.65a9 9 0 0 1-2.08 3.99c-1 1.12-2.3 2-3.88 2.62-1.58.61-3.39.92-5.42.92Z"/>
|
||||
<path fill="#fff" d="M263.56 32.1V67h-6.17V32.1h6.17Z"/>
|
||||
<path fill="#fff" d="M236.87 67.46a9.9 9.9 0 0 1-5.52-1.58 10.77 10.77 0 0 1-3.85-4.6 17.18 17.18 0 0 1-1.42-7.34c0-2.9.48-5.36 1.43-7.36a10.6 10.6 0 0 1 3.9-4.55 10.03 10.03 0 0 1 5.48-1.55c1.53 0 2.8.26 3.78.78a7.13 7.13 0 0 1 2.35 1.86c.58.72 1.03 1.4 1.35 2.03h.26V32.09h6.18V67h-6.06v-4.13h-.38c-.32.64-.78 1.32-1.38 2.03a7.6 7.6 0 0 1-6.12 2.56Zm1.72-5.06c1.3 0 2.42-.35 3.34-1.06a6.6 6.6 0 0 0 2.1-2.98c.48-1.27.72-2.76.72-4.45 0-1.7-.24-3.17-.72-4.42a6.28 6.28 0 0 0-2.08-2.91 5.38 5.38 0 0 0-3.36-1.04c-1.37 0-2.52.36-3.44 1.07a6.5 6.5 0 0 0-2.08 2.97c-.47 1.26-.7 2.7-.7 4.33 0 1.64.23 3.1.7 4.38a6.84 6.84 0 0 0 2.1 3.02 5.4 5.4 0 0 0 3.42 1.09Z"/>
|
||||
<path fill="#fff" d="M209.37 67.51c-2.56 0-4.77-.56-6.65-1.69a11.46 11.46 0 0 1-4.36-4.72 15.52 15.52 0 0 1-1.53-7.09c0-2.7.5-5.07 1.53-7.1a11.43 11.43 0 0 1 4.36-4.75 12.68 12.68 0 0 1 6.65-1.68c2.56 0 4.78.56 6.65 1.68a11.32 11.32 0 0 1 4.35 4.74 15.47 15.47 0 0 1 1.55 7.11c0 2.7-.52 5.07-1.55 7.1a11.34 11.34 0 0 1-4.35 4.71 12.68 12.68 0 0 1-6.65 1.7Zm.04-4.94c1.38 0 2.54-.38 3.47-1.14a6.89 6.89 0 0 0 2.08-3.1c.47-1.3.7-2.74.7-4.34 0-1.6-.23-3.05-.7-4.34a6.88 6.88 0 0 0-2.08-3.12 5.27 5.27 0 0 0-3.47-1.16c-1.42 0-2.6.39-3.55 1.16a7 7 0 0 0-2.1 3.12c-.45 1.3-.68 2.74-.68 4.34 0 1.6.23 3.04.68 4.33a7 7 0 0 0 2.1 3.1 5.46 5.46 0 0 0 3.55 1.15Z"/>
|
||||
<path fill="#fff" d="M180.17 67.51c-2.56 0-4.77-.56-6.65-1.69a11.46 11.46 0 0 1-4.36-4.72 15.52 15.52 0 0 1-1.54-7.09c0-2.7.51-5.07 1.54-7.1a11.43 11.43 0 0 1 4.36-4.75 12.68 12.68 0 0 1 6.65-1.68c2.56 0 4.77.56 6.65 1.68a11.32 11.32 0 0 1 4.34 4.74 15.49 15.49 0 0 1 1.55 7.11c0 2.7-.51 5.07-1.55 7.1a11.34 11.34 0 0 1-4.34 4.71 12.68 12.68 0 0 1-6.65 1.7Zm.03-4.94c1.39 0 2.55-.38 3.48-1.14a6.89 6.89 0 0 0 2.08-3.1c.47-1.3.7-2.74.7-4.34 0-1.6-.23-3.05-.7-4.34a6.88 6.88 0 0 0-2.08-3.12 5.26 5.26 0 0 0-3.48-1.16c-1.42 0-2.6.39-3.54 1.16a7 7 0 0 0-2.1 3.12c-.45 1.3-.68 2.74-.68 4.34 0 1.6.23 3.04.68 4.33a7 7 0 0 0 2.1 3.1 5.46 5.46 0 0 0 3.54 1.15Z"/>
|
||||
<path fill="#fff" d="M162.13 32.1V67h-5.62l-16.45-23.78h-.3V67h-6.32V32.1h5.66l16.43 23.79h.31v-23.8h6.3Z"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="a">
|
||||
<path fill="#fff" d="M0 0h293.14v100H0z"/>
|
||||
</clipPath>
|
||||
<clipPath id="b">
|
||||
<path fill="#fff" d="M0 0h100v100H0z"/>
|
||||
</clipPath>
|
||||
<linearGradient id="c" x1="0" x2="100" y1="50" y2="50" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F77062"/>
|
||||
<stop offset="1" stop-color="#FE5196"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
14
docs/public/company-logos/obsidian-dark.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg alt="Obsidian" height="22" viewBox="0 0 143 25" width="126" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="#A88BFA" d="m6.91927 14.5955c.64053-.1907 1.67255-.4839 2.85923-.5565-.71191-1.7968-.88376-3.3691-.74554-4.76905.15962-1.61678.72977-2.9662 1.28554-4.11442.1186-.24501.2326-.47313.3419-.69198.1549-.30984.3004-.60109.4365-.8953.2266-.48978.3948-.92231.4798-1.32416.0836-.39515.0841-.74806-.0148-1.08657-.099-.338982-.3093-.703864-.7093-1.1038132-.5222-.1353116-1.1017-.0165173-1.53613.3742922l-5.15591 4.638241c-.28758.25871-.47636.60929-.53406.99179l-.44455 2.94723c.69903.6179 2.42435 2.41414 3.47374 4.90644.09364.2224.1819.4505.26358.6838z"></path>
|
||||
<path fill="#A88BFA" d="m2.97347 10.3512c-.02431.1037-.05852.205-.10221.3024l-2.724986 6.0735c-.279882.6238-.15095061 1.3552.325357 1.8457l4.288349 4.4163c2.1899-3.2306 1.87062-6.2699.87032-8.6457-.75846-1.8013-1.90801-3.2112-2.65683-3.9922z"></path>
|
||||
<path fill="#A88BFA" d="m5.7507 23.5094c.07515.012.15135.0192.2281.0215.81383.0244 2.18251.0952 3.29249.2997.90551.1669 2.70051.6687 4.17761 1.1005 1.1271.3294 2.2886-.5707 2.4522-1.7336.1192-.8481.343-1.8075.7553-2.6869l-.0095.0033c-.6982-1.9471-1.5865-3.2044-2.5178-4.0073-.9284-.8004-1.928-1.1738-2.8932-1.3095-1.60474-.2257-3.07497.1961-4.00103.4682.55465 2.3107.38396 5.0295-1.48417 7.8441z"></path>
|
||||
<path fill="#A88BFA" d="m17.3708 19.3102c.9267-1.3985 1.5868-2.4862 1.9352-3.0758.1742-.295.1427-.6648-.0638-.9383-.5377-.7126-1.5666-2.1607-2.1272-3.5015-.5764-1.3785-.6624-3.51876-.6673-4.56119-.0019-.39626-.1275-.78328-.3726-1.09465l-3.3311-4.23183c-.0117.19075-.0392.37998-.0788.56747-.1109.52394-.32 1.04552-.5585 1.56101-.1398.30214-.3014.62583-.4646.95284-.1086.21764-.218.4368-.3222.652-.5385 1.11265-1.0397 2.32011-1.1797 3.73901-.1299 1.31514.0478 2.84484.8484 4.67094.1333.0113.2675.0262.4023.0452 1.1488.1615 2.3546.6115 3.4647 1.5685.9541.8226 1.8163 2.0012 2.5152 3.6463z"></path>
|
||||
<path fill="#151515" d="m39.752 4.5038c-5.952 0-10.248 3.744-10.248 8.88s4.296 8.88 10.248 8.88c5.928 0 10.224-3.744 10.224-8.88s-4.296-8.88-10.224-8.88zm0 3.47999c3.576 0 6.144 2.13601 6.144 5.40001s-2.568 5.4-6.144 5.4c-3.6 0-6.168-2.136-6.168-5.4s2.568-5.40001 6.168-5.40001z"></path>
|
||||
<path fill="#151515" d="m55.4847 20.5598c.864.936 2.472 1.704 4.584 1.704 4.32 0 6.8401-2.976 6.8401-6.576 0-3.624-2.5201-6.60001-6.8401-6.60001-2.112 0-3.72.79201-4.584 1.70401v-6.02401h-3.84v17.23201h3.84zm-.12-4.944c0-1.992 1.704-3.432 3.912-3.432 2.112 0 3.888 1.248 3.888 3.504s-1.776 3.48-3.888 3.48c-2.208 0-3.912-1.416-3.912-3.408z"></path>
|
||||
<path fill="#151515" d="m67.3181 19.9118c1.464 1.488 4.272 2.352 7.2 2.352 3.96 0 6.936-1.44 6.936-4.392 0-2.88-2.832-3.432-6.072-3.816-2.736-.312-3.576-.384-3.576-1.08 0-.648.864-1.056 2.496-1.056 1.968 0 3.672.6 4.824 1.656l1.992-2.304c-1.272-1.224-3.648-2.18401-6.624-2.18401-4.008 0-6.48 1.72801-6.48 4.32001 0 2.712 2.52 3.312 5.544 3.696 2.832.336 4.032.336 4.032 1.176 0 .792-1.056 1.128-2.784 1.128-2.16 0-4.152-.672-5.664-2.064z"></path>
|
||||
<path fill="#151515" d="m82.8395 8.05579h3.912v-3.288h-3.912zm3.864 1.29601h-3.84v12.648h3.84z"></path>
|
||||
<path fill="#151515" d="m99.8264 20.5598v1.44h3.8396v-17.23201h-3.8396v6.02401c-.864-.912-2.472-1.70401-4.584-1.70401-4.32 0-6.84 2.97601-6.84 6.60001 0 3.6 2.52 6.576 6.84 6.576 2.112 0 3.72-.768 4.584-1.704zm.12-4.944v.144c0 1.992-1.704 3.408-3.912 3.408-2.112 0-3.888-1.224-3.888-3.48s1.776-3.504 3.888-3.504c2.208 0 3.912 1.44 3.912 3.432z"></path>
|
||||
<path fill="#151515" d="m105.996 8.05579h3.912v-3.288h-3.912zm3.864 1.29601h-3.84v12.648h3.84z"></path>
|
||||
<path fill="#151515" d="m116.863 22.2638c2.232 0 4.056-.648 5.208-1.656.648 1.2 2.184 1.92 4.992 1.392v-2.832c-1.344.288-1.632-.024-1.632-.696v-4.608c0-3.168-2.376-4.77601-6.408-4.77601-3.48 0-6.264 1.51201-7.056 3.79201l3.456.936c.384-.984 1.704-1.704 3.432-1.704 2.04 0 2.856.768 2.856 1.728v.072l-5.04.456c-2.976.288-5.16 1.512-5.16 3.984 0 2.496 2.232 3.912 5.352 3.912zm4.848-5.112c0 1.464-2.184 2.304-4.152 2.304-1.488 0-2.328-.432-2.328-1.248 0-.84.672-1.152 1.992-1.272l4.488-.456z"></path>
|
||||
<path fill="#151515" d="m128.379 21.9998h3.84v-6.048c0-2.184 1.2-3.456 3.288-3.456 1.968 0 3 1.296 3 3.432v6.072h3.84v-7.2c0-3.504-2.232-5.71201-5.52-5.71201-2.04 0-3.624.76801-4.608 1.80001v-1.536h-3.84z"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
14
docs/public/company-logos/obsidian-light.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg alt="Obsidian" height="22" viewBox="0 0 143 25" width="126" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="#A88BFA" d="m6.91927 14.5955c.64053-.1907 1.67255-.4839 2.85923-.5565-.71191-1.7968-.88376-3.3691-.74554-4.76905.15962-1.61678.72977-2.9662 1.28554-4.11442.1186-.24501.2326-.47313.3419-.69198.1549-.30984.3004-.60109.4365-.8953.2266-.48978.3948-.92231.4798-1.32416.0836-.39515.0841-.74806-.0148-1.08657-.099-.338982-.3093-.703864-.7093-1.1038132-.5222-.1353116-1.1017-.0165173-1.53613.3742922l-5.15591 4.638241c-.28758.25871-.47636.60929-.53406.99179l-.44455 2.94723c.69903.6179 2.42435 2.41414 3.47374 4.90644.09364.2224.1819.4505.26358.6838z"></path>
|
||||
<path fill="#A88BFA" d="m2.97347 10.3512c-.02431.1037-.05852.205-.10221.3024l-2.724986 6.0735c-.279882.6238-.15095061 1.3552.325357 1.8457l4.288349 4.4163c2.1899-3.2306 1.87062-6.2699.87032-8.6457-.75846-1.8013-1.90801-3.2112-2.65683-3.9922z"></path>
|
||||
<path fill="#A88BFA" d="m5.7507 23.5094c.07515.012.15135.0192.2281.0215.81383.0244 2.18251.0952 3.29249.2997.90551.1669 2.70051.6687 4.17761 1.1005 1.1271.3294 2.2886-.5707 2.4522-1.7336.1192-.8481.343-1.8075.7553-2.6869l-.0095.0033c-.6982-1.9471-1.5865-3.2044-2.5178-4.0073-.9284-.8004-1.928-1.1738-2.8932-1.3095-1.60474-.2257-3.07497.1961-4.00103.4682.55465 2.3107.38396 5.0295-1.48417 7.8441z"></path>
|
||||
<path fill="#A88BFA" d="m17.3708 19.3102c.9267-1.3985 1.5868-2.4862 1.9352-3.0758.1742-.295.1427-.6648-.0638-.9383-.5377-.7126-1.5666-2.1607-2.1272-3.5015-.5764-1.3785-.6624-3.51876-.6673-4.56119-.0019-.39626-.1275-.78328-.3726-1.09465l-3.3311-4.23183c-.0117.19075-.0392.37998-.0788.56747-.1109.52394-.32 1.04552-.5585 1.56101-.1398.30214-.3014.62583-.4646.95284-.1086.21764-.218.4368-.3222.652-.5385 1.11265-1.0397 2.32011-1.1797 3.73901-.1299 1.31514.0478 2.84484.8484 4.67094.1333.0113.2675.0262.4023.0452 1.1488.1615 2.3546.6115 3.4647 1.5685.9541.8226 1.8163 2.0012 2.5152 3.6463z"></path>
|
||||
<path fill="#fff" d="m39.752 4.5038c-5.952 0-10.248 3.744-10.248 8.88s4.296 8.88 10.248 8.88c5.928 0 10.224-3.744 10.224-8.88s-4.296-8.88-10.224-8.88zm0 3.47999c3.576 0 6.144 2.13601 6.144 5.40001s-2.568 5.4-6.144 5.4c-3.6 0-6.168-2.136-6.168-5.4s2.568-5.40001 6.168-5.40001z"></path>
|
||||
<path fill="#fff" d="m55.4847 20.5598c.864.936 2.472 1.704 4.584 1.704 4.32 0 6.8401-2.976 6.8401-6.576 0-3.624-2.5201-6.60001-6.8401-6.60001-2.112 0-3.72.79201-4.584 1.70401v-6.02401h-3.84v17.23201h3.84zm-.12-4.944c0-1.992 1.704-3.432 3.912-3.432 2.112 0 3.888 1.248 3.888 3.504s-1.776 3.48-3.888 3.48c-2.208 0-3.912-1.416-3.912-3.408z"></path>
|
||||
<path fill="#fff" d="m67.3181 19.9118c1.464 1.488 4.272 2.352 7.2 2.352 3.96 0 6.936-1.44 6.936-4.392 0-2.88-2.832-3.432-6.072-3.816-2.736-.312-3.576-.384-3.576-1.08 0-.648.864-1.056 2.496-1.056 1.968 0 3.672.6 4.824 1.656l1.992-2.304c-1.272-1.224-3.648-2.18401-6.624-2.18401-4.008 0-6.48 1.72801-6.48 4.32001 0 2.712 2.52 3.312 5.544 3.696 2.832.336 4.032.336 4.032 1.176 0 .792-1.056 1.128-2.784 1.128-2.16 0-4.152-.672-5.664-2.064z"></path>
|
||||
<path fill="#fff" d="m82.8395 8.05579h3.912v-3.288h-3.912zm3.864 1.29601h-3.84v12.648h3.84z"></path>
|
||||
<path fill="#fff" d="m99.8264 20.5598v1.44h3.8396v-17.23201h-3.8396v6.02401c-.864-.912-2.472-1.70401-4.584-1.70401-4.32 0-6.84 2.97601-6.84 6.60001 0 3.6 2.52 6.576 6.84 6.576 2.112 0 3.72-.768 4.584-1.704zm.12-4.944v.144c0 1.992-1.704 3.408-3.912 3.408-2.112 0-3.888-1.224-3.888-3.48s1.776-3.504 3.888-3.504c2.208 0 3.912 1.44 3.912 3.432z"></path>
|
||||
<path fill="#fff" d="m105.996 8.05579h3.912v-3.288h-3.912zm3.864 1.29601h-3.84v12.648h3.84z"></path>
|
||||
<path fill="#fff" d="m116.863 22.2638c2.232 0 4.056-.648 5.208-1.656.648 1.2 2.184 1.92 4.992 1.392v-2.832c-1.344.288-1.632-.024-1.632-.696v-4.608c0-3.168-2.376-4.77601-6.408-4.77601-3.48 0-6.264 1.51201-7.056 3.79201l3.456.936c.384-.984 1.704-1.704 3.432-1.704 2.04 0 2.856.768 2.856 1.728v.072l-5.04.456c-2.976.288-5.16 1.512-5.16 3.984 0 2.496 2.232 3.912 5.352 3.912zm4.848-5.112c0 1.464-2.184 2.304-4.152 2.304-1.488 0-2.328-.432-2.328-1.248 0-.84.672-1.152 1.992-1.272l4.488-.456z"></path>
|
||||
<path fill="#fff" d="m128.379 21.9998h3.84v-6.048c0-2.184 1.2-3.456 3.288-3.456 1.968 0 3 1.296 3 3.432v6.072h3.84v-7.2c0-3.504-2.232-5.71201-5.52-5.71201-2.04 0-3.624.76801-4.608 1.80001v-1.536h-3.84z"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
5
docs/public/company-logos/open-collective-dark.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="22 268.7 600 106">
|
||||
<path fill="#b8d3f4" d="M109 321.8c0 6.7-1.9 13.1-5.3 18.4l13.6 13.7c6.7-8.9 10.8-20.1 10.8-32.1s-4.2-23.2-10.8-32.1l-13.6 13.7c3.3 5.3 5.3 11.5 5.3 18.4z"/>
|
||||
<path fill="#3385ff" d="M75.1 355.9c-18.6 0-33.9-15.4-33.9-34.1 0-18.7 15.3-34.1 33.9-34.1 6.9 0 13.1 2 18.3 5.6l13.6-13.7c-8.9-6.7-20-10.9-32-10.9-29.2 0-53.1 23.7-53.1 53.3s23.9 53 53.1 53c12.2 0 23.4-4.2 32.2-10.9l-13.6-13.7c-5.2 3.5-11.6 5.5-18.5 5.5z"/>
|
||||
<path fill="#000" d="M604.45 333.8c-3.4 0-6.4-1.4-8.5-3.8-.1-.2-.1-.5.1-.6l19.9-8.4 5.8-2.5c.2-.1.2-.2.2-.4a18 18 0 0 0-18.1-13.9c-9.2.4-17 7.8-17.3 17.1a18.01 18.01 0 0 0 34.6 7.8c.1-.2 0-.5-.2-.5l-5.8-1.1c-.1 0-.4 0-.4.2-2.1 3.6-5.9 6.1-10.3 6.1zm0-23c3.4 0 6.5 1.5 8.5 3.9.1.2.1.5-.1.6 0 0-19.2 8.2-19.4 8.3-.2.1-.5-.1-.5-.2v-.9c-.1-6.6 5.1-11.7 11.5-11.7zM585.75 304.8h-5.7c-.1 0-.2.1-.4.2l-9.2 27.1c-.2.6-.9.6-1.2 0l-9.2-27.1c0-.1-.1-.2-.4-.2h-5.7c-.2 0-.4.2-.4.5l11.7 34.1c0 .1.1.2.4.2h8.1c.1 0 .2-.1.4-.2l11.7-34.1c.2-.2.1-.5-.1-.5zM548.25 304.8h-5.8c-.2 0-.4.1-.4.4v34.1c0 .2.1.4.4.4h5.8c.2 0 .4-.1.4-.4v-34.1c0-.1-.2-.4-.4-.4zM548.25 293.7h-5.8c-.2 0-.4.1-.4.4v5.8c0 .2.1.4.4.4h5.8c.2 0 .4-.1.4-.4V294c0-.2-.2-.3-.4-.3zM536.25 304.8h-6.5c-.1 0-.2-.1-.2-.2v-14.8c0-.2-.1-.4-.4-.4h-5.8c-.2 0-.4.1-.4.4v14.8c0 .1-.1.2-.2.2h-6.4c-.2 0-.4.1-.4.4v5.8c0 .2.1.4.4.4h6.4c.1 0 .2.1.2.2v27.7c0 .2.1.4.4.4h5.8c.2 0 .4-.1.4-.4v-27.7c0-.1.1-.2.2-.2h6.5c.2 0 .4-.1.4-.4v-5.8c0-.1-.3-.4-.4-.4zM498.25 333.8c-7.1 0-12.7-6.4-11.4-13.8.7-4 4.7-8.2 8.8-9 4.4-.9 8.5.6 11.1 3.6.1.1.4.1.5 0l4.1-4.1c.1-.1.1-.4 0-.5-3.4-3.8-8.5-6-14.1-5.8-9.1.5-16.7 7.9-17.2 17.1-.5 10.3 7.7 18.9 18 18.9 5.2 0 10-2.3 13.3-5.8.1-.1.1-.2 0-.4l-4.1-4.1c-.1-.1-.4-.1-.5 0-2 2.4-5.1 3.9-8.5 3.9zM459.45 333.8c-3.4 0-6.4-1.4-8.5-3.8-.1-.2-.1-.5.1-.6l19.9-8.4 5.8-2.5c.2-.1.2-.2.2-.4a18 18 0 0 0-18.1-13.9c-9.2.4-17 7.8-17.3 17.1a18.01 18.01 0 0 0 34.6 7.8c.1-.2 0-.5-.2-.5l-5.8-1.1c-.1 0-.4 0-.4.2-2.1 3.6-6 6.1-10.3 6.1zm0-23c3.4 0 6.5 1.5 8.5 3.9.1.2.1.5-.1.6 0 0-19.2 8.2-19.4 8.3-.2.1-.5-.1-.5-.2v-.9c-.1-6.6 5.1-11.7 11.5-11.7zM436.55 289.4h-5.8c-.2 0-.4.1-.4.4v49.6c0 .2.1.4.4.4h5.8c.2 0 .4-.1.4-.4v-49.6c0-.3-.3-.4-.4-.4zM423.85 289.4h-5.8c-.2 0-.4.1-.4.4v49.6c0 .2.1.4.4.4h5.8c.2 0 .4-.1.4-.4v-49.6c-.1-.3-.3-.4-.4-.4zM395.45 310.8c6.4 0 11.5 5.2 11.5 11.5s-5.2 11.5-11.5 11.5-11.5-5.2-11.5-11.5 5.1-11.5 11.5-11.5zm0-6.6a17.99 17.99 0 1 0-.03 35.98 17.99 17.99 0 0 0 .03-35.98zM362.35 333.8c-7.1 0-12.7-6.4-11.4-13.8.7-4 4.7-8.2 8.8-9 4.4-.9 8.5.6 11.1 3.6.1.1.4.1.5 0l4.1-4.1c.1-.1.1-.4 0-.5-3.4-3.8-8.5-6-14.1-5.8-9.1.5-16.7 7.9-17.2 17.1-.5 10.3 7.7 18.9 18 18.9 5.2 0 10-2.3 13.3-5.8.1-.1.1-.2 0-.4l-4.1-4.1c-.1-.1-.4-.1-.5 0-2 2.4-5.1 3.9-8.5 3.9zM303.45 304.2c-3.8 0-8.2 2.4-10.2 5.2-.1.2-.6.1-.6-.1v-4.1c0-.1-.1-.4-.4-.4h-5.8c-.1 0-.4.1-.4.4v34.3c0 .1.1.4.4.4h5.8c.1 0 .4-.1.4-.4v-17.1c0-6.5 4.4-11.1 10.7-11.1 8.3 0 10.8 5.5 10.8 11.9v16.4c0 .1.1.4.4.4h5.8c.1 0 .4-.1.4-.4v-16.4c0-10.1-4.8-19-17.3-19zM265.15 333.8c-3.4 0-6.4-1.4-8.5-3.8-.1-.2-.1-.5.1-.6l19.9-8.4 5.8-2.5c.2-.1.2-.2.2-.4a18 18 0 0 0-18.1-13.9c-9.2.4-17 7.8-17.3 17.1a18.01 18.01 0 0 0 34.6 7.8c.1-.2 0-.5-.2-.5l-5.8-1.1c-.1 0-.4 0-.4.2-2.2 3.6-6 6.1-10.3 6.1zm0-23c3.4 0 6.5 1.5 8.5 3.9.1.2.1.5-.1.6 0 0-19.2 8.2-19.4 8.3-.2.1-.5-.1-.5-.2v-.9c0-6.6 5.2-11.7 11.5-11.7zM225.75 303.9c-4.5.1-8.1 1.9-10.6 4.9-.2.2-.6.1-.6-.2v-3.3c0-.2-.1-.4-.4-.4h-5.8c-.2 0-.4.1-.4.4V355c0 .2.1.4.4.4h5.7c.2 0 .4-.1.4-.4v-19.6c0-.4.4-.5.6-.2 2.5 3 6.2 4.9 10.9 4.9 11 0 19.8-10 17.7-21.3-1.4-8.9-9.2-15-17.9-14.9zm2.2 29.4c-7.8 1.3-14.6-5.5-13.3-13.3.8-4.7 4.6-8.7 9.4-9.4 7.8-1.3 14.6 5.5 13.3 13.3-.7 4.8-4.6 8.5-9.4 9.4zM186.75 304.2a17.99 17.99 0 1 0 0 36 17.99 17.99 0 1 0 0-36zm0 6.6c6.4 0 11.5 5.2 11.5 11.5s-5.2 11.5-11.5 11.5-11.5-5.2-11.5-11.5 5.2-11.5 11.5-11.5z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
5
docs/public/company-logos/open-collective-light.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="22 268.7 600 106">
|
||||
<path fill="#b8d3f4" d="M109 321.8c0 6.7-1.9 13.1-5.3 18.4l13.6 13.7c6.7-8.9 10.8-20.1 10.8-32.1s-4.2-23.2-10.8-32.1l-13.6 13.7c3.3 5.3 5.3 11.5 5.3 18.4z"/>
|
||||
<path fill="#3385ff" d="M75.1 355.9c-18.6 0-33.9-15.4-33.9-34.1 0-18.7 15.3-34.1 33.9-34.1 6.9 0 13.1 2 18.3 5.6l13.6-13.7c-8.9-6.7-20-10.9-32-10.9-29.2 0-53.1 23.7-53.1 53.3s23.9 53 53.1 53c12.2 0 23.4-4.2 32.2-10.9l-13.6-13.7c-5.2 3.5-11.6 5.5-18.5 5.5z"/>
|
||||
<path fill="#fff" d="M604.45 333.8c-3.4 0-6.4-1.4-8.5-3.8-.1-.2-.1-.5.1-.6l19.9-8.4 5.8-2.5c.2-.1.2-.2.2-.4a18 18 0 0 0-18.1-13.9c-9.2.4-17 7.8-17.3 17.1a18.01 18.01 0 0 0 34.6 7.8c.1-.2 0-.5-.2-.5l-5.8-1.1c-.1 0-.4 0-.4.2-2.1 3.6-5.9 6.1-10.3 6.1zm0-23c3.4 0 6.5 1.5 8.5 3.9.1.2.1.5-.1.6 0 0-19.2 8.2-19.4 8.3-.2.1-.5-.1-.5-.2v-.9c-.1-6.6 5.1-11.7 11.5-11.7zM585.75 304.8h-5.7c-.1 0-.2.1-.4.2l-9.2 27.1c-.2.6-.9.6-1.2 0l-9.2-27.1c0-.1-.1-.2-.4-.2h-5.7c-.2 0-.4.2-.4.5l11.7 34.1c0 .1.1.2.4.2h8.1c.1 0 .2-.1.4-.2l11.7-34.1c.2-.2.1-.5-.1-.5zM548.25 304.8h-5.8c-.2 0-.4.1-.4.4v34.1c0 .2.1.4.4.4h5.8c.2 0 .4-.1.4-.4v-34.1c0-.1-.2-.4-.4-.4zM548.25 293.7h-5.8c-.2 0-.4.1-.4.4v5.8c0 .2.1.4.4.4h5.8c.2 0 .4-.1.4-.4V294c0-.2-.2-.3-.4-.3zM536.25 304.8h-6.5c-.1 0-.2-.1-.2-.2v-14.8c0-.2-.1-.4-.4-.4h-5.8c-.2 0-.4.1-.4.4v14.8c0 .1-.1.2-.2.2h-6.4c-.2 0-.4.1-.4.4v5.8c0 .2.1.4.4.4h6.4c.1 0 .2.1.2.2v27.7c0 .2.1.4.4.4h5.8c.2 0 .4-.1.4-.4v-27.7c0-.1.1-.2.2-.2h6.5c.2 0 .4-.1.4-.4v-5.8c0-.1-.3-.4-.4-.4zM498.25 333.8c-7.1 0-12.7-6.4-11.4-13.8.7-4 4.7-8.2 8.8-9 4.4-.9 8.5.6 11.1 3.6.1.1.4.1.5 0l4.1-4.1c.1-.1.1-.4 0-.5-3.4-3.8-8.5-6-14.1-5.8-9.1.5-16.7 7.9-17.2 17.1-.5 10.3 7.7 18.9 18 18.9 5.2 0 10-2.3 13.3-5.8.1-.1.1-.2 0-.4l-4.1-4.1c-.1-.1-.4-.1-.5 0-2 2.4-5.1 3.9-8.5 3.9zM459.45 333.8c-3.4 0-6.4-1.4-8.5-3.8-.1-.2-.1-.5.1-.6l19.9-8.4 5.8-2.5c.2-.1.2-.2.2-.4a18 18 0 0 0-18.1-13.9c-9.2.4-17 7.8-17.3 17.1a18.01 18.01 0 0 0 34.6 7.8c.1-.2 0-.5-.2-.5l-5.8-1.1c-.1 0-.4 0-.4.2-2.1 3.6-6 6.1-10.3 6.1zm0-23c3.4 0 6.5 1.5 8.5 3.9.1.2.1.5-.1.6 0 0-19.2 8.2-19.4 8.3-.2.1-.5-.1-.5-.2v-.9c-.1-6.6 5.1-11.7 11.5-11.7zM436.55 289.4h-5.8c-.2 0-.4.1-.4.4v49.6c0 .2.1.4.4.4h5.8c.2 0 .4-.1.4-.4v-49.6c0-.3-.3-.4-.4-.4zM423.85 289.4h-5.8c-.2 0-.4.1-.4.4v49.6c0 .2.1.4.4.4h5.8c.2 0 .4-.1.4-.4v-49.6c-.1-.3-.3-.4-.4-.4zM395.45 310.8c6.4 0 11.5 5.2 11.5 11.5s-5.2 11.5-11.5 11.5-11.5-5.2-11.5-11.5 5.1-11.5 11.5-11.5zm0-6.6a17.99 17.99 0 1 0-.03 35.98 17.99 17.99 0 0 0 .03-35.98zM362.35 333.8c-7.1 0-12.7-6.4-11.4-13.8.7-4 4.7-8.2 8.8-9 4.4-.9 8.5.6 11.1 3.6.1.1.4.1.5 0l4.1-4.1c.1-.1.1-.4 0-.5-3.4-3.8-8.5-6-14.1-5.8-9.1.5-16.7 7.9-17.2 17.1-.5 10.3 7.7 18.9 18 18.9 5.2 0 10-2.3 13.3-5.8.1-.1.1-.2 0-.4l-4.1-4.1c-.1-.1-.4-.1-.5 0-2 2.4-5.1 3.9-8.5 3.9zM303.45 304.2c-3.8 0-8.2 2.4-10.2 5.2-.1.2-.6.1-.6-.1v-4.1c0-.1-.1-.4-.4-.4h-5.8c-.1 0-.4.1-.4.4v34.3c0 .1.1.4.4.4h5.8c.1 0 .4-.1.4-.4v-17.1c0-6.5 4.4-11.1 10.7-11.1 8.3 0 10.8 5.5 10.8 11.9v16.4c0 .1.1.4.4.4h5.8c.1 0 .4-.1.4-.4v-16.4c0-10.1-4.8-19-17.3-19zM265.15 333.8c-3.4 0-6.4-1.4-8.5-3.8-.1-.2-.1-.5.1-.6l19.9-8.4 5.8-2.5c.2-.1.2-.2.2-.4a18 18 0 0 0-18.1-13.9c-9.2.4-17 7.8-17.3 17.1a18.01 18.01 0 0 0 34.6 7.8c.1-.2 0-.5-.2-.5l-5.8-1.1c-.1 0-.4 0-.4.2-2.2 3.6-6 6.1-10.3 6.1zm0-23c3.4 0 6.5 1.5 8.5 3.9.1.2.1.5-.1.6 0 0-19.2 8.2-19.4 8.3-.2.1-.5-.1-.5-.2v-.9c0-6.6 5.2-11.7 11.5-11.7zM225.75 303.9c-4.5.1-8.1 1.9-10.6 4.9-.2.2-.6.1-.6-.2v-3.3c0-.2-.1-.4-.4-.4h-5.8c-.2 0-.4.1-.4.4V355c0 .2.1.4.4.4h5.7c.2 0 .4-.1.4-.4v-19.6c0-.4.4-.5.6-.2 2.5 3 6.2 4.9 10.9 4.9 11 0 19.8-10 17.7-21.3-1.4-8.9-9.2-15-17.9-14.9zm2.2 29.4c-7.8 1.3-14.6-5.5-13.3-13.3.8-4.7 4.6-8.7 9.4-9.4 7.8-1.3 14.6 5.5 13.3 13.3-.7 4.8-4.6 8.5-9.4 9.4zM186.75 304.2a17.99 17.99 0 1 0 0 36 17.99 17.99 0 1 0 0-36zm0 6.6c6.4 0 11.5 5.2 11.5 11.5s-5.2 11.5-11.5 11.5-11.5-5.2-11.5-11.5 5.2-11.5 11.5-11.5z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |