advanced-filter-system 1.5.2 → 1.6.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.
package/README.md CHANGED
@@ -1,627 +1,283 @@
1
1
  # Advanced Filter System (AFS)
2
2
 
3
- A powerful and flexible vanilla JavaScript filtering system that provides advanced filtering, searching, sorting, and pagination capabilities for DOM elements. Zero dependencies, lightweight, and highly customizable.
4
-
5
- > **✨ NEW in v1.5.1**: Enhanced mixed mode filtering, improved event system, and comprehensive URL state management!
6
-
7
- [Live Demo](https://misits.github.io/advanced-filter-system) | [NPM Package](https://www.npmjs.com/package/advanced-filter-system) | [Interactive Examples](examples/demo.html)
8
-
9
- ## Table of Contents
10
-
11
- - [Advanced Filter System (AFS)](#advanced-filter-system-afs)
12
- - [Table of Contents](#table-of-contents)
13
- - [Features](#features)
14
- - [Installation](#installation)
15
- - [Quick Start](#quick-start)
16
- - [HTML Structure](#html-structure)
17
- - [JavaScript Initialization](#javascript-initialization)
18
- - [Filter Logic Modes](#filter-logic-modes)
19
- - [Mixed Mode (Recommended)](#mixed-mode-recommended)
20
- - [Per-Type Logic Configuration](#per-type-logic-configuration)
21
- - [Legacy Modes](#legacy-modes)
22
- - [Filter Types & UI Components](#filter-types--ui-components)
23
- - [Button Filters](#button-filters)
24
- - [Select Dropdowns](#select-dropdowns)
25
- - [Radio Buttons](#radio-buttons)
26
- - [Checkboxes](#checkboxes)
27
- - [Range Sliders](#range-sliders)
28
- - [Date Range Filters](#date-range-filters)
29
- - [Advanced Features](#advanced-features)
30
- - [Search & Filtering](#search--filtering)
31
- - [Sorting](#sorting)
32
- - [Pagination](#pagination)
33
- - [URL State Management](#url-state-management)
34
- - [Animations](#animations)
35
- - [Configuration Options](#configuration-options)
36
- - [API Reference](#api-reference)
37
- - [Examples](#examples)
38
- - [Browser Support](#browser-support)
39
- - [TypeScript Support](#typescript-support)
40
- - [Contributing](#contributing)
41
- - [License](#license)
3
+ A flexible, dependency-free JavaScript library for filtering DOM elements with search, sorting, range filters, pagination and URL state built in.
4
+
5
+ [Live Demo](https://misits.github.io/advanced-filter-system) · [NPM](https://www.npmjs.com/package/advanced-filter-system) · [Documentation](docs/README.md)
42
6
 
43
7
  ## Features
44
8
 
45
- - 🎯 **Advanced Filter Logic**
46
- - Mixed mode (OR within categories, AND between)
47
- - Per-type logic configuration
48
- - Multi-select and toggle modes
49
- - Category-specific clearing
50
- - 🔍 **Multiple Filter Types**
51
- - Button filters (toggle/multi-select)
52
- - Select dropdowns
53
- - Radio buttons (exclusive)
54
- - Checkboxes (multi-select)
55
- - Range sliders with histograms
56
- - Date range filters
57
- - 🔎 **Smart Search**
58
- - Real-time fuzzy search
59
- - Multiple searchable fields
60
- - Configurable debouncing
61
- - Minimum character threshold
62
- - ↕️ **Flexible Sorting**
63
- - Multi-column sorting
64
- - Custom sort functions
65
- - Auto-detect data types
66
- - Sort direction indicators
67
- - 📄 **Advanced Pagination**
68
- - Dynamic page sizes
69
- - Smooth transitions
70
- - Scroll-to-top option
71
- - Custom pagination controls
72
- - 🎨 **Rich Animations**
73
- - 14+ animation types (fade, slide, scale, flip, etc.)
74
- - Hardware-accelerated transitions
75
- - Customizable duration and easing
76
- - 🔗 **State Management**
77
- - URL state persistence
78
- - Browser history support
79
- - Shareable filtered URLs
80
- - State import/export
81
- - ⚡ **Performance Optimized**
82
- - Debounced updates
83
- - Efficient DOM manipulation
84
- - Minimal reflows and repaints
85
- - 🎯 **Event System**
86
- - Comprehensive event API
87
- - Custom event support
88
- - Debug mode with logging
9
+ - **Filtering** buttons, checkboxes, radios and dropdowns, with OR / AND / mixed logic configurable per filter type
10
+ - **Search** debounced text search across any data attributes, with optional match highlighting
11
+ - **Sorting** — by any data attribute (numbers, dates, strings auto-detected), multi-criteria, custom comparators, shuffle
12
+ - **Range filters** draggable sliders (with optional histogram), min/max number inputs, date ranges
13
+ - **Pagination** — page controls, items-per-page, smooth scroll-to-top, fully aware of active filters and sort order
14
+ - **URL state** the full filter state lives in the URL: shareable links, back/forward navigation, restored on load
15
+ - **Animations** fade, slide, scale, flip, rotate, zoom, bounce, blur and more
16
+ - **TypeScript** — complete type definitions included
89
17
 
90
18
  ## Installation
91
19
 
92
20
  ```bash
93
- # NPM
94
21
  npm install advanced-filter-system
95
-
96
- # Yarn
97
- yarn add advanced-filter-system
98
-
99
- # PNPM
100
- pnpm add advanced-filter-system
101
22
  ```
102
23
 
103
- Or include via CDN:
24
+ Or via CDN:
104
25
 
105
26
  ```html
106
27
  <script type="module">
107
- import { AFS } from 'https://unpkg.com/advanced-filter-system@latest/dist/afs.modern.js';
28
+ import { AFS } from 'https://unpkg.com/advanced-filter-system@latest/dist/afs.modern.js';
108
29
  </script>
109
30
  ```
110
31
 
111
- ## Quick Start
32
+ ## Quick start
112
33
 
113
- ### HTML Structure
34
+ A minimal, complete setup — filter buttons, search, counter and pagination:
114
35
 
115
36
  ```html
116
- <!DOCTYPE html>
117
- <html>
118
- <head>
119
- <title>AFS Demo</title>
120
- </head>
121
- <body>
122
- <!-- Filter Controls -->
123
- <div class="filter-controls">
124
- <button class="btn-filter" data-filter="*">All</button>
125
- <button class="btn-filter" data-filter="category:tech">Technology</button>
126
- <button class="btn-filter" data-filter="category:design">Design</button>
127
- </div>
128
-
129
- <!-- Search Input -->
130
- <input type="text" class="filter-search" placeholder="Search...">
131
-
132
- <!-- Results Counter -->
133
- <div class="filter-counter"></div>
134
-
135
- <!-- Filterable Items -->
136
- <div class="items-container">
137
- <div class="filter-item"
138
- data-categories="category:tech brand:apple"
139
- data-title="MacBook Pro"
140
- data-price="2499"
141
- data-date="2024-03-15">
142
- <h3>MacBook Pro</h3>
143
- <p>$2,499</p>
144
- </div>
145
- <!-- More items... -->
146
- </div>
147
-
148
- <!-- Pagination Container -->
149
- <div class="afs-pagination-container"></div>
150
- </body>
151
- </html>
37
+ <!-- Filter controls -->
38
+ <button class="btn-filter" data-filter="*">All</button>
39
+ <button class="btn-filter" data-filter="category:tech">Tech</button>
40
+ <button class="btn-filter" data-filter="category:design">Design</button>
41
+
42
+ <!-- Search and counter -->
43
+ <input type="text" class="filter-search" placeholder="Search…">
44
+ <div class="filter-counter"></div>
45
+
46
+ <!-- Items: data-categories holds space-separated "type:value" pairs -->
47
+ <div class="items-container">
48
+ <div class="filter-item" data-categories="category:tech brand:apple"
49
+ data-title="MacBook Pro" data-price="2499">
50
+ MacBook Pro $2,499
51
+ </div>
52
+ <div class="filter-item" data-categories="category:design brand:moleskine"
53
+ data-title="Sketchbook" data-price="29">
54
+ Sketchbook — $29
55
+ </div>
56
+ </div>
57
+
58
+ <!-- Pagination controls are rendered in here -->
59
+ <div class="afs-pagination-container"></div>
152
60
  ```
153
61
 
154
- ### JavaScript Initialization
155
-
156
62
  ```javascript
157
63
  import { AFS } from 'advanced-filter-system';
158
64
 
159
65
  const afs = new AFS({
160
- // Required selectors
161
- containerSelector: '.items-container',
162
- itemSelector: '.filter-item',
163
- filterButtonSelector: '.btn-filter',
164
- searchInputSelector: '.filter-search',
165
- counterSelector: '.filter-counter',
166
-
167
- // Search configuration
168
- searchKeys: ['title', 'categories'],
169
-
170
- // NEW: Advanced filter logic
171
- filterCategoryMode: 'mixed', // OR within categories, AND between
172
- filterTypeLogic: {
173
- category: { mode: 'OR', multi: true }, // Multi-select OR
174
- brand: 'OR', // Toggle mode
175
- price: 'AND' // Multi-select AND
176
- },
177
-
178
- // Pagination
179
- pagination: {
180
- enabled: true,
181
- itemsPerPage: 12
182
- },
183
-
184
- // Animations
185
- animation: {
186
- type: 'fade',
187
- duration: 300
188
- },
189
-
190
- // Debug mode
191
- debug: true
66
+ containerSelector: '.items-container', // required
67
+ itemSelector: '.filter-item', // required
68
+ filterButtonSelector: '.btn-filter',
69
+ searchInputSelector: '.filter-search',
70
+ counterSelector: '.filter-counter',
71
+ searchKeys: ['title', 'categories'],
72
+ pagination: { enabled: true, itemsPerPage: 12 },
73
+ animation: { type: 'fade', duration: 300 },
192
74
  });
193
75
  ```
194
76
 
195
- ## Filter Logic Modes
196
-
197
- ### Mixed Mode (Recommended)
198
-
199
- The most intuitive filtering experience - OR logic within filter categories, AND logic between different categories.
200
-
201
- ```javascript
202
- const afs = new AFS({
203
- filterCategoryMode: 'mixed',
204
- // When user selects: Tech OR Design AND Apple OR Samsung
205
- // Shows: (Tech OR Design) AND (Apple OR Samsung)
206
- });
207
- ```
208
-
209
- ### Per-Type Logic Configuration
210
-
211
- Configure each filter type independently for maximum flexibility.
212
-
213
- ```javascript
214
- const afs = new AFS({
215
- filterCategoryMode: 'mixed',
216
- filterTypeLogic: {
217
- category: { mode: 'OR', multi: true }, // Multi-select checkboxes
218
- brand: 'OR', // Toggle buttons (exclusive)
219
- price: 'AND', // Multi-select with AND logic
220
- features: { mode: 'OR', multi: true } // Multi-select with OR logic
221
- }
222
- });
223
-
224
- // Update logic at runtime
225
- afs.filter.setFilterTypeLogic('brand', { mode: 'OR', multi: true });
77
+ ```css
78
+ /* AFS toggles these two classes — style them however you like */
79
+ .btn-filter.active { background: #000; color: #fff; }
80
+ .filter-item.hidden { display: none !important; }
226
81
  ```
227
82
 
228
- ### Legacy Modes
83
+ That's it. Clicking a filter button, typing in the search box or changing pages all update the items, the counter and the URL.
229
84
 
230
- ```javascript
231
- // Legacy OR mode (all filters use OR logic)
232
- const afs = new AFS({ filterCategoryMode: 'OR' });
85
+ ## How filtering works
233
86
 
234
- // Legacy AND mode (all filters use AND logic)
235
- const afs = new AFS({ filterCategoryMode: 'AND' });
236
- ```
237
-
238
- ## Filter Types & UI Components
239
-
240
- ### Button Filters
87
+ Every item declares its facets in `data-categories`, as space-separated `type:value` pairs:
241
88
 
242
89
  ```html
243
- <!-- Toggle mode (exclusive) -->
244
- <button class="btn-filter" data-filter="category:tech">Technology</button>
245
-
246
- <!-- Multi-select mode -->
247
- <button class="btn-filter" data-filter="brand:apple">Apple</button>
248
- <button class="btn-filter" data-filter="brand:samsung">Samsung</button>
249
-
250
- <!-- Clear specific category -->
251
- <button class="btn-filter" data-filter="category:*">Clear Categories</button>
90
+ <div class="filter-item" data-categories="category:tech brand:apple color:silver">
252
91
  ```
253
92
 
254
- ### Select Dropdowns
93
+ Filter controls target those pairs through `data-filter`:
255
94
 
256
- ```html
257
- <select class="afs-filter-dropdown">
258
- <option value="*">All Categories</option>
259
- <option value="category:tech">Technology</option>
260
- <option value="category:design">Design</option>
261
- </select>
262
- ```
95
+ | `data-filter` value | Meaning |
96
+ |---|---|
97
+ | `category:tech` | Toggle this filter |
98
+ | `*` | Reset — show everything |
99
+ | `category:*` | Clear every active `category:` filter |
263
100
 
264
- ### Radio Buttons
265
-
266
- ```html
267
- <label><input type="radio" name="category" class="btn-filter" data-filter="*" checked> All</label>
268
- <label><input type="radio" name="category" class="btn-filter" data-filter="category:tech"> Tech</label>
269
- <label><input type="radio" name="category" class="btn-filter" data-filter="category:design"> Design</label>
270
- ```
271
-
272
- ### Checkboxes
273
-
274
- ```html
275
- <label><input type="checkbox" class="btn-filter" data-filter="category:tech"> Technology</label>
276
- <label><input type="checkbox" class="btn-filter" data-filter="category:design"> Design</label>
277
- ```
278
-
279
- ### Range Sliders
101
+ By default AFS runs in **mixed mode**: filters of the same type combine with OR, different types combine with AND. Selecting *Tech*, *Design* and *Apple* shows items that are `(tech OR design) AND apple`. Each type's logic is configurable:
280
102
 
281
103
  ```javascript
282
- // Add price range slider with histogram
283
- afs.rangeFilter.addRangeSlider({
284
- key: 'price',
285
- type: 'number',
286
- container: '.price-range-container',
287
- min: 0,
288
- max: 3000,
289
- step: 50,
290
- ui: {
291
- showHistogram: true,
292
- bins: 10
293
- }
294
- });
295
-
296
- // Add rating range slider
297
- afs.rangeFilter.addRangeSlider({
298
- key: 'rating',
299
- type: 'number',
300
- container: '.rating-range-container',
301
- min: 4.0,
302
- max: 5.0,
303
- step: 0.1
304
- });
305
- ```
306
-
307
- ### Date Range Filters
308
-
309
- ```javascript
310
- // Add date range filter
311
- afs.dateFilter.addDateRange({
312
- key: 'date',
313
- container: '.date-range-container',
314
- minDate: new Date('2024-01-01'),
315
- maxDate: new Date(),
316
- format: 'YYYY-MM-DD'
317
- });
318
- ```
319
-
320
- ## Advanced Features
321
-
322
- ### Search & Filtering
323
-
324
- ```javascript
325
- // Programmatic search
326
- afs.search.search('query');
327
- afs.search.clearSearch();
328
- afs.search.setValue('new query');
329
-
330
- // Programmatic filtering
331
- afs.filter.addFilter('category:tech');
332
- afs.filter.removeFilter('category:tech');
333
- afs.filter.clearAllFilters();
334
- afs.filter.clearFilterCategory('category:*');
335
- ```
336
-
337
- ### Sorting
338
-
339
- ```javascript
340
- // Sort by single field
341
- afs.sort.sort('price', 'desc');
342
-
343
- // Custom sorting
344
- afs.sort.sortWithComparator('title', (a, b) => {
345
- return a.localeCompare(b, 'en', { numeric: true });
346
- });
347
-
348
- // Shuffle items
349
- afs.sort.shuffle();
350
- ```
351
-
352
- ### Pagination
353
-
354
- ```javascript
355
- // Pagination navigation
356
- afs.pagination.goToPage(2);
357
- afs.pagination.nextPage();
358
- afs.pagination.previousPage();
359
-
360
- // Toggle pagination mode
361
- afs.pagination.setPaginationMode(true); // Enable
362
- afs.pagination.setPaginationMode(false); // Show all
363
- ```
364
-
365
- ### URL State Management
366
-
367
- ```javascript
368
- // Enable URL state persistence
369
104
  const afs = new AFS({
370
- preserveState: true,
371
- urlStateKey: 'filters' // Custom URL parameter name
105
+ filterCategoryMode: 'mixed',
106
+ filterTypeLogic: {
107
+ category: { mode: 'OR', multi: true }, // multi-select (checkbox-style)
108
+ brand: 'OR', // exclusive (one at a time)
109
+ tags: 'AND', // items must match all selected
110
+ },
372
111
  });
373
-
374
- // Manual state management
375
- const state = afs.getState();
376
- afs.setState(state);
377
112
  ```
378
113
 
379
- ### Animations
114
+ Buttons, checkboxes (`<input type="checkbox" data-filter>`), radios (`<input type="radio" data-filter>`) and dropdowns (`<select data-filter-type>`) are all supported — see the [Filter documentation](docs/filter.md).
380
115
 
381
- ```javascript
382
- const afs = new AFS({
383
- animation: {
384
- type: 'fade', // fade, slide, scale, flip, rotate, zoom, bounce, blur, etc.
385
- duration: 400,
386
- easing: 'ease-out'
387
- }
388
- });
116
+ ## Documentation
389
117
 
390
- // Change animation options at runtime
391
- afs.updateOptions({
392
- animation: {
393
- type: 'slide',
394
- duration: 400
395
- }
396
- });
397
- ```
118
+ | Module | Covers |
119
+ |---|---|
120
+ | [Filter](docs/filter.md) | Buttons, checkboxes, radios, dropdowns, logic modes, filter groups |
121
+ | [Search](docs/search.md) | Text search, debouncing, highlighting |
122
+ | [Sort](docs/sort.md) | Sort buttons, multi-criteria, custom comparators, shuffle |
123
+ | [Pagination](docs/pagination.md) | Page controls, items-per-page, scroll-to-top |
124
+ | [Range Filter](docs/range-filter.md) | Slider with optional histogram (numbers or dates) |
125
+ | [Input Range Filter](docs/input-range-filter.md) | Min/max number inputs |
126
+ | [Date Filter](docs/date-filter.md) | Date range pickers |
127
+ | [URL Manager](docs/url-manager.md) | URL parameters, shareable state, history |
128
+
129
+ ## Common options
398
130
 
399
- ## Configuration Options
131
+ All options with their defaults live in [`src/core/Options.js`](src/core/Options.js). The ones you'll touch most:
400
132
 
401
133
  ```javascript
402
134
  const afs = new AFS({
403
- // Required selectors
404
- containerSelector: '.items-container',
405
- itemSelector: '.filter-item',
406
- filterButtonSelector: '.btn-filter',
407
- searchInputSelector: '.filter-search',
408
- counterSelector: '.filter-counter',
409
-
410
- // Filter logic (NEW!)
411
- filterCategoryMode: 'mixed', // 'mixed', 'OR', 'AND'
412
- filterTypeLogic: {
413
- category: { mode: 'OR', multi: true },
414
- brand: 'OR',
415
- price: 'AND'
416
- },
417
-
418
- // Search configuration
419
- searchKeys: ['title', 'categories', 'description'],
420
- debounceTime: 300,
421
-
422
- // Pagination
423
- pagination: {
424
- enabled: true,
425
- itemsPerPage: 12,
426
- container: '.afs-pagination-container',
427
- showPrevNext: true,
428
- scrollToTop: true,
429
- scrollBehavior: 'smooth'
430
- },
431
-
432
- // Counter display
433
- counter: {
434
- template: 'Showing {visible} of {total}',
435
- showFiltered: true,
436
- filteredTemplate: '({filtered} filtered)',
437
- noResultsTemplate: 'No items found',
438
- formatter: (num) => num.toLocaleString()
439
- },
440
-
441
- // Animations
442
- animation: {
443
- type: 'fade',
444
- duration: 300,
445
- easing: 'ease-out'
446
- },
447
-
448
- // State management
449
- preserveState: true,
450
- stateExpiry: 86400000, // 24 hours
451
- observeDOM: false,
452
-
453
- // CSS Classes
454
- activeClass: 'active',
455
- hiddenClass: 'hidden',
456
- activeSortClass: 'sort-active',
457
-
458
- // Debug mode
459
- debug: true
135
+ // Selectors (containerSelector and itemSelector are required)
136
+ containerSelector: '.afs-filter-container',
137
+ itemSelector: '.afs-filter-item',
138
+ filterButtonSelector: '.afs-btn-filter',
139
+ filterDropdownSelector: '.afs-filter-dropdown',
140
+ searchInputSelector: '.afs-filter-search',
141
+ counterSelector: '.afs-filter-counter',
142
+ sortButtonSelector: '.afs-btn-sort',
143
+
144
+ // CSS classes AFS toggles
145
+ activeClass: 'active',
146
+ hiddenClass: 'hidden',
147
+ activeSortClass: 'sort-active',
148
+
149
+ // Filter logic
150
+ filterCategoryMode: 'mixed', // 'mixed' | 'OR' | 'AND'
151
+ filterTypeLogic: {}, // per-type config, see above
152
+
153
+ // Search
154
+ searchKeys: ['title'],
155
+ debounceTime: 300,
156
+
157
+ // Pagination (disabled by default)
158
+ pagination: {
159
+ enabled: false,
160
+ itemsPerPage: 10,
161
+ container: '.afs-pagination-container',
162
+ showPrevNext: true,
163
+ scrollToTop: false, // scrolls back to the top of the items list
164
+ scrollOffset: 50,
165
+ scrollBehavior: 'smooth', // 'smooth' | 'auto'
166
+ },
167
+
168
+ // Counter
169
+ counter: {
170
+ template: 'Showing {visible} of {total}',
171
+ showFiltered: true,
172
+ filteredTemplate: '({filtered} filtered)',
173
+ noResultsTemplate: 'No items found',
174
+ },
175
+
176
+ // Animations
177
+ animation: { type: 'fade', duration: 300 },
178
+
179
+ // Misc
180
+ debug: false, // log to console
181
+ preserveState: false, // persist state in sessionStorage across tab switches
460
182
  });
461
183
  ```
462
184
 
463
- ## API Reference
185
+ ## API at a glance
464
186
 
465
- ### Core Methods
187
+ Each feature lives on the instance: `afs.filter`, `afs.search`, `afs.sort`, `afs.pagination`, `afs.rangeFilter`, `afs.inputRangeFilter`, `afs.dateFilter`, `afs.urlManager`.
466
188
 
467
189
  ```javascript
468
- // Filter management
190
+ // Filtering
469
191
  afs.filter.addFilter('category:tech');
470
192
  afs.filter.removeFilter('category:tech');
471
- afs.filter.clearAllFilters();
472
- afs.filter.clearFilterCategory('category:*');
473
- afs.filter.setFilterTypeLogic('brand', { mode: 'OR', multi: true });
474
- afs.filter.toggleFilterExclusive('category:tech');
193
+ afs.filter.clearAllFilters(); // filters + search + dropdowns + checkboxes
475
194
 
476
195
  // Search
477
- afs.search.search('query');
196
+ afs.search.setValue('macbook');
478
197
  afs.search.clearSearch();
479
- afs.search.setValue('new query');
480
- const currentQuery = afs.search.getValue();
481
198
 
482
- // Sorting
199
+ // Sorting
483
200
  afs.sort.sort('price', 'desc');
484
- afs.sort.sortMultiple([
485
- { key: 'category', direction: 'asc' },
486
- { key: 'price', direction: 'desc' }
487
- ]);
488
201
  afs.sort.shuffle();
489
202
  afs.sort.reset();
490
203
 
491
204
  // Pagination
492
205
  afs.pagination.goToPage(2);
493
206
  afs.pagination.nextPage();
494
- afs.pagination.previousPage();
495
- afs.pagination.setPaginationMode(true);
207
+ afs.pagination.setItemsPerPage(24);
208
+ afs.pagination.getPageInfo(); // { currentPage, itemsPerPage, totalPages }
496
209
 
497
- // Range Filters
210
+ // Range widgets (containers are DOM elements)
498
211
  afs.rangeFilter.addRangeSlider({
499
- key: 'price',
500
- container: '.price-range-container'
212
+ key: 'price', type: 'number',
213
+ container: document.querySelector('.price-slider'),
214
+ min: 0, max: 1000, step: 10,
215
+ ui: { showHistogram: true, bins: 12 },
501
216
  });
217
+ afs.inputRangeFilter.addInputRange({ key: 'rating', container: el, min: 0, max: 5, step: 0.5 });
218
+ afs.dateFilter.addDateRange({ key: 'date', container: el });
502
219
 
503
- // Date Filters
504
- afs.dateFilter.addDateRange({
505
- key: 'date',
506
- container: '.date-range-container'
507
- });
508
-
509
- // State
510
- const state = afs.getState();
511
- afs.setState(state);
512
-
513
- // Events
514
- afs.on('filtersApplied', (data) => {
515
- console.log(`Showing ${data.visibleItems} of ${data.total} items`);
516
- });
220
+ // Lifecycle
221
+ afs.refresh(); // re-scan items (after DOM changes)
222
+ afs.destroy();
517
223
  ```
518
224
 
519
- ### Event System
225
+ ### Events
520
226
 
521
227
  ```javascript
522
- // Available events
523
- afs.on('filtersApplied', callback);
524
- afs.on('search', callback);
525
- afs.on('sort', callback);
526
- afs.on('pageChanged', callback);
527
- afs.on('urlStateLoaded', callback);
228
+ afs.on('filtersApplied', ({ activeFilters, visibleItems }) => { /* … */ });
229
+ afs.on('search', ({ query, matches, total }) => { /* … */ });
230
+ afs.on('sort', ({ key, direction }) => { /* … */ });
231
+ afs.on('pageChanged', ({ currentPage, totalPages }) => { /* … */ });
232
+ afs.on('filtersCleared', () => { /* … */ });
233
+ afs.on('urlStateLoaded', ({ params }) => { /* … */ });
528
234
  ```
529
235
 
530
- ## Examples
531
-
532
- The project includes comprehensive examples demonstrating all features:
533
-
534
- - **[Interactive Demo](examples/demo.html)** - Complete demo with all filter types
535
- - **[Button Filters](examples/demo.html#buttons)** - Toggle and multi-select buttons
536
- - **[Select Dropdowns](examples/demo.html#select)** - Dropdown filter controls
537
- - **[Radio Buttons](examples/demo.html#radio)** - Exclusive radio button filters
538
- - **[Checkboxes](examples/demo.html#checkbox)** - Multi-select checkbox filters
539
- - **[Range Filters](examples/demo.html#range)** - Sliders with histogram support
540
- - **[Search Functionality](examples/demo.html#search)** - Real-time search examples
236
+ `on`, `once`, `off`, `removeAllListeners` are available. Each module's documentation lists its events and payloads.
541
237
 
542
- ### Running Examples Locally
238
+ ## TypeScript
543
239
 
544
- ```bash
545
- # Clone the repository
546
- git clone https://github.com/misits/advanced-filter-system.git
547
- cd advanced-filter-system
548
-
549
- # Open examples in browser
550
- open examples/index.html
551
- ```
552
-
553
- ## Browser Support
554
-
555
- - Chrome (latest)
556
- - Firefox (latest)
557
- - Safari (latest)
558
- - Edge (latest)
559
- - Opera (latest)
560
-
561
- Modern browser features used:
562
- - ES6 Modules
563
- - CSS Custom Properties
564
- - IntersectionObserver API
565
- - URLSearchParams API
566
-
567
- ## TypeScript Support
568
-
569
- Full TypeScript support with comprehensive type definitions:
240
+ Type definitions ship with the package:
570
241
 
571
242
  ```typescript
572
243
  import { AFS, AFSOptions, FilterTypeLogic } from 'advanced-filter-system';
573
244
 
574
- interface CustomOptions extends AFSOptions {
575
- customProperty: string;
576
- }
577
-
578
- const filterLogic: FilterTypeLogic = {
579
- category: { mode: 'OR', multi: true },
580
- brand: 'OR'
245
+ const logic: FilterTypeLogic = {
246
+ category: { mode: 'OR', multi: true },
247
+ brand: 'OR',
581
248
  };
582
249
 
583
250
  const afs = new AFS({
584
- containerSelector: '#items',
585
- itemSelector: '.item',
586
- filterTypeLogic: filterLogic
587
- } as CustomOptions);
251
+ containerSelector: '#items',
252
+ itemSelector: '.item',
253
+ filterTypeLogic: logic,
254
+ });
588
255
  ```
589
256
 
590
- ## Contributing
257
+ ## Browser support
591
258
 
592
- We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details on:
259
+ Modern evergreen browsers (Chrome, Firefox, Safari, Edge). Uses ES modules, `URLSearchParams` and the History API. `dist/afs.legacy.js` (UMD) is provided for non-module environments.
593
260
 
594
- 1. Setting up the development environment
595
- 2. Code style and standards
596
- 3. Testing requirements
597
- 4. Pull request process
598
- 5. Bug reporting guidelines
599
- 6. Feature request templates
600
-
601
- ### Development Setup
261
+ ## Development
602
262
 
603
263
  ```bash
604
- # Clone and install
605
264
  git clone https://github.com/misits/advanced-filter-system.git
606
265
  cd advanced-filter-system
607
266
  npm install
608
267
 
609
- # Run development server
610
- npm run dev
611
-
612
- # Build for production
613
- npm run build
268
+ npm test # jest test suite
269
+ npm run build # build dist/ (development)
270
+ npm run build:prod # minified production build
614
271
 
615
- # Run tests
616
- npm test
272
+ # Try the demo (imports ../dist/afs.modern.js, so build first)
273
+ npm run build && npx serve .
274
+ # then open http://localhost:3000/examples/demo.html
617
275
  ```
618
276
 
619
277
  ## License
620
278
 
621
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
279
+ MIT see [LICENSE](LICENSE).
622
280
 
623
281
  ---
624
282
 
625
283
  Made with ♥ by [misits](https://github.com/misits)
626
-
627
- **Star ⭐ this repo if you find it helpful!**