advanced-filter-system 1.0.7 → 1.0.9
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 +17 -57
- package/dist/AFS.esm.js +564 -154
- package/dist/AFS.esm.js.map +1 -1
- package/dist/AFS.js +564 -154
- package/dist/AFS.js.map +1 -1
- package/dist/AFS.min.js +1 -1
- package/dist/AFS.min.js.map +1 -1
- package/package.json +1 -1
package/dist/AFS.esm.js
CHANGED
|
@@ -139,68 +139,111 @@ class Options {
|
|
|
139
139
|
*/
|
|
140
140
|
static defaults = {
|
|
141
141
|
// Selectors
|
|
142
|
-
containerSelector:
|
|
143
|
-
itemSelector:
|
|
144
|
-
filterButtonSelector:
|
|
145
|
-
searchInputSelector:
|
|
146
|
-
counterSelector:
|
|
142
|
+
containerSelector: ".afs-filter-container",
|
|
143
|
+
itemSelector: ".afs-filter-item",
|
|
144
|
+
filterButtonSelector: ".afs-btn-filter",
|
|
145
|
+
searchInputSelector: ".afs-filter-search",
|
|
146
|
+
counterSelector: ".afs-filter-counter",
|
|
147
147
|
// Classes
|
|
148
|
-
activeClass:
|
|
149
|
-
hiddenClass:
|
|
150
|
-
// Animation
|
|
151
|
-
animationDuration: 300,
|
|
152
|
-
animationType: 'fade',
|
|
153
|
-
animationEasing: 'ease-out',
|
|
148
|
+
activeClass: "active",
|
|
149
|
+
hiddenClass: "hidden",
|
|
154
150
|
// Filtering
|
|
155
|
-
filterMode:
|
|
156
|
-
searchKeys: [
|
|
151
|
+
filterMode: "OR",
|
|
152
|
+
searchKeys: ["title"],
|
|
157
153
|
debounceTime: 300,
|
|
158
154
|
// Debug
|
|
159
155
|
debug: false,
|
|
160
|
-
logLevel:
|
|
156
|
+
logLevel: "info",
|
|
161
157
|
// Date handling
|
|
162
|
-
dateFormat:
|
|
158
|
+
dateFormat: "YYYY-MM-DD",
|
|
163
159
|
counter: {
|
|
164
|
-
template:
|
|
160
|
+
template: "Showing {visible} of {total}",
|
|
165
161
|
showFiltered: true,
|
|
166
|
-
filteredTemplate:
|
|
167
|
-
noResultsTemplate:
|
|
162
|
+
filteredTemplate: "({filtered} filtered)",
|
|
163
|
+
noResultsTemplate: "No items found",
|
|
168
164
|
formatter: num => num.toLocaleString()
|
|
169
165
|
},
|
|
170
166
|
// Styles
|
|
171
167
|
styles: {
|
|
172
168
|
slider: {
|
|
173
|
-
class: 'afs-range-slider',
|
|
174
|
-
trackClass: 'afs-range-track',
|
|
175
|
-
thumbClass: 'afs-range-thumb',
|
|
176
|
-
valueClass: 'afs-range-value',
|
|
177
|
-
selectedClass: 'afs-range-selected',
|
|
178
169
|
// Add new UI options
|
|
179
170
|
ui: {
|
|
180
171
|
showHistogram: false,
|
|
181
|
-
bins: 10
|
|
172
|
+
bins: 10,
|
|
173
|
+
// Number of bins for histogram
|
|
174
|
+
track: {
|
|
175
|
+
radius: "0",
|
|
176
|
+
// Button radius
|
|
177
|
+
background: "#e5e7eb" // Track color
|
|
178
|
+
},
|
|
179
|
+
thumb: {
|
|
180
|
+
radius: "50%",
|
|
181
|
+
// Button radius
|
|
182
|
+
size: "16px",
|
|
183
|
+
// Button size
|
|
184
|
+
background: "#000" // Button color
|
|
185
|
+
},
|
|
186
|
+
histogram: {
|
|
187
|
+
background: "#e5e7eb",
|
|
188
|
+
// Histogram background
|
|
189
|
+
bar: {
|
|
190
|
+
background: "#000" // Bar color
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
pagination: {
|
|
196
|
+
ui: {
|
|
197
|
+
button: {
|
|
198
|
+
background: "transparent",
|
|
199
|
+
border: "1px solid #000",
|
|
200
|
+
borderRadius: "4px",
|
|
201
|
+
padding: "8px 12px",
|
|
202
|
+
color: "#000",
|
|
203
|
+
active: {
|
|
204
|
+
background: "#000",
|
|
205
|
+
color: "#fff"
|
|
206
|
+
},
|
|
207
|
+
hover: {
|
|
208
|
+
background: "#000",
|
|
209
|
+
color: "#fff"
|
|
210
|
+
}
|
|
211
|
+
}
|
|
182
212
|
}
|
|
183
213
|
},
|
|
184
214
|
colors: {
|
|
185
|
-
primary:
|
|
186
|
-
background:
|
|
187
|
-
text:
|
|
188
|
-
histogram: '#e5e7eb',
|
|
189
|
-
// For histogram bars
|
|
190
|
-
histogramActive: '#000' // For active histogram bars
|
|
215
|
+
primary: "#000",
|
|
216
|
+
background: "#e5e7eb",
|
|
217
|
+
text: "#000"
|
|
191
218
|
}
|
|
192
219
|
},
|
|
220
|
+
// Slider
|
|
221
|
+
slider: {
|
|
222
|
+
containerClass: "afs-range-slider",
|
|
223
|
+
trackClass: "afs-range-track",
|
|
224
|
+
thumbClass: "afs-range-thumb",
|
|
225
|
+
valueClass: "afs-range-value",
|
|
226
|
+
selectedClass: "afs-range-selected"
|
|
227
|
+
},
|
|
193
228
|
// Pagination
|
|
194
229
|
pagination: {
|
|
195
230
|
enabled: false,
|
|
196
231
|
itemsPerPage: 10,
|
|
197
|
-
container:
|
|
198
|
-
pageButtonClass:
|
|
199
|
-
activePageClass:
|
|
200
|
-
containerClass:
|
|
232
|
+
container: ".afs-pagination-container",
|
|
233
|
+
pageButtonClass: "afs-page-button",
|
|
234
|
+
activePageClass: "afs-page-active",
|
|
235
|
+
containerClass: "afs-pagination",
|
|
201
236
|
scrollToTop: false,
|
|
202
237
|
scrollOffset: 50,
|
|
203
|
-
scrollBehavior:
|
|
238
|
+
scrollBehavior: "smooth" // or 'auto' for instant scroll
|
|
239
|
+
},
|
|
240
|
+
// Animation
|
|
241
|
+
animation: {
|
|
242
|
+
type: "fade",
|
|
243
|
+
duration: 300,
|
|
244
|
+
easing: "ease-out",
|
|
245
|
+
inClass: "afs-animation-enter",
|
|
246
|
+
outClass: "afs-animation-leave"
|
|
204
247
|
}
|
|
205
248
|
};
|
|
206
249
|
constructor() {
|
|
@@ -238,9 +281,9 @@ class Options {
|
|
|
238
281
|
...target
|
|
239
282
|
};
|
|
240
283
|
for (const key in source) {
|
|
241
|
-
if (source[key] !== null && typeof source[key] ===
|
|
284
|
+
if (source[key] !== null && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
242
285
|
// If the key doesn't exist in target or isn't an object, create/override it
|
|
243
|
-
if (!target[key] || typeof target[key] !==
|
|
286
|
+
if (!target[key] || typeof target[key] !== "object") {
|
|
244
287
|
result[key] = {};
|
|
245
288
|
}
|
|
246
289
|
// Recursively merge nested objects
|
|
@@ -260,37 +303,37 @@ class Options {
|
|
|
260
303
|
*/
|
|
261
304
|
validate() {
|
|
262
305
|
// Required selectors
|
|
263
|
-
const requiredSelectors = [
|
|
306
|
+
const requiredSelectors = ["containerSelector", "itemSelector"];
|
|
264
307
|
for (const selector of requiredSelectors) {
|
|
265
|
-
if (typeof this.options[selector] !==
|
|
308
|
+
if (typeof this.options[selector] !== "string") {
|
|
266
309
|
throw new Error(`${selector} must be a string`);
|
|
267
310
|
}
|
|
268
311
|
}
|
|
269
312
|
|
|
270
313
|
// Animation duration
|
|
271
|
-
if (typeof this.options.
|
|
272
|
-
throw new Error(
|
|
314
|
+
if (typeof this.options.animation.duration !== "number" || this.options.animation.duration < 0) {
|
|
315
|
+
throw new Error("animationDuration must be a positive number");
|
|
273
316
|
}
|
|
274
317
|
|
|
275
318
|
// Filter mode
|
|
276
|
-
if (![
|
|
319
|
+
if (!["OR", "AND"].includes(this.options.filterMode.toUpperCase())) {
|
|
277
320
|
throw new Error('filterMode must be either "OR" or "AND"');
|
|
278
321
|
}
|
|
279
322
|
|
|
280
323
|
// Search keys
|
|
281
324
|
if (!Array.isArray(this.options.searchKeys) || this.options.searchKeys.length === 0) {
|
|
282
|
-
throw new Error(
|
|
325
|
+
throw new Error("searchKeys must be a non-empty array");
|
|
283
326
|
}
|
|
284
327
|
|
|
285
328
|
// Counter validation
|
|
286
329
|
if (this.options.counter) {
|
|
287
|
-
if (typeof this.options.counter.template !==
|
|
288
|
-
throw new Error(
|
|
330
|
+
if (typeof this.options.counter.template !== "string") {
|
|
331
|
+
throw new Error("counter.template must be a string");
|
|
289
332
|
}
|
|
290
|
-
if (typeof this.options.counter.showFiltered !==
|
|
333
|
+
if (typeof this.options.counter.showFiltered !== "boolean") {
|
|
291
334
|
this.options.counter.showFiltered = true; // Set default
|
|
292
335
|
}
|
|
293
|
-
if (typeof this.options.counter.formatter !==
|
|
336
|
+
if (typeof this.options.counter.formatter !== "function") {
|
|
294
337
|
this.options.counter.formatter = num => num.toLocaleString(); // Set default
|
|
295
338
|
}
|
|
296
339
|
} else {
|
|
@@ -306,7 +349,7 @@ class Options {
|
|
|
306
349
|
* @returns {any} Option value
|
|
307
350
|
*/
|
|
308
351
|
get(path) {
|
|
309
|
-
return path.split(
|
|
352
|
+
return path.split(".").reduce((obj, key) => obj?.[key], this.options);
|
|
310
353
|
}
|
|
311
354
|
|
|
312
355
|
/**
|
|
@@ -315,7 +358,7 @@ class Options {
|
|
|
315
358
|
* @param {any} value - New value
|
|
316
359
|
*/
|
|
317
360
|
set(path, value) {
|
|
318
|
-
const parts = path.split(
|
|
361
|
+
const parts = path.split(".");
|
|
319
362
|
const last = parts.pop();
|
|
320
363
|
const target = parts.reduce((obj, key) => {
|
|
321
364
|
if (!(key in obj)) obj[key] = {};
|
|
@@ -515,24 +558,6 @@ class StyleManager {
|
|
|
515
558
|
constructor(options) {
|
|
516
559
|
this.options = options;
|
|
517
560
|
this.styleElement = null;
|
|
518
|
-
this.defaultStyles = {
|
|
519
|
-
slider: {
|
|
520
|
-
class: "afs-range-slider",
|
|
521
|
-
trackClass: "afs-range-track",
|
|
522
|
-
thumbClass: "afs-range-thumb",
|
|
523
|
-
valueClass: "afs-range-value",
|
|
524
|
-
selectedClass: "afs-range-selected"
|
|
525
|
-
},
|
|
526
|
-
colors: {
|
|
527
|
-
primary: "#000",
|
|
528
|
-
background: "#ddd",
|
|
529
|
-
text: "#000"
|
|
530
|
-
},
|
|
531
|
-
animation: {
|
|
532
|
-
duration: "300ms",
|
|
533
|
-
type: "ease-out"
|
|
534
|
-
}
|
|
535
|
-
};
|
|
536
561
|
}
|
|
537
562
|
|
|
538
563
|
/**
|
|
@@ -542,11 +567,11 @@ class StyleManager {
|
|
|
542
567
|
*/
|
|
543
568
|
createBaseStyles() {
|
|
544
569
|
const hiddenClass = this.options.get("hiddenClass") || "hidden";
|
|
545
|
-
const itemSelector = this.options.get("itemSelector") || ".filter-item";
|
|
546
|
-
const filterButtonSelector = this.options.get("filterButtonSelector") || ".btn-filter";
|
|
570
|
+
const itemSelector = this.options.get("itemSelector") || ".afs-filter-item";
|
|
571
|
+
const filterButtonSelector = this.options.get("filterButtonSelector") || ".afs-btn-filter";
|
|
547
572
|
const activeClass = this.options.get("activeClass") || "active";
|
|
548
|
-
const animationDuration = this.options.get("
|
|
549
|
-
const animationEasing = this.options.get("
|
|
573
|
+
const animationDuration = this.options.get("animation.duration") || '300ms';
|
|
574
|
+
const animationEasing = this.options.get("animation.easing") || 'ease-out';
|
|
550
575
|
return `
|
|
551
576
|
.${hiddenClass} {
|
|
552
577
|
display: none !important;
|
|
@@ -584,12 +609,18 @@ class StyleManager {
|
|
|
584
609
|
* @returns {string} CSS styles
|
|
585
610
|
*/
|
|
586
611
|
createRangeStyles() {
|
|
587
|
-
const styles = this.options.get("styles")
|
|
588
|
-
const
|
|
589
|
-
const
|
|
612
|
+
const styles = this.options.get("styles");
|
|
613
|
+
const sliderOptions = this.options.get("slider") || {};
|
|
614
|
+
const sliderStyles = styles.slider;
|
|
615
|
+
const colors = styles.colors;
|
|
616
|
+
const containerClass = sliderOptions.containerClass || "afs-range-slider";
|
|
617
|
+
const trackClass = sliderOptions.trackClass || "afs-range-track";
|
|
618
|
+
const thumbClass = sliderOptions.thumbClass || "afs-range-thumb";
|
|
619
|
+
const valueClass = sliderOptions.valueClass || "afs-range-value";
|
|
620
|
+
const selectedClass = sliderOptions.selectedClass || "afs-range-selected";
|
|
590
621
|
return `
|
|
591
622
|
/* Range Slider Styles */
|
|
592
|
-
.${
|
|
623
|
+
.${containerClass} {
|
|
593
624
|
position: relative;
|
|
594
625
|
width: auto;
|
|
595
626
|
height: 40px;
|
|
@@ -597,29 +628,29 @@ class StyleManager {
|
|
|
597
628
|
padding: 0 8px;
|
|
598
629
|
}
|
|
599
630
|
|
|
600
|
-
.${
|
|
631
|
+
.${trackClass} {
|
|
601
632
|
position: absolute;
|
|
602
633
|
top: 50%;
|
|
603
634
|
transform: translateY(-50%);
|
|
604
635
|
width: 100%;
|
|
605
636
|
height: 4px;
|
|
606
|
-
background: ${colors.background};
|
|
607
|
-
border-radius:
|
|
637
|
+
background: ${sliderStyles.ui.track.background || colors.background};
|
|
638
|
+
border-radius: ${sliderStyles.ui.track.radius || "0"};
|
|
608
639
|
}
|
|
609
640
|
|
|
610
|
-
.${
|
|
641
|
+
.${thumbClass} {
|
|
611
642
|
position: absolute;
|
|
612
643
|
top: 50%;
|
|
613
|
-
width: 16px;
|
|
614
|
-
height: 16px;
|
|
615
|
-
background: ${colors.primary};
|
|
616
|
-
border-radius: 50
|
|
644
|
+
width: ${sliderStyles.ui.thumb.size || "16px"};
|
|
645
|
+
height: ${sliderStyles.ui.thumb.size || "16px"};
|
|
646
|
+
background: ${sliderStyles.ui.thumb.background || colors.primary};
|
|
647
|
+
border-radius: ${sliderStyles.ui.thumb.radius || "50%"};
|
|
617
648
|
transform: translate(-50%, -50%);
|
|
618
649
|
cursor: pointer;
|
|
619
650
|
z-index: 2;
|
|
620
651
|
}
|
|
621
652
|
|
|
622
|
-
.${
|
|
653
|
+
.${valueClass} {
|
|
623
654
|
position: absolute;
|
|
624
655
|
top: -20px;
|
|
625
656
|
transform: translateX(-50%);
|
|
@@ -627,7 +658,7 @@ class StyleManager {
|
|
|
627
658
|
color: ${colors.text};
|
|
628
659
|
}
|
|
629
660
|
|
|
630
|
-
.${
|
|
661
|
+
.${selectedClass} {
|
|
631
662
|
position: absolute;
|
|
632
663
|
height: 4px;
|
|
633
664
|
background: ${colors.primary};
|
|
@@ -650,13 +681,13 @@ class StyleManager {
|
|
|
650
681
|
|
|
651
682
|
.afs-histogram-bar {
|
|
652
683
|
flex: 1;
|
|
653
|
-
background-color: ${colors.background};
|
|
684
|
+
background-color: ${sliderStyles.ui.histogram.background || colors.background};
|
|
654
685
|
min-height: 4px;
|
|
655
686
|
transition: background-color 0.2s ease;
|
|
656
687
|
}
|
|
657
688
|
|
|
658
689
|
.afs-histogram-bar.active {
|
|
659
|
-
background-color: ${colors.primary};
|
|
690
|
+
background-color: ${sliderStyles.ui.histogram.bar.background || colors.primary};
|
|
660
691
|
}
|
|
661
692
|
`;
|
|
662
693
|
}
|
|
@@ -667,7 +698,7 @@ class StyleManager {
|
|
|
667
698
|
* @returns {string} CSS styles
|
|
668
699
|
*/
|
|
669
700
|
createDateStyles() {
|
|
670
|
-
const colors =
|
|
701
|
+
const colors = this.options.get("styles").colors;
|
|
671
702
|
return `
|
|
672
703
|
.afs-date-range-container {
|
|
673
704
|
display: flex;
|
|
@@ -704,6 +735,49 @@ class StyleManager {
|
|
|
704
735
|
`;
|
|
705
736
|
}
|
|
706
737
|
|
|
738
|
+
/**
|
|
739
|
+
* Create date filter styles
|
|
740
|
+
* @private
|
|
741
|
+
* @returns {string} CSS styles
|
|
742
|
+
*/
|
|
743
|
+
createInputRangeStyles() {
|
|
744
|
+
const colors = this.options.get("styles").colors;
|
|
745
|
+
return `
|
|
746
|
+
.afs-input-range-container {
|
|
747
|
+
display: flex;
|
|
748
|
+
flex-wrap: wrap;
|
|
749
|
+
gap: 1rem;
|
|
750
|
+
margin: 10px 0;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
.afs-input-wrapper {
|
|
754
|
+
flex: 1;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
.afs-input-label {
|
|
758
|
+
display: block;
|
|
759
|
+
font-size: 0.875rem;
|
|
760
|
+
color: ${colors.text};
|
|
761
|
+
margin-bottom: 0.5rem;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
.afs-input {
|
|
765
|
+
width: 100%;
|
|
766
|
+
padding: 0.5rem;
|
|
767
|
+
border: 1px solid ${colors.background};
|
|
768
|
+
border-radius: 0.25rem;
|
|
769
|
+
font-size: 0.875rem;
|
|
770
|
+
color: ${colors.text};
|
|
771
|
+
transition: border-color 0.2s ease;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
.afs-input:focus {
|
|
775
|
+
outline: none;
|
|
776
|
+
border-color: ${colors.primary};
|
|
777
|
+
}
|
|
778
|
+
`;
|
|
779
|
+
}
|
|
780
|
+
|
|
707
781
|
/**
|
|
708
782
|
* Apply all styles
|
|
709
783
|
* @public
|
|
@@ -725,6 +799,9 @@ class StyleManager {
|
|
|
725
799
|
|
|
726
800
|
/* Search styles */
|
|
727
801
|
${this.createSearchStyles()}
|
|
802
|
+
|
|
803
|
+
/* Input range styles */
|
|
804
|
+
${this.createInputRangeStyles()}
|
|
728
805
|
`;
|
|
729
806
|
if (this.styleElement) {
|
|
730
807
|
this.styleElement.textContent = styles;
|
|
@@ -752,11 +829,13 @@ class StyleManager {
|
|
|
752
829
|
* @returns {string} CSS styles
|
|
753
830
|
*/
|
|
754
831
|
createPaginationStyles() {
|
|
832
|
+
const styles = this.options.get("styles");
|
|
755
833
|
const paginationOptions = this.options.get("pagination") || {};
|
|
756
|
-
const colors =
|
|
834
|
+
const colors = this.options.get("styles").colors;
|
|
757
835
|
const containerClass = paginationOptions.containerClass || "afs-pagination";
|
|
758
836
|
const buttonClass = paginationOptions.pageButtonClass || "afs-page-button";
|
|
759
837
|
const activeClass = paginationOptions.activePageClass || "afs-page-active";
|
|
838
|
+
const paginationStyles = styles.pagination;
|
|
760
839
|
return `
|
|
761
840
|
.${containerClass} {
|
|
762
841
|
display: flex;
|
|
@@ -766,23 +845,23 @@ class StyleManager {
|
|
|
766
845
|
}
|
|
767
846
|
|
|
768
847
|
.${buttonClass} {
|
|
769
|
-
padding: 8px 12px;
|
|
770
|
-
border: 1px solid
|
|
771
|
-
border-radius: 4px;
|
|
848
|
+
padding: ${paginationStyles.ui.button.padding || '8px 12px'};
|
|
849
|
+
border: ${paginationStyles.ui.button.border || '1px solid ' + colors.primary};
|
|
850
|
+
border-radius: ${paginationStyles.ui.button.borderRadius || '4px'};
|
|
772
851
|
cursor: pointer;
|
|
773
852
|
transition: all 200ms ease-out;
|
|
774
|
-
background: transparent;
|
|
775
|
-
color: ${colors.primary};
|
|
853
|
+
background: ${paginationStyles.ui.button.background || 'transparent'};
|
|
854
|
+
color: ${paginationStyles.ui.button.color || colors.primary};
|
|
776
855
|
}
|
|
777
856
|
|
|
778
857
|
.${buttonClass}:hover {
|
|
779
|
-
background: ${colors.primary};
|
|
780
|
-
color: white;
|
|
858
|
+
background: ${paginationStyles.ui.button.hover.background || colors.primary};
|
|
859
|
+
color: ${paginationStyles.ui.button.hover.color || 'white'};
|
|
781
860
|
}
|
|
782
861
|
|
|
783
862
|
.${buttonClass}.${activeClass} {
|
|
784
|
-
background: ${colors.primary};
|
|
785
|
-
color: white;
|
|
863
|
+
background: ${paginationStyles.ui.button.active.background || colors.primary};
|
|
864
|
+
color: ${paginationStyles.ui.button.active.color || 'white'};
|
|
786
865
|
}
|
|
787
866
|
|
|
788
867
|
.${buttonClass}:disabled {
|
|
@@ -799,7 +878,7 @@ class StyleManager {
|
|
|
799
878
|
*/
|
|
800
879
|
createSearchStyles() {
|
|
801
880
|
const searchClass = this.options.get("searchInputClass") || "afs-search";
|
|
802
|
-
const colors =
|
|
881
|
+
const colors = this.options.get("styles").colors;
|
|
803
882
|
return `
|
|
804
883
|
.${searchClass} {
|
|
805
884
|
padding: 8px;
|
|
@@ -1143,9 +1222,14 @@ class Animation {
|
|
|
1143
1222
|
}
|
|
1144
1223
|
applyShowAnimation(item) {
|
|
1145
1224
|
let animationType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'fade';
|
|
1146
|
-
const duration = this.options.get('
|
|
1225
|
+
const duration = this.options.get('animation.duration') || '300ms';
|
|
1147
1226
|
const animation = this.animations[animationType]?.in || this.animations.fade.in;
|
|
1227
|
+
|
|
1228
|
+
// Ensure display is set
|
|
1148
1229
|
item.style.display = 'block';
|
|
1230
|
+
item.style.opacity = '0'; // Start with opacity 0
|
|
1231
|
+
|
|
1232
|
+
// Apply animation in next frame
|
|
1149
1233
|
requestAnimationFrame(() => {
|
|
1150
1234
|
Object.assign(item.style, animation, {
|
|
1151
1235
|
transition: `opacity ${duration} ${animation.transitionTimingFunction}, transform ${duration} ${animation.transitionTimingFunction}`
|
|
@@ -1154,7 +1238,7 @@ class Animation {
|
|
|
1154
1238
|
}
|
|
1155
1239
|
applyHideAnimation(item) {
|
|
1156
1240
|
let animationType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'fade';
|
|
1157
|
-
const duration = this.options.get('
|
|
1241
|
+
const duration = this.options.get('animation.duration') || '300ms';
|
|
1158
1242
|
const animation = this.animations[animationType]?.out || this.animations.fade.out;
|
|
1159
1243
|
Object.assign(item.style, animation, {
|
|
1160
1244
|
transition: `opacity ${duration} ${animation.transitionTimingFunction}, transform ${duration} ${animation.transitionTimingFunction}`
|
|
@@ -1166,7 +1250,7 @@ class Animation {
|
|
|
1166
1250
|
item.addEventListener('transitionend', handleTransitionEnd);
|
|
1167
1251
|
}
|
|
1168
1252
|
setAnimation(animationType) {
|
|
1169
|
-
this.afs.options.set('
|
|
1253
|
+
this.afs.options.set('animation.type', animationType);
|
|
1170
1254
|
}
|
|
1171
1255
|
}
|
|
1172
1256
|
|
|
@@ -1313,26 +1397,39 @@ class Filter {
|
|
|
1313
1397
|
// Clear filter groups
|
|
1314
1398
|
this.filterGroups.clear();
|
|
1315
1399
|
|
|
1316
|
-
//
|
|
1317
|
-
const
|
|
1318
|
-
this.afs.state.setState("items.visible", visibleItems);
|
|
1400
|
+
// Create a promise to track animations
|
|
1401
|
+
const animationPromises = [];
|
|
1319
1402
|
|
|
1320
1403
|
// Show all items with animation
|
|
1321
1404
|
this.afs.items.forEach(item => {
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1405
|
+
const promise = new Promise(resolve => {
|
|
1406
|
+
item.classList.remove(this.afs.options.get('hiddenClass'));
|
|
1407
|
+
item.style.display = 'block'; // Ensure item is visible
|
|
1408
|
+
|
|
1409
|
+
requestAnimationFrame(() => {
|
|
1410
|
+
this.animation.applyShowAnimation(item, this.afs.options.get("animation.type"));
|
|
1411
|
+
// Resolve after animation duration
|
|
1412
|
+
setTimeout(resolve, this.afs.options.get("animation.duration") || 300);
|
|
1413
|
+
});
|
|
1325
1414
|
});
|
|
1415
|
+
animationPromises.push(promise);
|
|
1326
1416
|
});
|
|
1327
1417
|
|
|
1328
|
-
// Update
|
|
1329
|
-
this.afs.
|
|
1418
|
+
// Update state after all items are visible
|
|
1419
|
+
const visibleItems = new Set(this.afs.items);
|
|
1420
|
+
this.afs.state.setState("items.visible", visibleItems);
|
|
1330
1421
|
|
|
1331
|
-
//
|
|
1332
|
-
|
|
1422
|
+
// Wait for all animations to complete
|
|
1423
|
+
Promise.all(animationPromises).then(() => {
|
|
1424
|
+
// Update counter
|
|
1425
|
+
this.afs.updateCounter();
|
|
1333
1426
|
|
|
1334
|
-
|
|
1335
|
-
|
|
1427
|
+
// Update URL
|
|
1428
|
+
this.afs.urlManager.updateURL();
|
|
1429
|
+
|
|
1430
|
+
// Emit event
|
|
1431
|
+
this.afs.emit("filtersReset");
|
|
1432
|
+
});
|
|
1336
1433
|
}
|
|
1337
1434
|
|
|
1338
1435
|
/**
|
|
@@ -1403,60 +1500,64 @@ class Filter {
|
|
|
1403
1500
|
* @public
|
|
1404
1501
|
*/
|
|
1405
1502
|
applyFilters() {
|
|
1406
|
-
// Log active filters
|
|
1407
1503
|
const activeFilters = Array.from(this.activeFilters);
|
|
1408
1504
|
this.afs.logger.debug("Active filters:", activeFilters);
|
|
1409
|
-
this.afs.logger.debug("Applying filters");
|
|
1410
1505
|
const previouslyVisible = new Set(this.afs.state.getState().items.visible);
|
|
1411
1506
|
const visibleItems = new Set();
|
|
1412
1507
|
|
|
1413
|
-
// First
|
|
1508
|
+
// First determine visibility
|
|
1414
1509
|
this.afs.items.forEach(item => {
|
|
1415
1510
|
if (this.activeFilters.has("*") || this.itemMatchesFilters(item)) {
|
|
1416
1511
|
visibleItems.add(item);
|
|
1417
1512
|
}
|
|
1418
1513
|
});
|
|
1419
1514
|
|
|
1420
|
-
// Update state
|
|
1515
|
+
// Update state before animations
|
|
1421
1516
|
this.afs.state.setState("items.visible", visibleItems);
|
|
1422
1517
|
|
|
1423
|
-
//
|
|
1518
|
+
// Track animation promises
|
|
1519
|
+
const animationPromises = [];
|
|
1520
|
+
|
|
1521
|
+
// Apply animations
|
|
1424
1522
|
this.afs.items.forEach(item => {
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1523
|
+
const promise = new Promise(resolve => {
|
|
1524
|
+
if (visibleItems.has(item)) {
|
|
1525
|
+
// Show item
|
|
1526
|
+
item.classList.remove(this.afs.options.get('hiddenClass'));
|
|
1527
|
+
requestAnimationFrame(() => {
|
|
1528
|
+
this.animation.applyShowAnimation(item, this.afs.options.get("animation.type"));
|
|
1529
|
+
setTimeout(resolve, parseFloat(this.afs.options.get("animation.duration")) || 300);
|
|
1530
|
+
});
|
|
1531
|
+
} else {
|
|
1532
|
+
// Hide item
|
|
1533
|
+
requestAnimationFrame(() => {
|
|
1534
|
+
this.animation.applyHideAnimation(item, this.afs.options.get("animation.type"));
|
|
1535
|
+
setTimeout(resolve, parseFloat(this.afs.options.get("animation.duration")) || 300);
|
|
1536
|
+
});
|
|
1537
|
+
}
|
|
1538
|
+
});
|
|
1539
|
+
animationPromises.push(promise);
|
|
1438
1540
|
});
|
|
1439
1541
|
|
|
1440
|
-
//
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1542
|
+
// Handle completion
|
|
1543
|
+
Promise.all(animationPromises).then(() => {
|
|
1544
|
+
// Ensure visible items remain visible
|
|
1545
|
+
visibleItems.forEach(item => {
|
|
1546
|
+
item.style.display = 'block';
|
|
1547
|
+
item.style.opacity = '1';
|
|
1548
|
+
});
|
|
1447
1549
|
|
|
1448
|
-
// Update
|
|
1550
|
+
// Update UI
|
|
1449
1551
|
this.afs.updateCounter();
|
|
1450
|
-
|
|
1451
|
-
// Update URL
|
|
1452
1552
|
this.afs.urlManager.updateURL();
|
|
1453
|
-
|
|
1454
|
-
// Emit final event
|
|
1455
1553
|
this.afs.emit("filtersApplied", {
|
|
1456
1554
|
activeFilters,
|
|
1457
1555
|
visibleItems: visibleItems.size
|
|
1458
1556
|
});
|
|
1459
1557
|
});
|
|
1558
|
+
|
|
1559
|
+
// Emit visibility change events
|
|
1560
|
+
this.emitFilterEvents(previouslyVisible, visibleItems);
|
|
1460
1561
|
}
|
|
1461
1562
|
|
|
1462
1563
|
/**
|
|
@@ -2004,6 +2105,310 @@ function debounce(func, wait) {
|
|
|
2004
2105
|
};
|
|
2005
2106
|
}
|
|
2006
2107
|
|
|
2108
|
+
/**
|
|
2109
|
+
* @fileoverview Input range filter implementation for AFS
|
|
2110
|
+
*/
|
|
2111
|
+
|
|
2112
|
+
class InputRangeFilter {
|
|
2113
|
+
constructor(afs) {
|
|
2114
|
+
this.afs = afs;
|
|
2115
|
+
this.activeRanges = new Map();
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2118
|
+
/**
|
|
2119
|
+
* @typedef {Object} InputRangeOptions
|
|
2120
|
+
* @property {string} key - Data attribute key
|
|
2121
|
+
* @property {HTMLElement} container - Container element
|
|
2122
|
+
* @property {number} [min] - Minimum value
|
|
2123
|
+
* @property {number} [max] - Maximum value
|
|
2124
|
+
* @property {number} [step] - Step value
|
|
2125
|
+
* @property {string} [label] - Label for the input range
|
|
2126
|
+
*/
|
|
2127
|
+
|
|
2128
|
+
/**
|
|
2129
|
+
* Add input range filter
|
|
2130
|
+
* @param {InputRangeOptions} options - Input range options
|
|
2131
|
+
*/
|
|
2132
|
+
addInputRange(_ref) {
|
|
2133
|
+
let {
|
|
2134
|
+
key,
|
|
2135
|
+
container,
|
|
2136
|
+
min,
|
|
2137
|
+
max,
|
|
2138
|
+
step = 1,
|
|
2139
|
+
label = ''
|
|
2140
|
+
} = _ref;
|
|
2141
|
+
this.afs.logger.debug(`Adding input range for ${key}`);
|
|
2142
|
+
if (!container) {
|
|
2143
|
+
this.afs.logger.error('Container element required for input range');
|
|
2144
|
+
return;
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
// Calculate min/max if not provided
|
|
2148
|
+
const values = this.calculateMinMax(key);
|
|
2149
|
+
min = min ?? values.min;
|
|
2150
|
+
max = max ?? values.max;
|
|
2151
|
+
|
|
2152
|
+
// Create input elements
|
|
2153
|
+
const elements = this.createInputElements(label);
|
|
2154
|
+
const state = this.initializeState(min, max, step);
|
|
2155
|
+
|
|
2156
|
+
// Add elements to container
|
|
2157
|
+
this.appendElements(container, elements);
|
|
2158
|
+
|
|
2159
|
+
// Setup event handlers
|
|
2160
|
+
this.setupEventHandlers(elements, state, key);
|
|
2161
|
+
|
|
2162
|
+
// Store state
|
|
2163
|
+
this.activeRanges.set(key, {
|
|
2164
|
+
state,
|
|
2165
|
+
elements
|
|
2166
|
+
});
|
|
2167
|
+
|
|
2168
|
+
// Initial update
|
|
2169
|
+
this.updateInputUI(key);
|
|
2170
|
+
this.afs.logger.info(`Input range added for ${key}`);
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
/**
|
|
2174
|
+
* Calculate min and max values from items
|
|
2175
|
+
* @private
|
|
2176
|
+
*/
|
|
2177
|
+
calculateMinMax(key) {
|
|
2178
|
+
try {
|
|
2179
|
+
const values = Array.from(this.afs.items).map(item => {
|
|
2180
|
+
if (!item || !item.dataset || !item.dataset[key]) {
|
|
2181
|
+
return null;
|
|
2182
|
+
}
|
|
2183
|
+
const value = parseFloat(item.dataset[key]);
|
|
2184
|
+
return isNaN(value) ? null : value;
|
|
2185
|
+
}).filter(value => value !== null);
|
|
2186
|
+
if (values.length === 0) {
|
|
2187
|
+
return {
|
|
2188
|
+
min: 0,
|
|
2189
|
+
max: 100
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
2192
|
+
return {
|
|
2193
|
+
min: Math.min(...values),
|
|
2194
|
+
max: Math.max(...values)
|
|
2195
|
+
};
|
|
2196
|
+
} catch (error) {
|
|
2197
|
+
this.afs.logger.error('Error calculating range:', error);
|
|
2198
|
+
return {
|
|
2199
|
+
min: 0,
|
|
2200
|
+
max: 100
|
|
2201
|
+
};
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2205
|
+
/**
|
|
2206
|
+
* Create input elements
|
|
2207
|
+
* @private
|
|
2208
|
+
*/
|
|
2209
|
+
/**
|
|
2210
|
+
* Create input elements
|
|
2211
|
+
* @private
|
|
2212
|
+
*/
|
|
2213
|
+
createInputElements(label) {
|
|
2214
|
+
const container = document.createElement('div');
|
|
2215
|
+
container.className = 'afs-input-range-container';
|
|
2216
|
+
if (label) {
|
|
2217
|
+
const labelElement = document.createElement('div');
|
|
2218
|
+
labelElement.className = 'afs-input-range-label';
|
|
2219
|
+
labelElement.textContent = label;
|
|
2220
|
+
container.appendChild(labelElement);
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
// Min input wrapper
|
|
2224
|
+
const minWrapper = document.createElement('div');
|
|
2225
|
+
minWrapper.className = 'afs-input-wrapper';
|
|
2226
|
+
const minLabel = document.createElement('label');
|
|
2227
|
+
minLabel.textContent = 'Min';
|
|
2228
|
+
minLabel.className = 'afs-input-label';
|
|
2229
|
+
const minInput = document.createElement('input');
|
|
2230
|
+
minInput.type = 'number';
|
|
2231
|
+
minInput.className = 'afs-input min';
|
|
2232
|
+
minWrapper.appendChild(minLabel);
|
|
2233
|
+
minWrapper.appendChild(minInput);
|
|
2234
|
+
|
|
2235
|
+
// Max input wrapper
|
|
2236
|
+
const maxWrapper = document.createElement('div');
|
|
2237
|
+
maxWrapper.className = 'afs-input-wrapper';
|
|
2238
|
+
const maxLabel = document.createElement('label');
|
|
2239
|
+
maxLabel.textContent = 'Max';
|
|
2240
|
+
maxLabel.className = 'afs-input-label';
|
|
2241
|
+
const maxInput = document.createElement('input');
|
|
2242
|
+
maxInput.type = 'number';
|
|
2243
|
+
maxInput.className = 'afs-input max';
|
|
2244
|
+
maxWrapper.appendChild(maxLabel);
|
|
2245
|
+
maxWrapper.appendChild(maxInput);
|
|
2246
|
+
container.appendChild(minWrapper);
|
|
2247
|
+
container.appendChild(maxWrapper);
|
|
2248
|
+
return {
|
|
2249
|
+
container,
|
|
2250
|
+
minInput,
|
|
2251
|
+
maxInput
|
|
2252
|
+
};
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2255
|
+
/**
|
|
2256
|
+
* Initialize input range state
|
|
2257
|
+
* @private
|
|
2258
|
+
*/
|
|
2259
|
+
initializeState(min, max, step) {
|
|
2260
|
+
return {
|
|
2261
|
+
min,
|
|
2262
|
+
max,
|
|
2263
|
+
step,
|
|
2264
|
+
currentMin: min,
|
|
2265
|
+
currentMax: max
|
|
2266
|
+
};
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
/**
|
|
2270
|
+
* Append elements to container
|
|
2271
|
+
* @private
|
|
2272
|
+
*/
|
|
2273
|
+
appendElements(container, elements) {
|
|
2274
|
+
container.appendChild(elements.container);
|
|
2275
|
+
}
|
|
2276
|
+
|
|
2277
|
+
/**
|
|
2278
|
+
* Setup event handlers
|
|
2279
|
+
* @private
|
|
2280
|
+
*/
|
|
2281
|
+
setupEventHandlers(elements, state, key) {
|
|
2282
|
+
const {
|
|
2283
|
+
minInput,
|
|
2284
|
+
maxInput
|
|
2285
|
+
} = elements;
|
|
2286
|
+
const handleInputChange = debounce(() => {
|
|
2287
|
+
const minValue = parseFloat(minInput.value);
|
|
2288
|
+
const maxValue = parseFloat(maxInput.value);
|
|
2289
|
+
if (!isNaN(minValue) && !isNaN(maxValue)) {
|
|
2290
|
+
state.currentMin = Math.max(state.min, Math.min(maxValue, minValue));
|
|
2291
|
+
state.currentMax = Math.min(state.max, Math.max(minValue, maxValue));
|
|
2292
|
+
this.updateInputUI(key);
|
|
2293
|
+
this.applyFilter(key);
|
|
2294
|
+
}
|
|
2295
|
+
}, 300);
|
|
2296
|
+
minInput.addEventListener('input', handleInputChange);
|
|
2297
|
+
maxInput.addEventListener('input', handleInputChange);
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2300
|
+
/**
|
|
2301
|
+
* Update input UI
|
|
2302
|
+
* @private
|
|
2303
|
+
*/
|
|
2304
|
+
updateInputUI(key) {
|
|
2305
|
+
try {
|
|
2306
|
+
const {
|
|
2307
|
+
state,
|
|
2308
|
+
elements
|
|
2309
|
+
} = this.activeRanges.get(key);
|
|
2310
|
+
const {
|
|
2311
|
+
minInput,
|
|
2312
|
+
maxInput
|
|
2313
|
+
} = elements;
|
|
2314
|
+
|
|
2315
|
+
// Set constraints
|
|
2316
|
+
minInput.min = state.min;
|
|
2317
|
+
minInput.max = state.max;
|
|
2318
|
+
minInput.step = state.step;
|
|
2319
|
+
maxInput.min = state.min;
|
|
2320
|
+
maxInput.max = state.max;
|
|
2321
|
+
maxInput.step = state.step;
|
|
2322
|
+
|
|
2323
|
+
// Set current values
|
|
2324
|
+
minInput.value = state.currentMin;
|
|
2325
|
+
maxInput.value = state.currentMax;
|
|
2326
|
+
} catch (error) {
|
|
2327
|
+
this.afs.logger.error('Error updating input UI:', error);
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
/**
|
|
2332
|
+
* Apply filter
|
|
2333
|
+
* @private
|
|
2334
|
+
*/
|
|
2335
|
+
applyFilter(key) {
|
|
2336
|
+
this.afs.logger.info(`Applying input filter for ${key}`);
|
|
2337
|
+
const {
|
|
2338
|
+
state
|
|
2339
|
+
} = this.activeRanges.get(key);
|
|
2340
|
+
this.afs.items.forEach(item => {
|
|
2341
|
+
try {
|
|
2342
|
+
if (!item || !item.dataset || !item.dataset[key]) {
|
|
2343
|
+
this.afs.hideItem(item);
|
|
2344
|
+
return;
|
|
2345
|
+
}
|
|
2346
|
+
const itemValue = parseFloat(item.dataset[key]);
|
|
2347
|
+
if (isNaN(itemValue)) {
|
|
2348
|
+
this.afs.hideItem(item);
|
|
2349
|
+
return;
|
|
2350
|
+
}
|
|
2351
|
+
if (itemValue >= state.currentMin && itemValue <= state.currentMax) {
|
|
2352
|
+
this.afs.showItem(item);
|
|
2353
|
+
} else {
|
|
2354
|
+
this.afs.hideItem(item);
|
|
2355
|
+
}
|
|
2356
|
+
} catch (error) {
|
|
2357
|
+
this.afs.logger.error('Error filtering item:', error);
|
|
2358
|
+
this.afs.hideItem(item);
|
|
2359
|
+
}
|
|
2360
|
+
});
|
|
2361
|
+
this.afs.updateCounter();
|
|
2362
|
+
this.afs.urlManager.updateURL();
|
|
2363
|
+
this.afs.emit('inputRangeFilter', {
|
|
2364
|
+
key,
|
|
2365
|
+
min: state.currentMin,
|
|
2366
|
+
max: state.currentMax
|
|
2367
|
+
});
|
|
2368
|
+
}
|
|
2369
|
+
|
|
2370
|
+
/**
|
|
2371
|
+
* Get current range values
|
|
2372
|
+
* @param {string} key - Range key
|
|
2373
|
+
* @returns {Object} Current range values
|
|
2374
|
+
*/
|
|
2375
|
+
getRange(key) {
|
|
2376
|
+
const range = this.activeRanges.get(key);
|
|
2377
|
+
if (!range) return null;
|
|
2378
|
+
return {
|
|
2379
|
+
min: range.state.currentMin,
|
|
2380
|
+
max: range.state.currentMax
|
|
2381
|
+
};
|
|
2382
|
+
}
|
|
2383
|
+
|
|
2384
|
+
/**
|
|
2385
|
+
* Set range values
|
|
2386
|
+
* @param {string} key - Range key
|
|
2387
|
+
* @param {number} min - Minimum value
|
|
2388
|
+
* @param {number} max - Maximum value
|
|
2389
|
+
*/
|
|
2390
|
+
setRange(key, min, max) {
|
|
2391
|
+
const range = this.activeRanges.get(key);
|
|
2392
|
+
if (!range) return;
|
|
2393
|
+
range.state.currentMin = min;
|
|
2394
|
+
range.state.currentMax = max;
|
|
2395
|
+
this.updateInputUI(key);
|
|
2396
|
+
this.applyFilter(key);
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
/**
|
|
2400
|
+
* Remove input range
|
|
2401
|
+
* @param {string} key - Range key
|
|
2402
|
+
*/
|
|
2403
|
+
removeInputRange(key) {
|
|
2404
|
+
const range = this.activeRanges.get(key);
|
|
2405
|
+
if (!range) return;
|
|
2406
|
+
range.elements.container.remove();
|
|
2407
|
+
this.activeRanges.delete(key);
|
|
2408
|
+
this.afs.logger.info(`Input range removed for ${key}`);
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
|
|
2007
2412
|
/**
|
|
2008
2413
|
* @fileoverview Search functionality for AFS
|
|
2009
2414
|
*/
|
|
@@ -3172,6 +3577,9 @@ class URLManager {
|
|
|
3172
3577
|
currentPage,
|
|
3173
3578
|
itemsPerPage
|
|
3174
3579
|
} = state.pagination;
|
|
3580
|
+
if (!this.afs.options.get('pagination.enabled')) {
|
|
3581
|
+
return;
|
|
3582
|
+
}
|
|
3175
3583
|
if (currentPage > 1) {
|
|
3176
3584
|
params.set('page', currentPage.toString());
|
|
3177
3585
|
}
|
|
@@ -3464,6 +3872,7 @@ class RangeFilter {
|
|
|
3464
3872
|
constructor(afs) {
|
|
3465
3873
|
this.afs = afs;
|
|
3466
3874
|
this.activeRanges = new Map();
|
|
3875
|
+
this.options = this.afs.options.get("slider");
|
|
3467
3876
|
if (!this.afs.styleManager) {
|
|
3468
3877
|
this.afs.styleManager = new StyleManager(this.afs.options);
|
|
3469
3878
|
}
|
|
@@ -3578,14 +3987,14 @@ class RangeFilter {
|
|
|
3578
3987
|
*/
|
|
3579
3988
|
createSliderElements(histogramData, sliderUiOptions) {
|
|
3580
3989
|
const styles = this.afs.options.get("styles") || this.afs.styleManager.defaultStyles;
|
|
3581
|
-
const sliderStyles = styles.slider || this.afs.styleManager.defaultStyles.slider;
|
|
3582
3990
|
const colors = styles.colors || this.afs.styleManager.defaultStyles.colors;
|
|
3991
|
+
const sliderOptions = this.afs.options.get("slider") || {};
|
|
3583
3992
|
const container = document.createElement("div");
|
|
3584
|
-
container.className = "
|
|
3993
|
+
container.className = "afs-range-container";
|
|
3585
3994
|
const slider = document.createElement("div");
|
|
3586
|
-
slider.className =
|
|
3995
|
+
slider.className = sliderOptions.containerClass;
|
|
3587
3996
|
const track = document.createElement("div");
|
|
3588
|
-
track.className =
|
|
3997
|
+
track.className = sliderOptions.trackClass;
|
|
3589
3998
|
|
|
3590
3999
|
// Only add histogram if enabled in the slider-specific options
|
|
3591
4000
|
if (sliderUiOptions?.showHistogram && histogramData?.counts?.length > 0) {
|
|
@@ -3593,15 +4002,15 @@ class RangeFilter {
|
|
|
3593
4002
|
slider.appendChild(histogram);
|
|
3594
4003
|
}
|
|
3595
4004
|
const selectedRange = document.createElement("div");
|
|
3596
|
-
selectedRange.className =
|
|
4005
|
+
selectedRange.className = sliderOptions.selectedClass;
|
|
3597
4006
|
const minThumb = document.createElement("div");
|
|
3598
|
-
minThumb.className =
|
|
4007
|
+
minThumb.className = sliderOptions.thumbClass;
|
|
3599
4008
|
const maxThumb = document.createElement("div");
|
|
3600
|
-
maxThumb.className =
|
|
4009
|
+
maxThumb.className = sliderOptions.thumbClass;
|
|
3601
4010
|
const minValue = document.createElement("div");
|
|
3602
|
-
minValue.className =
|
|
4011
|
+
minValue.className = sliderOptions.valueClass;
|
|
3603
4012
|
const maxValue = document.createElement("div");
|
|
3604
|
-
maxValue.className =
|
|
4013
|
+
maxValue.className = sliderOptions.valueClass;
|
|
3605
4014
|
|
|
3606
4015
|
// Build the slider
|
|
3607
4016
|
slider.appendChild(track);
|
|
@@ -4321,7 +4730,7 @@ class DateFilter {
|
|
|
4321
4730
|
*/
|
|
4322
4731
|
|
|
4323
4732
|
// Version
|
|
4324
|
-
const VERSION = '1.0.
|
|
4733
|
+
const VERSION = '1.0.9';
|
|
4325
4734
|
class AFS extends EventEmitter {
|
|
4326
4735
|
/**
|
|
4327
4736
|
* @param {Object} options - Configuration options
|
|
@@ -4384,6 +4793,7 @@ class AFS extends EventEmitter {
|
|
|
4384
4793
|
this.urlManager = new URLManager(this);
|
|
4385
4794
|
this.dateFilter = new DateFilter(this);
|
|
4386
4795
|
this.pagination = new Pagination(this);
|
|
4796
|
+
this.inputRangeFilter = new InputRangeFilter(this);
|
|
4387
4797
|
|
|
4388
4798
|
// Apply styles
|
|
4389
4799
|
this.styleManager.applyStyles();
|