From a9c1dca801d0a8091b91c46d7c0a426eee317025 Mon Sep 17 00:00:00 2001
From: Sukomal Dutta <100500478+Sukomal07@users.noreply.github.com>
Date: Fri, 13 Oct 2023 18:02:34 +0530
Subject: [PATCH] fix #1579 issue added debounced in search (#1600)
* add debounced in search
* updated iconsCategoryOverview
* fix site loading issue
* apply suggestion
---
.../icons/IconsCategoryOverview.vue | 113 +++++++++---------
.../theme/components/icons/IconsOverview.vue | 94 +++++++--------
.../theme/composables/useSearchInput.ts | 33 +++--
3 files changed, 113 insertions(+), 127 deletions(-)
diff --git a/docs/.vitepress/theme/components/icons/IconsCategoryOverview.vue b/docs/.vitepress/theme/components/icons/IconsCategoryOverview.vue
index e178bca6f..12ef65017 100644
--- a/docs/.vitepress/theme/components/icons/IconsCategoryOverview.vue
+++ b/docs/.vitepress/theme/components/icons/IconsCategoryOverview.vue
@@ -1,93 +1,92 @@
@@ -100,11 +99,7 @@ const IconDetailOverlay = defineAsyncComponent(() =>
@focus="onFocusSearchInput"
/>
-
+
-import { ref, computed, watch, defineAsyncComponent } from 'vue'
-import type { IconEntity } from '../../types'
-import { useMediaQuery, useOffsetPagination } from '@vueuse/core'
-import IconGrid from './IconGrid.vue'
-import InputSearch from '../base/InputSearch.vue'
-import useSearch from '../../composables/useSearch'
-import EndOfPage from '../base/EndOfPage.vue'
-import useSearchInput from '../../composables/useSearchInput'
-import StickyBar from './StickyBar.vue'
-import useFetchTags from '../../composables/useFetchTags'
-import useFetchCategories from '../../composables/useFetchCategories'
+import { ref, computed, watch, defineAsyncComponent } from 'vue';
+import type { IconEntity } from '../../types';
+import { useMediaQuery, useOffsetPagination } from '@vueuse/core';
+import IconGrid from './IconGrid.vue';
+import InputSearch from '../base/InputSearch.vue';
+import useSearch from '../../composables/useSearch';
+import EndOfPage from '../base/EndOfPage.vue';
+import useSearchInput from '../../composables/useSearchInput';
+import StickyBar from './StickyBar.vue';
+import useFetchTags from '../../composables/useFetchTags';
+import useFetchCategories from '../../composables/useFetchCategories';
const props = defineProps<{
- icons: IconEntity[]
-}>()
+ icons: IconEntity[];
+}>();
-const activeIconName = ref(null)
+const activeIconName = ref(null);
const isExtraLargeScreen = useMediaQuery('(min-width: 1440px)');
const isLargeScreen = useMediaQuery('(min-width: 1280px)');
@@ -23,84 +23,78 @@ const isMediumScreen = useMediaQuery('(min-width: 960px)');
const isSmallScreen = useMediaQuery('(min-width: 640px)');
const pageSize = computed(() => {
- if(isExtraLargeScreen.value) {
+ if (isExtraLargeScreen.value) {
return 16 * 20;
}
- if(isLargeScreen.value) {
+ if (isLargeScreen.value) {
return 16 * 12;
}
- if(isMediumScreen.value) {
+ if (isMediumScreen.value) {
return 13 * 12;
}
- if(isSmallScreen.value) {
+ if (isSmallScreen.value) {
return 10 * 10;
}
return 10 * 5;
-})
+});
-const { execute: fetchTags, data: tags } = useFetchTags()
-const { execute: fetchCategories, data: categories } = useFetchCategories()
+const { execute: fetchTags, data: tags } = useFetchTags();
+const { execute: fetchCategories, data: categories } = useFetchCategories();
const mappedIcons = computed(() => {
- if(tags.value == null) {
- return props.icons
+ if (tags.value == null) {
+ return props.icons;
}
return props.icons.map((icon) => {
- const iconTags = tags.value[icon.name]
- const iconCategories = categories.value?.[icon.name] ?? []
+ const iconTags = tags.value[icon.name];
+ const iconCategories = categories.value?.[icon.name] ?? [];
return {
...icon,
tags: iconTags,
categories: iconCategories,
- }
- })
-})
+ };
+ });
+});
-const { searchInput, searchQuery, searchQueryThrottled } = useSearchInput()
-const searchResults = useSearch(searchQueryThrottled, mappedIcons, [
+const { searchInput, searchQuery, searchQueryDebounced } = useSearchInput();
+const searchResults = useSearch(searchQueryDebounced, mappedIcons, [
{ name: 'name', weight: 3 },
{ name: 'tags', weight: 2 },
{ name: 'categories', weight: 1 },
-])
-
-const { next, currentPage } = useOffsetPagination( { pageSize })
+]);
+const { next, currentPage } = useOffsetPagination({ pageSize });
const paginatedIcons = computed(() => {
- const end = pageSize.value * currentPage.value
+ const end = pageSize.value * currentPage.value;
- return searchResults.value.slice(0, end)
-})
+ return searchResults.value.slice(0, end);
+});
function setActiveIconName(name: string) {
- activeIconName.value = name
+ activeIconName.value = name;
}
-watch(searchQueryThrottled, (searchString) => {
- currentPage.value = 1
-})
+watch(searchQueryDebounced, (searchString) => {
+ currentPage.value = 1;
+});
function onFocusSearchInput() {
if (tags.value == null) {
- fetchTags()
+ fetchTags();
}
if (categories.value == null) {
- fetchCategories()
+ fetchCategories();
}
}
-const NoResults = defineAsyncComponent(() =>
- import('./NoResults.vue')
-)
-
-const IconDetailOverlay = defineAsyncComponent(() =>
- import('./IconDetailOverlay.vue')
-)
+const NoResults = defineAsyncComponent(() => import('./NoResults.vue'));
+const IconDetailOverlay = defineAsyncComponent(() => import('./IconDetailOverlay.vue'));
@@ -124,7 +118,7 @@ const IconDetailOverlay = defineAsyncComponent(() =>
:icons="paginatedIcons"
@setActiveIcon="setActiveIconName"
/>
-
+
{
- const searchInput = ref()
+ const searchInput = ref();
const searchQuery = ref(
typeof window === 'undefined'
- ? ''
- : (
- new URLSearchParams(window.location.search).get('search')
- || ''
- )
- )
- const searchQueryThrottled = refThrottled(searchQuery, 400)
+ ? ''
+ : new URLSearchParams(window.location.search).get('search') || ''
+ );
+ const searchQueryDebounced = useDebounce(searchQuery, 250);
- watch(searchQueryThrottled, (searchString) => {
+ watch(searchQueryDebounced, (searchString) => {
const newUrl = new URL(window.location.href);
- if(searchString === '') {
+ if (searchString === '') {
newUrl.searchParams.delete('search');
} else {
newUrl.searchParams.set('search', searchString);
}
nextTick(() => {
- window.history.replaceState({}, '', newUrl)
- })
- })
+ window.history.replaceState({}, '', newUrl);
+ });
+ });
onMounted(() => {
const searchParams = new URLSearchParams(window.location.search);
- if(searchParams.has('focus')) {
- searchInput.value.focus()
+ if (searchParams.has('focus')) {
+ searchInput.value.focus();
}
- })
+ });
return {
searchInput,
searchQuery,
- searchQueryThrottled
+ searchQueryDebounced,
};
};