Compare commits

...

3 Commits

Author SHA1 Message Date
Ilia Mashkov
b0afa0145d feat(FiltersSidebar): add callback to clear all filters
Some checks failed
Lint / Lint Code (push) Failing after 7m40s
Test / Svelte Checks (push) Failing after 7m20s
Build / build (pull_request) Failing after 7m28s
Lint / Lint Code (pull_request) Failing after 7m16s
Test / Svelte Checks (pull_request) Failing after 7m20s
2026-01-03 13:54:56 +03:00
Ilia Mashkov
e01a746460 feat(FilterFonts): join all the filters in one feature 2026-01-03 13:54:27 +03:00
Ilia Mashkov
53baacf05a feature(CheckboxFilter): move filter counter badge 2026-01-03 13:52:11 +03:00
15 changed files with 114 additions and 145 deletions

View File

@@ -1,7 +0,0 @@
import { FONT_CATEGORIES } from './model/state';
import { categoryFilterStore } from './store/categoryFilterStore';
export {
categoryFilterStore,
FONT_CATEGORIES,
};

View File

@@ -1,40 +0,0 @@
import type {
FilterModel,
Property,
} from '$shared/store/createFilterStore';
/**
* Model of state for CategoryFilter
*/
export type CategoryFilterModel = FilterModel;
export const FONT_CATEGORIES: Property[] = [
{
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

@@ -0,0 +1,5 @@
export { categoryFilterStore } from './model/stores/categoryFilterStore';
export { providersFilterStore } from './model/stores/providersFilterStore';
export { subsetsFilterStore } from './model/stores/subsetsFilterStore';
export { clearAllFilters } from './model/services/clearAllFilters/clearAllFilters';

View File

@@ -0,0 +1,70 @@
import type { Property } from '$shared/store/createFilterStore';
export const FONT_CATEGORIES: Property[] = [
{
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;
export const FONT_PROVIDERS: Property[] = [
{
id: 'google',
name: 'Google Fonts',
},
{
id: 'fontshare',
name: 'Fontshare',
},
] as const;
export const FONT_SUBSETS: Property[] = [
{
id: 'latin',
name: 'Latin',
},
{
id: 'latin-ext',
name: 'Latin Extended',
},
{
id: 'cyrillic',
name: 'Cyrillic',
},
{
id: 'greek',
name: 'Greek',
},
{
id: 'arabic',
name: 'Arabic',
},
{
id: 'devanagari',
name: 'Devanagari',
},
] as const;

View File

@@ -0,0 +1,9 @@
import { categoryFilterStore } from '../../stores/categoryFilterStore';
import { providersFilterStore } from '../../stores/providersFilterStore';
import { subsetsFilterStore } from '../../stores/subsetsFilterStore';
export function clearAllFilters() {
categoryFilterStore.deselectAllProperties();
providersFilterStore.deselectAllProperties();
subsetsFilterStore.deselectAllProperties();
}

View File

@@ -1,13 +1,13 @@
import { createFilterStore } from '$shared/store/createFilterStore';
import { import {
type CategoryFilterModel, type FilterModel,
FONT_CATEGORIES, createFilterStore,
} from '../model/state'; } from '$shared/store/createFilterStore';
import { FONT_CATEGORIES } from '../const/const';
/** /**
* Initial state for CategoryFilter * Initial state for CategoryFilter
*/ */
export const initialState: CategoryFilterModel = { export const initialState: FilterModel = {
searchQuery: '', searchQuery: '',
properties: FONT_CATEGORIES, properties: FONT_CATEGORIES,
}; };

View File

@@ -1,13 +1,13 @@
import { createFilterStore } from '$shared/store/createFilterStore';
import { import {
FONT_PROVIDERS, type FilterModel,
type ProvidersFilterModel, createFilterStore,
} from '../model/state'; } from '$shared/store/createFilterStore';
import { FONT_PROVIDERS } from '../const/const';
/** /**
* Initial state for ProvidersFilter * Initial state for ProvidersFilter
*/ */
export const initialState: ProvidersFilterModel = { export const initialState: FilterModel = {
searchQuery: '', searchQuery: '',
properties: FONT_PROVIDERS, properties: FONT_PROVIDERS,
}; };

View File

@@ -1,13 +1,13 @@
import { createFilterStore } from '$shared/store/createFilterStore';
import { import {
FONT_SUBSETS, type FilterModel,
type SubsetsFilterModel, createFilterStore,
} from '../model/state'; } from '$shared/store/createFilterStore';
import { FONT_SUBSETS } from '../const/const';
/** /**
* Initial state for SubsetsFilter * Initial state for SubsetsFilter
*/ */
export const initialState: SubsetsFilterModel = { const initialState: FilterModel = {
searchQuery: '', searchQuery: '',
properties: FONT_SUBSETS, properties: FONT_SUBSETS,
}; };

View File

@@ -1,7 +0,0 @@
import { FONT_PROVIDERS } from './model/state';
import { providersFilterStore } from './store/providersFilterStore';
export {
FONT_PROVIDERS,
providersFilterStore,
};

View File

@@ -1,20 +0,0 @@
import type {
FilterModel,
Property,
} from '$shared/store/createFilterStore';
/**
* Model of state for ProvidersFilter
*/
export type ProvidersFilterModel = FilterModel;
export const FONT_PROVIDERS: Property[] = [
{
id: 'google',
name: 'Google Fonts',
},
{
id: 'fontshare',
name: 'Fontshare',
},
] as const;

View File

@@ -1,7 +0,0 @@
import { FONT_SUBSETS } from './model/state';
import { subsetsFilterStore } from './store/subsetsFilterStore';
export {
FONT_SUBSETS,
subsetsFilterStore,
};

View File

@@ -1,36 +0,0 @@
import type {
FilterModel,
Property,
} from '$shared/store/createFilterStore';
/**
* Model of state for SubsetsFilter
*/
export type SubsetsFilterModel = FilterModel;
export const FONT_SUBSETS: Property[] = [
{
id: 'latin',
name: 'Latin',
},
{
id: 'latin-ext',
name: 'Latin Extended',
},
{
id: 'cyrillic',
name: 'Cyrillic',
},
{
id: 'greek',
name: 'Greek',
},
{
id: 'arabic',
name: 'Arabic',
},
{
id: 'devanagari',
name: 'Devanagari',
},
] as const;

View File

@@ -84,6 +84,16 @@ const hasSelection = $derived(selectedCount > 0);
> >
<h4 class="text-sm font-semibold">{displayedLabel}</h4> <h4 class="text-sm font-semibold">{displayedLabel}</h4>
<!-- Badge only appears when items are selected to avoid clutter -->
{#if hasSelection}
<Badge
variant="secondary"
class="mr-auto h-5 min-w-5 px-1.5 text-xs font-medium tabular-nums"
>
{selectedCount}
</Badge>
{/if}
<!-- Chevron rotates based on open state for visual feedback --> <!-- Chevron rotates based on open state for visual feedback -->
<div <div
class="shrink-0 transition-transform duration-200 ease-out" class="shrink-0 transition-transform duration-200 ease-out"
@@ -91,15 +101,6 @@ const hasSelection = $derived(selectedCount > 0);
> >
<ChevronDownIcon class="h-4 w-4" /> <ChevronDownIcon class="h-4 w-4" />
</div> </div>
<!-- Badge only appears when items are selected to avoid clutter -->
{#if hasSelection}
<Badge
variant="secondary"
class="ml-auto h-5 min-w-5 px-1.5 text-xs font-medium tabular-nums"
>
{selectedCount}
</Badge>
{/if}
</Collapsible.Trigger> </Collapsible.Trigger>
</div> </div>

View File

@@ -10,11 +10,12 @@
* Buttons are equally sized (flex-1) for balanced layout. Note: * Buttons are equally sized (flex-1) for balanced layout. Note:
* Functionality not yet implemented - wire up to filter stores. * Functionality not yet implemented - wire up to filter stores.
*/ */
import { clearAllFilters } from '$features/FilterFonts';
import { Button } from '$shared/shadcn/ui/button'; import { Button } from '$shared/shadcn/ui/button';
</script> </script>
<div class="flex flex-row gap-2"> <div class="flex flex-row gap-2">
<Button variant="outline" class="flex-1 cursor-pointer"> <Button variant="outline" class="flex-1 cursor-pointer" onclick={clearAllFilters}>
Reset Reset
</Button> </Button>
<Button class="flex-1 cursor-pointer"> <Button class="flex-1 cursor-pointer">

View File

@@ -12,9 +12,9 @@
* Uses $derived for reactive access to filter states, ensuring UI updates * Uses $derived for reactive access to filter states, ensuring UI updates
* when selections change through any means (sidebar, programmatically, etc.). * when selections change through any means (sidebar, programmatically, etc.).
*/ */
import { categoryFilterStore } from '$features/CategoryFilter'; import { categoryFilterStore } from '$features/FilterFonts';
import { providersFilterStore } from '$features/ProvidersFilter'; import { providersFilterStore } from '$features/FilterFonts';
import { subsetsFilterStore } from '$features/SubsetsFilter'; import { subsetsFilterStore } from '$features/FilterFonts';
import CheckboxFilter from '$shared/ui/CheckboxFilter/CheckboxFilter.svelte'; import CheckboxFilter from '$shared/ui/CheckboxFilter/CheckboxFilter.svelte';
/** Reactive properties from providers filter store */ /** Reactive properties from providers filter store */