advanced-filter-system 1.0.6 → 1.0.7

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,324 +1,562 @@
1
- # Advanced Filter System
2
-
3
- A powerful and flexible JavaScript library for filtering DOM elements with comprehensive search, sorting, and filtering capabilities.
1
+ # Advanced Filter System (AFS)
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
+ [Live Demo](https://misits.github.io/advanced-filter-system) | [NPM Package](https://www.npmjs.com/package/advanced-filter-system)
6
+
7
+ ## Table of Contents
8
+
9
+ - [Advanced Filter System (AFS)](#advanced-filter-system-afs)
10
+ - [Table of Contents](#table-of-contents)
11
+ - [Features](#features)
12
+ - [Installation](#installation)
13
+ - [Quick Start](#quick-start)
14
+ - [HTML Structure](#html-structure)
15
+ - [JavaScript Initialization](#javascript-initialization)
16
+ - [Basic Usage](#basic-usage)
17
+ - [Filtering](#filtering)
18
+ - [Searching](#searching)
19
+ - [Sorting](#sorting)
20
+ - [Pagination](#pagination)
21
+ - [Advanced Usage](#advanced-usage)
22
+ - [Custom Animation](#custom-animation)
23
+ - [Filter Groups](#filter-groups)
24
+ - [Custom Sorting](#custom-sorting)
25
+ - [URL State Management](#url-state-management)
26
+ - [Components](#components)
27
+ - [Filter System](#filter-system)
28
+ - [Range Filter](#range-filter)
29
+ - [Date Filter](#date-filter)
30
+ - [Search System](#search-system)
31
+ - [Sort System](#sort-system)
32
+ - [Pagination](#pagination-1)
33
+ - [URL Manager](#url-manager)
34
+ - [Styling \& Theming](#styling--theming)
35
+ - [Built-in Themes](#built-in-themes)
36
+ - [Custom Themes](#custom-themes)
37
+ - [Animations](#animations)
38
+ - [Browser Support](#browser-support)
39
+ - [TypeScript Support](#typescript-support)
40
+ - [Contributing](#contributing)
41
+ - [License](#license)
4
42
 
5
43
  ## Features
6
44
 
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
12
- - 📊 Multi-criteria sorting
13
- - 🔎 Text search with debouncing
14
- - 📱 Responsive design support
15
- - Smooth animations and transitions
16
- - 🔢 Results counter
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
45
+ - 🔍 **Advanced Filtering**
46
+ - Multiple filter types (text, range, date)
47
+ - AND/OR logic
48
+ - Filter groups
49
+ - Dynamic filters
50
+ - 🔎 **Smart Search**
51
+ - Real-time search
52
+ - Multiple fields
53
+ - Highlight matches
54
+ - Minimum character threshold
55
+ - ↕️ **Flexible Sorting**
56
+ - Multi-column sort
57
+ - Custom comparators
58
+ - Auto-detect data types
59
+ - 📄 **Pagination**
60
+ - Dynamic page size
61
+ - Custom controls
62
+ - Scroll to top
63
+ - 🔗 **URL Management**
64
+ - State persistence
65
+ - Browser history support
66
+ - Shareable URLs
67
+ - **Performance**
68
+ - Debounced updates
69
+ - Efficient DOM manipulation
70
+ - Minimal reflows
71
+ - 🎨 **Rich Animation**
72
+ - 15+ built-in animations
73
+ - Custom transitions
74
+ - Hardware acceleration
75
+ - 💾 **State Management**
76
+ - Centralized state
77
+ - Import/Export
78
+ - Undo/Redo support
79
+ - 🎯 **Event System**
80
+ - Rich event API
81
+ - Custom events
82
+ - Event debugging
31
83
 
32
84
  ## Installation
33
85
 
34
- ### Via npm
35
-
36
86
  ```bash
87
+ # NPM
37
88
  npm install advanced-filter-system
38
- ```
39
89
 
40
- ### Via yarn
41
-
42
- ```bash
90
+ # Yarn
43
91
  yarn add advanced-filter-system
92
+
93
+ # PNPM
94
+ pnpm add advanced-filter-system
44
95
  ```
45
96
 
46
- ### Direct Download
97
+ Or include via CDN:
47
98
 
48
- Download `src/AFS.js` from this repository and include it in your project.
99
+ ```html
100
+ <script src="https://unpkg.com/advanced-filter-system@1.0.6/dist/afs.min.js"></script>
101
+ <link rel="stylesheet" href="https://unpkg.com/advanced-filter-system@1.0.6/dist/afs.min.css">
102
+ ```
49
103
 
50
- ## Usage Guide
104
+ ## Quick Start
51
105
 
52
- ### Basic Setup
106
+ ### HTML Structure
53
107
 
54
108
  ```html
55
- <div class="filter-container">
56
- <!-- Filter buttons -->
57
- <div class="filters">
58
- <button class="btn-filter" data-filter="*">All</button>
59
- <button class="btn-filter" data-filter="category:web">Web</button>
60
- <button class="btn-filter" data-filter="category:design">Design</button>
61
- </div>
109
+ <!DOCTYPE html>
110
+ <html>
111
+ <head>
112
+ <title>AFS Demo</title>
113
+ <link rel="stylesheet" href="https://unpkg.com/advanced-filter-system@1.0.6/dist/afs.min.css">
114
+ </head>
115
+ <body>
116
+ <!-- Counter -->
117
+ <div class="filter-counter"></div>
62
118
 
63
- <!-- Optional components -->
119
+ <!-- Search -->
64
120
  <input type="text" class="filter-search" placeholder="Search...">
65
- <div class="filter-counter"></div>
121
+
122
+ <!-- Filter Buttons -->
123
+ <div class="filter-buttons">
124
+ <button class="btn-filter" data-filter="all">All</button>
125
+ <button class="btn-filter" data-filter="category1">Category 1</button>
126
+ <button class="btn-filter" data-filter="category2">Category 2</button>
127
+ </div>
128
+
129
+ <!-- Sort Buttons -->
130
+ <div class="sort-buttons">
131
+ <button class="btn-sort" data-sort-key="price">
132
+ Price <span class="sort-direction">↑</span>
133
+ </button>
134
+ <button class="btn-sort" data-sort-key="date">
135
+ Date <span class="sort-direction">↑</span>
136
+ </button>
137
+ </div>
66
138
 
67
- <!-- Filterable items -->
68
- <div class="items">
139
+ <!-- Range Filter -->
140
+ <div id="price-range"></div>
141
+
142
+ <!-- Date Filter -->
143
+ <div id="date-filter"></div>
144
+
145
+ <!-- Items Container -->
146
+ <div id="items-container">
69
147
  <div class="filter-item"
70
- data-categories="category:web"
71
- data-title="Project 1"
72
- data-price="599"
73
- data-year="2023">
74
- <!-- Content -->
148
+ data-categories="category1"
149
+ data-price="99.99"
150
+ data-date="2024-03-15"
151
+ data-title="Item 1"
152
+ data-description="Description for item 1">
153
+ <h3>Item 1</h3>
154
+ <p>$99.99</p>
155
+ <p>March 15, 2024</p>
75
156
  </div>
157
+ <!-- More items... -->
76
158
  </div>
77
- </div>
159
+
160
+ <!-- Pagination -->
161
+ <div class="pagination-container"></div>
162
+
163
+ <!-- Scripts -->
164
+ <script src="https://unpkg.com/advanced-filter-system@1.0.6/dist/afs.min.js"></script>
165
+ <script>
166
+ const afs = AFS.createAFS({
167
+ containerSelector: '#items-container',
168
+ itemSelector: '.filter-item',
169
+ searchInputSelector: '.filter-search',
170
+ filterButtonSelector: '.btn-filter',
171
+ sortButtonSelector: '.btn-sort',
172
+ counterSelector: '.filter-counter',
173
+ debug: true,
174
+ responsive: true,
175
+ preserveState: true,
176
+ animation: {
177
+ type: 'fade',
178
+ duration: 300
179
+ },
180
+ pagination: {
181
+ enabled: true,
182
+ itemsPerPage: 10
183
+ }
184
+ });
185
+
186
+ // Add range filter
187
+ afs.rangeFilter.addRangeSlider({
188
+ key: 'price',
189
+ container: document.querySelector('#price-range'),
190
+ min: 0,
191
+ max: 1000,
192
+ step: 10
193
+ });
194
+
195
+ // Add date filter
196
+ afs.dateFilter.addDateRange({
197
+ key: 'date',
198
+ container: document.querySelector('#date-filter')
199
+ });
200
+ </script>
201
+ </body>
202
+ </html>
78
203
  ```
79
204
 
80
- ### Basic JavaScript Initialization
205
+ ### JavaScript Initialization
206
+
207
+ Using ES modules:
81
208
 
82
209
  ```javascript
83
- import { AFS } from 'advanced-filter-system';
210
+ import { createAFS } from 'advanced-filter-system';
84
211
 
85
- const filter = new AFS({
86
- containerSelector: '.filter-container',
212
+ const afs = createAFS({
213
+ containerSelector: '#items-container',
87
214
  itemSelector: '.filter-item',
88
- filterButtonSelector: '.btn-filter'
215
+ debug: true,
216
+ animation: {
217
+ type: 'fade',
218
+ duration: 300
219
+ }
89
220
  });
90
221
  ```
91
222
 
92
- ## Feature Documentation
223
+ ## Basic Usage
93
224
 
94
- ### 1. Filter Modes
225
+ ### Filtering
95
226
 
96
227
  ```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
228
+ // HTML
229
+ <button class="btn-filter" data-filter="category1">Category 1</button>
230
+ <button class="btn-filter" data-filter="category2">Category 2</button>
100
231
 
101
- // Alternative method
102
- filter.setLogic('AND');
103
- filter.setLogic(true); // true = AND, false = OR
104
- ```
105
-
106
- ### 2. Filter Groups
232
+ <div class="filter-item" data-categories="category1,category2">
233
+ Item content
234
+ </div>
107
235
 
108
- Groups allow complex filtering logic with independent AND/OR operations.
236
+ // JavaScript
237
+ // Set filter mode
238
+ afs.filter.setFilterMode('AND'); // or 'OR'
109
239
 
110
- ```javascript
111
- // Add filter groups
112
- filter.addFilterGroup('categories', ['category:tech', 'category:web'], 'OR');
113
- filter.addFilterGroup('price', ['price:low', 'price:medium'], 'AND');
240
+ // Add filter programmatically
241
+ afs.filter.addFilter('category1');
114
242
 
115
- // Set how groups combine
116
- filter.setGroupMode('AND'); // Items must match all groups
117
- filter.setGroupMode('OR'); // Items must match any group
243
+ // Remove filter
244
+ afs.filter.removeFilter('category1');
118
245
 
119
- // Remove groups
120
- filter.removeFilterGroup('price');
246
+ // Clear all filters
247
+ afs.filter.clearAllFilters();
121
248
  ```
122
249
 
123
- ### 3. Search Functionality
250
+ ### Searching
124
251
 
125
252
  ```javascript
253
+ // HTML
254
+ <input type="text" class="filter-search">
255
+ <div class="filter-item"
256
+ data-title="Product Name"
257
+ data-description="Product description">
258
+ Item content
259
+ </div>
260
+
261
+ // JavaScript
126
262
  // Configure search
127
- const filter = new AFS({
128
- searchInputSelector: '.filter-search',
129
- searchKeys: ['title', 'description'], // Data attributes to search in
130
- debounceTime: 300 // Milliseconds
263
+ afs.search.updateConfig({
264
+ searchKeys: ['title', 'description'],
265
+ minSearchLength: 2,
266
+ highlightMatches: true,
267
+ debounceTime: 300
131
268
  });
132
269
 
133
- // Programmatic search
134
- filter.search('query');
270
+ // Perform search programmatically
271
+ afs.search.search('query');
272
+
273
+ // Clear search
274
+ afs.search.clearSearch();
135
275
  ```
136
276
 
137
- ### 4. Sorting
277
+ ### Sorting
138
278
 
139
279
  ```javascript
140
- // Multi-criteria sorting
141
- filter.sortMultiple([
142
- { key: 'year', direction: 'desc' },
143
- { key: 'title', direction: 'asc' }
144
- ]);
280
+ // HTML
281
+ <button class="btn-sort" data-sort-key="price">Sort by Price</button>
282
+ <button class="btn-sort" data-sort-key="date">Sort by Date</button>
145
283
 
146
- // Custom comparator
147
- filter.sortWithComparator('price', (a, b) => parseFloat(a) - parseFloat(b));
148
- ```
149
-
150
- ### 5. Range Filtering
284
+ <div class="filter-item" data-price="99.99" data-date="2024-03-15">
285
+ Item content
286
+ </div>
151
287
 
152
- ```javascript
153
- // Filter by numeric range
154
- filter.addRangeFilter('price', 100, 500);
155
- ```
288
+ // JavaScript
289
+ // Basic sort
290
+ afs.sort.sort('price', 'asc');
156
291
 
157
- ### 6. Pagination
292
+ // Multiple criteria sort
293
+ afs.sort.sortMultiple([
294
+ { key: 'category', direction: 'asc' },
295
+ { key: 'price', direction: 'desc' }
296
+ ]);
158
297
 
159
- ```javascript
160
- // Enable pagination
161
- filter.setPagination(12); // 12 items per page
298
+ // Reset sort
299
+ afs.sort.reset();
162
300
  ```
163
301
 
164
- ### 7. State Management
302
+ ### Pagination
165
303
 
166
304
  ```javascript
167
- // URL State
168
- // Automatically managed, creates URLs like:
169
- // ?category=web,design&price=low,medium&search=project
305
+ // HTML
306
+ <div class="pagination-container"></div>
307
+
308
+ // JavaScript
309
+ // Configure pagination
310
+ const afs = createAFS({
311
+ pagination: {
312
+ enabled: true,
313
+ itemsPerPage: 10,
314
+ maxButtons: 7,
315
+ showPrevNext: true,
316
+ scrollToTop: true
317
+ }
318
+ });
170
319
 
171
- // Export/Import State
172
- const state = filter.exportState();
173
- filter.importState(state);
320
+ // Navigate pages
321
+ afs.pagination.goToPage(2);
174
322
 
175
- // Presets
176
- filter.savePreset('myFilters');
177
- filter.loadPreset('myFilters');
323
+ // Change items per page
324
+ afs.pagination.setItemsPerPage(20);
325
+
326
+ // Get pagination info
327
+ const info = afs.pagination.getPageInfo();
178
328
  ```
179
329
 
180
- ### 8. Analytics
330
+ ## Advanced Usage
331
+
332
+ ### Custom Animation
181
333
 
182
334
  ```javascript
183
- filter.enableAnalytics((data) => {
184
- console.log('Filter event:', data);
185
- // { type: 'filter', filters: [...], visibleItems: 10, timestamp: '...' }
335
+ // Custom animation configuration
336
+ const afs = createAFS({
337
+ animation: {
338
+ type: 'custom',
339
+ duration: 500,
340
+ easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
341
+ inClass: 'my-enter',
342
+ outClass: 'my-leave'
343
+ }
186
344
  });
345
+
346
+ // CSS
347
+ .my-enter {
348
+ opacity: 0;
349
+ transform: scale(0.9);
350
+ }
351
+
352
+ .my-enter.my-enter-active {
353
+ opacity: 1;
354
+ transform: scale(1);
355
+ transition: opacity 500ms cubic-bezier(0.4, 0, 0.2, 1),
356
+ transform 500ms cubic-bezier(0.4, 0, 0.2, 1);
357
+ }
358
+
359
+ .my-leave {
360
+ opacity: 1;
361
+ transform: scale(1);
362
+ }
363
+
364
+ .my-leave.my-leave-active {
365
+ opacity: 0;
366
+ transform: scale(0.9);
367
+ transition: opacity 500ms cubic-bezier(0.4, 0, 0.2, 1),
368
+ transform 500ms cubic-bezier(0.4, 0, 0.2, 1);
369
+ }
187
370
  ```
188
371
 
189
- ### 9. Responsive Design
372
+ ### Filter Groups
190
373
 
191
374
  ```javascript
192
- filter.setResponsiveOptions({
193
- '768': {
194
- animationDuration: 200,
195
- itemsPerPage: 8
196
- },
197
- '480': {
198
- animationDuration: 0,
199
- itemsPerPage: 4
200
- }
375
+ // Create filter groups with different operators
376
+ afs.filter.addFilterGroup('price', {
377
+ ranges: [[0, 100], [101, 500], [501, 1000]],
378
+ operator: 'OR'
379
+ });
380
+
381
+ afs.filter.addFilterGroup('categories', {
382
+ filters: ['electronics', 'books'],
383
+ operator: 'AND'
201
384
  });
385
+
386
+ // Set group mode
387
+ afs.filter.setGroupMode('AND');
388
+
389
+ // Remove group
390
+ afs.filter.removeFilterGroup('price');
202
391
  ```
203
392
 
204
- ### 10. Animation Configuration
393
+ ### Custom Sorting
205
394
 
206
395
  ```javascript
207
- filter.setAnimationOptions({
208
- duration: 300,
209
- type: 'ease-out'
396
+ // Custom comparator for special sorting needs
397
+ afs.sort.sortWithComparator('title', (a, b) => {
398
+ // Sort by last word
399
+ const getLastWord = str => str.split(' ').pop();
400
+ const lastA = getLastWord(a);
401
+ const lastB = getLastWord(b);
402
+ return lastA.localeCompare(lastB);
403
+ });
404
+
405
+ // Sort with multiple languages
406
+ afs.sort.sortWithComparator('title', (a, b) => {
407
+ return a.localeCompare(b, 'es', {
408
+ sensitivity: 'base',
409
+ numeric: true
410
+ });
210
411
  });
211
412
  ```
212
413
 
213
- ### 11. Event System
414
+ ### URL State Management
214
415
 
215
416
  ```javascript
216
- filter.on('filter', (data) => {
217
- console.log('Filter changed:', data);
417
+ // Enable URL state
418
+ const afs = createAFS({
419
+ urlStateEnabled: true,
420
+ urlStateKey: 'filter'
218
421
  });
219
- ```
220
422
 
221
- ### 12. Keyboard Navigation
423
+ // Handle state changes
424
+ afs.on('urlStateLoaded', (state) => {
425
+ console.log('State loaded:', state);
426
+ });
222
427
 
223
- ```javascript
224
- filter.enableKeyboardNavigation();
428
+ // Manual control
429
+ afs.urlManager.updateURL();
430
+ afs.urlManager.loadFromURL();
431
+ afs.urlManager.clearURL();
432
+
433
+ // Get specific parameter
434
+ const searchQuery = afs.urlManager.getParam('search');
225
435
  ```
226
436
 
227
- ### 13. Sort asc/desc
437
+ ## Components
228
438
 
229
- ```javascript
230
- filter.sortWithComparator('price', (a, b) => parseFloat(a) - parseFloat(b), 'asc');
439
+ Each component can be used independently or as part of the AFS system.
231
440
 
232
- // or
441
+ ### Filter System
442
+ See [Filter Documentation](docs/filter.md)
233
443
 
234
- filter.sortWithOrder('price');
235
- ```
444
+ ### Range Filter
445
+ See [Range Filter Documentation](docs/range-filter.md)
236
446
 
237
- ### 13. Shuffle
447
+ ### Date Filter
448
+ See [Date Filter Documentation](docs/date-filter.md)
238
449
 
239
- ```javascript
240
- filter.shuffle();
241
- ```
450
+ ### Search System
451
+ See [Search Documentation](docs/search.md)
452
+
453
+ ### Sort System
454
+ See [Sort Documentation](docs/sort.md)
455
+
456
+ ### Pagination
457
+ See [Pagination Documentation](docs/pagination.md)
242
458
 
243
- ## Browser Compatibility
459
+ ### URL Manager
460
+ See [URL Manager Documentation](docs/url-manager.md)
244
461
 
245
- - Chrome
246
- - ✅ Firefox
247
- - ✅ Safari
248
- - ✅ Edge
249
- - ✅ IE11 (with polyfills)
462
+ ## Styling & Theming
250
463
 
251
- ## Full Configuration Options
464
+ ### Built-in Themes
252
465
 
253
466
  ```javascript
254
- const filter = new AFS({
255
- // Required
256
- containerSelector: '.filter-container',
257
- itemSelector: '.filter-item',
258
- filterButtonSelector: '.btn-filter',
259
-
260
- // Optional (with defaults)
261
- searchInputSelector: '.filter-search',
262
- counterSelector: '.filter-counter',
263
- activeClass: 'active',
264
- hiddenClass: 'hidden',
265
- animationDuration: 300,
266
- filterMode: 'OR',
267
- searchKeys: ['title'],
268
- debounceTime: 300,
269
- debug: false, // Enable console logs
270
- logLevel: 'info', // 'info', 'warn', 'error', 'debug'
467
+ const afs = createAFS({
468
+ styles: {
469
+ colors: {
470
+ primary: '#3b82f6',
471
+ background: '#f3f4f6',
472
+ text: '#1f2937'
473
+ }
474
+ }
271
475
  });
272
476
  ```
273
477
 
274
- ## API Methods Reference
478
+ ### Custom Themes
275
479
 
276
- ### Filter Management
480
+ ```javascript
481
+ const afs = createAFS({
482
+ styles: {
483
+ colors: {
484
+ primary: '#custom-color',
485
+ background: '#custom-bg',
486
+ text: '#custom-text'
487
+ },
488
+ components: {
489
+ button: {
490
+ borderRadius: '8px',
491
+ padding: '8px 16px'
492
+ },
493
+ input: {
494
+ borderWidth: '2px',
495
+ focusRing: '3px'
496
+ }
497
+ }
498
+ }
499
+ });
500
+ ```
277
501
 
278
- - `addFilter(type, value)`
279
- - `removeFilter(type, value)`
280
- - `getActiveFiltersByType(type)`
281
- - `setFilterMode(mode)`
282
- - `resetFilters()`
502
+ ### Animations
283
503
 
284
- ### Filter Groups
504
+ ```javascript
505
+ const afs = createAFS({
506
+ animation: {
507
+ type: 'fade', // or 'slide', 'scale', etc.
508
+ duration: 300,
509
+ }
510
+ });
511
+ ```
285
512
 
286
- - `addFilterGroup(groupId, filters, operator)`
287
- - `removeFilterGroup(groupId)`
288
- - `setGroupMode(mode)`
513
+ ## Browser Support
289
514
 
290
- ### Search and Sort
515
+ - Chrome (last 2 versions)
516
+ - Firefox (last 2 versions)
517
+ - Safari (last 2 versions)
518
+ - Edge (last 2 versions)
519
+ - iOS Safari (last 2 versions)
520
+ - Android Chrome (last 2 versions)
291
521
 
292
- - `search(query)`
293
- - `sortMultiple(criteria)`
294
- - `sortWithComparator(key, comparator)`
295
- - `addRangeFilter(key, min, max)`
296
- - `shuffle()`
297
- - `sortWithOrder(key)`
522
+ Required browser features:
298
523
 
299
- ### State Management
524
+ - CSS Transitions
525
+ - Flexbox
526
+ - CSS Grid (optional)
527
+ - History API
528
+ - localStorage
529
+ - MutationObserver
300
530
 
301
- - `exportState()`
302
- - `importState(state)`
303
- - `savePreset(presetName)`
304
- - `loadPreset(presetName)`
531
+ ## TypeScript Support
305
532
 
306
- ### UI and Display
533
+ Full TypeScript support with type definitions included:
307
534
 
308
- - `setPagination(itemsPerPage)`
309
- - `setAnimationOptions(options)`
310
- - `setResponsiveOptions(breakpoints)`
311
- - `enableKeyboardNavigation()`
535
+ ```typescript
536
+ import { createAFS, AFSOptions } from 'advanced-filter-system';
312
537
 
313
- ### Events and Analytics
538
+ const options: AFSOptions = {
539
+ containerSelector: '#items-container',
540
+ itemSelector: '.filter-item'
541
+ };
314
542
 
315
- - `on(eventName, callback)`
316
- - `enableAnalytics(callback)`
543
+ const afs = createAFS(options);
544
+ ```
317
545
 
318
546
  ## Contributing
319
547
 
320
- Contributions are welcome! Please feel free to submit issues and pull requests.
548
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details on:
549
+
550
+ 1. Setting up the development environment
551
+ 2. Coding standards
552
+ 3. Pull request process
553
+ 4. Bug reporting
554
+ 5. Feature requests
321
555
 
322
556
  ## License
323
557
 
324
- MIT License - feel free to use this in your projects!
558
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
559
+
560
+ ---
561
+
562
+ Made with ♥ by [misits](https://github.com/misits)