Try optimizing for categories

This commit is contained in:
Eric Fennis
2023-05-11 16:50:14 +02:00
parent 3099bffb8c
commit 4deb649f50
6 changed files with 80 additions and 34 deletions
@@ -8,6 +8,7 @@ const props = defineProps<{
icons: IconEntity[]
activeIcon?: string
overlayMode?: boolean
hideIcons?: boolean
}>()
function setActiveIcon(name: string) {
@@ -25,6 +26,7 @@ function setActiveIcon(name: string) {
:active="activeIcon === icon.name"
customizable
:overlayMode="overlayMode"
:hideIcon="hideIcons"
/>
</div>
</div>
@@ -15,6 +15,7 @@ const props = defineProps<{
active: boolean;
customizable?: boolean;
overlayMode?: boolean
hideIcon?: boolean
}>()
const emit = defineEmits(['setActiveIcon'])
@@ -45,7 +46,12 @@ function navigateToIcon() {
:href="`/icons/${props.name}`"
>
<KeepAlive>
<component :is="icon" class="lucide-icon" :class="{ customizable }" />
<component
v-if="!hideIcon"
:is="icon"
class="lucide-icon"
:class="{ customizable }"
/>
</KeepAlive>
</button>
</template>
@@ -0,0 +1,56 @@
<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
}>()
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 class="title" >
<a class="header-anchor" :href="`#${category.name}`" :aria-label="`Permalink to &quot;${category.title}&quot;`">&ZeroWidthSpace;</a>
{{ category.title }}
</h2>
<IconGrid
:activeIcon="activeIconName"
:icons="category.icons"
@setActiveIcon="$event => $emit('setActiveIcon', $event)"
overlayMode
:hideIcons="!showIcons"
/>
</section>
</template>
<style scoped>
.title {
margin-bottom: 24px;
font-size: 19px;
font-weight: 500;
padding-top: 86px;
/* scroll-padding-top: 240px; */
}
.category {
margin-bottom: calc(-86px + 32px);
}
</style>
@@ -2,11 +2,11 @@
import { ref, computed, defineAsyncComponent } from 'vue'
import type { IconEntity, Category } from '../../types'
import IconDetailOverlay from './IconDetailOverlay.vue'
import IconGrid from './IconGrid.vue'
import useSearch from '../../composables/useSearch'
import InputSearch from '../base/InputSearch.vue'
import useSearchInput from '../../composables/useSearchInput'
import StickyBar from './StickyBar.vue'
import IconsCategory from './IconsCategory.vue'
const props = defineProps<{
icons: IconEntity[]
@@ -58,7 +58,7 @@ const NoResults = defineAsyncComponent(() =>
</script>
<template>
<StickyBar>
<StickyBar class="search-bar">
<InputSearch
:placeholder="`Search ${icons.length} icons ...`"
v-model="searchQuery"
@@ -71,41 +71,22 @@ const NoResults = defineAsyncComponent(() =>
:searchQuery="searchQuery"
@clear="searchQuery = ''"
/>
<section class="category" v-for="category in categories" :key="category.name">
<h2 class="title" :id="category.name">
<a class="header-anchor" :href="`#${category.name}`" :aria-label="`Permalink to &quot;${category.title}&quot;`">&ZeroWidthSpace;</a>
{{ category.title }}
</h2>
<IconGrid
:activeIcon="activeIconName"
:icons="category.icons"
@setActiveIcon="setActiveIconName"
overlayMode
/>
</section>
<IconsCategory
v-for="category in categories"
:key="category.name"
:category="category"
:activeIconName="activeIconName"
@setActiveIcon="setActiveIconName"
/>
<IconDetailOverlay :icon="activeIcon" @close="setActiveIconName('')"/>
</template>
<style scoped>
.icon {
aspect-ratio: 1/1;
}
.title {
margin-bottom: 24px;
font-size: 19px;
font-weight: 500;
}
.category {
margin-bottom: 32px;
}
.input-wrapper {
width: 100%;
}
/* .input-wrapper {
margin-bottom: 32px;
} */
.search-bar {
margin-bottom: -54px;
}
</style>
@@ -8,13 +8,13 @@
.search-bar {
margin-bottom: 16px;
position: sticky;
z-index: 70;
z-index: 30;
top: 48px;
padding-top: 24px;
margin-top: -32px;
width: 100%;
display: flex;
margin-bottom: 32px;;
margin-bottom: 32px;
background: var(--vp-c-bg);
box-shadow: 0 16px 24px var(--vp-c-bg);
}
+1
View File
@@ -15,6 +15,7 @@ export interface Category {
title: string
icon?: string
iconCount: number
icons?: IconEntity[]
}
interface Shield {