feat(filterManager): add debouced state support and move manager

This commit is contained in:
Ilia Mashkov
2026-01-13 19:52:36 +03:00
parent 1a76e9387a
commit e098da2dbb

View File

@@ -0,0 +1,63 @@
import { createFilter } from '$shared/lib';
import { createDebouncedState } from '$shared/lib/helpers';
import type { FilterConfig } from '../../model';
/**
* Create a filter manager instance.
*/
export function createFilterManager<TValue extends string>(config: FilterConfig<TValue>) {
const search = createDebouncedState(config.queryValue ?? '');
// Create filter instances upfront
const groups = $state(
config.groups.map(config => ({
id: config.id,
label: config.label,
instance: createFilter({ properties: config.properties }),
})),
);
// Derived: any selection across all groups
const hasAnySelection = $derived(
groups.some(group => group.instance.selectedProperties.length > 0),
);
return {
// Getter for queryValue (immediate value for UI)
get queryValue() {
return search.immediate;
},
// Setter for queryValue
set queryValue(value) {
search.immediate = value;
},
// Getter for queryValue (debounced value for logic)
get debouncedQueryValue() {
return search.debounced;
},
// Direct array reference (reactive)
get groups() {
return groups;
},
// Derived values
get hasAnySelection() {
return hasAnySelection;
},
// Global action
deselectAllGlobal: () => {
groups.forEach(group => group.instance.deselectAll());
},
// Helper to get group by id
getGroup: (id: string) => {
return groups.find(g => g.id === id);
},
};
}
export type FilterManager = ReturnType<typeof createFilterManager>;