@umituz/react-native-bottom-sheet 1.3.4 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,95 @@
1
+ /**
2
+ * useListFilters Hook
3
+ */
4
+
5
+ import { useState, useCallback, useMemo } from 'react';
6
+ import { FilterOption } from '../../domain/entities/Filter';
7
+
8
+ export interface FilterItem extends FilterOption {
9
+ active?: boolean;
10
+ }
11
+
12
+ export interface UseListFiltersReturn<T> {
13
+ filters: FilterItem[];
14
+ setFilters: (filters: FilterItem[]) => void;
15
+ activeFilters: FilterItem[];
16
+ selectedIds: string[];
17
+ applyFilters: (items: T[]) => T[];
18
+ toggleFilter: (id: string) => void;
19
+ handleFilterPress: (id: string) => void;
20
+ clearFilters: () => void;
21
+ handleClearFilters: () => void;
22
+ }
23
+
24
+ export interface UseListFiltersConfig<T> {
25
+ options: FilterOption[];
26
+ defaultFilterId?: string;
27
+ singleSelect?: boolean;
28
+ filterFn?: (item: T, activeFilters: FilterItem[]) => boolean;
29
+ }
30
+
31
+ // Overload 1: When config object is passed
32
+ export function useListFilters<T>(config: UseListFiltersConfig<T>): UseListFiltersReturn<T>;
33
+ // Overload 2: When initial filters array and optional filterFn are passed
34
+ export function useListFilters<T>(initialFilters: FilterItem[], filterFn?: (item: T, activeFilters: FilterItem[]) => boolean): UseListFiltersReturn<T>;
35
+ // Unified implementation
36
+ export function useListFilters<T>(
37
+ configOrFilters: FilterItem[] | UseListFiltersConfig<T>,
38
+ filterFnParam?: (item: T, activeFilters: FilterItem[]) => boolean
39
+ ): UseListFiltersReturn<T> {
40
+ const isConfig = !Array.isArray(configOrFilters);
41
+
42
+ // Normalize initial state
43
+ const initialFilters = isConfig
44
+ ? (configOrFilters as UseListFiltersConfig<T>).options.map(opt => ({
45
+ ...opt,
46
+ active: (configOrFilters as UseListFiltersConfig<T>).defaultFilterId
47
+ ? opt.id === (configOrFilters as UseListFiltersConfig<T>).defaultFilterId
48
+ : false
49
+ }))
50
+ : (configOrFilters as FilterItem[]);
51
+
52
+ const filterFn = isConfig
53
+ ? (configOrFilters as UseListFiltersConfig<T>).filterFn
54
+ : filterFnParam;
55
+
56
+ const singleSelect = isConfig
57
+ ? (configOrFilters as UseListFiltersConfig<T>).singleSelect
58
+ : false;
59
+
60
+ const [filters, setFilters] = useState<FilterItem[]>(initialFilters);
61
+
62
+ const activeFilters = useMemo(() => filters.filter((f) => f.active), [filters]);
63
+
64
+ const toggleFilter = useCallback((id: string) => {
65
+ setFilters((current) => {
66
+ if (singleSelect) {
67
+ return current.map((f) => ({ ...f, active: f.id === id }));
68
+ }
69
+ return current.map((f) => (f.id === id ? { ...f, active: !f.active } : f));
70
+ });
71
+ }, [singleSelect]);
72
+
73
+ const clearFilters = useCallback(() => {
74
+ setFilters((current) => current.map((f) => ({ ...f, active: false })));
75
+ }, []);
76
+
77
+ const applyFilters = useCallback((items: T[]) => {
78
+ if (activeFilters.length === 0 || !filterFn) return items;
79
+ return items.filter((item) => filterFn(item, activeFilters));
80
+ }, [activeFilters, filterFn]);
81
+
82
+ const selectedIds = useMemo(() => activeFilters.map((f) => f.id), [activeFilters]);
83
+
84
+ return {
85
+ filters,
86
+ setFilters,
87
+ activeFilters,
88
+ selectedIds,
89
+ applyFilters,
90
+ toggleFilter,
91
+ handleFilterPress: toggleFilter,
92
+ clearFilters,
93
+ handleClearFilters: clearFilters,
94
+ };
95
+ }