feat(CategoryFilter): create CategoryFilter component

This commit is contained in:
Ilia Mashkov
2026-01-02 11:15:02 +03:00
parent e885560c45
commit 7bc0a690cb
3 changed files with 63 additions and 42 deletions

View File

@@ -1,17 +1,37 @@
import type { FilterModel } from '$shared/store/createFilterStore';
/** /**
* Model of state for CategoryFilter * Model of state for CategoryFilter
*/ */
export interface CategoryFilterStateModel { export type CategoryFilterModel = FilterModel;
/**
* Search query export const FONT_CATEGORIES = [
*/ {
searchQuery?: string; id: 'serif',
/** name: 'Serif',
* Categories },
*/ {
categories: string[]; id: 'sans-serif',
/** name: 'Sans-serif',
* Selected categories },
*/ {
selectedCategories: string[]; id: 'display',
} name: 'Display',
},
{
id: 'handwriting',
name: 'Handwriting',
},
{
id: 'monospace',
name: 'Monospace',
},
{
id: 'script',
name: 'Script',
},
{
id: 'slab',
name: 'Slab',
},
] as const;

View File

@@ -1,35 +1,16 @@
import { writable } from 'svelte/store'; import { FONT_CATEGORIES } from '$entities/Font/model/font';
import type { CategoryFilterStateModel } from '../model/state'; import { createFilterStore } from '$shared/store/createFilterStore';
import type { CategoryFilterModel } from '../model/state';
/** /**
* Initial state for CategoryFilter * Initial state for CategoryFilter
*/ */
export const initialState: CategoryFilterStateModel = { export const initialState: CategoryFilterModel = {
searchQuery: '', searchQuery: '',
categories: [], categories: FONT_CATEGORIES,
selectedCategories: [],
}; };
const { subscribe, set, update } = writable<CategoryFilterStateModel>(initialState); /**
* CategoryFilter store
export const categoryFilterStore = { */
subscribe, export const categoryFilterStore = createFilterStore(initialState);
set,
update,
/**
* Update the search query filter.
*
* @param searchQuery - Search text (undefined to clear)
*
* Learning Note:
* We use update() to modify the store based on current state.
* This is like a Redux reducer but without the boilerplate!
*/
setSearchQuery: (searchQuery: string | undefined) => {
update(state => ({
...state,
searchQuery: searchQuery || undefined,
}));
},
};

View File

@@ -0,0 +1,20 @@
<script lang="ts">
import CheckboxFilter from '$shared/ui/CheckboxFilter/CheckboxFilter.svelte';
import { categoryFilterStore } from '../store/categoryFilterStore';
const { categories } = $derived($categoryFilterStore);
function didCategoryToggle(categoryId: string) {
if (categories?.find(category => category.id === categoryId)) {
categoryFilterStore.deselectCategory(categoryId);
} else {
categoryFilterStore.selectCategory(categoryId);
}
}
</script>
<CheckboxFilter
filterName="Font category"
categories={categories}
onCategoryToggle={didCategoryToggle}
/>