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
*/
export interface CategoryFilterStateModel {
/**
* Search query
*/
searchQuery?: string;
/**
* Categories
*/
categories: string[];
/**
* Selected categories
*/
selectedCategories: string[];
}
export type CategoryFilterModel = FilterModel;
export const FONT_CATEGORIES = [
{
id: 'serif',
name: 'Serif',
},
{
id: 'sans-serif',
name: 'Sans-serif',
},
{
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 type { CategoryFilterStateModel } from '../model/state';
import { FONT_CATEGORIES } from '$entities/Font/model/font';
import { createFilterStore } from '$shared/store/createFilterStore';
import type { CategoryFilterModel } from '../model/state';
/**
* Initial state for CategoryFilter
*/
export const initialState: CategoryFilterStateModel = {
export const initialState: CategoryFilterModel = {
searchQuery: '',
categories: [],
selectedCategories: [],
categories: FONT_CATEGORIES,
};
const { subscribe, set, update } = writable<CategoryFilterStateModel>(initialState);
export const categoryFilterStore = {
subscribe,
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!
/**
* CategoryFilter store
*/
setSearchQuery: (searchQuery: string | undefined) => {
update(state => ({
...state,
searchQuery: searchQuery || undefined,
}));
},
};
export const categoryFilterStore = createFilterStore(initialState);

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}
/>