advanced-filter-system 1.0.4 β†’ 1.0.5

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.
package/README.md CHANGED
@@ -1,17 +1,33 @@
1
-
2
1
  # Advanced Filter System
3
2
 
4
- A flexible and powerful JavaScript library for filtering DOM elements with search and sorting capabilities.
3
+ A powerful and flexible JavaScript library for filtering DOM elements with comprehensive search, sorting, and filtering capabilities.
5
4
 
6
5
  ## Features
7
6
 
8
- - πŸ” Multiple typed filters (category, price, etc.)
9
- - πŸ”Ž Text search with debouncing
7
+ ### Core Filtering
8
+
9
+ - πŸ” Multiple filter types (category, price, status, etc.)
10
+ - πŸ”€ Flexible filter modes (AND/OR logic)
11
+ - πŸ‘₯ Filter groups with independent logic
10
12
  - πŸ“Š Multi-criteria sorting
11
- - πŸ”— URL state management
12
- - ✨ Smooth animations
13
+ - πŸ”Ž Text search with debouncing
14
+ - πŸ“± Responsive design support
15
+ - ✨ Smooth animations and transitions
13
16
  - πŸ”’ Results counter
14
- - πŸ“± Responsive
17
+ - πŸ”— URL state management
18
+
19
+ ### Advanced Features
20
+
21
+ - πŸ“‘ Pagination support
22
+ - πŸ“Š Range-based filtering
23
+ - πŸ’Ύ Filter presets (save/load)
24
+ - πŸ“ˆ Analytics integration
25
+ - ⌨️ Keyboard navigation
26
+ - πŸ”„ Custom sort comparators
27
+ - 🎯 Event system
28
+ - πŸ“± Responsive breakpoints
29
+ - πŸ” Multiple search keys
30
+ - 🎨 Customizable animations
15
31
 
16
32
  ## Installation
17
33
 
@@ -21,36 +37,39 @@ A flexible and powerful JavaScript library for filtering DOM elements with searc
21
37
  npm install advanced-filter-system
22
38
  ```
23
39
 
40
+ ### Via yarn
41
+
42
+ ```bash
43
+ yarn add advanced-filter-system
44
+ ```
45
+
24
46
  ### Direct Download
25
47
 
26
48
  Download `src/AFS.js` from this repository and include it in your project.
27
49
 
28
- ## Basic Usage
50
+ ## Usage Guide
29
51
 
30
- ### HTML Structure
52
+ ### Basic Setup
31
53
 
32
54
  ```html
33
55
  <div class="filter-container">
34
- <!-- Filter buttons with types -->
56
+ <!-- Filter buttons -->
35
57
  <div class="filters">
36
58
  <button class="btn-filter" data-filter="*">All</button>
37
59
  <button class="btn-filter" data-filter="category:web">Web</button>
38
60
  <button class="btn-filter" data-filter="category:design">Design</button>
39
- <button class="btn-filter" data-filter="price:low">Low Price</button>
40
61
  </div>
41
62
 
42
- <!-- Search (optional) -->
63
+ <!-- Optional components -->
43
64
  <input type="text" class="filter-search" placeholder="Search...">
44
-
45
- <!-- Counter (optional) -->
46
65
  <div class="filter-counter"></div>
47
66
 
48
67
  <!-- Filterable items -->
49
68
  <div class="items">
50
69
  <div class="filter-item"
51
- data-categories="category:web category:low"
70
+ data-categories="category:web"
52
71
  data-title="Project 1"
53
- data-price="low"
72
+ data-price="599"
54
73
  data-year="2023">
55
74
  <!-- Content -->
56
75
  </div>
@@ -58,7 +77,7 @@ Download `src/AFS.js` from this repository and include it in your project.
58
77
  </div>
59
78
  ```
60
79
 
61
- ### JavaScript Initialization
80
+ ### Basic JavaScript Initialization
62
81
 
63
82
  ```javascript
64
83
  import { AFS } from 'advanced-filter-system';
@@ -70,135 +89,216 @@ const filter = new AFS({
70
89
  });
71
90
  ```
72
91
 
73
- ## Advanced Configuration
92
+ ## Feature Documentation
93
+
94
+ ### 1. Filter Modes
95
+
96
+ ```javascript
97
+ // Set filter logic mode
98
+ filter.setFilterMode('AND'); // Items must match all selected filters
99
+ filter.setFilterMode('OR'); // Items must match any selected filter
100
+
101
+ // Alternative method
102
+ filter.setLogic('AND');
103
+ filter.setLogic(true); // true = AND, false = OR
104
+ ```
105
+
106
+ ### 2. Filter Groups
107
+
108
+ Groups allow complex filtering logic with independent AND/OR operations.
109
+
110
+ ```javascript
111
+ // Add filter groups
112
+ filter.addFilterGroup('categories', ['category:tech', 'category:web'], 'OR');
113
+ filter.addFilterGroup('price', ['price:low', 'price:medium'], 'AND');
114
+
115
+ // Set how groups combine
116
+ filter.setGroupMode('AND'); // Items must match all groups
117
+ filter.setGroupMode('OR'); // Items must match any group
118
+
119
+ // Remove groups
120
+ filter.removeFilterGroup('price');
121
+ ```
74
122
 
75
- ### Full Options
123
+ ### 3. Search Functionality
76
124
 
77
125
  ```javascript
126
+ // Configure search
78
127
  const filter = new AFS({
79
- // Required
80
- containerSelector: '.filter-container',
81
- itemSelector: '.filter-item',
82
- filterButtonSelector: '.btn-filter',
83
-
84
- // Optional (default values)
85
128
  searchInputSelector: '.filter-search',
86
- counterSelector: '.filter-counter',
87
- activeClass: 'active',
88
- hiddenClass: 'hidden',
89
- animationDuration: 300,
90
- filterMode: 'OR',
91
- searchKeys: ['title'],
92
- debounceTime: 300
129
+ searchKeys: ['title', 'description'], // Data attributes to search in
130
+ debounceTime: 300 // Milliseconds
93
131
  });
132
+
133
+ // Programmatic search
134
+ filter.search('query');
94
135
  ```
95
136
 
96
- ### Managing Multiple Filters
137
+ ### 4. Sorting
97
138
 
98
139
  ```javascript
99
- // Add filters
100
- filter.addFilter('category', 'web');
101
- filter.addFilter('price', 'low');
140
+ // Multi-criteria sorting
141
+ filter.sortMultiple([
142
+ { key: 'year', direction: 'desc' },
143
+ { key: 'title', direction: 'asc' }
144
+ ]);
145
+
146
+ // Custom comparator
147
+ filter.sortWithComparator('price', (a, b) => parseFloat(a) - parseFloat(b));
148
+ ```
102
149
 
103
- // Remove filters
104
- filter.removeFilter('category', 'web');
150
+ ### 5. Range Filtering
105
151
 
106
- // Get active filters by type
107
- const activeCategories = filter.getActiveFiltersByType('category');
152
+ ```javascript
153
+ // Filter by numeric range
154
+ filter.addRangeFilter('price', 100, 500);
155
+ ```
108
156
 
109
- // Add filter groups
110
- filter.addFilterGroup('categories', ['category:tech', 'category:fashion'], 'OR');
111
- filter.addFilterGroup('price', ['price:low', 'price:medium'], 'AND');
157
+ ### 6. Pagination
112
158
 
113
- // Set how groups combine
114
- filter.setGroupMode('AND'); // Items must match both category AND price groups
159
+ ```javascript
160
+ // Enable pagination
161
+ filter.setPagination(12); // 12 items per page
162
+ ```
115
163
 
116
- // Remove a group
117
- filter.removeFilterGroup('price');
164
+ ### 7. State Management
165
+
166
+ ```javascript
167
+ // URL State
168
+ // Automatically managed, creates URLs like:
169
+ // ?category=web,design&price=low,medium&search=project
170
+
171
+ // Export/Import State
172
+ const state = filter.exportState();
173
+ filter.importState(state);
174
+
175
+ // Presets
176
+ filter.savePreset('myFilters');
177
+ filter.loadPreset('myFilters');
178
+ ```
179
+
180
+ ### 8. Analytics
181
+
182
+ ```javascript
183
+ filter.enableAnalytics((data) => {
184
+ console.log('Filter event:', data);
185
+ // { type: 'filter', filters: [...], visibleItems: 10, timestamp: '...' }
186
+ });
118
187
  ```
119
188
 
120
- ### URL State Management
189
+ ### 9. Responsive Design
190
+
191
+ ```javascript
192
+ filter.setResponsiveOptions({
193
+ '768': {
194
+ animationDuration: 200,
195
+ itemsPerPage: 8
196
+ },
197
+ '480': {
198
+ animationDuration: 0,
199
+ itemsPerPage: 4
200
+ }
201
+ });
202
+ ```
121
203
 
122
- Filters are automatically managed in the URL:
204
+ ### 10. Animation Configuration
123
205
 
124
206
  ```javascript
125
- // URL format:
126
- // ?category=web,design&price=low,medium&search=project
207
+ filter.setAnimationOptions({
208
+ duration: 300,
209
+ type: 'ease-out'
210
+ });
127
211
  ```
128
212
 
129
- ## Examples
213
+ ### 11. Event System
130
214
 
131
- ### Portfolio Filter with Multiple Categories
215
+ ```javascript
216
+ filter.on('filter', (data) => {
217
+ console.log('Filter changed:', data);
218
+ });
219
+ ```
132
220
 
133
- ```html
134
- <div class="portfolio filter-container">
135
- <div class="filters">
136
- <button class="btn-filter" data-filter="*">All</button>
137
- <button class="btn-filter" data-filter="type:web">Web</button>
138
- <button class="btn-filter" data-filter="type:app">Apps</button>
139
- <button class="btn-filter" data-filter="tech:react">React</button>
140
- <button class="btn-filter" data-filter="tech:vue">Vue</button>
141
- </div>
221
+ ### 12. Keyboard Navigation
142
222
 
143
- <div class="portfolio-items">
144
- <div class="filter-item"
145
- data-categories="type:web tech:react"
146
- data-title="React Project">
147
- <h3>React Web Project</h3>
148
- <p>Description...</p>
149
- </div>
150
- </div>
151
- </div>
223
+ ```javascript
224
+ filter.enableKeyboardNavigation();
225
+ ```
152
226
 
153
- <script>
154
- const portfolioFilter = new AFS({
155
- containerSelector: '.portfolio',
227
+ ## Browser Compatibility
228
+
229
+ - βœ… Chrome
230
+ - βœ… Firefox
231
+ - βœ… Safari
232
+ - βœ… Edge
233
+ - βœ… IE11 (with polyfills)
234
+
235
+ ## Full Configuration Options
236
+
237
+ ```javascript
238
+ const filter = new AFS({
239
+ // Required
240
+ containerSelector: '.filter-container',
156
241
  itemSelector: '.filter-item',
157
242
  filterButtonSelector: '.btn-filter',
158
- filterMode: 'AND' // Must match all selected filters
243
+
244
+ // Optional (with defaults)
245
+ searchInputSelector: '.filter-search',
246
+ counterSelector: '.filter-counter',
247
+ activeClass: 'active',
248
+ hiddenClass: 'hidden',
249
+ animationDuration: 300,
250
+ filterMode: 'OR',
251
+ searchKeys: ['title'],
252
+ debounceTime: 300
159
253
  });
160
- </script>
161
254
  ```
162
255
 
163
- ### Advanced Product Filter
256
+ ## API Methods Reference
164
257
 
165
- ```html
166
- <div class="products filter-container">
167
- <!-- Filters by type -->
168
- <div class="filters">
169
- <button class="btn-filter" data-filter="*">All</button>
170
- <button class="btn-filter" data-filter="category:electronics">Electronics</button>
171
- <button class="btn-filter" data-filter="price:low">Low Price</button>
172
- <button class="btn-filter" data-filter="price:medium">Medium Price</button>
173
- <button class="btn-filter" data-filter="stock:available">In Stock</button>
174
- </div>
258
+ ### Filter Management
175
259
 
176
- <input type="text" class="filter-search" placeholder="Search...">
177
- <div class="filter-counter"></div>
260
+ - `addFilter(type, value)`
261
+ - `removeFilter(type, value)`
262
+ - `getActiveFiltersByType(type)`
263
+ - `setFilterMode(mode)`
264
+ - `resetFilters()`
178
265
 
179
- <div class="product-grid">
180
- <div class="filter-item"
181
- data-categories="category:electronics price:low stock:available"
182
- data-title="Smartphone"
183
- data-price="599">
184
- <!-- Product content -->
185
- </div>
186
- </div>
187
- </div>
188
- ```
266
+ ### Filter Groups
189
267
 
190
- ## Browser Compatibility
268
+ - `addFilterGroup(groupId, filters, operator)`
269
+ - `removeFilterGroup(groupId)`
270
+ - `setGroupMode(mode)`
271
+
272
+ ### Search and Sort
273
+
274
+ - `search(query)`
275
+ - `sortMultiple(criteria)`
276
+ - `sortWithComparator(key, comparator)`
277
+ - `addRangeFilter(key, min, max)`
278
+
279
+ ### State Management
280
+
281
+ - `exportState()`
282
+ - `importState(state)`
283
+ - `savePreset(presetName)`
284
+ - `loadPreset(presetName)`
285
+
286
+ ### UI and Display
287
+
288
+ - `setPagination(itemsPerPage)`
289
+ - `setAnimationOptions(options)`
290
+ - `setResponsiveOptions(breakpoints)`
291
+ - `enableKeyboardNavigation()`
292
+
293
+ ### Events and Analytics
191
294
 
192
- - Chrome
193
- - Firefox
194
- - Safari
195
- - Edge
196
- - IE11 (with polyfills)
295
+ - `on(eventName, callback)`
296
+ - `enableAnalytics(callback)`
197
297
 
198
- ## Contribution
298
+ ## Contributing
199
299
 
200
- Contributions are welcome! Feel free to submit a Pull Request.
300
+ Contributions are welcome! Please feel free to submit issues and pull requests.
201
301
 
202
302
  ## License
203
303
 
204
- MIT License
304
+ MIT License - feel free to use this in your projects!
package/dist/AFS.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @fileoverview Advanced Filter System for DOM elements
3
- * @version 1.0.0
3
+ * @version 1.0.5
4
4
  *
5
5
  * A flexible and customizable filtering system that supports:
6
6
  * - Multiple filtering modes (OR/AND)
@@ -192,8 +192,12 @@ class AFS {
192
192
  if (button.classList.contains(this.options.activeClass)) {
193
193
  button.classList.remove(this.options.activeClass);
194
194
  this.currentFilters.delete(filterValue);
195
+
196
+ // If no filters are selected, reset to default state and clear URL
195
197
  if (this.currentFilters.size === 0) {
196
198
  this.resetFilters();
199
+ window.history.pushState({}, "", window.location.pathname);
200
+ return;
197
201
  }
198
202
  } else {
199
203
  button.classList.add(this.options.activeClass);
@@ -206,9 +210,9 @@ class AFS {
206
210
  * @public
207
211
  */
208
212
  /**
209
- * Apply current filters to items
210
- * @public
211
- */
213
+ * Apply current filters to items
214
+ * @public
215
+ */
212
216
  filter() {
213
217
  // Store the original filter logic
214
218
  const standardFilter = () => {
@@ -500,6 +504,11 @@ class AFS {
500
504
  * @private
501
505
  */
502
506
  updateURL() {
507
+ // If only "*" filter is active or no filters are active, clear the URL
508
+ if (this.currentFilters.size === 0 || this.currentFilters.size === 1 && this.currentFilters.has("*")) {
509
+ window.history.pushState({}, "", window.location.pathname);
510
+ return;
511
+ }
503
512
  const params = new URLSearchParams(window.location.search);
504
513
 
505
514
  // Add groups to URL if they exist
@@ -511,7 +520,7 @@ class AFS {
511
520
  params.set("groupMode", this.groupMode.toLowerCase());
512
521
  }
513
522
 
514
- // SΓ©parer les filtres par type
523
+ // Separate filters by type
515
524
  const filtersByType = {};
516
525
  for (const filter of this.currentFilters) {
517
526
  if (filter !== "*") {
@@ -523,7 +532,7 @@ class AFS {
523
532
  }
524
533
  }
525
534
 
526
- // Ajouter chaque type de filtre Γ  l'URL
535
+ // Add each filter type to the URL
527
536
  Object.entries(filtersByType).forEach(_ref => {
528
537
  let [type, values] = _ref;
529
538
  params.set(type, Array.from(values).join(","));