mirror of
https://github.com/lucide-icons/lucide.git
synced 2026-11-15 14:08:49 +00:00
* fix(docs): sync URL params with UI state on category and search interactions Search, category selection, and the icon detail drawer each modified the URL independently, causing parameters to be silently dropped. Searching didn't clear the category hash, clicking a category dropped the search param, and closing the drawer hard-coded the path without preserving either. Consolidate URL construction so every navigation preserves both ?search= and #category as appropriate. Split useCategoryView into a pure getter and a sync variant (useCategoryViewSync) so event listeners and route watchers are registered once in CategoryList.vue instead of in every consumer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(docs): disable click on inactive categories during search Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update docs/.vitepress/theme/components/icons/IconsCategoryOverview.vue Co-authored-by: Eric Fennis <eric.fennis@gmail.com> * Update docs/.vitepress/theme/components/icons/IconsOverview.vue Co-authored-by: Eric Fennis <eric.fennis@gmail.com> * refactor(docs): use URL constructor in CategoryListItem Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
67 lines
1.7 KiB
TypeScript
67 lines
1.7 KiB
TypeScript
import { useRoute } from 'vitepress';
|
|
import { ref, inject, Ref, onMounted, onUnmounted, watch } from 'vue';
|
|
|
|
export const CATEGORY_VIEW_CONTEXT = Symbol('categoryView');
|
|
|
|
interface CategoryViewContext {
|
|
selectedCategory: Ref<string>;
|
|
categoryCounts: Ref<Record<string, number>>;
|
|
}
|
|
|
|
export const categoryViewContext = {
|
|
selectedCategory: ref(),
|
|
categoryCounts: ref({}),
|
|
};
|
|
|
|
const CATEGORIES_PATH = '/icons/categories';
|
|
|
|
export function useCategoryView(): CategoryViewContext {
|
|
const context = inject<CategoryViewContext>(CATEGORY_VIEW_CONTEXT);
|
|
|
|
if (!context) {
|
|
throw new Error('useCategoryView must be used with categoryView context');
|
|
}
|
|
|
|
return context;
|
|
}
|
|
|
|
export function useCategoryViewSync(): CategoryViewContext {
|
|
const context = useCategoryView();
|
|
const route = useRoute();
|
|
|
|
function syncCategoryFromLocation() {
|
|
if (!window.location.pathname.startsWith(CATEGORIES_PATH)) {
|
|
context.selectedCategory.value = '';
|
|
context.categoryCounts.value = {};
|
|
return;
|
|
}
|
|
|
|
context.selectedCategory.value = window.location.hash
|
|
? decodeURIComponent(window.location.hash.slice(1))
|
|
: '';
|
|
}
|
|
|
|
onMounted(() => {
|
|
syncCategoryFromLocation();
|
|
window.addEventListener('hashchange', syncCategoryFromLocation);
|
|
window.addEventListener('popstate', syncCategoryFromLocation);
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
window.removeEventListener('hashchange', syncCategoryFromLocation);
|
|
window.removeEventListener('popstate', syncCategoryFromLocation);
|
|
});
|
|
|
|
watch(route, (currentRoute) => {
|
|
if (currentRoute.path !== CATEGORIES_PATH) {
|
|
context.selectedCategory.value = '';
|
|
context.categoryCounts.value = {};
|
|
return;
|
|
}
|
|
|
|
syncCategoryFromLocation();
|
|
});
|
|
|
|
return context;
|
|
}
|