Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cf568c38b | ||
|
|
a8b8dfc58e | ||
|
|
41dde6b574 | ||
|
|
ae35ca256c | ||
|
|
38142f24a5 | ||
|
|
b16f70993a | ||
|
|
ad1accb2e3 | ||
|
|
d255c6ac4e | ||
|
|
d67ef7b0ca | ||
|
|
198ccb8430 | ||
|
|
ce1b5bdefa | ||
|
|
45aa928369 | ||
|
|
93dc356fa1 | ||
|
|
a0aa132682 | ||
|
|
1a4dd64862 | ||
|
|
3481f70ad7 | ||
|
|
024f21e896 | ||
|
|
c30ccd472e | ||
|
|
28ec03ebc8 | ||
|
|
ab3a31367a | ||
|
|
148bae88d8 | ||
|
|
ca4a38ba85 | ||
|
|
f297765a13 | ||
|
|
4657ccbfff | ||
|
|
db222d4591 |
@@ -6,6 +6,8 @@ on:
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
@@ -14,4 +16,5 @@ jobs:
|
||||
close-pr-message: This PR was closed because it has been stalled for 5 days with no activity.
|
||||
close-pr-label: 🧶 stale
|
||||
days-before-stale: 30
|
||||
days-before-issue-stale: -1
|
||||
days-before-close: -1
|
||||
|
||||
@@ -25,11 +25,29 @@ const Grid = ({
|
||||
fill={fill}
|
||||
/>
|
||||
<path
|
||||
strokeDasharray={'0 0.1 ' + '0.1 0.15 '.repeat(11) + '0 0.15'}
|
||||
strokeWidth={0.1}
|
||||
d={
|
||||
props.d ||
|
||||
new Array(Math.floor(24 - 1))
|
||||
.fill(null)
|
||||
.flatMap((_, i) => [
|
||||
.map((_, i) => i)
|
||||
.filter((i) => i % 3 !== 2)
|
||||
.flatMap((i) => [
|
||||
`M${props.strokeWidth} ${i + 1}h${24 - props.strokeWidth * 2}`,
|
||||
`M${i + 1} ${props.strokeWidth}v${24 - props.strokeWidth * 2}`,
|
||||
])
|
||||
.join('')
|
||||
}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
props.d ||
|
||||
new Array(Math.floor(24 - 1))
|
||||
.fill(null)
|
||||
.map((_, i) => i)
|
||||
.filter((i) => i % 3 === 2)
|
||||
.flatMap((i) => [
|
||||
`M${props.strokeWidth} ${i + 1}h${24 - props.strokeWidth * 2}`,
|
||||
`M${i + 1} ${props.strokeWidth}v${24 - props.strokeWidth * 2}`,
|
||||
])
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { useData } from 'vitepress'
|
||||
import VPLink from 'vitepress/dist/client/theme-default/components/VPLink.vue'
|
||||
import { isActive } from 'vitepress/dist/client/shared'
|
||||
import { useActiveAnchor } from '../../composables/useActiveAnchor'
|
||||
import { data } from './CategoryList.data'
|
||||
import CategoryListItem from './CategoryListItem.vue'
|
||||
import { useCategoryView } from '../../composables/useCategoryView'
|
||||
|
||||
const { page } = useData()
|
||||
const { categoryCounts } = useCategoryView();
|
||||
|
||||
const categoriesIsActive = computed(() => {
|
||||
return isActive(page.value.relativePath, '/icons/categories');
|
||||
@@ -25,14 +27,21 @@ const headers = computed(() => {
|
||||
level: 2,
|
||||
link: `${linkPrefix}#${name}`,
|
||||
title,
|
||||
iconCount
|
||||
iconCount: categoryCounts.value[name] ?? iconCount,
|
||||
name
|
||||
}))
|
||||
})
|
||||
|
||||
const container = ref()
|
||||
const marker = ref()
|
||||
|
||||
useActiveAnchor(container, marker)
|
||||
const { setActiveLinkDebounced } = useActiveAnchor(container, marker)
|
||||
|
||||
watch(headers, () => {
|
||||
setTimeout(() => {
|
||||
setActiveLinkDebounced()
|
||||
}, 200)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -7,6 +7,7 @@ interface Header {
|
||||
slug: string;
|
||||
iconCount: number;
|
||||
link: string;
|
||||
name: string;
|
||||
children: Header[];
|
||||
}
|
||||
|
||||
@@ -14,36 +15,35 @@ type MenuItem = Omit<Header, 'slug' | 'children'> & {
|
||||
children?: MenuItem[];
|
||||
};
|
||||
|
||||
const props = defineProps<{
|
||||
defineProps<{
|
||||
headers: MenuItem[];
|
||||
root?: boolean;
|
||||
}>();
|
||||
|
||||
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 href = (target as HTMLAnchorElement)?.href;
|
||||
function onClick(categoryName: string) {
|
||||
selectedCategory.value = categoryName;
|
||||
|
||||
if (href) {
|
||||
const id = '#' + href.split('#')[1];
|
||||
const decodedId = decodeURIComponent(id);
|
||||
const heading = document.querySelector<HTMLAnchorElement>(categoryName);
|
||||
heading?.focus();
|
||||
|
||||
selectedCategory.value = decodedId.replace('#', '');
|
||||
|
||||
const heading = document.querySelector<HTMLAnchorElement>(decodedId);
|
||||
heading?.focus();
|
||||
}
|
||||
window.history.pushState({}, '', `/icons/categories#${categoryName}`)
|
||||
}
|
||||
</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">
|
||||
<li v-for="{ children, link, title, iconCount, name } in headers">
|
||||
<a
|
||||
class="outline-link"
|
||||
:href="link"
|
||||
@click="onClick(name)"
|
||||
:title="title"
|
||||
:class="{
|
||||
inactive: iconCount === 0,
|
||||
}"
|
||||
>
|
||||
<span>
|
||||
{{ title }}
|
||||
</span>
|
||||
@@ -83,6 +83,10 @@ function onClick(event: Event) {
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.outline-link.inactive {
|
||||
color: var(--vp-c-text-4);
|
||||
}
|
||||
|
||||
.outline-link.nested {
|
||||
padding-left: 13px;
|
||||
}
|
||||
@@ -93,4 +97,8 @@ function onClick(event: Event) {
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.outline-link.inactive .icon-count {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,7 +4,7 @@ import IconItem from './IconItem.vue'
|
||||
|
||||
const emit = defineEmits(['setActiveIcon'])
|
||||
|
||||
const props = defineProps<{
|
||||
defineProps<{
|
||||
icons: IconEntity[]
|
||||
activeIcon?: string
|
||||
overlayMode?: boolean
|
||||
@@ -40,7 +40,6 @@ function setActiveIcon(name: string) {
|
||||
.icons {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));
|
||||
/* padding: 32px 32px 96px; */
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -1,56 +1,53 @@
|
||||
<script lang="ts">
|
||||
import { IconEntity } from '../../types';
|
||||
|
||||
type CategoryNameRow = {
|
||||
type: 'category';
|
||||
title: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
type CategoryIconsRow = {
|
||||
type: 'icons';
|
||||
icons: IconEntity[];
|
||||
};
|
||||
|
||||
export type CategoryRow = CategoryNameRow | CategoryIconsRow;
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { Category } from '../../types';
|
||||
import IconGrid from './IconGrid.vue'
|
||||
import { vIntersectionObserver } from '@vueuse/components'
|
||||
|
||||
defineProps<{
|
||||
activeIconName: string
|
||||
category: Category
|
||||
categoryRow: CategoryRow
|
||||
}>()
|
||||
|
||||
|
||||
const emit = defineEmits(['setActiveIcon'])
|
||||
|
||||
const showIcons = ref(false)
|
||||
|
||||
// Added intersection observer to improve performance
|
||||
const onIntersectionObserver: IntersectionObserverCallback = ([{ isIntersecting }]) => {
|
||||
showIcons.value = isIntersecting
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section
|
||||
class="category"
|
||||
:key="category.name"
|
||||
:id="category.name"
|
||||
v-intersection-observer="onIntersectionObserver"
|
||||
<h2
|
||||
v-if="categoryRow.type === 'category'"
|
||||
class="title"
|
||||
>
|
||||
<h2 class="title" >
|
||||
<a class="header-anchor" :href="`#${category.name}`" :aria-label="`Permalink to "${category.title}"`">​</a>
|
||||
{{ category.title }}
|
||||
</h2>
|
||||
<IconGrid
|
||||
:activeIcon="activeIconName"
|
||||
:icons="category.icons"
|
||||
@setActiveIcon="$event => $emit('setActiveIcon', $event)"
|
||||
overlayMode
|
||||
:hideIcons="!showIcons"
|
||||
/>
|
||||
</section>
|
||||
<a class="header-anchor" :href="`#${categoryRow.name}`" :aria-label="`Permalink to "${categoryRow.title}"`">​</a>
|
||||
{{ categoryRow.title }}
|
||||
</h2>
|
||||
<IconGrid
|
||||
v-else-if="categoryRow.type === 'icons'"
|
||||
:activeIcon="activeIconName"
|
||||
:icons="categoryRow.icons"
|
||||
@setActiveIcon="$event => $emit('setActiveIcon', $event)"
|
||||
overlayMode
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.title {
|
||||
margin-bottom: 24px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 19px;
|
||||
font-weight: 500;
|
||||
padding-top: 86px;
|
||||
/* scroll-padding-top: 240px; */
|
||||
}
|
||||
|
||||
.category {
|
||||
margin-bottom: calc(-86px + 32px);
|
||||
padding: 24px 0 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, defineAsyncComponent } from 'vue';
|
||||
import { ref, computed, defineAsyncComponent, onMounted } from 'vue';
|
||||
import type { IconEntity, Category } from '../../types';
|
||||
import useSearch from '../../composables/useSearch';
|
||||
import InputSearch from '../base/InputSearch.vue';
|
||||
@@ -8,6 +8,13 @@ import StickyBar from './StickyBar.vue';
|
||||
import IconsCategory from './IconsCategory.vue';
|
||||
import useFetchTags from '../../composables/useFetchTags';
|
||||
import useFetchCategories from '../../composables/useFetchCategories';
|
||||
import { useElementSize, useEventListener, useVirtualList } from '@vueuse/core';
|
||||
import chunkArray from '../../utils/chunkArray';
|
||||
import { CategoryRow } from './IconsCategory.vue';
|
||||
import useScrollToCategory from '../../composables/useScrollToCategory';
|
||||
|
||||
const ICON_SIZE = 56;
|
||||
const ICON_GRID_GAP = 8;
|
||||
|
||||
const props = defineProps<{
|
||||
icons: IconEntity[];
|
||||
@@ -17,7 +24,6 @@ const props = defineProps<{
|
||||
|
||||
const activeIconName = ref(null);
|
||||
const { searchInput, searchQuery, searchQueryDebounced } = useSearchInput();
|
||||
|
||||
const isSearching = computed(() => !!searchQuery.value);
|
||||
|
||||
function setActiveIconName(name: string) {
|
||||
@@ -27,6 +33,13 @@ function setActiveIconName(name: string) {
|
||||
const { execute: fetchTags, data: tags } = useFetchTags();
|
||||
const { execute: fetchCategories, data: categoriesMap } = useFetchCategories();
|
||||
|
||||
const overviewEl = ref<HTMLElement | null>(null);
|
||||
const { width: containerWidth } = useElementSize(overviewEl)
|
||||
|
||||
const columnSize = computed(() => {
|
||||
return Math.floor((containerWidth.value) / ((ICON_SIZE + ICON_GRID_GAP)));
|
||||
});
|
||||
|
||||
const mappedIcons = computed(() => {
|
||||
if (tags.value == null) {
|
||||
return props.icons;
|
||||
@@ -43,9 +56,10 @@ const mappedIcons = computed(() => {
|
||||
});
|
||||
});
|
||||
|
||||
const searchResults = useSearch(searchQuery, mappedIcons, [
|
||||
{ name: 'name', weight: 2 },
|
||||
{ name: 'tags', weight: 1 },
|
||||
const searchResults = useSearch(searchQueryDebounced, mappedIcons, [
|
||||
{ name: 'name', weight: 3 },
|
||||
{ name: 'aliases', weight: 3 },
|
||||
{ name: 'tags', weight: 2 },
|
||||
]);
|
||||
|
||||
const categories = computed(() => {
|
||||
@@ -71,9 +85,43 @@ const categories = computed(() => {
|
||||
icons: searchedCategoryIcons,
|
||||
};
|
||||
})
|
||||
.filter(({ icons }) => icons.length);
|
||||
});
|
||||
|
||||
const categoriesList = computed(() => {
|
||||
return categories.value
|
||||
.filter(({ icons }) => icons.length)
|
||||
.reduce<CategoryRow[]>((acc, category) => {
|
||||
acc.push({ type: 'category', title: category.title, name: category.name });
|
||||
|
||||
const categoryIcons = chunkArray(category.icons, columnSize.value);
|
||||
categoryIcons.forEach((icons) => {
|
||||
acc.push({ type: 'icons', icons });
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
});
|
||||
|
||||
const { list, containerProps, wrapperProps, scrollTo } = useVirtualList(
|
||||
categoriesList,
|
||||
{
|
||||
itemHeight: ICON_SIZE + ICON_GRID_GAP,
|
||||
overscan: 10
|
||||
},
|
||||
)
|
||||
|
||||
useScrollToCategory({
|
||||
categories,
|
||||
categoriesList,
|
||||
scrollTo,
|
||||
searchQueryDebounced,
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
containerProps.ref.value = document.documentElement;
|
||||
useEventListener(window, 'scroll', containerProps.onScroll)
|
||||
})
|
||||
|
||||
function onFocusSearchInput() {
|
||||
if (tags.value == null) {
|
||||
fetchTags();
|
||||
@@ -84,28 +132,35 @@ function onFocusSearchInput() {
|
||||
}
|
||||
|
||||
const NoResults = defineAsyncComponent(() => import('./NoResults.vue'));
|
||||
|
||||
const IconDetailOverlay = defineAsyncComponent(() => import('./IconDetailOverlay.vue'));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StickyBar class="search-bar category-search">
|
||||
<InputSearch
|
||||
:placeholder="`Search ${icons.length} icons ...`"
|
||||
v-model="searchQuery"
|
||||
class="input-wrapper"
|
||||
ref="searchInput"
|
||||
@focus="onFocusSearchInput"
|
||||
<div ref="overviewEl" class="overview-container">
|
||||
<StickyBar class="category-search">
|
||||
<InputSearch
|
||||
:placeholder="`Search ${icons.length} icons ...`"
|
||||
v-model="searchQuery"
|
||||
class="input-wrapper"
|
||||
ref="searchInput"
|
||||
@focus="onFocusSearchInput"
|
||||
/>
|
||||
</StickyBar>
|
||||
<NoResults
|
||||
v-if="categories.length === 0"
|
||||
:searchQuery="searchQuery"
|
||||
@clear="searchQuery = ''"
|
||||
/>
|
||||
</StickyBar>
|
||||
<NoResults v-if="categories.length === 0" :searchQuery="searchQuery" @clear="searchQuery = ''" />
|
||||
<IconsCategory
|
||||
v-for="category in categories"
|
||||
:key="category.name"
|
||||
:category="category"
|
||||
:activeIconName="activeIconName"
|
||||
@setActiveIcon="setActiveIconName"
|
||||
/>
|
||||
<div v-bind="wrapperProps">
|
||||
<IconsCategory
|
||||
v-for="{ index, data } in list"
|
||||
:categoryRow="data"
|
||||
:activeIconName="activeIconName"
|
||||
@setActiveIcon="setActiveIconName"
|
||||
:key="index"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<IconDetailOverlay
|
||||
v-if="activeIconName != null"
|
||||
:iconName="activeIconName"
|
||||
@@ -119,6 +174,21 @@ const IconDetailOverlay = defineAsyncComponent(() => import('./IconDetailOverlay
|
||||
}
|
||||
|
||||
.search-bar.category-search {
|
||||
margin-bottom: -54px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 8px;
|
||||
font-size: 19px;
|
||||
font-weight: 500;
|
||||
padding: 24px 0 8px;
|
||||
}
|
||||
|
||||
.icons {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.overview-container {
|
||||
padding-bottom: 288px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, defineAsyncComponent } from 'vue';
|
||||
import { ref, computed, defineAsyncComponent, onMounted, watch } from 'vue';
|
||||
import type { IconEntity } from '../../types';
|
||||
import { useMediaQuery, useOffsetPagination } from '@vueuse/core';
|
||||
import { useElementSize, useEventListener, useVirtualList } 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 chunkArray from '../../utils/chunkArray';
|
||||
|
||||
const ICON_SIZE = 56;
|
||||
const ICON_GRID_GAP = 8;
|
||||
|
||||
const props = defineProps<{
|
||||
icons: IconEntity[];
|
||||
@@ -17,32 +20,16 @@ const props = defineProps<{
|
||||
|
||||
const activeIconName = ref(null);
|
||||
|
||||
const isExtraLargeScreen = useMediaQuery('(min-width: 1440px)');
|
||||
const isLargeScreen = useMediaQuery('(min-width: 1280px)');
|
||||
const isMediumScreen = useMediaQuery('(min-width: 960px)');
|
||||
const isSmallScreen = useMediaQuery('(min-width: 640px)');
|
||||
|
||||
const pageSize = computed(() => {
|
||||
if (isExtraLargeScreen.value) {
|
||||
return 16 * 20;
|
||||
}
|
||||
if (isLargeScreen.value) {
|
||||
return 16 * 12;
|
||||
}
|
||||
if (isMediumScreen.value) {
|
||||
return 13 * 12;
|
||||
}
|
||||
|
||||
if (isSmallScreen.value) {
|
||||
return 10 * 10;
|
||||
}
|
||||
|
||||
return 10 * 5;
|
||||
});
|
||||
|
||||
const { execute: fetchTags, data: tags } = useFetchTags();
|
||||
const { execute: fetchCategories, data: categories } = useFetchCategories();
|
||||
|
||||
const overviewEl = ref<HTMLElement | null>(null);
|
||||
const { width: containerWidth } = useElementSize(overviewEl)
|
||||
|
||||
const columnSize = computed(() => {
|
||||
return Math.floor((containerWidth.value) / ((ICON_SIZE + ICON_GRID_GAP)));
|
||||
});
|
||||
|
||||
const mappedIcons = computed(() => {
|
||||
if (tags.value == null) {
|
||||
return props.icons;
|
||||
@@ -63,26 +50,33 @@ const mappedIcons = computed(() => {
|
||||
const { searchInput, searchQuery, searchQueryDebounced } = useSearchInput();
|
||||
const searchResults = useSearch(searchQueryDebounced, mappedIcons, [
|
||||
{ name: 'name', weight: 3 },
|
||||
{ name: 'aliases', weight: 3 },
|
||||
{ name: 'tags', weight: 2 },
|
||||
{ name: 'categories', weight: 1 },
|
||||
]);
|
||||
|
||||
const { next, currentPage } = useOffsetPagination({ pageSize });
|
||||
|
||||
const paginatedIcons = computed(() => {
|
||||
const end = pageSize.value * currentPage.value;
|
||||
|
||||
return searchResults.value.slice(0, end);
|
||||
const chunkedIcons = computed(() => {
|
||||
return chunkArray(searchResults.value, columnSize.value);
|
||||
});
|
||||
|
||||
const { list, containerProps, wrapperProps, scrollTo } = useVirtualList(
|
||||
chunkedIcons,
|
||||
{
|
||||
itemHeight: ICON_SIZE + ICON_GRID_GAP,
|
||||
overscan: 10
|
||||
},
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
containerProps.ref.value = document.documentElement;
|
||||
useEventListener(window, 'scroll', containerProps.onScroll)
|
||||
})
|
||||
|
||||
|
||||
function setActiveIconName(name: string) {
|
||||
activeIconName.value = name;
|
||||
}
|
||||
|
||||
watch(searchQueryDebounced, (searchString) => {
|
||||
currentPage.value = 1;
|
||||
});
|
||||
|
||||
function onFocusSearchInput() {
|
||||
if (tags.value == null) {
|
||||
fetchTags();
|
||||
@@ -95,30 +89,40 @@ function onFocusSearchInput() {
|
||||
const NoResults = defineAsyncComponent(() => import('./NoResults.vue'));
|
||||
|
||||
const IconDetailOverlay = defineAsyncComponent(() => import('./IconDetailOverlay.vue'));
|
||||
|
||||
watch(searchQueryDebounced, () => {
|
||||
scrollTo(0)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<StickyBar>
|
||||
<InputSearch
|
||||
:placeholder="`Search ${icons.length} icons ...`"
|
||||
v-model="searchQuery"
|
||||
ref="searchInput"
|
||||
class="input-wrapper"
|
||||
@focus="onFocusSearchInput"
|
||||
<div ref="overviewEl" class="overview-container">
|
||||
<StickyBar>
|
||||
<InputSearch
|
||||
:placeholder="`Search ${icons.length} icons ...`"
|
||||
v-model="searchQuery"
|
||||
ref="searchInput"
|
||||
class="input-wrapper"
|
||||
@focus="onFocusSearchInput"
|
||||
/>
|
||||
</StickyBar>
|
||||
<NoResults
|
||||
v-if="list.length === 0"
|
||||
:searchQuery="searchQuery"
|
||||
@clear="searchQuery = ''"
|
||||
/>
|
||||
</StickyBar>
|
||||
<NoResults
|
||||
v-if="paginatedIcons.length === 0"
|
||||
:searchQuery="searchQuery"
|
||||
@clear="searchQuery = ''"
|
||||
/>
|
||||
<IconGrid
|
||||
overlayMode
|
||||
:activeIcon="activeIconName"
|
||||
:icons="paginatedIcons"
|
||||
@setActiveIcon="setActiveIconName"
|
||||
/>
|
||||
<EndOfPage @end-of-page="next" class="bottom-page" />
|
||||
<div v-bind="wrapperProps" class="icon">
|
||||
<IconGrid
|
||||
v-for="{ index, data: icons } in list"
|
||||
:key="index"
|
||||
overlayMode
|
||||
:icons="icons"
|
||||
:activeIcon="activeIconName"
|
||||
@setActiveIcon="setActiveIconName"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<IconDetailOverlay
|
||||
v-if="activeIconName != null"
|
||||
:iconName="activeIconName"
|
||||
@@ -128,10 +132,7 @@ const IconDetailOverlay = defineAsyncComponent(() => import('./IconDetailOverlay
|
||||
|
||||
<style>
|
||||
.icons {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
@@ -142,7 +143,7 @@ const IconDetailOverlay = defineAsyncComponent(() => import('./IconDetailOverlay
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bottom-page {
|
||||
height: 288px;
|
||||
.overview-container {
|
||||
padding-bottom: 288px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import {ref} from 'vue'
|
||||
import {bird} from '../../../data/iconNodes'
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { bird, squirrel, rabbit } from '../../../data/iconNodes'
|
||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon'
|
||||
import {useEventListener} from '@vueuse/core'
|
||||
import VPButton from 'vitepress/dist/client/theme-default/components/VPButton.vue'
|
||||
import { IconNode } from '../../types'
|
||||
|
||||
defineProps<{
|
||||
searchQuery: string
|
||||
@@ -11,32 +12,48 @@ defineProps<{
|
||||
|
||||
defineEmits(['clear'])
|
||||
|
||||
const birdIcon = ref<HTMLElement>()
|
||||
const Bird = createLucideIcon('bird', bird)
|
||||
const animalIcon = ref<HTMLElement>()
|
||||
const randomAnimal = computed<IconNode>(() => {
|
||||
return Math.random() > 0.5 ? squirrel : Math.random() > 0.5 ? rabbit : bird
|
||||
})
|
||||
const animalComponent = computed(() => createLucideIcon('animal', randomAnimal.value))
|
||||
const flip = ref(false)
|
||||
|
||||
useEventListener(document, 'mousemove', (mouseEvent) => {
|
||||
const {width, height, x, y} = birdIcon.value.getBoundingClientRect()
|
||||
onMounted(() => {
|
||||
useEventListener(document, 'mousemove', (mouseEvent) => {
|
||||
const {width, height, x, y} = animalIcon.value.getBoundingClientRect()
|
||||
|
||||
const centerX = (width / 2) + x
|
||||
const centerX = (width / 2) + x
|
||||
|
||||
flip.value = mouseEvent.x < centerX
|
||||
flip.value = mouseEvent.x < centerX
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="no-results">
|
||||
<Bird class="bird-icon" ref="birdIcon" :class="{ flip }" :strokeWidth="1"/>
|
||||
<component
|
||||
:is="animalComponent"
|
||||
class="animal-icon"
|
||||
ref="animalIcon"
|
||||
:class="{ flip }"
|
||||
:strokeWidth="1"
|
||||
/>
|
||||
<h2 class="no-results-text">
|
||||
No icons found for '{{ searchQuery }}'
|
||||
</h2>
|
||||
<VPButton text="Clear your search and try again" theme="alt" @click="$emit('clear')"/>
|
||||
<VPButton
|
||||
text="Clear your search and try again"
|
||||
theme="alt"
|
||||
@click="$emit('clear')"
|
||||
/>
|
||||
<span class="text-divider">or</span>
|
||||
<VPButton text="Search on Github issues"
|
||||
theme="alt"
|
||||
:href="`https://github.com/lucide-icons/lucide/issues?q=is%3Aopen+${searchQuery}`"
|
||||
target="_blank"
|
||||
<VPButton
|
||||
text="Search on Github issues"
|
||||
theme="alt"
|
||||
:href="`https://github.com/lucide-icons/lucide/issues?q=is%3Aopen+${searchQuery}`"
|
||||
target="_blank"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -48,7 +65,7 @@ useEventListener(document, 'mousemove', (mouseEvent) => {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bird-icon {
|
||||
.animal-icon {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
color: var(--vp-c-neutral);
|
||||
@@ -56,12 +73,12 @@ useEventListener(document, 'mousemove', (mouseEvent) => {
|
||||
margin-top: 72px;
|
||||
}
|
||||
|
||||
.bird-icon.flip {
|
||||
.animal-icon.flip {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.bird-icon {
|
||||
.animal-icon {
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
}
|
||||
|
||||
@@ -6,18 +6,18 @@ import { throttleAndDebounce } from 'vitepress/dist/client/theme-default/support
|
||||
*/
|
||||
|
||||
export function useActiveAnchor(container, marker) {
|
||||
const onScroll = throttleAndDebounce(setActiveLink, 100);
|
||||
const setActiveLinkDebounced = throttleAndDebounce(setActiveLink, 100);
|
||||
let prevActiveLink = null;
|
||||
onMounted(() => {
|
||||
requestAnimationFrame(setActiveLink);
|
||||
window.addEventListener('scroll', onScroll);
|
||||
window.addEventListener('scroll', setActiveLinkDebounced);
|
||||
});
|
||||
onUpdated(() => {
|
||||
// sidebar update means a route change
|
||||
activateLink(location.hash);
|
||||
});
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('scroll', onScroll);
|
||||
window.removeEventListener('scroll', setActiveLinkDebounced);
|
||||
});
|
||||
function setActiveLink() {
|
||||
const links = [].slice.call(container.value.querySelectorAll('.outline-link'));
|
||||
@@ -64,9 +64,13 @@ export function useActiveAnchor(container, marker) {
|
||||
marker.value.style.opacity = '0';
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
setActiveLinkDebounced,
|
||||
};
|
||||
}
|
||||
|
||||
const PAGE_OFFSET = 64;
|
||||
const PAGE_OFFSET = 128;
|
||||
|
||||
function getAnchorTop(anchor) {
|
||||
return anchor.parentElement.offsetTop - PAGE_OFFSET;
|
||||
@@ -74,7 +78,7 @@ function getAnchorTop(anchor) {
|
||||
function isAnchorActive(index, anchor, nextAnchor) {
|
||||
const scrollTop = window.scrollY;
|
||||
if (index === 0 && scrollTop === 0) {
|
||||
return [true, null];
|
||||
return [true, anchor.hash];
|
||||
}
|
||||
if (scrollTop < getAnchorTop(anchor)) {
|
||||
return [false, null];
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ref, inject, Ref } from 'vue';
|
||||
import { useRoute } from 'vitepress';
|
||||
import { ref, inject, Ref, onMounted, watch } from 'vue';
|
||||
|
||||
export const CATEGORY_VIEW_CONTEXT = Symbol('categoryView');
|
||||
|
||||
@@ -8,16 +9,30 @@ interface CategoryViewContext {
|
||||
}
|
||||
|
||||
export const categoryViewContext = {
|
||||
selectedCategory: ref(''),
|
||||
selectedCategory: ref(),
|
||||
categoryCounts: ref({}),
|
||||
};
|
||||
|
||||
export function useCategoryView(): CategoryViewContext {
|
||||
const context = inject<CategoryViewContext>(CATEGORY_VIEW_CONTEXT);
|
||||
const route = useRoute();
|
||||
|
||||
if (!context) {
|
||||
throw new Error('useCategoryView must be used with categoryView context');
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (window.location.hash) {
|
||||
context.selectedCategory.value = decodeURIComponent(window.location.hash.slice(1));
|
||||
}
|
||||
});
|
||||
|
||||
watch(route, (currentRoute) => {
|
||||
if (currentRoute.path !== '/icons/categories') {
|
||||
context.selectedCategory.value = '';
|
||||
context.categoryCounts.value = {};
|
||||
}
|
||||
});
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { Ref, onMounted, watch } from 'vue';
|
||||
import { CategoryRow } from '../components/icons/IconsCategory.vue';
|
||||
import { Category } from '../types';
|
||||
import { useCategoryView } from './useCategoryView';
|
||||
|
||||
interface UseScrollToCategory {
|
||||
categories: Ref<Pick<Category, 'name' | 'icons'>[]>;
|
||||
categoriesList: Ref<CategoryRow[]>;
|
||||
scrollTo: (index: number) => void;
|
||||
searchQueryDebounced: Ref<string>;
|
||||
}
|
||||
|
||||
export default function useScrollToCategory({
|
||||
categories,
|
||||
categoriesList,
|
||||
scrollTo,
|
||||
searchQueryDebounced,
|
||||
}: UseScrollToCategory) {
|
||||
const { selectedCategory, categoryCounts } = useCategoryView();
|
||||
|
||||
function scrollToSelectedCategory(selectedCategory: string) {
|
||||
const category = categories.value.find((category) => category.name === selectedCategory);
|
||||
|
||||
if (category != null) {
|
||||
const categoryRowIndex = categoriesList.value.findIndex(
|
||||
(row) => row.type === 'category' && row.name === selectedCategory,
|
||||
);
|
||||
|
||||
if (categoryRowIndex !== -1) {
|
||||
setTimeout(() => {
|
||||
scrollTo(categoryRowIndex);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watch(selectedCategory, scrollToSelectedCategory);
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
scrollToSelectedCategory(selectedCategory.value);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
watch(searchQueryDebounced, () => {
|
||||
scrollTo(0);
|
||||
});
|
||||
|
||||
watch(categories, (items) => {
|
||||
categoryCounts.value = Object.fromEntries(items.map(({ name, icons }) => [name, icons.length]));
|
||||
});
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { shallowRef, computed, Ref } from 'vue';
|
||||
const useSearch = <T>(
|
||||
query: Ref<string>,
|
||||
collection: Ref<T[]>,
|
||||
keys: Fuse.FuseOptionKey<T>[] = [],
|
||||
keys: Fuse.FuseOptionKeyObject<T>[] = [],
|
||||
) => {
|
||||
const index = shallowRef(
|
||||
new Fuse(collection.value, {
|
||||
@@ -20,6 +20,16 @@ const useSearch = <T>(
|
||||
return index.value.search(query.value).map((result) => result.item);
|
||||
}
|
||||
|
||||
if (keys.length !== 0) {
|
||||
const mainKey = keys[0].name;
|
||||
|
||||
return collection.value.sort((a, b) => {
|
||||
const aString = a[mainKey as keyof T] as string;
|
||||
const bString = b[mainKey as keyof T] as string;
|
||||
return aString.localeCompare(bString);
|
||||
});
|
||||
}
|
||||
|
||||
return collection.value;
|
||||
});
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
--vp-code-editor-property: #005cc5;
|
||||
--vp-code-editor-static: #f78c6c;
|
||||
--vp-code-editor-string: #032f62;
|
||||
|
||||
--vp-c-text-4: rgba(60, 60, 67, 0.32);
|
||||
}
|
||||
|
||||
.dark {
|
||||
@@ -38,6 +40,8 @@
|
||||
--vp-code-editor-property: #79b8ff;
|
||||
--vp-code-editor-static: #f78c6c;
|
||||
--vp-code-editor-string: #9ecbff;
|
||||
|
||||
--vp-c-text-4: rgba(235, 235, 245, 0.16);
|
||||
}
|
||||
|
||||
.VPNavBarTitle .logo {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
const chunkArray = <ArrayType>(stream: ArrayType, size: number) => {
|
||||
return stream.reduce<ArrayType[][]>(
|
||||
(chunks, item, idx, arr) =>
|
||||
idx % size == 0 ? [...chunks, arr.slice(idx, idx + size)] : chunks,
|
||||
[],
|
||||
);
|
||||
};
|
||||
|
||||
export default chunkArray;
|
||||
@@ -4,7 +4,7 @@ Implementation of the lucide icon library for React Native applications
|
||||
|
||||
## Installation
|
||||
|
||||
First, ensure that you have `react-native-svg` (version between 12 and 14) installed. Then, install the package:
|
||||
First, ensure that you have `react-native-svg` (version between 12 and 15) installed. Then, install the package:
|
||||
|
||||
::: code-group
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"cast",
|
||||
"mirroring",
|
||||
"screen",
|
||||
"monitor"
|
||||
"monitor",
|
||||
"macos",
|
||||
"osx"
|
||||
],
|
||||
"categories": [
|
||||
"multimedia",
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M5 17H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-1" />
|
||||
<polygon points="12 15 17 21 7 21 12 15" />
|
||||
<path d="m12 15 5 6H7Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 344 B After Width: | Height: | Size: 327 B |
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley"
|
||||
],
|
||||
"tags": [
|
||||
"application",
|
||||
"menu bar",
|
||||
"pane",
|
||||
"preferences",
|
||||
"macos",
|
||||
"osx",
|
||||
"executable"
|
||||
],
|
||||
"categories": [
|
||||
"layout",
|
||||
"design",
|
||||
"development",
|
||||
"files"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect width="20" height="16" x="2" y="4" rx="2" />
|
||||
<path d="M6 8h.01" />
|
||||
<path d="M10 8h.01" />
|
||||
<path d="M14 8h.01" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 335 B |
@@ -6,11 +6,14 @@
|
||||
],
|
||||
"tags": [
|
||||
"application",
|
||||
"menu bar",
|
||||
"pane",
|
||||
"executable"
|
||||
],
|
||||
"categories": [
|
||||
"layout",
|
||||
"design",
|
||||
"files",
|
||||
"layout"
|
||||
"development",
|
||||
"files"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph",
|
||||
"area"
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
"diagonal",
|
||||
"share",
|
||||
"open",
|
||||
"external"
|
||||
"external",
|
||||
"link"
|
||||
],
|
||||
"categories": [
|
||||
"arrows",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph"
|
||||
],
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph"
|
||||
],
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph"
|
||||
],
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph"
|
||||
],
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph"
|
||||
],
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph"
|
||||
],
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley"
|
||||
],
|
||||
"tags": [
|
||||
"robot",
|
||||
"ai",
|
||||
"chat",
|
||||
"assistant"
|
||||
],
|
||||
"categories": [
|
||||
"development",
|
||||
"social"
|
||||
]
|
||||
}
|
||||
@@ -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 6V2H8" />
|
||||
<path d="m8 18-4 4V8a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2Z" />
|
||||
<path d="M2 12h2" />
|
||||
<path d="M9 11v2" />
|
||||
<path d="M15 11v2" />
|
||||
<path d="M20 12h2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 402 B |
@@ -9,13 +9,17 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 4.5a2.5 2.5 0 0 0-4.96-.46 2.5 2.5 0 0 0-1.98 3 2.5 2.5 0 0 0-1.32 4.24 3 3 0 0 0 .34 5.58 2.5 2.5 0 0 0 2.96 3.08 2.5 2.5 0 0 0 4.91.05L12 20V4.5Z" />
|
||||
<path d="M16 8V5c0-1.1.9-2 2-2" />
|
||||
<path d="M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z" />
|
||||
<path d="M9 13a4.5 4.5 0 0 0 3-4" />
|
||||
<path d="M6.003 5.125A3 3 0 0 0 6.401 6.5" />
|
||||
<path d="M3.477 10.896a4 4 0 0 1 .585-.396" />
|
||||
<path d="M6 18a4 4 0 0 1-1.967-.516" />
|
||||
<path d="M12 13h4" />
|
||||
<path d="M12 18h6a2 2 0 0 1 2 2v1" />
|
||||
<path d="M12 8h8" />
|
||||
<path d="M20.5 8a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0Z" />
|
||||
<path d="M16.5 13a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0Z" />
|
||||
<path d="M20.5 21a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0Z" />
|
||||
<path d="M18.5 3a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0Z" />
|
||||
<path d="M16 8V5a2 2 0 0 1 2-2" />
|
||||
<circle cx="16" cy="13" r=".5" />
|
||||
<circle cx="18" cy="3" r=".5" />
|
||||
<circle cx="20" cy="21" r=".5" />
|
||||
<circle cx="20" cy="8" r=".5" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 717 B After Width: | Height: | Size: 752 B |
@@ -9,8 +9,14 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 5a3 3 0 1 0-5.997.142 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588 4 4 0 0 0 7.636 2.106 3.2 3.2 0 0 0 .164-.546c.028-.13.306-.13.335 0a3.2 3.2 0 0 0 .163.546 4 4 0 0 0 7.636-2.106 4 4 0 0 0 .556-6.588 4 4 0 0 0-2.526-5.77A3 3 0 1 0 12 5" />
|
||||
<path d="M17.599 6.5a3 3 0 0 0 .399-1.375" />
|
||||
<path d="M6.003 5.125A3 3 0 0 0 6.401 6.5" />
|
||||
<path d="M3.477 10.896a4 4 0 0 1 .585-.396" />
|
||||
<path d="M19.938 10.5a4 4 0 0 1 .585.396" />
|
||||
<path d="M6 18a4 4 0 0 1-1.967-.516" />
|
||||
<path d="M19.967 17.484A4 4 0 0 1 18 18" />
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
<path d="M12 4.5a2.5 2.5 0 0 0-4.96-.46 2.5 2.5 0 0 0-1.98 3 2.5 2.5 0 0 0-1.32 4.24 3 3 0 0 0 .34 5.58 2.5 2.5 0 0 0 2.96 3.08A2.5 2.5 0 0 0 12 19.5a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24 2.5 2.5 0 0 0-1.98-3A2.5 2.5 0 0 0 12 4.5" />
|
||||
<path d="m15.7 10.4-.9.4" />
|
||||
<path d="m9.2 13.2-.9.4" />
|
||||
<path d="m13.6 15.7-.4-.9" />
|
||||
|
||||
|
Before Width: | Height: | Size: 778 B After Width: | Height: | Size: 1.0 KiB |
@@ -9,6 +9,13 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24 2.5 2.5 0 0 1 1.98-3A2.5 2.5 0 0 1 9.5 2Z" />
|
||||
<path d="M14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24 2.5 2.5 0 0 0-1.98-3A2.5 2.5 0 0 0 14.5 2Z" />
|
||||
<path d="M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z" />
|
||||
<path d="M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.526 5.77 4 4 0 0 1-.556 6.588A4 4 0 1 1 12 18Z" />
|
||||
<path d="M15 13a4.5 4.5 0 0 1-3-4 4.5 4.5 0 0 1-3 4" />
|
||||
<path d="M17.599 6.5a3 3 0 0 0 .399-1.375" />
|
||||
<path d="M6.003 5.125A3 3 0 0 0 6.401 6.5" />
|
||||
<path d="M3.477 10.896a4 4 0 0 1 .585-.396" />
|
||||
<path d="M19.938 10.5a4 4 0 0 1 .585.396" />
|
||||
<path d="M6 18a4 4 0 0 1-1.967-.516" />
|
||||
<path d="M19.967 17.484A4 4 0 0 1 18 18" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 564 B After Width: | Height: | Size: 746 B |
@@ -19,6 +19,7 @@
|
||||
"exchange",
|
||||
"hedge fund",
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"jguddas",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"cannabis",
|
||||
"weed",
|
||||
"leaf"
|
||||
],
|
||||
"categories": [
|
||||
"nature",
|
||||
"smoking"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<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-4" />
|
||||
<path d="M7 12c-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 1.5 1.5 3.5 3 6 3 0-1.5-.5-3.5-2-5 0 0 2.5.5 6-1-.5-1.5-3.5-3-5-3 1.5-1 4-4 4-6-2.5 0-5.5 1.5-7 3 0-2.5-.5-5-2-7-1.5 2-2 4.5-2 7-1.5-1.5-4.5-3-7-3 0 2 2.5 5 4 6" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 486 B |
@@ -9,7 +9,7 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M2 18a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v2H2v-2Z" />
|
||||
<path d="M3 20a1 1 0 0 1-1-1v-1a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1Z" />
|
||||
<path d="M20 16a8 8 0 1 0-16 0" />
|
||||
<path d="M12 4v4" />
|
||||
<path d="M10 4h4" />
|
||||
|
||||
|
Before Width: | Height: | Size: 351 B After Width: | Height: | Size: 377 B |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley"
|
||||
],
|
||||
"tags": [
|
||||
"desktop",
|
||||
"applications",
|
||||
"launch",
|
||||
"home",
|
||||
"menu bar",
|
||||
"bottom",
|
||||
"line",
|
||||
"macos",
|
||||
"osx"
|
||||
],
|
||||
"categories": [
|
||||
"layout",
|
||||
"design",
|
||||
"development",
|
||||
"files"
|
||||
]
|
||||
}
|
||||
@@ -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="M2 8h20" />
|
||||
<rect width="20" height="16" x="2" y="4" rx="2" />
|
||||
<path d="M6 16h12" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 308 B |
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"mittalyashu",
|
||||
"ericfennis",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"vpn",
|
||||
"private",
|
||||
"privacy",
|
||||
"network",
|
||||
"world",
|
||||
"browser",
|
||||
"security",
|
||||
"encryption",
|
||||
"protection",
|
||||
"connection"
|
||||
],
|
||||
"categories": [
|
||||
"security",
|
||||
"development",
|
||||
"devices"
|
||||
]
|
||||
}
|
||||
@@ -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="M7 3.34V5a3 3 0 0 0 3 3" />
|
||||
<path d="M11 21.95V18a2 2 0 0 0-2-2 2 2 0 0 1-2-2v-1a2 2 0 0 0-2-2H2.05" />
|
||||
<path d="M21.54 15H17a2 2 0 0 0-2 2v4.54" />
|
||||
<path d="M12 2a10 10 0 1 0 9.54 13" />
|
||||
<path d="M20 6V4a2 2 0 1 0-4 0v2" />
|
||||
<rect width="8" height="5" x="14" y="6" rx="1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 504 B |
@@ -9,10 +9,14 @@
|
||||
"world",
|
||||
"browser",
|
||||
"language",
|
||||
"translate"
|
||||
"translate",
|
||||
"globe"
|
||||
],
|
||||
"categories": [
|
||||
"maps",
|
||||
"navigation"
|
||||
],
|
||||
"aliases": [
|
||||
"globe-2"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 479 B After Width: | Height: | Size: 479 B |
@@ -6,6 +6,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph",
|
||||
"presentation"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph",
|
||||
"presentation"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph",
|
||||
"presentation"
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"karsa-mistmere",
|
||||
"danielbayley"
|
||||
"danielbayley",
|
||||
"jguddas"
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph",
|
||||
"presentation"
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M16 22h2a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3" />
|
||||
<path d="M14 2v4a2 2 0 0 0 2 2h4" />
|
||||
<path d="M4 11.5a6.02 6.02 0 1 0 8.5 8.5" />
|
||||
<path d="M14 16c0-3.3-2.7-6-6-6v6Z" />
|
||||
<path d="M16 22h2a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3.5" />
|
||||
<path d="M4.017 11.512a6 6 0 1 0 8.466 8.475" />
|
||||
<path d="M8 16v-6a6 6 0 0 1 6 6z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 398 B After Width: | Height: | Size: 402 B |
@@ -3,7 +3,8 @@
|
||||
"contributors": [
|
||||
"ericfennis",
|
||||
"karsa-mistmere",
|
||||
"danielbayley"
|
||||
"danielbayley",
|
||||
"jguddas"
|
||||
],
|
||||
"tags": [
|
||||
"lost",
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3" />
|
||||
<path d="M14 2v4a2 2 0 0 0 2 2h4" />
|
||||
<circle cx="5" cy="14" r="3" />
|
||||
<path d="M4.268 21a2 2 0 0 0 1.727 1H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3" />
|
||||
<path d="m9 18-1.5-1.5" />
|
||||
<circle cx="5" cy="14" r="3" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 373 B After Width: | Height: | Size: 395 B |
@@ -2,7 +2,8 @@
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"karsa-mistmere",
|
||||
"danielbayley"
|
||||
"danielbayley",
|
||||
"jguddas"
|
||||
],
|
||||
"tags": [
|
||||
"audio",
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3" />
|
||||
<path d="M14 2v4a2 2 0 0 0 2 2h4" />
|
||||
<path d="m7 10-3 2H2v4h2l3 2Z" />
|
||||
<path d="M11 11a5 5 0 0 1 0 6" />
|
||||
<path d="M14 2v4a2 2 0 0 0 2 2h4" />
|
||||
<path d="M4.268 21A2 2 0 0 0 6 22h12a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3" />
|
||||
<path d="m7 10-3 2H2v4h2l3 2z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 382 B After Width: | Height: | Size: 401 B |
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"colebemis",
|
||||
"csandman",
|
||||
"ericfennis",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"vpn",
|
||||
"private",
|
||||
"privacy",
|
||||
"network",
|
||||
"world",
|
||||
"browser",
|
||||
"security",
|
||||
"encryption",
|
||||
"protection",
|
||||
"connection"
|
||||
],
|
||||
"categories": [
|
||||
"security",
|
||||
"development",
|
||||
"devices"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M15.686 15A14.5 14.5 0 0 1 12 22a14.5 14.5 0 0 1 0-20 10 10 0 1 0 9.542 13" />
|
||||
<path d="M2 12h8.5" />
|
||||
<path d="M20 6V4a2 2 0 1 0-4 0v2" />
|
||||
<rect width="8" height="5" x="14" y="6" rx="1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 414 B |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"guillermo-angeles"
|
||||
"guillermo-angeles",
|
||||
"jguddas"
|
||||
],
|
||||
"tags": [
|
||||
"flag",
|
||||
|
||||
@@ -10,6 +10,6 @@
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 13V2l8 4-8 4" />
|
||||
<path d="M20.55 10.23A9 9 0 1 1 8 4.94" />
|
||||
<path d="M8 10a5 5 0 1 0 8.9 2.02" />
|
||||
</svg>
|
||||
<path d="M20.561 10.222a9 9 0 1 1-12.55-5.29" />
|
||||
<path d="M8.002 9.997a5 5 0 1 0 8.9 2.02" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 338 B |
@@ -9,13 +9,13 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect width="20" height="16" x="2" y="4" rx="2" ry="2" />
|
||||
<path d="M6 8h.001" />
|
||||
<path d="M10 8h.001" />
|
||||
<path d="M14 8h.001" />
|
||||
<path d="M18 8h.001" />
|
||||
<path d="M8 12h.001" />
|
||||
<path d="M12 12h.001" />
|
||||
<path d="M16 12h.001" />
|
||||
<path d="M10 8h.01" />
|
||||
<path d="M12 12h.01" />
|
||||
<path d="M14 8h.01" />
|
||||
<path d="M16 12h.01" />
|
||||
<path d="M18 8h.01" />
|
||||
<path d="M6 8h.01" />
|
||||
<path d="M7 16h10" />
|
||||
<path d="M8 12h.01" />
|
||||
<rect x="2" y="4" width="20" height="16" rx="2" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 475 B After Width: | Height: | Size: 461 B |
@@ -5,6 +5,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph"
|
||||
],
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M20.91 8.84 8.56 2.23a1.93 1.93 0 0 0-1.81 0L3.1 4.13a2.12 2.12 0 0 0-.05 3.69l12.22 6.93a2 2 0 0 0 1.94 0L21 12.51a2.12 2.12 0 0 0-.09-3.67Z" />
|
||||
<path d="m3.09 8.84 12.35-6.61a1.93 1.93 0 0 1 1.81 0l3.65 1.9a2.12 2.12 0 0 1 .1 3.69L8.73 14.75a2 2 0 0 1-1.94 0L3 12.51a2.12 2.12 0 0 1 .09-3.67Z" />
|
||||
<line x1="12" x2="12" y1="22" y2="13" />
|
||||
<path d="M20 13.5v3.37a2.06 2.06 0 0 1-1.11 1.83l-6 3.08a1.93 1.93 0 0 1-1.78 0l-6-3.08A2.06 2.06 0 0 1 4 16.87V13.5" />
|
||||
<path d="M12 22v-9" />
|
||||
<path d="M15.17 2.21a1.67 1.67 0 0 1 1.63 0L21 4.57a1.93 1.93 0 0 1 0 3.36L8.82 14.79a1.655 1.655 0 0 1-1.64 0L3 12.43a1.93 1.93 0 0 1 0-3.36z" />
|
||||
<path d="M20 13v3.87a2.06 2.06 0 0 1-1.11 1.83l-6 3.08a1.93 1.93 0 0 1-1.78 0l-6-3.08A2.06 2.06 0 0 1 4 16.87V13" />
|
||||
<path d="M21 12.43a1.93 1.93 0 0 0 0-3.36L8.83 2.2a1.64 1.64 0 0 0-1.63 0L3 4.57a1.93 1.93 0 0 0 0 3.36l12.18 6.86a1.636 1.636 0 0 0 1.63 0z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 686 B After Width: | Height: | Size: 648 B |
@@ -7,6 +7,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"presentation"
|
||||
],
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<polygon points="5 3 19 12 5 21 5 3" />
|
||||
<polygon points="6 3 20 12 6 21 6 3" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 250 B |
@@ -6,8 +6,14 @@
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"audio",
|
||||
"music",
|
||||
"mic",
|
||||
"music"
|
||||
"talk",
|
||||
"voice",
|
||||
"subscribe",
|
||||
"subscription",
|
||||
"stream"
|
||||
],
|
||||
"categories": [
|
||||
"multimedia",
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<circle cx="12" cy="11" r="1" />
|
||||
<path d="M11 17a1 1 0 0 1 2 0c0 .5-.34 3-.5 4.5a.5.5 0 0 1-1 0c-.16-1.5-.5-4-.5-4.5Z" />
|
||||
<path d="M16.85 18.58a9 9 0 1 0-9.7 0" />
|
||||
<path d="M8 14a5 5 0 1 1 8 0" />
|
||||
<path d="M17 18.5a9 9 0 1 0-10 0" />
|
||||
<circle cx="12" cy="11" r="1" />
|
||||
<path d="M13 17a1 1 0 1 0-2 0l.5 4.5a.5.5 0 1 0 1 0Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 408 B After Width: | Height: | Size: 381 B |
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley"
|
||||
],
|
||||
"tags": [
|
||||
"screens",
|
||||
"sizes",
|
||||
"rotate",
|
||||
"rotation",
|
||||
"adjust",
|
||||
"aspect ratio",
|
||||
"16:9",
|
||||
"widescreen",
|
||||
"4:3",
|
||||
"resolution",
|
||||
"responsive",
|
||||
"mobile",
|
||||
"desktop",
|
||||
"dimensions",
|
||||
"monitor",
|
||||
"orientation",
|
||||
"portrait",
|
||||
"landscape"
|
||||
],
|
||||
"categories": [
|
||||
"layout",
|
||||
"design",
|
||||
"photography",
|
||||
"devices"
|
||||
]
|
||||
}
|
||||
@@ -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"
|
||||
>
|
||||
<rect width="20" height="16" x="2" y="4" rx="2" />
|
||||
<path d="M12 9v11" />
|
||||
<path d="M2 9h13a2 2 0 0 1 2 2v9" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 324 B |
@@ -5,25 +5,30 @@
|
||||
],
|
||||
"tags": [
|
||||
"screens",
|
||||
"sizes",
|
||||
"rotate",
|
||||
"rotation",
|
||||
"adjust",
|
||||
"aspect ratio",
|
||||
"proportions",
|
||||
"16:9",
|
||||
"widescreen",
|
||||
"4:3",
|
||||
"resolution",
|
||||
"responsive",
|
||||
"mobile",
|
||||
"desktop",
|
||||
"dimensions",
|
||||
"monitor",
|
||||
"orientation",
|
||||
"portrait",
|
||||
"landscape"
|
||||
],
|
||||
"categories": [
|
||||
"connectivity",
|
||||
"devices",
|
||||
"layout",
|
||||
"design",
|
||||
"photography"
|
||||
"photography",
|
||||
"devices",
|
||||
"connectivity"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley"
|
||||
],
|
||||
"tags": [
|
||||
"left",
|
||||
"counter-clockwise",
|
||||
"rotate",
|
||||
"image",
|
||||
"90",
|
||||
"45",
|
||||
"degrees",
|
||||
"°"
|
||||
],
|
||||
"categories": [
|
||||
"layout",
|
||||
"design",
|
||||
"photography",
|
||||
"tools",
|
||||
"shapes",
|
||||
"arrows"
|
||||
]
|
||||
}
|
||||
@@ -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="M20 9V7a2 2 0 0 0-2-2h-6" />
|
||||
<path d="m15 2-3 3 3 3" />
|
||||
<path d="M20 13v5a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 349 B |
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley"
|
||||
],
|
||||
"tags": [
|
||||
"right",
|
||||
"clockwise",
|
||||
"rotate",
|
||||
"image",
|
||||
"90",
|
||||
"45",
|
||||
"degrees",
|
||||
"°"
|
||||
],
|
||||
"categories": [
|
||||
"layout",
|
||||
"design",
|
||||
"photography",
|
||||
"tools",
|
||||
"shapes",
|
||||
"arrows"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 5H6a2 2 0 0 0-2 2v3" />
|
||||
<path d="m9 8 3-3-3-3" />
|
||||
<path d="M4 14v4a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 348 B |
@@ -6,6 +6,7 @@
|
||||
],
|
||||
"tags": [
|
||||
"statistics",
|
||||
"analytics",
|
||||
"diagram",
|
||||
"graph"
|
||||
],
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"mittalyashu",
|
||||
"ericfennis"
|
||||
"ericfennis",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"unshielded",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
|
||||
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
||||
<path d="M12 8v4" />
|
||||
<path d="M12 16h.01" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 435 B |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley"
|
||||
"danielbayley",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"unshielded",
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
|
||||
<path d="m4 5 14 12" />
|
||||
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
||||
<path d="m4.243 5.21 14.39 12.472" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 292 B After Width: | Height: | Size: 426 B |
@@ -2,7 +2,8 @@
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"mittalyashu",
|
||||
"ericfennis"
|
||||
"ericfennis",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"cybersecurity",
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
|
||||
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
||||
<path d="m9 12 2 2 4-4" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 415 B |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley"
|
||||
"danielbayley",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"cybersecurity",
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
|
||||
<path d="M8 11h.01" />
|
||||
<path d="M12 11h.01" />
|
||||
<path d="M16 11h.01" />
|
||||
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
||||
<path d="M8 12h.01" />
|
||||
<path d="M12 12h.01" />
|
||||
<path d="M16 12h.01" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 343 B After Width: | Height: | Size: 463 B |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley"
|
||||
"danielbayley",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"cybersecurity",
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
|
||||
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
||||
<path d="M12 22V2" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 290 B After Width: | Height: | Size: 410 B |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley"
|
||||
"danielbayley",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"unshield",
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
|
||||
<path d="M9 11h6" />
|
||||
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
||||
<path d="M9 12h6" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 289 B After Width: | Height: | Size: 409 B |
@@ -9,7 +9,7 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M19.7 14a6.9 6.9 0 0 0 .3-2V5l-8-3-3.2 1.2" />
|
||||
<path d="m2 2 20 20" />
|
||||
<path d="M4.7 4.7 4 5v7c0 6 8 10 8 10a20.3 20.3 0 0 0 5.62-4.38" />
|
||||
<path d="M5 5a1 1 0 0 0-1 1v7c0 5 3.5 7.5 7.67 8.94a1 1 0 0 0 .67.01c2.35-.82 4.48-1.97 5.9-3.71" />
|
||||
<path d="M9.309 3.652A12.252 12.252 0 0 0 11.24 2.28a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1v7a9.784 9.784 0 0 1-.08 1.264" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 362 B After Width: | Height: | Size: 484 B |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley"
|
||||
"danielbayley",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"cybersecurity",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
|
||||
<path d="M9 11h6" />
|
||||
<path d="M12 8v6" />
|
||||
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
||||
<path d="M9 12h6" />
|
||||
<path d="M12 9v6" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 312 B After Width: | Height: | Size: 432 B |
@@ -2,7 +2,8 @@
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"danielbayley",
|
||||
"jguddas"
|
||||
"jguddas",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"unshielded",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
|
||||
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
||||
<path d="M9.1 9a3 3 0 0 1 5.82 1c0 2-3 3-3 3" />
|
||||
<path d="M12 17h.01" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 343 B After Width: | Height: | Size: 463 B |
@@ -2,7 +2,8 @@
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"mittalyashu",
|
||||
"ericfennis"
|
||||
"ericfennis",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"unshielded",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
|
||||
<path d="m14.5 9-5 5" />
|
||||
<path d="m9.5 9 5 5" />
|
||||
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
||||
<path d="m14.5 9.5-5 5" />
|
||||
<path d="m9.5 9.5 5 5" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 319 B After Width: | Height: | Size: 443 B |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"colebemis"
|
||||
"colebemis",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"cybersecurity",
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
|
||||
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 266 B After Width: | Height: | Size: 386 B |
@@ -9,8 +9,8 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<polyline points="12.41 6.75 13 2 10.57 4.92" />
|
||||
<polyline points="18.57 12.91 21 10 15.66 10" />
|
||||
<polyline points="8 8 3 14 12 14 11 22 16 16" />
|
||||
<line x1="2" x2="22" y1="2" y2="22" />
|
||||
<path d="M10.513 4.856 13.12 2.17a.5.5 0 0 1 .86.46l-1.377 4.317" />
|
||||
<path d="M15.656 10H20a1 1 0 0 1 .78 1.63l-1.72 1.773" />
|
||||
<path d="M16.273 16.273 10.88 21.83a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14H4a1 1 0 0 1-.78-1.63l4.507-4.643" />
|
||||
<path d="m2 2 20 20" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 402 B After Width: | Height: | Size: 485 B |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"colebemis"
|
||||
"colebemis",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"tags": [
|
||||
"flash",
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
|
||||
<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 270 B After Width: | Height: | Size: 379 B |
@@ -19,6 +19,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@figma/plugin-typings": "^1.36.0",
|
||||
"@lucide/shared": "workspace:*",
|
||||
"@types/react": "^17.0.0",
|
||||
"@types/react-dom": "^17.0.0",
|
||||
"@vitejs/plugin-react": "^1.0.0",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { forwardRef, createElement, SVGProps } from 'react';
|
||||
import { IconNode } from '../api/fetchIcons';
|
||||
import { toKebabCase } from '@lucide/shared';
|
||||
|
||||
const defaultAttributes = {
|
||||
xmlns: 'http://www.w3.org/2000/svg',
|
||||
@@ -17,17 +18,6 @@ export interface LucideProps extends Partial<SVGProps<SVGSVGElement>> {
|
||||
size?: string | number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts string to KebabCase
|
||||
* Copied from scripts/helper. If anyone knows how to properly import it here
|
||||
* then please fix it.
|
||||
*
|
||||
* @param {string} string
|
||||
* @returns {string} A kebabized string
|
||||
*/
|
||||
export const toKebabCase = (string: string) =>
|
||||
string.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
|
||||
const createIconComponent = (iconName: string, iconNode: IconNode) => {
|
||||
const Component = forwardRef<SVGSVGElement, LucideProps>(
|
||||
({ color = 'currentColor', size = 24, strokeWidth = 2, children, ...rest }, ref) =>
|
||||
|
||||