Compare commits
20 Commits
version-se
...
next
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5fab4e7bc8 | ||
|
|
d391bda369 | ||
|
|
69bf052ee5 | ||
|
|
6b4075b89b | ||
|
|
7a68e10b12 | ||
|
|
a4531a9985 | ||
|
|
3edcd9e0c3 | ||
|
|
0b8f99326c | ||
|
|
881e733159 | ||
|
|
7abb61630e | ||
|
|
3b0d158ea1 | ||
|
|
124572c83b | ||
|
|
d58a2e43c6 | ||
|
|
5ecf78bb8a | ||
|
|
aa8f74eb9e | ||
|
|
7327637532 | ||
|
|
08bd4b33a0 | ||
|
|
b1675c4c33 | ||
|
|
758fa4b75f | ||
|
|
7bbb1e1fea |
@@ -9,9 +9,3 @@ strikethrough
|
||||
touchpad
|
||||
ungroup
|
||||
toc
|
||||
|
||||
# Brands
|
||||
codepen
|
||||
codesandbox
|
||||
dribbble
|
||||
x.com
|
||||
|
||||
43
.github/workflows/lucide-vue.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: Lucide Vue checks
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- packages/lucide-vue/**
|
||||
- packages/shared/**
|
||||
- tools/build-icons/**
|
||||
- tools/rollup-plugins/**
|
||||
- pnpm-lock.yaml
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: 'pnpm'
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter @lucide/vue build
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: 'pnpm'
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Test
|
||||
run: pnpm --filter @lucide/vue test
|
||||
1
.github/workflows/release.yml
vendored
@@ -60,6 +60,7 @@ jobs:
|
||||
'lucide-svelte',
|
||||
'@lucide/astro',
|
||||
'@lucide/svelte',
|
||||
'@lucide/vue',
|
||||
]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"adobe": "Adobe",
|
||||
"airplay": "AirPlay",
|
||||
"amazon": "Amazon",
|
||||
"android": "Android",
|
||||
"angular": "Angular",
|
||||
"aws": "AWS",
|
||||
"azure": "Azure",
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Brands",
|
||||
"icon": "facebook"
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { eventHandler, setResponseHeader } from 'h3';
|
||||
import releaseMeta from '../../data/releaseMetaData.json';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
setResponseHeader(event, 'Cache-Control', 'public, max-age=86400');
|
||||
setResponseHeader(event, 'Access-Control-Allow-Origin', '*');
|
||||
|
||||
return Object.fromEntries(
|
||||
Object.entries(releaseMeta).map(
|
||||
([name, { createdRelease }]) => [name, createdRelease.version]
|
||||
)
|
||||
);
|
||||
});
|
||||
3
docs/.vitepress/api/test.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default eventHandler(() => {
|
||||
return { nitro: 'Is Awesome! asda' };
|
||||
});
|
||||
@@ -15,10 +15,6 @@
|
||||
"name": "arrows",
|
||||
"title": "Arrows"
|
||||
},
|
||||
{
|
||||
"name": "brands",
|
||||
"title": "Brands"
|
||||
},
|
||||
{
|
||||
"name": "buildings",
|
||||
"title": "Buildings"
|
||||
|
||||
@@ -31,20 +31,12 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-vue-next": {
|
||||
"@lucide/vue": {
|
||||
"order": 2,
|
||||
"icon": "vue-next",
|
||||
"icon": "vue",
|
||||
"docsAlias": "lucide-vue",
|
||||
"packageDirname": "vue",
|
||||
"shields": [
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/v/lucide-vue-next",
|
||||
"href": "https://www.npmjs.com/package/lucide-vue-next"
|
||||
},
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/dw/lucide-vue-next",
|
||||
"href": "https://www.npmjs.com/package/lucide-vue-next"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-svelte": {
|
||||
|
||||
@@ -43,7 +43,7 @@ export default App;
|
||||
language: 'vue',
|
||||
title: 'Vue',
|
||||
code: `<script setup>
|
||||
import { $PascalCase } from 'lucide-vue-next';
|
||||
import { $PascalCase } from '@lucide/vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createLucideIcon } from 'lucide-react/src/lucide-react';
|
||||
import { type LucideProps, type IconNode } from 'lucide-react/src/createLucideIcon';
|
||||
import { type LucideProps, type IconNode } from 'lucide-react/src/types';
|
||||
import { IconEntity } from '../theme/types';
|
||||
import { renderToStaticMarkup } from 'react-dom/server';
|
||||
import { IconContent } from './generateZip';
|
||||
|
||||
@@ -74,7 +74,7 @@ const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
|
||||
},
|
||||
{
|
||||
text: 'Lucide Vue',
|
||||
link: '/guide/packages/lucide-vue-next',
|
||||
link: '/guide/packages/lucide-vue',
|
||||
},
|
||||
{
|
||||
text: 'Lucide Svelte',
|
||||
|
||||
@@ -1,23 +1,31 @@
|
||||
<script setup lang="ts">
|
||||
import { useData } from 'vitepress';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: string
|
||||
id: string
|
||||
}>()
|
||||
modelValue: string;
|
||||
id: string;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const { isDark } = useData();
|
||||
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const value = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emit('update:modelValue', val)
|
||||
})
|
||||
get: () => {
|
||||
if (props.modelValue == null || props.modelValue === 'currentColor') {
|
||||
return isDark.value ? '#ffffff' : '#000000';
|
||||
}
|
||||
|
||||
return props.modelValue;
|
||||
},
|
||||
set: (val) => emit('update:modelValue', val),
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="color-picker">
|
||||
<div class="color-input-wrapper">
|
||||
<!-- TODO: Add currentColor div if value is currentColor -->
|
||||
<input
|
||||
type="color"
|
||||
:id="id"
|
||||
@@ -33,6 +41,7 @@ const value = computed({
|
||||
class="color-input-text"
|
||||
aria-label="Color picker input"
|
||||
v-model="value"
|
||||
placeholder="[default]"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -45,27 +54,33 @@ const value = computed({
|
||||
top: -5px;
|
||||
left: -5px;
|
||||
}
|
||||
|
||||
.color-input-wrapper {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
border-radius: 12px;
|
||||
border-radius: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.color-picker {
|
||||
background: var(--color-picker-bg, var(--vp-c-bg-alt));
|
||||
border-radius: 8px;
|
||||
color: var(--vp-c-text-2);
|
||||
padding: 4px 8px;
|
||||
padding: 3px 8px 3px 3px;
|
||||
height: auto;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
border: 1px solid transparent;
|
||||
cursor: text;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
transition:
|
||||
color 0.25s,
|
||||
border-color 0.25s,
|
||||
background-color 0.25s;
|
||||
}
|
||||
|
||||
.color-input-text {
|
||||
@@ -75,19 +90,22 @@ const value = computed({
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--vp-c-text-1);
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
border-radius: 8px;
|
||||
cursor: text;
|
||||
transition: border-color 0.25s, background 0.4s ease;
|
||||
transition:
|
||||
border-color 0.25s,
|
||||
background 0.4s ease;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.color-picker:hover, .color-picker:focus {
|
||||
.color-picker:hover,
|
||||
.color-picker:focus {
|
||||
border-color: var(--vp-c-brand);
|
||||
background: var(--vp-c-bg-alt);
|
||||
}
|
||||
|
||||
.color-input[value="currentColor"] {
|
||||
|
||||
.color-input[value='currentColor'] {
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
<script setup>
|
||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon'
|
||||
import { search } from '../../../data/iconNodes'
|
||||
|
||||
const SearchIcon = createLucideIcon('search', search)
|
||||
import Icon from 'lucide-vue-next/src/Icon';
|
||||
import { search } from '../../../data/iconNodes';
|
||||
|
||||
defineProps({
|
||||
shortcut: {
|
||||
type: String,
|
||||
required: false
|
||||
}
|
||||
})
|
||||
required: false,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button class="fake-input">
|
||||
<component :is="SearchIcon" class="search-icon"/>
|
||||
<slot/>
|
||||
<kbd v-if="shortcut" class="shortcut">{{ shortcut }}</kbd>
|
||||
<Icon
|
||||
:iconNode="search"
|
||||
class="search-icon"
|
||||
/>
|
||||
<slot />
|
||||
<kbd
|
||||
v-if="shortcut"
|
||||
class="shortcut"
|
||||
>{{ shortcut }}</kbd
|
||||
>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
@@ -34,10 +39,14 @@ defineProps({
|
||||
cursor: text;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
transition: color 0.25s, border-color 0.25s, background-color 0.25s;
|
||||
transition:
|
||||
color 0.25s,
|
||||
border-color 0.25s,
|
||||
background-color 0.25s;
|
||||
}
|
||||
|
||||
.fake-input:hover, .fake-input:focus {
|
||||
.fake-input:hover,
|
||||
.fake-input:focus {
|
||||
border-color: var(--vp-c-brand);
|
||||
background: var(--vp-c-bg-alt);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.icon-button {
|
||||
display: inline-flex;
|
||||
border: 1px solid transparent;
|
||||
@@ -30,9 +29,9 @@
|
||||
}
|
||||
|
||||
.icon-button:active {
|
||||
border-color: var(--vp-button-alt-active-border);
|
||||
color: var(--vp-button-alt-active-text);
|
||||
background-color: var(--vp-button-alt-active-bg);
|
||||
border-color: var(--vp-button-alt-active-border);
|
||||
color: var(--vp-button-alt-active-text);
|
||||
background-color: var(--vp-button-alt-active-bg);
|
||||
}
|
||||
|
||||
.icon-button.active {
|
||||
|
||||
@@ -12,6 +12,9 @@ export interface InputProps {
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, nextTick, watch } from 'vue';
|
||||
import Icon from 'lucide-vue-next/src/Icon';
|
||||
import { x } from '../../../data/iconNodes';
|
||||
import IconButton from './IconButton.vue';
|
||||
|
||||
const props = withDefaults(defineProps<InputProps>(), {
|
||||
type: 'text',
|
||||
@@ -21,7 +24,7 @@ const input = ref();
|
||||
const wrapperEl = ref();
|
||||
const shortcutEl = ref();
|
||||
|
||||
defineEmits(['change', 'input', 'update:modelValue']);
|
||||
const emit = defineEmits(['change', 'input', 'update:modelValue']);
|
||||
|
||||
const updateShortcutSpacing = () => {
|
||||
nextTick(() => {
|
||||
@@ -35,6 +38,11 @@ const updateShortcutSpacing = () => {
|
||||
onMounted(updateShortcutSpacing);
|
||||
watch(() => props.shortcut, updateShortcutSpacing);
|
||||
|
||||
function onClear() {
|
||||
emit('update:modelValue', '');
|
||||
input.value.focus();
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
focus: () => {
|
||||
input.value.focus();
|
||||
@@ -60,6 +68,17 @@ defineExpose({
|
||||
v-bind="$attrs"
|
||||
@input="$emit('update:modelValue', $event.target.value)"
|
||||
/>
|
||||
<IconButton
|
||||
@click="onClear"
|
||||
v-if="type === 'search' && modelValue"
|
||||
class="clear-button"
|
||||
aria-label="Clear input"
|
||||
>
|
||||
<Icon
|
||||
:iconNode="x"
|
||||
:size="20"
|
||||
/>
|
||||
</IconButton>
|
||||
<kbd
|
||||
v-if="shortcut"
|
||||
class="shortcut"
|
||||
@@ -73,6 +92,7 @@ defineExpose({
|
||||
.input-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.input {
|
||||
justify-content: flex-start;
|
||||
border: 1px solid transparent;
|
||||
@@ -82,7 +102,10 @@ defineExpose({
|
||||
height: 40px;
|
||||
background-color: var(--vp-c-bg-alt);
|
||||
font-size: 14px;
|
||||
transition: border-color 0.2s ease-in-out;
|
||||
transition:
|
||||
color 0.25s,
|
||||
border-color 0.25s,
|
||||
background-color 0.25s;
|
||||
}
|
||||
|
||||
.input.has-shortcut {
|
||||
@@ -99,6 +122,14 @@ defineExpose({
|
||||
padding-left: 52px;
|
||||
}
|
||||
|
||||
.clear-button {
|
||||
position: absolute;
|
||||
right: 56px;
|
||||
top: 9px;
|
||||
padding: 4px;
|
||||
transition: background-color .25s;
|
||||
}
|
||||
|
||||
.shortcut {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
|
||||
@@ -7,11 +7,8 @@ export default {
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import Input from './Input.vue';
|
||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon';
|
||||
import { search, x } from '../../../data/iconNodes';
|
||||
|
||||
const SearchIcon = createLucideIcon('search', search);
|
||||
const XIcon = createLucideIcon('close', x);
|
||||
import Icon from 'lucide-vue-next/src/Icon';
|
||||
import { search } from '../../../data/iconNodes';
|
||||
|
||||
interface Props {
|
||||
modelValue: string;
|
||||
@@ -34,10 +31,6 @@ const value = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emit('update:modelValue', val),
|
||||
});
|
||||
|
||||
const clear = () => {
|
||||
value.value = '';
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -50,26 +43,12 @@ const clear = () => {
|
||||
v-model="value"
|
||||
class="input-wrapper"
|
||||
>
|
||||
<template #startIcon>
|
||||
<component
|
||||
:is="SearchIcon"
|
||||
<template #icon>
|
||||
<Icon
|
||||
:iconNode="search"
|
||||
class="search-icon"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #endIcon>
|
||||
<button
|
||||
class="clear-button"
|
||||
type="button"
|
||||
v-if="value"
|
||||
>
|
||||
<component
|
||||
:is="XIcon"
|
||||
class="x-icon"
|
||||
@click="clear"
|
||||
/>
|
||||
</button>
|
||||
</template>
|
||||
</Input>
|
||||
</template>
|
||||
|
||||
@@ -81,9 +60,7 @@ const clear = () => {
|
||||
padding: 0 10px 0 12px;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
color: var(--vp-c-text-1);
|
||||
background-color: var(--vp-c-bg-alt);
|
||||
transition: border-color 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.input:hover,
|
||||
@@ -93,31 +70,9 @@ const clear = () => {
|
||||
}
|
||||
|
||||
.input-wrapper:deep(.input) {
|
||||
/* padding: 12px 24px; */
|
||||
padding-block: 12px;
|
||||
font-size: 14px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.clear-button {
|
||||
position: absolute;
|
||||
padding: 4px;
|
||||
right: 8px;
|
||||
top: 8px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: transparent;
|
||||
border-radius: 6px;
|
||||
transition: background 0.2s ease;
|
||||
}
|
||||
|
||||
.clear-button:hover {
|
||||
background: var(--vp-button-alt-bg);
|
||||
}
|
||||
|
||||
.input-wrapper:deep(.input)::-webkit-search-decoration,
|
||||
.input-wrapper:deep(.input)::-webkit-search-cancel-button,
|
||||
.input-wrapper:deep(.input)::-webkit-search-results-button,
|
||||
.input-wrapper:deep(.input)::-webkit-search-results-decoration {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { rotateCw } from '../../../data/iconNodes'
|
||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon'
|
||||
import IconButton from "./IconButton.vue";
|
||||
|
||||
const RotateIcon = createLucideIcon('RotateIcon', rotateCw)
|
||||
import { rotateCw } from '../../../data/iconNodes';
|
||||
import Icon from 'lucide-vue-next/src/Icon';
|
||||
import IconButton from './IconButton.vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<IconButton class="reset-button">
|
||||
<RotateIcon :size="20"/>
|
||||
<Icon
|
||||
:size="20"
|
||||
:iconNode="rotateCw"
|
||||
/>
|
||||
</IconButton>
|
||||
</template>
|
||||
|
||||
@@ -32,6 +33,7 @@ const RotateIcon = createLucideIcon('RotateIcon', rotateCw)
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
/* background-color: var(--vp-c-neutral); */
|
||||
box-shadow: var(--vp-shadow-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,25 +13,25 @@ export default {
|
||||
label: 'Lucide documentation for React',
|
||||
},
|
||||
{
|
||||
name: 'lucide-vue-next',
|
||||
name: 'lucide-vue',
|
||||
logo: '/framework-logos/vue.svg',
|
||||
label: 'Lucide documentation for Vue 3',
|
||||
label: 'Lucide documentation for Vue',
|
||||
},
|
||||
{
|
||||
name: 'lucide-svelte',
|
||||
logo: '/framework-logos/svelte.svg',
|
||||
label: 'Lucide documentation for Svelte',
|
||||
},
|
||||
{
|
||||
name: 'lucide-preact',
|
||||
logo: '/framework-logos/preact.svg',
|
||||
label: 'Lucide documentation for Preact',
|
||||
},
|
||||
{
|
||||
name: 'lucide-solid',
|
||||
logo: '/framework-logos/solid.svg',
|
||||
label: 'Lucide documentation for Solid',
|
||||
},
|
||||
{
|
||||
name: 'lucide-preact',
|
||||
logo: '/framework-logos/preact.svg',
|
||||
label: 'Lucide documentation for Preact',
|
||||
},
|
||||
{
|
||||
name: 'lucide-angular',
|
||||
logo: '/framework-logos/angular.svg',
|
||||
@@ -48,11 +48,6 @@ export default {
|
||||
logo: '/framework-logos/react-native.svg',
|
||||
label: 'Lucide documentation for React Native',
|
||||
},
|
||||
{
|
||||
name: 'lucide-flutter',
|
||||
logo: '/framework-logos/flutter.svg',
|
||||
label: 'Lucide documentation for Flutter',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
@@ -2,45 +2,48 @@
|
||||
import { useData } from 'vitepress';
|
||||
import { useSessionStorage } from '@vueuse/core';
|
||||
import IconButton from '../base/IconButton.vue';
|
||||
// import VPDocAsideCarbonAds from 'vitepress/dist/client/theme-default/components/VPDocAsideCarbonAds.vue'
|
||||
import { x } from '../../../data/iconNodes'
|
||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon';
|
||||
import VPDocAsideCarbonAds from 'vitepress/dist/client/theme-default/components/VPDocAsideCarbonAds.vue';
|
||||
import { x } from '../../../data/iconNodes';
|
||||
import Icon from 'lucide-vue-next/src/Icon';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
const { theme } = useData()
|
||||
const showAd = useSessionStorage('show-carbon-ads', true)
|
||||
const carbonLoaded = ref(true)
|
||||
const { theme } = useData();
|
||||
const showAd = useSessionStorage('show-carbon-ads', true);
|
||||
const carbonLoaded = ref(true);
|
||||
|
||||
defineProps<{
|
||||
drawerOpen: boolean
|
||||
}>()
|
||||
|
||||
const CloseIcon = createLucideIcon('Close', x)
|
||||
drawerOpen: boolean;
|
||||
}>();
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
if (window?._carbonads == null) {
|
||||
carbonLoaded.value = false
|
||||
carbonLoaded.value = false;
|
||||
}
|
||||
}, 5000)
|
||||
})
|
||||
}, 5000);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'drawer-open': drawerOpen,
|
||||
'hide-ad': !(showAd && carbonLoaded)
|
||||
'hide-ad': !(showAd && carbonLoaded),
|
||||
}"
|
||||
class="floating-ad"
|
||||
v-if="theme.carbonAds"
|
||||
>
|
||||
<IconButton @click="showAd = false" class="hide-button">
|
||||
<component :is="CloseIcon" :size="20" absoluteStrokeWidth />
|
||||
<IconButton
|
||||
@click="showAd = false"
|
||||
class="hide-button"
|
||||
>
|
||||
<Icon
|
||||
:iconNode="x"
|
||||
:size="20"
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
</IconButton>
|
||||
<VPDocAsideCarbonAds
|
||||
:carbon-ads="theme.carbonAds"
|
||||
/>
|
||||
<VPDocAsideCarbonAds :carbon-ads="theme.carbonAds" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -51,7 +54,9 @@ onMounted(() => {
|
||||
bottom: 32px;
|
||||
width: 224px;
|
||||
right: 32px;
|
||||
transition: opacity 0.5s, transform 0.25s ease;
|
||||
transition:
|
||||
opacity 0.5s,
|
||||
transform 0.25s ease;
|
||||
}
|
||||
|
||||
.floating-ad.drawer-open {
|
||||
@@ -67,8 +72,11 @@ onMounted(() => {
|
||||
transform: translateY(-288px) translateX(224px);
|
||||
}
|
||||
|
||||
.floating-ad.drawer-open, .floating-ad.hide-ad {
|
||||
transition: opacity 0.25s, transform 0.5s cubic-bezier(0.19, 1, 0.22, 1);
|
||||
.floating-ad.drawer-open,
|
||||
.floating-ad.hide-ad {
|
||||
transition:
|
||||
opacity 0.25s,
|
||||
transform 0.5s cubic-bezier(0.19, 1, 0.22, 1);
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
|
||||
@@ -1,70 +1,68 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import ButtonMenu from '../base/ButtonMenu.vue'
|
||||
import ButtonMenu from '../base/ButtonMenu.vue';
|
||||
import { useIconStyleContext } from '../../composables/useIconStyle';
|
||||
import useConfetti from '../../composables/useConfetti';
|
||||
import getSVGIcon from '../../utils/getSVGIcon';
|
||||
import downloadData from '../../utils/downloadData';
|
||||
|
||||
const downloadText = 'Download!'
|
||||
const copiedText = 'Copied!'
|
||||
const confettiText = ref(copiedText)
|
||||
const downloadText = 'Download!';
|
||||
const copiedText = 'Copied!';
|
||||
const confettiText = ref(copiedText);
|
||||
const props = defineProps<{
|
||||
name: string
|
||||
popoverPosition?: 'top' | 'bottom'
|
||||
}>()
|
||||
name: string;
|
||||
popoverPosition?: 'top' | 'bottom';
|
||||
}>();
|
||||
|
||||
const { size } = useIconStyleContext()
|
||||
const { size } = useIconStyleContext();
|
||||
|
||||
const { animate, confetti } = useConfetti()
|
||||
const { animate, confetti } = useConfetti();
|
||||
|
||||
function copySVG() {
|
||||
confettiText.value = copiedText
|
||||
const svgString = getSVGIcon()
|
||||
confettiText.value = copiedText;
|
||||
const svgString = getSVGIcon();
|
||||
|
||||
navigator.clipboard.writeText(svgString)
|
||||
navigator.clipboard.writeText(svgString);
|
||||
|
||||
confetti()
|
||||
confetti();
|
||||
}
|
||||
|
||||
function copyDataUrl() {
|
||||
confettiText.value = copiedText
|
||||
const svgString = getSVGIcon()
|
||||
confettiText.value = copiedText;
|
||||
const svgString = getSVGIcon();
|
||||
|
||||
// Create SVG data url
|
||||
const dataUrl = `data:image/svg+xml;base64,${btoa(svgString)}`
|
||||
navigator.clipboard.writeText(dataUrl)
|
||||
const dataUrl = `data:image/svg+xml;base64,${btoa(svgString)}`;
|
||||
navigator.clipboard.writeText(dataUrl);
|
||||
|
||||
confetti()
|
||||
confetti();
|
||||
}
|
||||
|
||||
function downloadSVG() {
|
||||
confettiText.value = downloadText
|
||||
const svgString = getSVGIcon()
|
||||
confettiText.value = downloadText;
|
||||
const svgString = getSVGIcon();
|
||||
|
||||
downloadData(`${props.name}.svg`, `data:image/svg+xml;base64,${btoa(svgString)}`)
|
||||
confetti()
|
||||
downloadData(`${props.name}.svg`, `data:image/svg+xml;base64,${btoa(svgString)}`);
|
||||
confetti();
|
||||
}
|
||||
|
||||
function downloadPNG() {
|
||||
confettiText.value = downloadText
|
||||
const svgString = getSVGIcon()
|
||||
confettiText.value = downloadText;
|
||||
const svgString = getSVGIcon();
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = size.value;
|
||||
canvas.height = size.value;
|
||||
const ctx = canvas.getContext("2d");
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
const image = new Image();
|
||||
image.src = `data:image/svg+xml;base64,${btoa(svgString)}`;
|
||||
image.onload = function() {
|
||||
image.onload = function () {
|
||||
ctx.drawImage(image, 0, 0);
|
||||
downloadData(`${props.name}.png`, canvas.toDataURL('image/png'))
|
||||
confetti()
|
||||
}
|
||||
downloadData(`${props.name}.png`, canvas.toDataURL('image/png'));
|
||||
confetti();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -75,10 +73,10 @@ function downloadPNG() {
|
||||
:data-confetti-text="confettiText"
|
||||
:popoverPosition="popoverPosition"
|
||||
:options="[
|
||||
{ text: 'Copy SVG' , onClick: copySVG },
|
||||
{ text: 'Copy Data URL' , onClick: copyDataUrl },
|
||||
{ text: 'Download SVG' , onClick: downloadSVG },
|
||||
{ text: 'Download PNG' , onClick: downloadPNG },
|
||||
{ text: 'Copy SVG', onClick: copySVG },
|
||||
{ text: 'Copy Data URL', onClick: copyDataUrl },
|
||||
{ text: 'Download SVG', onClick: downloadSVG },
|
||||
{ text: 'Download PNG', onClick: downloadPNG },
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,41 +1,44 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, useSlots } from 'vue';
|
||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon'
|
||||
import { copy } from '../../../data/iconNodes'
|
||||
import { copy } from '../../../data/iconNodes';
|
||||
import useConfetti from '../../composables/useConfetti';
|
||||
const { animate, confetti } = useConfetti()
|
||||
const slots = useSlots()
|
||||
import Icon from 'lucide-vue-next/src/Icon';
|
||||
const { animate, confetti } = useConfetti();
|
||||
const slots = useSlots();
|
||||
|
||||
const copiedText = computed(() => slots.default?.()[0].children)
|
||||
const copiedText = computed(() => slots.default?.()[0].children);
|
||||
|
||||
function copyText() {
|
||||
navigator.clipboard.writeText(copiedText.value)
|
||||
navigator.clipboard.writeText(copiedText.value);
|
||||
|
||||
confetti()
|
||||
confetti();
|
||||
}
|
||||
|
||||
const Copy = createLucideIcon('ChevronUp', copy)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1
|
||||
class="icon-name confetti-button"
|
||||
:class="{animate}"
|
||||
:class="{ animate }"
|
||||
data-confetti-text="Copied!"
|
||||
@click="copyText"
|
||||
>
|
||||
<slot />
|
||||
<Copy :size="20" class="copy-icon"/>
|
||||
<Icon
|
||||
:iconNode="copy"
|
||||
:size="20"
|
||||
class="copy-icon"
|
||||
/>
|
||||
</h1>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@import './confetti.css';
|
||||
|
||||
.icon-name {
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
line-height: 32px;
|
||||
transition: background ease-in .15s;;
|
||||
transition: background ease-in 0.15s;
|
||||
padding: 2px 8px;
|
||||
border-radius: 8px;
|
||||
width: auto;
|
||||
@@ -48,7 +51,7 @@ const Copy = createLucideIcon('ChevronUp', copy)
|
||||
}
|
||||
|
||||
.icon-name:hover .copy-icon {
|
||||
opacity: .9;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.icon-name:before,
|
||||
@@ -65,10 +68,10 @@ const Copy = createLucideIcon('ChevronUp', copy)
|
||||
opacity: 0;
|
||||
margin-left: 12px;
|
||||
margin-top: 6px;
|
||||
transition:ease .3s opacity;
|
||||
transition: ease 0.3s opacity;
|
||||
}
|
||||
|
||||
.icon-name:hover .copy-icon:hover {
|
||||
opacity: .6;
|
||||
opacity: 0.6;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -29,7 +29,12 @@ const props = defineProps<{
|
||||
|
||||
const iconComponent = computed(() => {
|
||||
if (!props.name || !props.iconNode) return null;
|
||||
return createLucideIcon(props.name, props.iconNode);
|
||||
try {
|
||||
return createLucideIcon(props.name, props.iconNode);
|
||||
} catch (error) {
|
||||
console.warn(`Icon ${props.name} not found, using fallback`);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
const CalendarIcon = createLucideIcon('calendar', Calendar.iconNode);
|
||||
@@ -61,7 +66,7 @@ const prettyName = props.name
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="showcase">
|
||||
<section class="showcase" v-if="iconComponent">
|
||||
<h2 class="title">See this icon in action</h2>
|
||||
<div class="showcase-grid">
|
||||
<div class="showcase-item column">
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { getAllData } from '../../../lib/icons';
|
||||
import { getAllCategoryFiles, mapCategoryIconCount } from '../../../lib/categories';
|
||||
import iconsMetaData from '../../../data/iconMetaData';
|
||||
import { fetchAllReleases } from '../../../../scripts/writeReleaseMetadata.mts';
|
||||
import { satisfies } from 'semver';
|
||||
|
||||
export default {
|
||||
async load() {
|
||||
const versions = await fetchAllReleases();
|
||||
|
||||
const mappedVersions = versions
|
||||
.map((tag) => tag.replace('v', ''))
|
||||
.reverse()
|
||||
|
||||
mappedVersions.length = 100
|
||||
|
||||
return {
|
||||
versions: mappedVersions,
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, defineAsyncComponent, onMounted, watch, watchEffect } from 'vue';
|
||||
import { ref, computed, defineAsyncComponent, onMounted, watch } from 'vue';
|
||||
import type { IconEntity } from '../../types';
|
||||
import { useElementSize, useEventListener, useVirtualList } from '@vueuse/core';
|
||||
import { useRoute } from 'vitepress';
|
||||
@@ -11,13 +11,9 @@ import useSearchShortcut from '../../utils/useSearchShortcut';
|
||||
import StickyBar from './StickyBar.vue';
|
||||
import useFetchTags from '../../composables/useFetchTags';
|
||||
import useFetchCategories from '../../composables/useFetchCategories';
|
||||
import useFetchVersionIcons from '../../composables/useFetchVersionIcons';
|
||||
import chunkArray from '../../utils/chunkArray';
|
||||
import CarbonAdOverlay from './CarbonAdOverlay.vue';
|
||||
import VersionSelect from './VersionSelect.vue';
|
||||
import { sort, satisfies } from 'semver';
|
||||
import useSearchPlaceholder from '../../utils/useSearchPlaceholder.ts';
|
||||
import { data as versionData } from './IconsOverview.data';
|
||||
|
||||
const ICON_SIZE = 56;
|
||||
const ICON_GRID_GAP = 8;
|
||||
@@ -36,15 +32,9 @@ const props = defineProps<{
|
||||
}>();
|
||||
|
||||
const activeIconName = ref(null);
|
||||
const selectedVersion = ref();
|
||||
|
||||
const { execute: fetchTags, data: tags } = useFetchTags();
|
||||
const { execute: fetchCategories, data: categories } = useFetchCategories();
|
||||
const { execute: fetchVersionIcons, data: versionIcons } = useFetchVersionIcons(selectedVersion);
|
||||
|
||||
watch(selectedVersion, () => {
|
||||
fetchVersionIcons();
|
||||
});
|
||||
|
||||
const overviewEl = ref<HTMLElement | null>(null);
|
||||
const { width: containerWidth } = useElementSize(overviewEl);
|
||||
@@ -54,31 +44,20 @@ const columnSize = computed(() => {
|
||||
});
|
||||
|
||||
const mappedIcons = computed(() => {
|
||||
let icons = props.icons;
|
||||
|
||||
if (tags.value != null && categories.value != null) {
|
||||
icons = props.icons.map((icon) => {
|
||||
const iconTags = tags.value[icon.name];
|
||||
const iconCategories = categories.value?.[icon.name] ?? [];
|
||||
|
||||
return {
|
||||
...icon,
|
||||
tags: iconTags,
|
||||
categories: iconCategories,
|
||||
};
|
||||
});
|
||||
if (tags.value == null) {
|
||||
return props.icons;
|
||||
}
|
||||
|
||||
if (selectedVersion.value == null || versionIcons.value == null) {
|
||||
console.log('no release info');
|
||||
return props.icons.map((icon) => {
|
||||
const iconTags = tags.value[icon.name];
|
||||
const iconCategories = categories.value?.[icon.name] ?? [];
|
||||
|
||||
return icons;
|
||||
}
|
||||
|
||||
return Object.values(versionIcons.value).filter(([name, iconNode]) => ({
|
||||
name,
|
||||
iconNode,
|
||||
}));
|
||||
return {
|
||||
...icon,
|
||||
tags: iconTags,
|
||||
categories: iconCategories,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
const { searchInput, searchQuery, searchQueryDebounced } = useSearchInput();
|
||||
@@ -128,12 +107,6 @@ function onFocusSearchInput() {
|
||||
}
|
||||
}
|
||||
|
||||
// function onFocusVersionSelect() {
|
||||
// if (releaseInfo.value == null) {
|
||||
// fetchReleaseInfo();
|
||||
// }
|
||||
// }
|
||||
|
||||
const NoResults = defineAsyncComponent(() => import('./NoResults.vue'));
|
||||
|
||||
const IconDetailOverlay = defineAsyncComponent(() => import('./IconDetailOverlay.vue'));
|
||||
@@ -156,17 +129,13 @@ function handleCloseDrawer() {
|
||||
>
|
||||
<StickyBar>
|
||||
<InputSearch
|
||||
:placeholder="`Search ${mappedIcons.length} icons ...`"
|
||||
:placeholder="`Search ${icons.length} icons ...`"
|
||||
v-model="searchQuery"
|
||||
ref="searchInput"
|
||||
:shortcut="kbdSearchShortcut"
|
||||
class="input-wrapper"
|
||||
@focus="onFocusSearchInput"
|
||||
/>
|
||||
<VersionSelect
|
||||
v-model="selectedVersion"
|
||||
:versions="versionData.versions"
|
||||
/>
|
||||
</StickyBar>
|
||||
<NoResults
|
||||
v-if="searchPlaceholder.isNoResults"
|
||||
|
||||
@@ -1,75 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import { shallowRef, type Ref, watch, computed } from 'vue'
|
||||
import { useCssVar, syncRef } from '@vueuse/core'
|
||||
import { STYLE_DEFAULTS, useIconStyleContext } from '../../composables/useIconStyle'
|
||||
import RangeSlider from '../base/RangeSlider.vue'
|
||||
import InputField from '../base/InputField.vue'
|
||||
import ColorPicker from '../base/ColorPicker.vue'
|
||||
import ResetButton from '../base/ResetButton.vue'
|
||||
import Switch from '../base/Switch.vue'
|
||||
import { shallowRef, type Ref, watch, computed } from 'vue';
|
||||
import { useCssVar, syncRef } from '@vueuse/core';
|
||||
import { STYLE_DEFAULTS, useIconStyleContext } from '../../composables/useIconStyle';
|
||||
import RangeSlider from '../base/RangeSlider.vue';
|
||||
import InputField from '../base/InputField.vue';
|
||||
import ColorPicker from '../base/ColorPicker.vue';
|
||||
import ResetButton from '../base/ResetButton.vue';
|
||||
import Switch from '../base/Switch.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
rootEl?: Ref<HTMLElement>
|
||||
}>()
|
||||
rootEl?: Ref<HTMLElement>;
|
||||
}>();
|
||||
|
||||
const { color, strokeWidth, size, absoluteStrokeWidth } = useIconStyleContext()
|
||||
const documentRef = shallowRef<HTMLElement | undefined>(typeof document !== 'undefined' ? document?.documentElement : undefined)
|
||||
const { color, strokeWidth, size, absoluteStrokeWidth } = useIconStyleContext();
|
||||
const documentRef = shallowRef<HTMLElement | undefined>(
|
||||
typeof document !== 'undefined' ? document?.documentElement : undefined,
|
||||
);
|
||||
|
||||
const colorCssVar = useCssVar(
|
||||
'--customize-color',
|
||||
props.rootEl?.value ?? documentRef.value,
|
||||
{
|
||||
initialValue: `${STYLE_DEFAULTS.color}`
|
||||
}
|
||||
)
|
||||
const colorCssVar = useCssVar('--customize-color', props.rootEl?.value ?? documentRef.value, {
|
||||
initialValue: `${STYLE_DEFAULTS.color}`,
|
||||
});
|
||||
|
||||
const strokeWidthCssVar = useCssVar(
|
||||
'--customize-strokeWidth',
|
||||
props.rootEl?.value ?? documentRef.value,
|
||||
{
|
||||
initialValue: `${STYLE_DEFAULTS.strokeWidth}`
|
||||
}
|
||||
)
|
||||
initialValue: `${STYLE_DEFAULTS.strokeWidth}`,
|
||||
},
|
||||
);
|
||||
|
||||
const sizeCssVar = useCssVar(
|
||||
'--customize-size',
|
||||
props.rootEl?.value ?? documentRef.value,
|
||||
{
|
||||
initialValue: `${STYLE_DEFAULTS.size}`
|
||||
}
|
||||
)
|
||||
const sizeCssVar = useCssVar('--customize-size', props.rootEl?.value ?? documentRef.value, {
|
||||
initialValue: `${STYLE_DEFAULTS.size}`,
|
||||
});
|
||||
|
||||
syncRef(color, colorCssVar, { direction: 'ltr' })
|
||||
syncRef(strokeWidth, strokeWidthCssVar, { direction: 'ltr' })
|
||||
syncRef(size, sizeCssVar, { direction: 'ltr' })
|
||||
syncRef(color, colorCssVar, { direction: 'ltr' });
|
||||
syncRef(strokeWidth, strokeWidthCssVar, { direction: 'ltr' });
|
||||
syncRef(size, sizeCssVar, { direction: 'ltr' });
|
||||
|
||||
function resetStyle () {
|
||||
color.value = STYLE_DEFAULTS.color
|
||||
strokeWidth.value = STYLE_DEFAULTS.strokeWidth
|
||||
size.value = STYLE_DEFAULTS.size
|
||||
absoluteStrokeWidth.value = STYLE_DEFAULTS.absoluteStrokeWidth
|
||||
function resetStyle() {
|
||||
color.value = STYLE_DEFAULTS.color;
|
||||
strokeWidth.value = STYLE_DEFAULTS.strokeWidth;
|
||||
size.value = STYLE_DEFAULTS.size;
|
||||
absoluteStrokeWidth.value = STYLE_DEFAULTS.absoluteStrokeWidth;
|
||||
}
|
||||
|
||||
watch(absoluteStrokeWidth, (enabled) => {
|
||||
const htmlEl = document.documentElement
|
||||
const htmlEl = document.documentElement;
|
||||
|
||||
htmlEl.classList.toggle('absolute-stroke-width', enabled)
|
||||
})
|
||||
htmlEl.classList.toggle('absolute-stroke-width', enabled);
|
||||
});
|
||||
|
||||
const customizingActive = computed(() => {
|
||||
return color.value !== STYLE_DEFAULTS.color
|
||||
|| strokeWidth.value !== STYLE_DEFAULTS.strokeWidth
|
||||
|| size.value !== STYLE_DEFAULTS.size
|
||||
|| absoluteStrokeWidth.value !== STYLE_DEFAULTS.absoluteStrokeWidth
|
||||
})
|
||||
return (
|
||||
color.value !== STYLE_DEFAULTS.color ||
|
||||
strokeWidth.value !== STYLE_DEFAULTS.strokeWidth ||
|
||||
size.value !== STYLE_DEFAULTS.size ||
|
||||
absoluteStrokeWidth.value !== STYLE_DEFAULTS.absoluteStrokeWidth
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="customizer-card" :class="{ customized: customizingActive }">
|
||||
<div
|
||||
class="customizer-card"
|
||||
:class="{ customized: customizingActive }"
|
||||
>
|
||||
<div class="card-header">
|
||||
<h2 class="card-title">
|
||||
Customizer
|
||||
</h2>
|
||||
<h2 class="card-title">Customizer</h2>
|
||||
<ResetButton @click="resetStyle"></ResetButton>
|
||||
</div>
|
||||
<InputField
|
||||
@@ -77,7 +74,11 @@ const customizingActive = computed(() => {
|
||||
label="Color"
|
||||
>
|
||||
<template #display>
|
||||
<ColorPicker v-model="color" id="icon-color" class="color-picker"/>
|
||||
<ColorPicker
|
||||
v-model="color"
|
||||
id="icon-color"
|
||||
class="color-picker"
|
||||
/>
|
||||
</template>
|
||||
</InputField>
|
||||
|
||||
@@ -117,7 +118,7 @@ const customizingActive = computed(() => {
|
||||
|
||||
<InputField
|
||||
id="absolute-stroke-width"
|
||||
label="Absolute Stroke width"
|
||||
label="Absolute stroke width"
|
||||
>
|
||||
<Switch
|
||||
id="absolute-stroke-width"
|
||||
@@ -143,6 +144,7 @@ const customizingActive = computed(() => {
|
||||
font-size: 16px;
|
||||
/* margin-bottom: 12px; */
|
||||
}
|
||||
|
||||
.customizer-card {
|
||||
background: var(--vp-c-bg);
|
||||
padding: 12px 24px 24px;
|
||||
@@ -151,7 +153,7 @@ const customizingActive = computed(() => {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
border: 1px solid transparent;
|
||||
transition: border-color .4s ease-in-out;
|
||||
transition: border-color 0.4s ease-in-out;
|
||||
}
|
||||
|
||||
.customizer-card.customized {
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
margin-top: -32px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-bottom: 32px;
|
||||
background: var(--vp-c-bg);
|
||||
box-shadow: 0 16px 24px var(--vp-c-bg);
|
||||
|
||||
@@ -1,221 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import {
|
||||
Combobox,
|
||||
ComboboxInput,
|
||||
ComboboxButton,
|
||||
ComboboxOptions,
|
||||
ComboboxOption,
|
||||
} from '@headlessui/vue';
|
||||
|
||||
import { chevronsUpDown, check } from '../../../data/iconNodes';
|
||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon';
|
||||
|
||||
const model = defineModel<string | undefined>();
|
||||
const props = defineProps<{
|
||||
versions: string[];
|
||||
}>();
|
||||
|
||||
let query = ref('');
|
||||
|
||||
let filteredVersions = computed(() =>
|
||||
query.value === ''
|
||||
? [...props.versions]
|
||||
: props.versions.filter((version) =>
|
||||
version
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, '')
|
||||
.includes(query.value.toLowerCase().replace(/\s+/g, '')),
|
||||
),
|
||||
);
|
||||
|
||||
const emit = defineEmits(['focus']);
|
||||
|
||||
const ChevronUpDown = createLucideIcon('ChevronUpDown', chevronsUpDown);
|
||||
const Check = createLucideIcon('Check', check);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Combobox v-model="model">
|
||||
<div class="combobox-container">
|
||||
<div class="combobox-input-container">
|
||||
<ComboboxInput
|
||||
class="combobox-input"
|
||||
placeholder="Latest version"
|
||||
@change="query = $event.target.value"
|
||||
@focus="emit('focus')"
|
||||
/>
|
||||
<ComboboxButton class="combobox-button">
|
||||
<ChevronUpDown
|
||||
class="icon-chevron"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</ComboboxButton>
|
||||
</div>
|
||||
|
||||
<ComboboxOptions class="combobox-options">
|
||||
<div
|
||||
v-if="versions.length === 0 && query !== ''"
|
||||
class="combobox-no-results"
|
||||
>
|
||||
No match!
|
||||
</div>
|
||||
|
||||
<ComboboxOption
|
||||
v-for="version in filteredVersions"
|
||||
as="template"
|
||||
:key="version"
|
||||
:value="version"
|
||||
v-slot="{ selected, active }"
|
||||
>
|
||||
<li
|
||||
class="combobox-option"
|
||||
:class="{ active: active }"
|
||||
>
|
||||
<span
|
||||
class="combobox-option-text"
|
||||
:class="{ selected: selected }"
|
||||
>
|
||||
{{ version }}
|
||||
</span>
|
||||
<span
|
||||
v-if="selected"
|
||||
class="combobox-option-icon"
|
||||
:class="{ active: active }"
|
||||
>
|
||||
<Check
|
||||
class="icon-check"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</span>
|
||||
</li>
|
||||
</ComboboxOption>
|
||||
</ComboboxOptions>
|
||||
</div>
|
||||
</Combobox>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.combobox-input-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
min-width: 160px;
|
||||
cursor: default;
|
||||
overflow: hidden;
|
||||
background-color: var(--vp-c-bg-alt);
|
||||
text-align: left;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.combobox-input {
|
||||
width: 100%;
|
||||
border: none;
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
color: var(--vp-c-text-1);
|
||||
border: 1px solid transparent;
|
||||
transition: border-color 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.combobox-input:hover,
|
||||
.combobox-input:focus {
|
||||
border-color: var(--vp-c-brand);
|
||||
background: var(--vp-c-bg-alt);
|
||||
}
|
||||
|
||||
.combobox-button {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
padding: 9px 8px;
|
||||
right: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 0.5rem;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.icon-chevron {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
.combobox-options {
|
||||
position: absolute;
|
||||
margin-top: 0.25rem;
|
||||
width: 100%;
|
||||
max-width: 160px;
|
||||
padding: 12px;
|
||||
min-width: 128px;
|
||||
overflow-y: auto;
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
background-color: var(--vp-c-bg-elv);
|
||||
box-shadow: var(--vp-shadow-3);
|
||||
transition: background-color 0.5s;
|
||||
max-height: 240px;
|
||||
outline: none;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.combobox-no-results {
|
||||
position: relative;
|
||||
cursor: default;
|
||||
padding: 0.5rem 1rem;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.combobox-option {
|
||||
position: relative;
|
||||
cursor: default;
|
||||
padding: 2px 8px;
|
||||
border-radius: 6px;
|
||||
color: var(--vp-c-text-1);
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
transition:
|
||||
background-color 0.25s,
|
||||
color 0.25s;
|
||||
}
|
||||
|
||||
.combobox-option.active {
|
||||
color: var(--vp-c-brand);
|
||||
background-color: var(--vp-c-default-soft);
|
||||
}
|
||||
|
||||
.combobox-option-text {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.combobox-option-text.selected {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.combobox-option-icon {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 0.75rem;
|
||||
color: var(--vp-c-brand) !important;
|
||||
}
|
||||
|
||||
.combobox-option-icon.active {
|
||||
color: var(--vp-c-brand) !important;
|
||||
}
|
||||
|
||||
.icon-check {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,17 +0,0 @@
|
||||
import { useFetch } from '@vueuse/core';
|
||||
import { computed, Ref } from 'vue';
|
||||
|
||||
const useFetchVersionIcons = (version: Ref<string | undefined>) =>{
|
||||
const fetchUrl = computed(() => {
|
||||
if(version.value == null ) return ''
|
||||
return `https://unpkg.com/lucide-static@${version.value}/icon-nodes.json`
|
||||
})
|
||||
return useFetch<Record<string, string>>(
|
||||
fetchUrl,
|
||||
{
|
||||
refetch: true
|
||||
}
|
||||
).json();
|
||||
}
|
||||
|
||||
export default useFetchVersionIcons;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IconNode } from 'lucide-vue-next/src/createLucideIcon';
|
||||
import { type IconNode } from 'lucide-vue-next/src/types';
|
||||
import Vue from 'vue';
|
||||
|
||||
declare module '*.vue' {
|
||||
@@ -20,5 +20,6 @@ declare module 'node:module' {
|
||||
}
|
||||
|
||||
declare module '*.node.json' {
|
||||
export default IconNode;
|
||||
const value: IconNode;
|
||||
export default value;
|
||||
}
|
||||
@@ -64,25 +64,24 @@ Implementation of the lucide icon library for Vue applications.
|
||||
::: code-group
|
||||
|
||||
```sh [pnpm]
|
||||
pnpm add lucide-vue-next
|
||||
pnpm add @lucide/vue
|
||||
```
|
||||
|
||||
```sh [yarn]
|
||||
yarn add lucide-vue-next
|
||||
yarn add @lucide/vue
|
||||
```
|
||||
|
||||
```sh [npm]
|
||||
npm install lucide-vue-next
|
||||
npm install @lucide/vue
|
||||
```
|
||||
|
||||
```sh [bun]
|
||||
bun add lucide-vue-next
|
||||
bun add @lucide/vue
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
For more details, see the [documentation](packages/lucide-vue-next.md).
|
||||
For Vue 2 use the `lucide-vue` package.
|
||||
For more details, see the [documentation](packages/lucide-vue.md).
|
||||
|
||||
## Svelte
|
||||
|
||||
@@ -91,22 +90,22 @@ Implementation of the lucide icon library for Svelte applications.
|
||||
::: code-group
|
||||
|
||||
```sh [pnpm]
|
||||
pnpm add lucide-svelte
|
||||
pnpm add @lucide/svelte
|
||||
```
|
||||
|
||||
```sh [yarn]
|
||||
yarn add lucide-svelte
|
||||
yarn add @lucide/svelte
|
||||
```
|
||||
|
||||
```sh [npm]
|
||||
npm install lucide-svelte
|
||||
npm install @lucide/svelte
|
||||
```
|
||||
|
||||
```sh [bun]
|
||||
bun add lucide-svelte
|
||||
bun add @lucide/svelte
|
||||
```
|
||||
|
||||
:::
|
||||
> `@lucide/svelte` is only for Svelte 5, for Svelte 4 use the `lucide-svelte` package.
|
||||
|
||||
For more details, see the [documentation](packages/lucide-svelte.md).
|
||||
|
||||
|
||||
@@ -102,10 +102,16 @@ The example below imports all ES Modules, so exercise caution when using it. Imp
|
||||
|
||||
### Icon Component Example
|
||||
|
||||
```jsx
|
||||
import { icons } from 'lucide-react-native';
|
||||
```tsx
|
||||
import * as icons from 'lucide-react-native/icons';
|
||||
|
||||
const Icon = ({ name, color, size }) => {
|
||||
interface IconProps {
|
||||
name: keyof typeof icons;
|
||||
color?: string;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
const Icon = ({ name, color, size }: IconProps) => {
|
||||
const LucideIcon = icons[name];
|
||||
|
||||
return <LucideIcon color={color} size={size} />;
|
||||
@@ -116,11 +122,11 @@ export default Icon;
|
||||
|
||||
#### Using the Icon Component
|
||||
|
||||
```jsx
|
||||
```tsx
|
||||
import Icon from './Icon';
|
||||
|
||||
const App = () => {
|
||||
return <Icon name="house" />;
|
||||
return <Icon name="House" />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -30,14 +30,7 @@ This package includes the following implementations of Lucide icons:
|
||||
|
||||
SVG sprites and icon fonts include **all icons**, which can significantly increase your app's bundle size and load time.
|
||||
|
||||
For production environments, we recommend using a bundler with tree-shaking support to include only the icons you actually use. Consider using:
|
||||
|
||||
- [lucide](lucide)
|
||||
- [lucide-react](lucide-react)
|
||||
- [lucide-vue](lucide-vue)
|
||||
- [lucide-vue-next](lucide-vue-next)
|
||||
- [lucide-angular](lucide-angular)
|
||||
- [lucide-preact](lucide-preact)
|
||||
For production environments, we recommend using a bundler with tree-shaking support to include only the icons you actually use. Consider using one of the framework-specific [packages](../../packages).
|
||||
:::
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
# Lucide Vue Next
|
||||
|
||||
Vue 3 components for Lucide icons that leverage the Composition API and modern Vue features. Each icon is a reactive Vue component that renders as an inline SVG, providing excellent performance and developer experience in Vue 3 applications.
|
||||
|
||||
**What you can accomplish:**
|
||||
- Use icons as Vue 3 components with full reactivity and TypeScript support
|
||||
- Bind icon properties to reactive data and computed values
|
||||
- Customize icons with props, slots, and Vue's powerful templating system
|
||||
- Integrate seamlessly with Vue 3's Composition API and script setup syntax
|
||||
- Build dynamic interfaces where icons respond to application state changes
|
||||
|
||||
## Installation
|
||||
|
||||
::: code-group
|
||||
|
||||
```sh [pnpm]
|
||||
pnpm add lucide-vue-next
|
||||
```
|
||||
|
||||
```sh [yarn]
|
||||
yarn add lucide-vue-next
|
||||
```
|
||||
|
||||
```sh [npm]
|
||||
npm install lucide-vue-next
|
||||
```
|
||||
|
||||
```sh [bun]
|
||||
bun add lucide-vue-next
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## How to use
|
||||
|
||||
Lucide is built with ES Modules, so it's completely tree-shakable.
|
||||
|
||||
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
|
||||
|
||||
You can pass additional props to adjust the icon.
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Camera } from 'lucide-vue-next';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Camera
|
||||
color="red"
|
||||
:size="32"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Props
|
||||
|
||||
| name | type | default |
|
||||
| ----------------------- | --------- | ------------ |
|
||||
| `size` | *number* | 24 |
|
||||
| `color` | *string* | currentColor |
|
||||
| `stroke-width` | *number* | 2 |
|
||||
| `absoluteStrokeWidth` | *boolean* | false |
|
||||
| `default-class` | *string* | lucide-icon |
|
||||
|
||||
### Applying props
|
||||
|
||||
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>
|
||||
<Camera fill="red" />
|
||||
</template>
|
||||
```
|
||||
|
||||
## With Lucide lab or custom icons
|
||||
|
||||
[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library.
|
||||
|
||||
They can be used by using the `Icon` component.
|
||||
All props like regular lucide icons can be passed to adjust the icon appearance.
|
||||
|
||||
### Using the `Icon` component
|
||||
|
||||
This creates a single icon based on the iconNode passed and renders a Lucide icon component.
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Icon } from 'lucide-vue-next';
|
||||
import { baseball } from '@lucide/lab';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Icon :iconNode="baseball" />
|
||||
</template>
|
||||
```
|
||||
|
||||
## One generic icon component
|
||||
|
||||
It is possible to create one generic icon component to load icons, but it is not recommended.
|
||||
|
||||
::: danger
|
||||
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
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import * as icons from "lucide-vue-next";
|
||||
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
size: Number,
|
||||
color: String,
|
||||
strokeWidth: Number,
|
||||
defaultClass: String
|
||||
})
|
||||
|
||||
const icon = computed(() => icons[props.name]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="icon"
|
||||
:size="size"
|
||||
:color="color"
|
||||
:stroke-width="strokeWidth" :default-class="defaultClass"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
### Using the Icon Component
|
||||
|
||||
All other props listed above also work on the `Icon` Component.
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div id="app">
|
||||
<Icon name="Airplay" />
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
@@ -9,28 +9,24 @@ Vue 2 components for Lucide icons that integrate with Vue's Options API and temp
|
||||
- Build applications using Vue 2's familiar syntax and patterns
|
||||
- Bridge the gap while planning migration to Vue 3
|
||||
|
||||
::: danger
|
||||
This package is deprecated. Vue 2 is EOF See [Announcement](https://v2.vuejs.org/eol/). Migrate to Vue 3.
|
||||
:::
|
||||
|
||||
## Installation
|
||||
|
||||
::: code-group
|
||||
|
||||
```sh [pnpm]
|
||||
pnpm add lucide-vue
|
||||
pnpm add @lucide/vue
|
||||
```
|
||||
|
||||
```sh [yarn]
|
||||
yarn add lucide-vue
|
||||
yarn add @lucide/vue
|
||||
```
|
||||
|
||||
```sh [npm]
|
||||
npm install lucide-vue
|
||||
npm install @lucide/vue
|
||||
```
|
||||
|
||||
```sh [bun]
|
||||
bun add lucide-vue
|
||||
bun add @lucide/vue
|
||||
```
|
||||
|
||||
:::
|
||||
@@ -43,21 +39,19 @@ Each icon can be imported as a Vue component, which renders an inline SVG Elemen
|
||||
|
||||
### Example
|
||||
|
||||
Additional props can be passed to adjust the icon:
|
||||
You can pass additional props to adjust the icon.
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<Camera color="red" :size="32" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Camera } from 'lucide-vue';
|
||||
|
||||
export default {
|
||||
name: 'My Component',
|
||||
components: { Camera }
|
||||
};
|
||||
<script setup>
|
||||
import { Camera } from '@lucide/vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Camera
|
||||
color="red"
|
||||
:size="32"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Props
|
||||
@@ -80,6 +74,28 @@ To customize the appearance of an icon, you can pass custom properties as props
|
||||
</template>
|
||||
```
|
||||
|
||||
## With Lucide lab or custom icons
|
||||
|
||||
[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library.
|
||||
|
||||
They can be used by using the `Icon` component.
|
||||
All props like regular lucide icons can be passed to adjust the icon appearance.
|
||||
|
||||
### Using the `Icon` component
|
||||
|
||||
This creates a single icon based on the iconNode passed and renders a Lucide icon component.
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Icon } from '@lucide/vue';
|
||||
import { baseball } from '@lucide/lab';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Icon :iconNode="baseball" />
|
||||
</template>
|
||||
```
|
||||
|
||||
## One generic icon component
|
||||
|
||||
It is possible to create one generic icon component to load icons, but it is not recommended.
|
||||
@@ -91,30 +107,37 @@ The example below imports all ES Modules, so exercise caution when using it. Imp
|
||||
### Icon Component Example
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<component :is="icon" />
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import * as icons from "@lucide/vue";
|
||||
|
||||
<script>
|
||||
import * as icons from 'lucide-vue';
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
size: Number,
|
||||
color: String,
|
||||
strokeWidth: Number,
|
||||
defaultClass: String
|
||||
})
|
||||
|
||||
export default {
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
icon() {
|
||||
return icons[this.name];
|
||||
}
|
||||
}
|
||||
};
|
||||
const icon = computed(() => icons[props.name]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="icon"
|
||||
:size="size"
|
||||
:color="color"
|
||||
:stroke-width="strokeWidth" :default-class="defaultClass"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### Using the Icon Component
|
||||
### Using the Icon Component
|
||||
|
||||
All other props listed above also work on the `Icon` Component.
|
||||
|
||||
```vue
|
||||
<template>
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
"docs:build": "pnpm run /^prebuild:.*/ && vitepress build",
|
||||
"docs:preview": "vitepress preview",
|
||||
"build:docs": "vitepress build",
|
||||
"prebuild:iconNodes": "node ./scripts/writeIconNodes.mts",
|
||||
"prebuild:metaJson": "node ./scripts/writeIconMetaIndex.mts",
|
||||
"prebuild:releaseJson": "node ./scripts/writeReleaseMetadata.mts",
|
||||
"prebuild:categoriesJson": "node ./scripts/writeCategoriesMetadata.mts",
|
||||
"prebuild:relatedIcons": "node ./scripts/writeIconRelatedIcons.mts",
|
||||
"prebuild:iconDetails": "node ./scripts/writeIconDetails.mts",
|
||||
"prebuild:brandStopwords": "node ./scripts/writeBrandStopwords.mts",
|
||||
"postbuild:vercelJson": "node ./scripts/writeVercelOutput.mts",
|
||||
"prebuild:iconNodes": "node ./scripts/writeIconNodes.mjs",
|
||||
"prebuild:metaJson": "node ./scripts/writeIconMetaIndex.mjs",
|
||||
"prebuild:releaseJson": "node ./scripts/writeReleaseMetadata.mjs",
|
||||
"prebuild:categoriesJson": "node ./scripts/writeCategoriesMetadata.mjs",
|
||||
"prebuild:relatedIcons": "node ./scripts/writeIconRelatedIcons.mjs",
|
||||
"prebuild:iconDetails": "node ./scripts/writeIconDetails.mjs",
|
||||
"prebuild:brandStopwords": "node ./scripts/writeBrandStopwords.mjs",
|
||||
"postbuild:vercelJson": "node ./scripts/writeVercelOutput.mjs",
|
||||
"dev": "npx nitropack dev",
|
||||
"prebuild:api": "npx nitropack prepare",
|
||||
"build:api": "npx nitropack build",
|
||||
|
||||
@@ -42,7 +42,7 @@ const getRelatedIcons = (currentIcon, icons) => {
|
||||
};
|
||||
|
||||
const iconsMetaDataPromises = svgFiles.map(async (iconName) => {
|
||||
const metaDataFileContent = await fs.promises.readFile(`../icons/${iconName}`, 'utf-8');
|
||||
const metaDataFileContent = await fs.promises.readFile(`../icons/${iconName}`);
|
||||
const metaData = JSON.parse(metaDataFileContent);
|
||||
|
||||
const name = iconName.replace('.json', '');
|
||||
@@ -29,7 +29,7 @@ if (!fs.existsSync(releaseMetaDataDirectory)) {
|
||||
fs.mkdirSync(releaseMetaDataDirectory);
|
||||
}
|
||||
|
||||
export const fetchAllReleases = async () => {
|
||||
const fetchAllReleases = async () => {
|
||||
await git.fetch('https://github.com/lucide-icons/lucide.git', '--tags');
|
||||
|
||||
return Promise.all(
|
||||
@@ -73,7 +73,7 @@ const comparisonsPromises = tags.map(async (tag, index) => {
|
||||
const comparisons = await Promise.all(comparisonsPromises);
|
||||
const newReleaseMetaData = {};
|
||||
|
||||
comparisons.forEach(({ tag, iconFiles, date } = {} as typeof comparisons[number]) => {
|
||||
comparisons.forEach(({ tag, iconFiles, date } = {}) => {
|
||||
if (tag == null) return;
|
||||
|
||||
iconFiles.forEach(({ status, file, renamedFile }) => {
|
||||
@@ -11,7 +11,7 @@ const iconMetaData = await getIconMetaData(path.resolve(scriptDir, '../../icons'
|
||||
const iconAliasesRedirectRoutes = Object.entries(iconMetaData)
|
||||
.filter(([, { aliases }]) => aliases?.length)
|
||||
.map(([iconName, { aliases }]) => {
|
||||
const aliasRouteMatches = aliases.map((alias) => typeof alias === 'string' ? alias : alias.name).join('|');
|
||||
const aliasRouteMatches = aliases.map((alias) => alias.name).join('|');
|
||||
|
||||
return {
|
||||
src: `/icons/${aliasRouteMatches}`,
|
||||
@@ -34,6 +34,11 @@
|
||||
],
|
||||
"destination": "/icons",
|
||||
"permanent": false
|
||||
},
|
||||
{
|
||||
"source": "/guide/packages/lucide-vue-next",
|
||||
"destination": "/guide/packages/lucide-vue",
|
||||
"permanent": false
|
||||
}
|
||||
],
|
||||
"headers": [
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
"account",
|
||||
"animals",
|
||||
"arrows",
|
||||
"brands",
|
||||
"buildings",
|
||||
"charts",
|
||||
"communication",
|
||||
@@ -134,7 +133,7 @@
|
||||
"$defs": {
|
||||
"iconDeprecationReasons": {
|
||||
"type": "string",
|
||||
"enum": ["icon.brand"]
|
||||
"enum": ["icon.renamed"]
|
||||
},
|
||||
"aliasDeprecationReasons": {
|
||||
"type": "string",
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
],
|
||||
"categories": [
|
||||
"multimedia",
|
||||
"connectivity",
|
||||
"devices",
|
||||
"brands"
|
||||
"connectivity"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
"payment"
|
||||
],
|
||||
"categories": [
|
||||
"brands",
|
||||
"development",
|
||||
"finance"
|
||||
]
|
||||
|
||||
14
icons/cannabis-off.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"nickveles"
|
||||
],
|
||||
"tags": [
|
||||
"cannabis",
|
||||
"weed",
|
||||
"leaf"
|
||||
],
|
||||
"categories": [
|
||||
"nature"
|
||||
]
|
||||
}
|
||||
18
icons/cannabis-off.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22v-4c1.5 1.5 3.5 3 6 3 0-1.5-.5-3.5-2-5" />
|
||||
<path d="M13.988 8.327C13.902 6.054 13.365 3.82 12 2a9.3 9.3 0 0 0-1.445 2.9" />
|
||||
<path d="M17.375 11.725C18.882 10.53 21 7.841 21 6c-2.324 0-5.08 1.296-6.662 2.684" />
|
||||
<path d="m2 2 20 20" />
|
||||
<path d="M21.024 15.378A15 15 0 0 0 22 15c-.426-1.279-2.67-2.557-4.25-2.907" />
|
||||
<path d="M6.995 6.992C5.714 6.4 4.29 6 3 6c0 2 2.5 5 4 6-1.5 0-4.5 1.5-5 3 3.5 1.5 6 1 6 1-1.5 1.5-2 3.5-2 5 2.5 0 4.5-1.5 6-3" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 681 B |
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"ericfennis"
|
||||
],
|
||||
"tags": [
|
||||
"browser",
|
||||
"logo"
|
||||
],
|
||||
"categories": [
|
||||
"brands"
|
||||
],
|
||||
"aliases": [
|
||||
{
|
||||
"name": "chrome",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "alias.name",
|
||||
"toBeRemovedInVersion": "v1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M10.88 21.94 15.46 14" />
|
||||
<path d="M21.17 8H12" />
|
||||
<path d="M3.95 6.06 8.54 14" />
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<circle cx="12" cy="12" r="4" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 377 B |
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"ericfennis"
|
||||
],
|
||||
"tags": [
|
||||
"logo"
|
||||
],
|
||||
"categories": [
|
||||
"brands",
|
||||
"development"
|
||||
]
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2" />
|
||||
<line x1="12" x2="12" y1="22" y2="15.5" />
|
||||
<polyline points="22 8.5 12 15.5 2 8.5" />
|
||||
<polyline points="2 15.5 12 8.5 22 15.5" />
|
||||
<line x1="12" x2="12" y1="2" y2="8.5" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 454 B |
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"csandman",
|
||||
"ericfennis"
|
||||
],
|
||||
"tags": [
|
||||
"logo"
|
||||
],
|
||||
"categories": [
|
||||
"brands",
|
||||
"development"
|
||||
]
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
|
||||
<polyline points="7.5 4.21 12 6.81 16.5 4.21" />
|
||||
<polyline points="7.5 19.79 7.5 14.6 3 12" />
|
||||
<polyline points="21 12 16.5 14.6 16.5 19.79" />
|
||||
<polyline points="3.27 6.96 12 12.01 20.73 6.96" />
|
||||
<line x1="12" x2="12" y1="22.08" y2="12" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 595 B |
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"ahtohbi4"
|
||||
],
|
||||
"tags": [
|
||||
"design",
|
||||
"social"
|
||||
],
|
||||
"categories": [
|
||||
"brands",
|
||||
"social",
|
||||
"design"
|
||||
]
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<path d="M19.13 5.09C15.22 9.14 10 10.44 2.25 10.94" />
|
||||
<path d="M21.75 12.84c-6.62-1.41-12.14 1-16.38 6.32" />
|
||||
<path d="M8.56 2.75c4.37 6 6 9.42 8 17.72" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 408 B |
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"csandman",
|
||||
"ericfennis"
|
||||
],
|
||||
"tags": [
|
||||
"logo",
|
||||
"social"
|
||||
],
|
||||
"categories": [
|
||||
"social",
|
||||
"brands"
|
||||
]
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 289 B |
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"csandman",
|
||||
"mittalyashu",
|
||||
"ericfennis"
|
||||
],
|
||||
"tags": [
|
||||
"logo",
|
||||
"design",
|
||||
"tool"
|
||||
],
|
||||
"categories": [
|
||||
"brands",
|
||||
"design"
|
||||
]
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M5 5.5A3.5 3.5 0 0 1 8.5 2H12v7H8.5A3.5 3.5 0 0 1 5 5.5z" />
|
||||
<path d="M12 2h3.5a3.5 3.5 0 1 1 0 7H12V2z" />
|
||||
<path d="M12 12.5a3.5 3.5 0 1 1 7 0 3.5 3.5 0 1 1-7 0z" />
|
||||
<path d="M5 19.5A3.5 3.5 0 0 1 8.5 16H12v3.5a3.5 3.5 0 1 1-7 0z" />
|
||||
<path d="M5 12.5A3.5 3.5 0 0 1 8.5 9H12v7H8.5A3.5 3.5 0 0 1 5 12.5z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 534 B |
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"csandman",
|
||||
"mittalyashu",
|
||||
"ericfennis"
|
||||
],
|
||||
"tags": [
|
||||
"logo",
|
||||
"design",
|
||||
"tool"
|
||||
],
|
||||
"categories": [
|
||||
"brands",
|
||||
"design"
|
||||
]
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M5 16V9h14V2H5l14 14h-7m-7 0 7 7v-7m-7 0h7" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 266 B |
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"csandman",
|
||||
"ericfennis",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"logo",
|
||||
"version control"
|
||||
],
|
||||
"categories": [
|
||||
"brands",
|
||||
"development"
|
||||
]
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4" />
|
||||
<path d="M9 18c-4.51 2-5-2-7-2" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 509 B |
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"csandman",
|
||||
"ericfennis",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"logo",
|
||||
"version control"
|
||||
],
|
||||
"categories": [
|
||||
"brands",
|
||||
"development"
|
||||
]
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m22 13.29-3.33-10a.42.42 0 0 0-.14-.18.38.38 0 0 0-.22-.11.39.39 0 0 0-.23.07.42.42 0 0 0-.14.18l-2.26 6.67H8.32L6.1 3.26a.42.42 0 0 0-.1-.18.38.38 0 0 0-.26-.08.39.39 0 0 0-.23.07.42.42 0 0 0-.14.18L2 13.29a.74.74 0 0 0 .27.83L12 21l9.69-6.88a.71.71 0 0 0 .31-.83Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 489 B |
@@ -12,7 +12,6 @@
|
||||
],
|
||||
"categories": [
|
||||
"shapes",
|
||||
"brands",
|
||||
"development"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"csandman",
|
||||
"ericfennis"
|
||||
],
|
||||
"tags": [
|
||||
"logo",
|
||||
"camera",
|
||||
"social"
|
||||
],
|
||||
"categories": [
|
||||
"brands",
|
||||
"social",
|
||||
"photography"
|
||||
]
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect width="20" height="20" x="2" y="2" rx="5" ry="5" />
|
||||
<path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z" />
|
||||
<line x1="17.5" x2="17.51" y1="6.5" y2="6.5" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 381 B |
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"okcoker",
|
||||
"csandman",
|
||||
"ericfennis"
|
||||
],
|
||||
"tags": [
|
||||
"logo",
|
||||
"social media",
|
||||
"social"
|
||||
],
|
||||
"categories": [
|
||||
"social",
|
||||
"brands"
|
||||
]
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z" />
|
||||
<rect width="4" height="12" x="2" y="9" />
|
||||
<circle cx="4" cy="4" r="2" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 380 B |
@@ -9,8 +9,8 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M19 12H2" />
|
||||
<path d="M11 7 6 2" />
|
||||
<path d="M18.992 12H2.041" />
|
||||
<path d="M21.145 18.38A3.34 3.34 0 0 1 20 16.5a3.3 3.3 0 0 1-1.145 1.88c-.575.46-.855 1.02-.855 1.595A2 2 0 0 0 20 22a2 2 0 0 0 2-2.025c0-.58-.285-1.13-.855-1.595" />
|
||||
<path d="m6 2 5 5" />
|
||||
<path d="m8.5 4.5 2.148-2.148a1.205 1.205 0 0 1 1.704 0l7.296 7.296a1.205 1.205 0 0 1 0 1.704l-7.592 7.592a3.615 3.615 0 0 1-5.112 0l-3.888-3.888a3.615 3.615 0 0 1 0-5.112L5.67 7.33" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 613 B After Width: | Height: | Size: 622 B |
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"csandman",
|
||||
"ericfennis"
|
||||
],
|
||||
"tags": [
|
||||
"logo",
|
||||
"save"
|
||||
],
|
||||
"categories": [
|
||||
"brands"
|
||||
]
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M20 3a2 2 0 0 1 2 2v6a1 1 0 0 1-20 0V5a2 2 0 0 1 2-2z" />
|
||||
<path d="m8 10 4 4 4-4" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 306 B |
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley"
|
||||
],
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"tags": [
|
||||
"railway",
|
||||
"train",
|
||||
"track",
|
||||
"line"
|
||||
],
|
||||
"categories": [
|
||||
"transportation",
|
||||
"navigation"
|
||||
]
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M5 15h14" />
|
||||
<path d="M5 9h14" />
|
||||
<path d="m14 20-5-5 6-6-5-5" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 289 B |
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"ashygee",
|
||||
"wojtekmaj",
|
||||
"mittalyashu",
|
||||
"ericfennis"
|
||||
],
|
||||
"tags": [
|
||||
"logo"
|
||||
],
|
||||
"categories": [
|
||||
"account",
|
||||
"social",
|
||||
"brands",
|
||||
"development"
|
||||
]
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect width="3" height="8" x="13" y="2" rx="1.5" />
|
||||
<path d="M19 8.5V10h1.5A1.5 1.5 0 1 0 19 8.5" />
|
||||
<rect width="3" height="8" x="8" y="14" rx="1.5" />
|
||||
<path d="M5 15.5V14H3.5A1.5 1.5 0 1 0 5 15.5" />
|
||||
<rect width="8" height="3" x="14" y="13" rx="1.5" />
|
||||
<path d="M15.5 19H14v1.5a1.5 1.5 0 1 0 1.5-1.5" />
|
||||
<rect width="8" height="3" x="2" y="8" rx="1.5" />
|
||||
<path d="M8.5 5H10V3.5A1.5 1.5 0 1 0 8.5 5" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 628 B |
24
icons/stone.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"Alportan",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"mineral",
|
||||
"geology",
|
||||
"nature",
|
||||
"solid",
|
||||
"pebble",
|
||||
"crystal",
|
||||
"ore",
|
||||
"hard",
|
||||
"coal",
|
||||
"stone",
|
||||
"rock",
|
||||
"boulder"
|
||||
],
|
||||
"categories": [
|
||||
"nature"
|
||||
]
|
||||
}
|
||||
15
icons/stone.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M11.264 2.205A4 4 0 0 0 6.42 4.211l-4 8a4 4 0 0 0 1.359 5.117l6 4a4 4 0 0 0 4.438 0l6-4a4 4 0 0 0 1.576-4.592l-2-6a4 4 0 0 0-2.53-2.53z" />
|
||||
<path d="M11.99 22 14 12l7.822 3.184" />
|
||||
<path d="M14 12 8.47 2.302" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 435 B |
@@ -13,7 +13,6 @@
|
||||
"productivity"
|
||||
],
|
||||
"categories": [
|
||||
"brands",
|
||||
"gaming"
|
||||
]
|
||||
}
|
||||
|
||||
37
icons/toolbox.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"toolkit",
|
||||
"tools",
|
||||
"trunk",
|
||||
"chest",
|
||||
"box",
|
||||
"storage",
|
||||
"utility",
|
||||
"utilities",
|
||||
"container",
|
||||
"kit",
|
||||
"set",
|
||||
"repair",
|
||||
"fix",
|
||||
"service",
|
||||
"maintenance",
|
||||
"mechanic",
|
||||
"workshop",
|
||||
"construction",
|
||||
"hardware",
|
||||
"equipment",
|
||||
"gear",
|
||||
"handyman",
|
||||
"engineering",
|
||||
"craft",
|
||||
"diy"
|
||||
],
|
||||
"categories": [
|
||||
"tools",
|
||||
"home"
|
||||
]
|
||||
}
|
||||
17
icons/toolbox.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M16 12v4" />
|
||||
<path d="M16 6a2 2 0 0 1 1.414.586l4 4A2 2 0 0 1 22 12v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 .586-1.414l4-4A2 2 0 0 1 8 6z" />
|
||||
<path d="M16 6V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2" />
|
||||
<path d="M2 14h20" />
|
||||
<path d="M8 12v4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 471 B |
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"bdbch",
|
||||
"csandman",
|
||||
"mittalyashu",
|
||||
"ericfennis"
|
||||
],
|
||||
"tags": [
|
||||
"logo",
|
||||
"brand"
|
||||
],
|
||||
"categories": [
|
||||
"account",
|
||||
"brands",
|
||||
"development"
|
||||
]
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect width="18" height="18" x="3" y="3" rx="2" ry="2" />
|
||||
<rect width="3" height="9" x="7" y="7" />
|
||||
<rect width="3" height="5" x="14" y="7" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 357 B |
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"ahtohbi4",
|
||||
"johnletey"
|
||||
],
|
||||
"tags": [
|
||||
"logo",
|
||||
"social"
|
||||
],
|
||||
"categories": [
|
||||
"brands",
|
||||
"social",
|
||||
"account",
|
||||
"gaming"
|
||||
]
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M21 2H3v16h5v4l4-4h5l4-4V2zm-10 9V7m5 4V7" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 265 B |
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"csandman",
|
||||
"ericfennis",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"logo",
|
||||
"social"
|
||||
],
|
||||
"categories": [
|
||||
"brands",
|
||||
"social",
|
||||
"account"
|
||||
]
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 359 B |
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"deprecated": true,
|
||||
"deprecationReason": "icon.brand",
|
||||
"toBeRemovedInVersion": "v1.0",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"csandman",
|
||||
"ericfennis",
|
||||
"karsa-mistmere",
|
||||
"jguddas"
|
||||
],
|
||||
"tags": [
|
||||
"logo",
|
||||
"social",
|
||||
"video",
|
||||
"play"
|
||||
],
|
||||
"categories": [
|
||||
"multimedia",
|
||||
"social",
|
||||
"brands"
|
||||
]
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M2.5 17a24.12 24.12 0 0 1 0-10 2 2 0 0 1 1.4-1.4 49.56 49.56 0 0 1 16.2 0A2 2 0 0 1 21.5 7a24.12 24.12 0 0 1 0 10 2 2 0 0 1-1.4 1.4 49.55 49.55 0 0 1-16.2 0A2 2 0 0 1 2.5 17" />
|
||||
<path d="m10 15 5-3-5-3z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 428 B |
@@ -24,9 +24,7 @@
|
||||
"author": "Eric Fennis",
|
||||
"amdName": "lucide-preact",
|
||||
"main": "dist/cjs/lucide-preact.js",
|
||||
"main:umd": "dist/umd/lucide-preact.js",
|
||||
"module": "dist/esm/lucide-preact.js",
|
||||
"unpkg": "dist/umd/lucide-preact.min.js",
|
||||
"typings": "dist/lucide-preact.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
@@ -46,7 +44,7 @@
|
||||
"@lucide/rollup-plugins": "workspace:*",
|
||||
"@lucide/shared": "workspace:*",
|
||||
"@preact/preset-vite": "^2.10.2",
|
||||
"@testing-library/jest-dom": "^6.1.4",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/preact": "^3.2.3",
|
||||
"jest-serializer-html": "^7.1.0",
|
||||
"preact": "^10.19.2",
|
||||
|
||||
@@ -7,17 +7,6 @@ const outputFileName = 'lucide-preact';
|
||||
const outputDir = 'dist';
|
||||
const inputs = [`src/lucide-preact.ts`];
|
||||
const bundles = [
|
||||
{
|
||||
format: 'umd',
|
||||
inputs,
|
||||
outputDir,
|
||||
minify: true,
|
||||
},
|
||||
{
|
||||
format: 'umd',
|
||||
inputs,
|
||||
outputDir,
|
||||
},
|
||||
{
|
||||
format: 'cjs',
|
||||
inputs,
|
||||
@@ -32,7 +21,7 @@ const bundles = [
|
||||
];
|
||||
|
||||
const configs = bundles
|
||||
.map(({ inputs, outputDir, format, minify, preserveModules }) =>
|
||||
.map(({ inputs, outputDir, format, preserveModules }) =>
|
||||
inputs.map((input) => ({
|
||||
input,
|
||||
plugins: plugins({ pkg, minify }),
|
||||
@@ -44,7 +33,7 @@ const configs = bundles
|
||||
dir: `${outputDir}/${format}`,
|
||||
}
|
||||
: {
|
||||
file: `${outputDir}/${format}/${outputFileName}${minify ? '.min' : ''}.js`,
|
||||
file: `${outputDir}/${format}/${outputFileName}.js`,
|
||||
}),
|
||||
preserveModules,
|
||||
format,
|
||||
|
||||
@@ -24,11 +24,23 @@
|
||||
"author": "Eric Fennis",
|
||||
"amdName": "lucide-react-native",
|
||||
"main": "dist/cjs/lucide-react-native.js",
|
||||
"main:umd": "dist/umd/lucide-react-native.js",
|
||||
"module": "dist/esm/lucide-react-native.js",
|
||||
"unpkg": "dist/umd/lucide-react-native.min.js",
|
||||
"typings": "dist/lucide-react-native.d.ts",
|
||||
"react-native": "dist/esm/lucide-react-native.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/lucide-react-native.d.ts",
|
||||
"import": "./dist/esm/lucide-react-native.js",
|
||||
"browser": "./dist/esm/lucide-react-native.js",
|
||||
"require": "./dist/cjs/lucide-react-native.js"
|
||||
},
|
||||
"./icons": {
|
||||
"types": "./dist/icons.d.ts",
|
||||
"import": "./dist/esm/icons/index.js",
|
||||
"browser": "./dist/esm/icons/index.js",
|
||||
"require": "./dist/cjs/icons/index.js"
|
||||
}
|
||||
},
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"dist"
|
||||
@@ -46,7 +58,7 @@
|
||||
"@lucide/rollup-plugins": "workspace:*",
|
||||
"@lucide/build-icons": "workspace:*",
|
||||
"@lucide/shared": "workspace:*",
|
||||
"@testing-library/jest-dom": "^6.1.6",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^14.1.2",
|
||||
"@types/prop-types": "^15.7.5",
|
||||
"@types/react": "^18.0.21",
|
||||
|
||||
@@ -5,7 +5,7 @@ import pkg from './package.json' with { type: 'json' };
|
||||
const packageName = 'LucideReact';
|
||||
const outputFileName = 'lucide-react-native';
|
||||
const outputDir = 'dist';
|
||||
const inputs = ['src/lucide-react-native.ts'];
|
||||
const inputs = ['src/lucide-react-native.ts', 'src/icons/index.ts'];
|
||||
const bundles = [
|
||||
{
|
||||
format: 'cjs',
|
||||
@@ -22,10 +22,10 @@ const bundles = [
|
||||
];
|
||||
|
||||
const configs = bundles
|
||||
.map(({ inputs, outputDir, format, minify, preserveModules }) =>
|
||||
.map(({ inputs, outputDir, format, preserveModules }) =>
|
||||
inputs.map((input) => ({
|
||||
input,
|
||||
plugins: plugins({ pkg, minify }),
|
||||
plugins: plugins({ pkg }),
|
||||
external: ['react', 'react-native-svg'],
|
||||
output: {
|
||||
name: packageName,
|
||||
@@ -35,7 +35,7 @@ const configs = bundles
|
||||
exports: 'auto',
|
||||
}
|
||||
: {
|
||||
file: `${outputDir}/${format}/${outputFileName}${minify ? '.min' : ''}.js`,
|
||||
file: `${outputDir}/${format}/${outputFileName}.js`,
|
||||
}),
|
||||
format,
|
||||
preserveModules,
|
||||
@@ -60,6 +60,16 @@ export default [
|
||||
],
|
||||
plugins: [dts()],
|
||||
},
|
||||
{
|
||||
input: inputs[1],
|
||||
output: [
|
||||
{
|
||||
file: `dist/icons.d.ts`,
|
||||
format: 'es',
|
||||
},
|
||||
],
|
||||
plugins: [dts()],
|
||||
},
|
||||
{
|
||||
input: `src/${outputFileName}.suffixed.ts`,
|
||||
output: [
|
||||
|
||||