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.js
CHANGED
|
@@ -145,68 +145,111 @@
|
|
|
145
145
|
*/
|
|
146
146
|
static defaults = {
|
|
147
147
|
// Selectors
|
|
148
|
-
containerSelector:
|
|
149
|
-
itemSelector:
|
|
150
|
-
filterButtonSelector:
|
|
151
|
-
searchInputSelector:
|
|
152
|
-
counterSelector:
|
|
148
|
+
containerSelector: ".afs-filter-container",
|
|
149
|
+
itemSelector: ".afs-filter-item",
|
|
150
|
+
filterButtonSelector: ".afs-btn-filter",
|
|
151
|
+
searchInputSelector: ".afs-filter-search",
|
|
152
|
+
counterSelector: ".afs-filter-counter",
|
|
153
153
|
// Classes
|
|
154
|
-
activeClass:
|
|
155
|
-
hiddenClass:
|
|
156
|
-
// Animation
|
|
157
|
-
animationDuration: 300,
|
|
158
|
-
animationType: 'fade',
|
|
159
|
-
animationEasing: 'ease-out',
|
|
154
|
+
activeClass: "active",
|
|
155
|
+
hiddenClass: "hidden",
|
|
160
156
|
// Filtering
|
|
161
|
-
filterMode:
|
|
162
|
-
searchKeys: [
|
|
157
|
+
filterMode: "OR",
|
|
158
|
+
searchKeys: ["title"],
|
|
163
159
|
debounceTime: 300,
|
|
164
160
|
// Debug
|
|
165
161
|
debug: false,
|
|
166
|
-
logLevel:
|
|
162
|
+
logLevel: "info",
|
|
167
163
|
// Date handling
|
|
168
|
-
dateFormat:
|
|
164
|
+
dateFormat: "YYYY-MM-DD",
|
|
169
165
|
counter: {
|
|
170
|
-
template:
|
|
166
|
+
template: "Showing {visible} of {total}",
|
|
171
167
|
showFiltered: true,
|
|
172
|
-
filteredTemplate:
|
|
173
|
-
noResultsTemplate:
|
|
168
|
+
filteredTemplate: "({filtered} filtered)",
|
|
169
|
+
noResultsTemplate: "No items found",
|
|
174
170
|
formatter: num => num.toLocaleString()
|
|
175
171
|
},
|
|
176
172
|
// Styles
|
|
177
173
|
styles: {
|
|
178
174
|
slider: {
|
|
179
|
-
class: 'afs-range-slider',
|
|
180
|
-
trackClass: 'afs-range-track',
|
|
181
|
-
thumbClass: 'afs-range-thumb',
|
|
182
|
-
valueClass: 'afs-range-value',
|
|
183
|
-
selectedClass: 'afs-range-selected',
|
|
184
175
|
// Add new UI options
|
|
185
176
|
ui: {
|
|
186
177
|
showHistogram: false,
|
|
187
|
-
bins: 10
|
|
178
|
+
bins: 10,
|
|
179
|
+
// Number of bins for histogram
|
|
180
|
+
track: {
|
|
181
|
+
radius: "0",
|
|
182
|
+
// Button radius
|
|
183
|
+
background: "#e5e7eb" // Track color
|
|
184
|
+
},
|
|
185
|
+
thumb: {
|
|
186
|
+
radius: "50%",
|
|
187
|
+
// Button radius
|
|
188
|
+
size: "16px",
|
|
189
|
+
// Button size
|
|
190
|
+
background: "#000" // Button color
|
|
191
|
+
},
|
|
192
|
+
histogram: {
|
|
193
|
+
background: "#e5e7eb",
|
|
194
|
+
// Histogram background
|
|
195
|
+
bar: {
|
|
196
|
+
background: "#000" // Bar color
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
pagination: {
|
|
202
|
+
ui: {
|
|
203
|
+
button: {
|
|
204
|
+
background: "transparent",
|
|
205
|
+
border: "1px solid #000",
|
|
206
|
+
borderRadius: "4px",
|
|
207
|
+
padding: "8px 12px",
|
|
208
|
+
color: "#000",
|
|
209
|
+
active: {
|
|
210
|
+
background: "#000",
|
|
211
|
+
color: "#fff"
|
|
212
|
+
},
|
|
213
|
+
hover: {
|
|
214
|
+
background: "#000",
|
|
215
|
+
color: "#fff"
|
|
216
|
+
}
|
|
217
|
+
}
|
|
188
218
|
}
|
|
189
219
|
},
|
|
190
220
|
colors: {
|
|
191
|
-
primary:
|
|
192
|
-
background:
|
|
193
|
-
text:
|
|
194
|
-
histogram: '#e5e7eb',
|
|
195
|
-
// For histogram bars
|
|
196
|
-
histogramActive: '#000' // For active histogram bars
|
|
221
|
+
primary: "#000",
|
|
222
|
+
background: "#e5e7eb",
|
|
223
|
+
text: "#000"
|
|
197
224
|
}
|
|
198
225
|
},
|
|
226
|
+
// Slider
|
|
227
|
+
slider: {
|
|
228
|
+
containerClass: "afs-range-slider",
|
|
229
|
+
trackClass: "afs-range-track",
|
|
230
|
+
thumbClass: "afs-range-thumb",
|
|
231
|
+
valueClass: "afs-range-value",
|
|
232
|
+
selectedClass: "afs-range-selected"
|
|
233
|
+
},
|
|
199
234
|
// Pagination
|
|
200
235
|
pagination: {
|
|
201
236
|
enabled: false,
|
|
202
237
|
itemsPerPage: 10,
|
|
203
|
-
container:
|
|
204
|
-
pageButtonClass:
|
|
205
|
-
activePageClass:
|
|
206
|
-
containerClass:
|
|
238
|
+
container: ".afs-pagination-container",
|
|
239
|
+
pageButtonClass: "afs-page-button",
|
|
240
|
+
activePageClass: "afs-page-active",
|
|
241
|
+
containerClass: "afs-pagination",
|
|
207
242
|
scrollToTop: false,
|
|
208
243
|
scrollOffset: 50,
|
|
209
|
-
scrollBehavior:
|
|
244
|
+
scrollBehavior: "smooth" // or 'auto' for instant scroll
|
|
245
|
+
},
|
|
246
|
+
// Animation
|
|
247
|
+
animation: {
|
|
248
|
+
type: "fade",
|
|
249
|
+
duration: 300,
|
|
250
|
+
easing: "ease-out",
|
|
251
|
+
inClass: "afs-animation-enter",
|
|
252
|
+
outClass: "afs-animation-leave"
|
|
210
253
|
}
|
|
211
254
|
};
|
|
212
255
|
constructor() {
|
|
@@ -244,9 +287,9 @@
|
|
|
244
287
|
...target
|
|
245
288
|
};
|
|
246
289
|
for (const key in source) {
|
|
247
|
-
if (source[key] !== null && typeof source[key] ===
|
|
290
|
+
if (source[key] !== null && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
248
291
|
// If the key doesn't exist in target or isn't an object, create/override it
|
|
249
|
-
if (!target[key] || typeof target[key] !==
|
|
292
|
+
if (!target[key] || typeof target[key] !== "object") {
|
|
250
293
|
result[key] = {};
|
|
251
294
|
}
|
|
252
295
|
// Recursively merge nested objects
|
|
@@ -266,37 +309,37 @@
|
|
|
266
309
|
*/
|
|
267
310
|
validate() {
|
|
268
311
|
// Required selectors
|
|
269
|
-
const requiredSelectors = [
|
|
312
|
+
const requiredSelectors = ["containerSelector", "itemSelector"];
|
|
270
313
|
for (const selector of requiredSelectors) {
|
|
271
|
-
if (typeof this.options[selector] !==
|
|
314
|
+
if (typeof this.options[selector] !== "string") {
|
|
272
315
|
throw new Error(`${selector} must be a string`);
|
|
273
316
|
}
|
|
274
317
|
}
|
|
275
318
|
|
|
276
319
|
// Animation duration
|
|
277
|
-
if (typeof this.options.
|
|
278
|
-
throw new Error(
|
|
320
|
+
if (typeof this.options.animation.duration !== "number" || this.options.animation.duration < 0) {
|
|
321
|
+
throw new Error("animationDuration must be a positive number");
|
|
279
322
|
}
|
|
280
323
|
|
|
281
324
|
// Filter mode
|
|
282
|
-
if (![
|
|
325
|
+
if (!["OR", "AND"].includes(this.options.filterMode.toUpperCase())) {
|
|
283
326
|
throw new Error('filterMode must be either "OR" or "AND"');
|
|
284
327
|
}
|
|
285
328
|
|
|
286
329
|
// Search keys
|
|
287
330
|
if (!Array.isArray(this.options.searchKeys) || this.options.searchKeys.length === 0) {
|
|
288
|
-
throw new Error(
|
|
331
|
+
throw new Error("searchKeys must be a non-empty array");
|
|
289
332
|
}
|
|
290
333
|
|
|
291
334
|
// Counter validation
|
|
292
335
|
if (this.options.counter) {
|
|
293
|
-
if (typeof this.options.counter.template !==
|
|
294
|
-
throw new Error(
|
|
336
|
+
if (typeof this.options.counter.template !== "string") {
|
|
337
|
+
throw new Error("counter.template must be a string");
|
|
295
338
|
}
|
|
296
|
-
if (typeof this.options.counter.showFiltered !==
|
|
339
|
+
if (typeof this.options.counter.showFiltered !== "boolean") {
|
|
297
340
|
this.options.counter.showFiltered = true; // Set default
|
|
298
341
|
}
|
|
299
|
-
if (typeof this.options.counter.formatter !==
|
|
342
|
+
if (typeof this.options.counter.formatter !== "function") {
|
|
300
343
|
this.options.counter.formatter = num => num.toLocaleString(); // Set default
|
|
301
344
|
}
|
|
302
345
|
} else {
|
|
@@ -312,7 +355,7 @@
|
|
|
312
355
|
* @returns {any} Option value
|
|
313
356
|
*/
|
|
314
357
|
get(path) {
|
|
315
|
-
return path.split(
|
|
358
|
+
return path.split(".").reduce((obj, key) => obj?.[key], this.options);
|
|
316
359
|
}
|
|
317
360
|
|
|
318
361
|
/**
|
|
@@ -321,7 +364,7 @@
|
|
|
321
364
|
* @param {any} value - New value
|
|
322
365
|
*/
|
|
323
366
|
set(path, value) {
|
|
324
|
-
const parts = path.split(
|
|
367
|
+
const parts = path.split(".");
|
|
325
368
|
const last = parts.pop();
|
|
326
369
|
const target = parts.reduce((obj, key) => {
|
|
327
370
|
if (!(key in obj)) obj[key] = {};
|
|
@@ -521,24 +564,6 @@
|
|
|
521
564
|
constructor(options) {
|
|
522
565
|
this.options = options;
|
|
523
566
|
this.styleElement = null;
|
|
524
|
-
this.defaultStyles = {
|
|
525
|
-
slider: {
|
|
526
|
-
class: "afs-range-slider",
|
|
527
|
-
trackClass: "afs-range-track",
|
|
528
|
-
thumbClass: "afs-range-thumb",
|
|
529
|
-
valueClass: "afs-range-value",
|
|
530
|
-
selectedClass: "afs-range-selected"
|
|
531
|
-
},
|
|
532
|
-
colors: {
|
|
533
|
-
primary: "#000",
|
|
534
|
-
background: "#ddd",
|
|
535
|
-
text: "#000"
|
|
536
|
-
},
|
|
537
|
-
animation: {
|
|
538
|
-
duration: "300ms",
|
|
539
|
-
type: "ease-out"
|
|
540
|
-
}
|
|
541
|
-
};
|
|
542
567
|
}
|
|
543
568
|
|
|
544
569
|
/**
|
|
@@ -548,11 +573,11 @@
|
|
|
548
573
|
*/
|
|
549
574
|
createBaseStyles() {
|
|
550
575
|
const hiddenClass = this.options.get("hiddenClass") || "hidden";
|
|
551
|
-
const itemSelector = this.options.get("itemSelector") || ".filter-item";
|
|
552
|
-
const filterButtonSelector = this.options.get("filterButtonSelector") || ".btn-filter";
|
|
576
|
+
const itemSelector = this.options.get("itemSelector") || ".afs-filter-item";
|
|
577
|
+
const filterButtonSelector = this.options.get("filterButtonSelector") || ".afs-btn-filter";
|
|
553
578
|
const activeClass = this.options.get("activeClass") || "active";
|
|
554
|
-
const animationDuration = this.options.get("
|
|
555
|
-
const animationEasing = this.options.get("
|
|
579
|
+
const animationDuration = this.options.get("animation.duration") || '300ms';
|
|
580
|
+
const animationEasing = this.options.get("animation.easing") || 'ease-out';
|
|
556
581
|
return `
|
|
557
582
|
.${hiddenClass} {
|
|
558
583
|
display: none !important;
|
|
@@ -590,12 +615,18 @@
|
|
|
590
615
|
* @returns {string} CSS styles
|
|
591
616
|
*/
|
|
592
617
|
createRangeStyles() {
|
|
593
|
-
const styles = this.options.get("styles")
|
|
594
|
-
const
|
|
595
|
-
const
|
|
618
|
+
const styles = this.options.get("styles");
|
|
619
|
+
const sliderOptions = this.options.get("slider") || {};
|
|
620
|
+
const sliderStyles = styles.slider;
|
|
621
|
+
const colors = styles.colors;
|
|
622
|
+
const containerClass = sliderOptions.containerClass || "afs-range-slider";
|
|
623
|
+
const trackClass = sliderOptions.trackClass || "afs-range-track";
|
|
624
|
+
const thumbClass = sliderOptions.thumbClass || "afs-range-thumb";
|
|
625
|
+
const valueClass = sliderOptions.valueClass || "afs-range-value";
|
|
626
|
+
const selectedClass = sliderOptions.selectedClass || "afs-range-selected";
|
|
596
627
|
return `
|
|
597
628
|
/* Range Slider Styles */
|
|
598
|
-
.${
|
|
629
|
+
.${containerClass} {
|
|
599
630
|
position: relative;
|
|
600
631
|
width: auto;
|
|
601
632
|
height: 40px;
|
|
@@ -603,29 +634,29 @@
|
|
|
603
634
|
padding: 0 8px;
|
|
604
635
|
}
|
|
605
636
|
|
|
606
|
-
.${
|
|
637
|
+
.${trackClass} {
|
|
607
638
|
position: absolute;
|
|
608
639
|
top: 50%;
|
|
609
640
|
transform: translateY(-50%);
|
|
610
641
|
width: 100%;
|
|
611
642
|
height: 4px;
|
|
612
|
-
background: ${colors.background};
|
|
613
|
-
border-radius:
|
|
643
|
+
background: ${sliderStyles.ui.track.background || colors.background};
|
|
644
|
+
border-radius: ${sliderStyles.ui.track.radius || "0"};
|
|
614
645
|
}
|
|
615
646
|
|
|
616
|
-
.${
|
|
647
|
+
.${thumbClass} {
|
|
617
648
|
position: absolute;
|
|
618
649
|
top: 50%;
|
|
619
|
-
width: 16px;
|
|
620
|
-
height: 16px;
|
|
621
|
-
background: ${colors.primary};
|
|
622
|
-
border-radius: 50
|
|
650
|
+
width: ${sliderStyles.ui.thumb.size || "16px"};
|
|
651
|
+
height: ${sliderStyles.ui.thumb.size || "16px"};
|
|
652
|
+
background: ${sliderStyles.ui.thumb.background || colors.primary};
|
|
653
|
+
border-radius: ${sliderStyles.ui.thumb.radius || "50%"};
|
|
623
654
|
transform: translate(-50%, -50%);
|
|
624
655
|
cursor: pointer;
|
|
625
656
|
z-index: 2;
|
|
626
657
|
}
|
|
627
658
|
|
|
628
|
-
.${
|
|
659
|
+
.${valueClass} {
|
|
629
660
|
position: absolute;
|
|
630
661
|
top: -20px;
|
|
631
662
|
transform: translateX(-50%);
|
|
@@ -633,7 +664,7 @@
|
|
|
633
664
|
color: ${colors.text};
|
|
634
665
|
}
|
|
635
666
|
|
|
636
|
-
.${
|
|
667
|
+
.${selectedClass} {
|
|
637
668
|
position: absolute;
|
|
638
669
|
height: 4px;
|
|
639
670
|
background: ${colors.primary};
|
|
@@ -656,13 +687,13 @@
|
|
|
656
687
|
|
|
657
688
|
.afs-histogram-bar {
|
|
658
689
|
flex: 1;
|
|
659
|
-
background-color: ${colors.background};
|
|
690
|
+
background-color: ${sliderStyles.ui.histogram.background || colors.background};
|
|
660
691
|
min-height: 4px;
|
|
661
692
|
transition: background-color 0.2s ease;
|
|
662
693
|
}
|
|
663
694
|
|
|
664
695
|
.afs-histogram-bar.active {
|
|
665
|
-
background-color: ${colors.primary};
|
|
696
|
+
background-color: ${sliderStyles.ui.histogram.bar.background || colors.primary};
|
|
666
697
|
}
|
|
667
698
|
`;
|
|
668
699
|
}
|
|
@@ -673,7 +704,7 @@
|
|
|
673
704
|
* @returns {string} CSS styles
|
|
674
705
|
*/
|
|
675
706
|
createDateStyles() {
|
|
676
|
-
const colors =
|
|
707
|
+
const colors = this.options.get("styles").colors;
|
|
677
708
|
return `
|
|
678
709
|
.afs-date-range-container {
|
|
679
710
|
display: flex;
|
|
@@ -710,6 +741,49 @@
|
|
|
710
741
|
`;
|
|
711
742
|
}
|
|
712
743
|
|
|
744
|
+
/**
|
|
745
|
+
* Create date filter styles
|
|
746
|
+
* @private
|
|
747
|
+
* @returns {string} CSS styles
|
|
748
|
+
*/
|
|
749
|
+
createInputRangeStyles() {
|
|
750
|
+
const colors = this.options.get("styles").colors;
|
|
751
|
+
return `
|
|
752
|
+
.afs-input-range-container {
|
|
753
|
+
display: flex;
|
|
754
|
+
flex-wrap: wrap;
|
|
755
|
+
gap: 1rem;
|
|
756
|
+
margin: 10px 0;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
.afs-input-wrapper {
|
|
760
|
+
flex: 1;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
.afs-input-label {
|
|
764
|
+
display: block;
|
|
765
|
+
font-size: 0.875rem;
|
|
766
|
+
color: ${colors.text};
|
|
767
|
+
margin-bottom: 0.5rem;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
.afs-input {
|
|
771
|
+
width: 100%;
|
|
772
|
+
padding: 0.5rem;
|
|
773
|
+
border: 1px solid ${colors.background};
|
|
774
|
+
border-radius: 0.25rem;
|
|
775
|
+
font-size: 0.875rem;
|
|
776
|
+
color: ${colors.text};
|
|
777
|
+
transition: border-color 0.2s ease;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
.afs-input:focus {
|
|
781
|
+
outline: none;
|
|
782
|
+
border-color: ${colors.primary};
|
|
783
|
+
}
|
|
784
|
+
`;
|
|
785
|
+
}
|
|
786
|
+
|
|
713
787
|
/**
|
|
714
788
|
* Apply all styles
|
|
715
789
|
* @public
|
|
@@ -731,6 +805,9 @@
|
|
|
731
805
|
|
|
732
806
|
/* Search styles */
|
|
733
807
|
${this.createSearchStyles()}
|
|
808
|
+
|
|
809
|
+
/* Input range styles */
|
|
810
|
+
${this.createInputRangeStyles()}
|
|
734
811
|
`;
|
|
735
812
|
if (this.styleElement) {
|
|
736
813
|
this.styleElement.textContent = styles;
|
|
@@ -758,11 +835,13 @@
|
|
|
758
835
|
* @returns {string} CSS styles
|
|
759
836
|
*/
|
|
760
837
|
createPaginationStyles() {
|
|
838
|
+
const styles = this.options.get("styles");
|
|
761
839
|
const paginationOptions = this.options.get("pagination") || {};
|
|
762
|
-
const colors =
|
|
840
|
+
const colors = this.options.get("styles").colors;
|
|
763
841
|
const containerClass = paginationOptions.containerClass || "afs-pagination";
|
|
764
842
|
const buttonClass = paginationOptions.pageButtonClass || "afs-page-button";
|
|
765
843
|
const activeClass = paginationOptions.activePageClass || "afs-page-active";
|
|
844
|
+
const paginationStyles = styles.pagination;
|
|
766
845
|
return `
|
|
767
846
|
.${containerClass} {
|
|
768
847
|
display: flex;
|
|
@@ -772,23 +851,23 @@
|
|
|
772
851
|
}
|
|
773
852
|
|
|
774
853
|
.${buttonClass} {
|
|
775
|
-
padding: 8px 12px;
|
|
776
|
-
border: 1px solid
|
|
777
|
-
border-radius: 4px;
|
|
854
|
+
padding: ${paginationStyles.ui.button.padding || '8px 12px'};
|
|
855
|
+
border: ${paginationStyles.ui.button.border || '1px solid ' + colors.primary};
|
|
856
|
+
border-radius: ${paginationStyles.ui.button.borderRadius || '4px'};
|
|
778
857
|
cursor: pointer;
|
|
779
858
|
transition: all 200ms ease-out;
|
|
780
|
-
background: transparent;
|
|
781
|
-
color: ${colors.primary};
|
|
859
|
+
background: ${paginationStyles.ui.button.background || 'transparent'};
|
|
860
|
+
color: ${paginationStyles.ui.button.color || colors.primary};
|
|
782
861
|
}
|
|
783
862
|
|
|
784
863
|
.${buttonClass}:hover {
|
|
785
|
-
background: ${colors.primary};
|
|
786
|
-
color: white;
|
|
864
|
+
background: ${paginationStyles.ui.button.hover.background || colors.primary};
|
|
865
|
+
color: ${paginationStyles.ui.button.hover.color || 'white'};
|
|
787
866
|
}
|
|
788
867
|
|
|
789
868
|
.${buttonClass}.${activeClass} {
|
|
790
|
-
background: ${colors.primary};
|
|
791
|
-
color: white;
|
|
869
|
+
background: ${paginationStyles.ui.button.active.background || colors.primary};
|
|
870
|
+
color: ${paginationStyles.ui.button.active.color || 'white'};
|
|
792
871
|
}
|
|
793
872
|
|
|
794
873
|
.${buttonClass}:disabled {
|
|
@@ -805,7 +884,7 @@
|
|
|
805
884
|
*/
|
|
806
885
|
createSearchStyles() {
|
|
807
886
|
const searchClass = this.options.get("searchInputClass") || "afs-search";
|
|
808
|
-
const colors =
|
|
887
|
+
const colors = this.options.get("styles").colors;
|
|
809
888
|
return `
|
|
810
889
|
.${searchClass} {
|
|
811
890
|
padding: 8px;
|
|
@@ -1149,9 +1228,14 @@
|
|
|
1149
1228
|
}
|
|
1150
1229
|
applyShowAnimation(item) {
|
|
1151
1230
|
let animationType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'fade';
|
|
1152
|
-
const duration = this.options.get('
|
|
1231
|
+
const duration = this.options.get('animation.duration') || '300ms';
|
|
1153
1232
|
const animation = this.animations[animationType]?.in || this.animations.fade.in;
|
|
1233
|
+
|
|
1234
|
+
// Ensure display is set
|
|
1154
1235
|
item.style.display = 'block';
|
|
1236
|
+
item.style.opacity = '0'; // Start with opacity 0
|
|
1237
|
+
|
|
1238
|
+
// Apply animation in next frame
|
|
1155
1239
|
requestAnimationFrame(() => {
|
|
1156
1240
|
Object.assign(item.style, animation, {
|
|
1157
1241
|
transition: `opacity ${duration} ${animation.transitionTimingFunction}, transform ${duration} ${animation.transitionTimingFunction}`
|
|
@@ -1160,7 +1244,7 @@
|
|
|
1160
1244
|
}
|
|
1161
1245
|
applyHideAnimation(item) {
|
|
1162
1246
|
let animationType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'fade';
|
|
1163
|
-
const duration = this.options.get('
|
|
1247
|
+
const duration = this.options.get('animation.duration') || '300ms';
|
|
1164
1248
|
const animation = this.animations[animationType]?.out || this.animations.fade.out;
|
|
1165
1249
|
Object.assign(item.style, animation, {
|
|
1166
1250
|
transition: `opacity ${duration} ${animation.transitionTimingFunction}, transform ${duration} ${animation.transitionTimingFunction}`
|
|
@@ -1172,7 +1256,7 @@
|
|
|
1172
1256
|
item.addEventListener('transitionend', handleTransitionEnd);
|
|
1173
1257
|
}
|
|
1174
1258
|
setAnimation(animationType) {
|
|
1175
|
-
this.afs.options.set('
|
|
1259
|
+
this.afs.options.set('animation.type', animationType);
|
|
1176
1260
|
}
|
|
1177
1261
|
}
|
|
1178
1262
|
|
|
@@ -1319,26 +1403,39 @@
|
|
|
1319
1403
|
// Clear filter groups
|
|
1320
1404
|
this.filterGroups.clear();
|
|
1321
1405
|
|
|
1322
|
-
//
|
|
1323
|
-
const
|
|
1324
|
-
this.afs.state.setState("items.visible", visibleItems);
|
|
1406
|
+
// Create a promise to track animations
|
|
1407
|
+
const animationPromises = [];
|
|
1325
1408
|
|
|
1326
1409
|
// Show all items with animation
|
|
1327
1410
|
this.afs.items.forEach(item => {
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1411
|
+
const promise = new Promise(resolve => {
|
|
1412
|
+
item.classList.remove(this.afs.options.get('hiddenClass'));
|
|
1413
|
+
item.style.display = 'block'; // Ensure item is visible
|
|
1414
|
+
|
|
1415
|
+
requestAnimationFrame(() => {
|
|
1416
|
+
this.animation.applyShowAnimation(item, this.afs.options.get("animation.type"));
|
|
1417
|
+
// Resolve after animation duration
|
|
1418
|
+
setTimeout(resolve, this.afs.options.get("animation.duration") || 300);
|
|
1419
|
+
});
|
|
1331
1420
|
});
|
|
1421
|
+
animationPromises.push(promise);
|
|
1332
1422
|
});
|
|
1333
1423
|
|
|
1334
|
-
// Update
|
|
1335
|
-
this.afs.
|
|
1424
|
+
// Update state after all items are visible
|
|
1425
|
+
const visibleItems = new Set(this.afs.items);
|
|
1426
|
+
this.afs.state.setState("items.visible", visibleItems);
|
|
1336
1427
|
|
|
1337
|
-
//
|
|
1338
|
-
|
|
1428
|
+
// Wait for all animations to complete
|
|
1429
|
+
Promise.all(animationPromises).then(() => {
|
|
1430
|
+
// Update counter
|
|
1431
|
+
this.afs.updateCounter();
|
|
1339
1432
|
|
|
1340
|
-
|
|
1341
|
-
|
|
1433
|
+
// Update URL
|
|
1434
|
+
this.afs.urlManager.updateURL();
|
|
1435
|
+
|
|
1436
|
+
// Emit event
|
|
1437
|
+
this.afs.emit("filtersReset");
|
|
1438
|
+
});
|
|
1342
1439
|
}
|
|
1343
1440
|
|
|
1344
1441
|
/**
|
|
@@ -1409,60 +1506,64 @@
|
|
|
1409
1506
|
* @public
|
|
1410
1507
|
*/
|
|
1411
1508
|
applyFilters() {
|
|
1412
|
-
// Log active filters
|
|
1413
1509
|
const activeFilters = Array.from(this.activeFilters);
|
|
1414
1510
|
this.afs.logger.debug("Active filters:", activeFilters);
|
|
1415
|
-
this.afs.logger.debug("Applying filters");
|
|
1416
1511
|
const previouslyVisible = new Set(this.afs.state.getState().items.visible);
|
|
1417
1512
|
const visibleItems = new Set();
|
|
1418
1513
|
|
|
1419
|
-
// First
|
|
1514
|
+
// First determine visibility
|
|
1420
1515
|
this.afs.items.forEach(item => {
|
|
1421
1516
|
if (this.activeFilters.has("*") || this.itemMatchesFilters(item)) {
|
|
1422
1517
|
visibleItems.add(item);
|
|
1423
1518
|
}
|
|
1424
1519
|
});
|
|
1425
1520
|
|
|
1426
|
-
// Update state
|
|
1521
|
+
// Update state before animations
|
|
1427
1522
|
this.afs.state.setState("items.visible", visibleItems);
|
|
1428
1523
|
|
|
1429
|
-
//
|
|
1524
|
+
// Track animation promises
|
|
1525
|
+
const animationPromises = [];
|
|
1526
|
+
|
|
1527
|
+
// Apply animations
|
|
1430
1528
|
this.afs.items.forEach(item => {
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1529
|
+
const promise = new Promise(resolve => {
|
|
1530
|
+
if (visibleItems.has(item)) {
|
|
1531
|
+
// Show item
|
|
1532
|
+
item.classList.remove(this.afs.options.get('hiddenClass'));
|
|
1533
|
+
requestAnimationFrame(() => {
|
|
1534
|
+
this.animation.applyShowAnimation(item, this.afs.options.get("animation.type"));
|
|
1535
|
+
setTimeout(resolve, parseFloat(this.afs.options.get("animation.duration")) || 300);
|
|
1536
|
+
});
|
|
1537
|
+
} else {
|
|
1538
|
+
// Hide item
|
|
1539
|
+
requestAnimationFrame(() => {
|
|
1540
|
+
this.animation.applyHideAnimation(item, this.afs.options.get("animation.type"));
|
|
1541
|
+
setTimeout(resolve, parseFloat(this.afs.options.get("animation.duration")) || 300);
|
|
1542
|
+
});
|
|
1543
|
+
}
|
|
1544
|
+
});
|
|
1545
|
+
animationPromises.push(promise);
|
|
1444
1546
|
});
|
|
1445
1547
|
|
|
1446
|
-
//
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1548
|
+
// Handle completion
|
|
1549
|
+
Promise.all(animationPromises).then(() => {
|
|
1550
|
+
// Ensure visible items remain visible
|
|
1551
|
+
visibleItems.forEach(item => {
|
|
1552
|
+
item.style.display = 'block';
|
|
1553
|
+
item.style.opacity = '1';
|
|
1554
|
+
});
|
|
1453
1555
|
|
|
1454
|
-
// Update
|
|
1556
|
+
// Update UI
|
|
1455
1557
|
this.afs.updateCounter();
|
|
1456
|
-
|
|
1457
|
-
// Update URL
|
|
1458
1558
|
this.afs.urlManager.updateURL();
|
|
1459
|
-
|
|
1460
|
-
// Emit final event
|
|
1461
1559
|
this.afs.emit("filtersApplied", {
|
|
1462
1560
|
activeFilters,
|
|
1463
1561
|
visibleItems: visibleItems.size
|
|
1464
1562
|
});
|
|
1465
1563
|
});
|
|
1564
|
+
|
|
1565
|
+
// Emit visibility change events
|
|
1566
|
+
this.emitFilterEvents(previouslyVisible, visibleItems);
|
|
1466
1567
|
}
|
|
1467
1568
|
|
|
1468
1569
|
/**
|
|
@@ -2010,6 +2111,310 @@
|
|
|
2010
2111
|
};
|
|
2011
2112
|
}
|
|
2012
2113
|
|
|
2114
|
+
/**
|
|
2115
|
+
* @fileoverview Input range filter implementation for AFS
|
|
2116
|
+
*/
|
|
2117
|
+
|
|
2118
|
+
class InputRangeFilter {
|
|
2119
|
+
constructor(afs) {
|
|
2120
|
+
this.afs = afs;
|
|
2121
|
+
this.activeRanges = new Map();
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
/**
|
|
2125
|
+
* @typedef {Object} InputRangeOptions
|
|
2126
|
+
* @property {string} key - Data attribute key
|
|
2127
|
+
* @property {HTMLElement} container - Container element
|
|
2128
|
+
* @property {number} [min] - Minimum value
|
|
2129
|
+
* @property {number} [max] - Maximum value
|
|
2130
|
+
* @property {number} [step] - Step value
|
|
2131
|
+
* @property {string} [label] - Label for the input range
|
|
2132
|
+
*/
|
|
2133
|
+
|
|
2134
|
+
/**
|
|
2135
|
+
* Add input range filter
|
|
2136
|
+
* @param {InputRangeOptions} options - Input range options
|
|
2137
|
+
*/
|
|
2138
|
+
addInputRange(_ref) {
|
|
2139
|
+
let {
|
|
2140
|
+
key,
|
|
2141
|
+
container,
|
|
2142
|
+
min,
|
|
2143
|
+
max,
|
|
2144
|
+
step = 1,
|
|
2145
|
+
label = ''
|
|
2146
|
+
} = _ref;
|
|
2147
|
+
this.afs.logger.debug(`Adding input range for ${key}`);
|
|
2148
|
+
if (!container) {
|
|
2149
|
+
this.afs.logger.error('Container element required for input range');
|
|
2150
|
+
return;
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
// Calculate min/max if not provided
|
|
2154
|
+
const values = this.calculateMinMax(key);
|
|
2155
|
+
min = min ?? values.min;
|
|
2156
|
+
max = max ?? values.max;
|
|
2157
|
+
|
|
2158
|
+
// Create input elements
|
|
2159
|
+
const elements = this.createInputElements(label);
|
|
2160
|
+
const state = this.initializeState(min, max, step);
|
|
2161
|
+
|
|
2162
|
+
// Add elements to container
|
|
2163
|
+
this.appendElements(container, elements);
|
|
2164
|
+
|
|
2165
|
+
// Setup event handlers
|
|
2166
|
+
this.setupEventHandlers(elements, state, key);
|
|
2167
|
+
|
|
2168
|
+
// Store state
|
|
2169
|
+
this.activeRanges.set(key, {
|
|
2170
|
+
state,
|
|
2171
|
+
elements
|
|
2172
|
+
});
|
|
2173
|
+
|
|
2174
|
+
// Initial update
|
|
2175
|
+
this.updateInputUI(key);
|
|
2176
|
+
this.afs.logger.info(`Input range added for ${key}`);
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
/**
|
|
2180
|
+
* Calculate min and max values from items
|
|
2181
|
+
* @private
|
|
2182
|
+
*/
|
|
2183
|
+
calculateMinMax(key) {
|
|
2184
|
+
try {
|
|
2185
|
+
const values = Array.from(this.afs.items).map(item => {
|
|
2186
|
+
if (!item || !item.dataset || !item.dataset[key]) {
|
|
2187
|
+
return null;
|
|
2188
|
+
}
|
|
2189
|
+
const value = parseFloat(item.dataset[key]);
|
|
2190
|
+
return isNaN(value) ? null : value;
|
|
2191
|
+
}).filter(value => value !== null);
|
|
2192
|
+
if (values.length === 0) {
|
|
2193
|
+
return {
|
|
2194
|
+
min: 0,
|
|
2195
|
+
max: 100
|
|
2196
|
+
};
|
|
2197
|
+
}
|
|
2198
|
+
return {
|
|
2199
|
+
min: Math.min(...values),
|
|
2200
|
+
max: Math.max(...values)
|
|
2201
|
+
};
|
|
2202
|
+
} catch (error) {
|
|
2203
|
+
this.afs.logger.error('Error calculating range:', error);
|
|
2204
|
+
return {
|
|
2205
|
+
min: 0,
|
|
2206
|
+
max: 100
|
|
2207
|
+
};
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
/**
|
|
2212
|
+
* Create input elements
|
|
2213
|
+
* @private
|
|
2214
|
+
*/
|
|
2215
|
+
/**
|
|
2216
|
+
* Create input elements
|
|
2217
|
+
* @private
|
|
2218
|
+
*/
|
|
2219
|
+
createInputElements(label) {
|
|
2220
|
+
const container = document.createElement('div');
|
|
2221
|
+
container.className = 'afs-input-range-container';
|
|
2222
|
+
if (label) {
|
|
2223
|
+
const labelElement = document.createElement('div');
|
|
2224
|
+
labelElement.className = 'afs-input-range-label';
|
|
2225
|
+
labelElement.textContent = label;
|
|
2226
|
+
container.appendChild(labelElement);
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
// Min input wrapper
|
|
2230
|
+
const minWrapper = document.createElement('div');
|
|
2231
|
+
minWrapper.className = 'afs-input-wrapper';
|
|
2232
|
+
const minLabel = document.createElement('label');
|
|
2233
|
+
minLabel.textContent = 'Min';
|
|
2234
|
+
minLabel.className = 'afs-input-label';
|
|
2235
|
+
const minInput = document.createElement('input');
|
|
2236
|
+
minInput.type = 'number';
|
|
2237
|
+
minInput.className = 'afs-input min';
|
|
2238
|
+
minWrapper.appendChild(minLabel);
|
|
2239
|
+
minWrapper.appendChild(minInput);
|
|
2240
|
+
|
|
2241
|
+
// Max input wrapper
|
|
2242
|
+
const maxWrapper = document.createElement('div');
|
|
2243
|
+
maxWrapper.className = 'afs-input-wrapper';
|
|
2244
|
+
const maxLabel = document.createElement('label');
|
|
2245
|
+
maxLabel.textContent = 'Max';
|
|
2246
|
+
maxLabel.className = 'afs-input-label';
|
|
2247
|
+
const maxInput = document.createElement('input');
|
|
2248
|
+
maxInput.type = 'number';
|
|
2249
|
+
maxInput.className = 'afs-input max';
|
|
2250
|
+
maxWrapper.appendChild(maxLabel);
|
|
2251
|
+
maxWrapper.appendChild(maxInput);
|
|
2252
|
+
container.appendChild(minWrapper);
|
|
2253
|
+
container.appendChild(maxWrapper);
|
|
2254
|
+
return {
|
|
2255
|
+
container,
|
|
2256
|
+
minInput,
|
|
2257
|
+
maxInput
|
|
2258
|
+
};
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2261
|
+
/**
|
|
2262
|
+
* Initialize input range state
|
|
2263
|
+
* @private
|
|
2264
|
+
*/
|
|
2265
|
+
initializeState(min, max, step) {
|
|
2266
|
+
return {
|
|
2267
|
+
min,
|
|
2268
|
+
max,
|
|
2269
|
+
step,
|
|
2270
|
+
currentMin: min,
|
|
2271
|
+
currentMax: max
|
|
2272
|
+
};
|
|
2273
|
+
}
|
|
2274
|
+
|
|
2275
|
+
/**
|
|
2276
|
+
* Append elements to container
|
|
2277
|
+
* @private
|
|
2278
|
+
*/
|
|
2279
|
+
appendElements(container, elements) {
|
|
2280
|
+
container.appendChild(elements.container);
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2283
|
+
/**
|
|
2284
|
+
* Setup event handlers
|
|
2285
|
+
* @private
|
|
2286
|
+
*/
|
|
2287
|
+
setupEventHandlers(elements, state, key) {
|
|
2288
|
+
const {
|
|
2289
|
+
minInput,
|
|
2290
|
+
maxInput
|
|
2291
|
+
} = elements;
|
|
2292
|
+
const handleInputChange = debounce(() => {
|
|
2293
|
+
const minValue = parseFloat(minInput.value);
|
|
2294
|
+
const maxValue = parseFloat(maxInput.value);
|
|
2295
|
+
if (!isNaN(minValue) && !isNaN(maxValue)) {
|
|
2296
|
+
state.currentMin = Math.max(state.min, Math.min(maxValue, minValue));
|
|
2297
|
+
state.currentMax = Math.min(state.max, Math.max(minValue, maxValue));
|
|
2298
|
+
this.updateInputUI(key);
|
|
2299
|
+
this.applyFilter(key);
|
|
2300
|
+
}
|
|
2301
|
+
}, 300);
|
|
2302
|
+
minInput.addEventListener('input', handleInputChange);
|
|
2303
|
+
maxInput.addEventListener('input', handleInputChange);
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
/**
|
|
2307
|
+
* Update input UI
|
|
2308
|
+
* @private
|
|
2309
|
+
*/
|
|
2310
|
+
updateInputUI(key) {
|
|
2311
|
+
try {
|
|
2312
|
+
const {
|
|
2313
|
+
state,
|
|
2314
|
+
elements
|
|
2315
|
+
} = this.activeRanges.get(key);
|
|
2316
|
+
const {
|
|
2317
|
+
minInput,
|
|
2318
|
+
maxInput
|
|
2319
|
+
} = elements;
|
|
2320
|
+
|
|
2321
|
+
// Set constraints
|
|
2322
|
+
minInput.min = state.min;
|
|
2323
|
+
minInput.max = state.max;
|
|
2324
|
+
minInput.step = state.step;
|
|
2325
|
+
maxInput.min = state.min;
|
|
2326
|
+
maxInput.max = state.max;
|
|
2327
|
+
maxInput.step = state.step;
|
|
2328
|
+
|
|
2329
|
+
// Set current values
|
|
2330
|
+
minInput.value = state.currentMin;
|
|
2331
|
+
maxInput.value = state.currentMax;
|
|
2332
|
+
} catch (error) {
|
|
2333
|
+
this.afs.logger.error('Error updating input UI:', error);
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
/**
|
|
2338
|
+
* Apply filter
|
|
2339
|
+
* @private
|
|
2340
|
+
*/
|
|
2341
|
+
applyFilter(key) {
|
|
2342
|
+
this.afs.logger.info(`Applying input filter for ${key}`);
|
|
2343
|
+
const {
|
|
2344
|
+
state
|
|
2345
|
+
} = this.activeRanges.get(key);
|
|
2346
|
+
this.afs.items.forEach(item => {
|
|
2347
|
+
try {
|
|
2348
|
+
if (!item || !item.dataset || !item.dataset[key]) {
|
|
2349
|
+
this.afs.hideItem(item);
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
const itemValue = parseFloat(item.dataset[key]);
|
|
2353
|
+
if (isNaN(itemValue)) {
|
|
2354
|
+
this.afs.hideItem(item);
|
|
2355
|
+
return;
|
|
2356
|
+
}
|
|
2357
|
+
if (itemValue >= state.currentMin && itemValue <= state.currentMax) {
|
|
2358
|
+
this.afs.showItem(item);
|
|
2359
|
+
} else {
|
|
2360
|
+
this.afs.hideItem(item);
|
|
2361
|
+
}
|
|
2362
|
+
} catch (error) {
|
|
2363
|
+
this.afs.logger.error('Error filtering item:', error);
|
|
2364
|
+
this.afs.hideItem(item);
|
|
2365
|
+
}
|
|
2366
|
+
});
|
|
2367
|
+
this.afs.updateCounter();
|
|
2368
|
+
this.afs.urlManager.updateURL();
|
|
2369
|
+
this.afs.emit('inputRangeFilter', {
|
|
2370
|
+
key,
|
|
2371
|
+
min: state.currentMin,
|
|
2372
|
+
max: state.currentMax
|
|
2373
|
+
});
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
/**
|
|
2377
|
+
* Get current range values
|
|
2378
|
+
* @param {string} key - Range key
|
|
2379
|
+
* @returns {Object} Current range values
|
|
2380
|
+
*/
|
|
2381
|
+
getRange(key) {
|
|
2382
|
+
const range = this.activeRanges.get(key);
|
|
2383
|
+
if (!range) return null;
|
|
2384
|
+
return {
|
|
2385
|
+
min: range.state.currentMin,
|
|
2386
|
+
max: range.state.currentMax
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
/**
|
|
2391
|
+
* Set range values
|
|
2392
|
+
* @param {string} key - Range key
|
|
2393
|
+
* @param {number} min - Minimum value
|
|
2394
|
+
* @param {number} max - Maximum value
|
|
2395
|
+
*/
|
|
2396
|
+
setRange(key, min, max) {
|
|
2397
|
+
const range = this.activeRanges.get(key);
|
|
2398
|
+
if (!range) return;
|
|
2399
|
+
range.state.currentMin = min;
|
|
2400
|
+
range.state.currentMax = max;
|
|
2401
|
+
this.updateInputUI(key);
|
|
2402
|
+
this.applyFilter(key);
|
|
2403
|
+
}
|
|
2404
|
+
|
|
2405
|
+
/**
|
|
2406
|
+
* Remove input range
|
|
2407
|
+
* @param {string} key - Range key
|
|
2408
|
+
*/
|
|
2409
|
+
removeInputRange(key) {
|
|
2410
|
+
const range = this.activeRanges.get(key);
|
|
2411
|
+
if (!range) return;
|
|
2412
|
+
range.elements.container.remove();
|
|
2413
|
+
this.activeRanges.delete(key);
|
|
2414
|
+
this.afs.logger.info(`Input range removed for ${key}`);
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2013
2418
|
/**
|
|
2014
2419
|
* @fileoverview Search functionality for AFS
|
|
2015
2420
|
*/
|
|
@@ -3178,6 +3583,9 @@
|
|
|
3178
3583
|
currentPage,
|
|
3179
3584
|
itemsPerPage
|
|
3180
3585
|
} = state.pagination;
|
|
3586
|
+
if (!this.afs.options.get('pagination.enabled')) {
|
|
3587
|
+
return;
|
|
3588
|
+
}
|
|
3181
3589
|
if (currentPage > 1) {
|
|
3182
3590
|
params.set('page', currentPage.toString());
|
|
3183
3591
|
}
|
|
@@ -3470,6 +3878,7 @@
|
|
|
3470
3878
|
constructor(afs) {
|
|
3471
3879
|
this.afs = afs;
|
|
3472
3880
|
this.activeRanges = new Map();
|
|
3881
|
+
this.options = this.afs.options.get("slider");
|
|
3473
3882
|
if (!this.afs.styleManager) {
|
|
3474
3883
|
this.afs.styleManager = new StyleManager(this.afs.options);
|
|
3475
3884
|
}
|
|
@@ -3584,14 +3993,14 @@
|
|
|
3584
3993
|
*/
|
|
3585
3994
|
createSliderElements(histogramData, sliderUiOptions) {
|
|
3586
3995
|
const styles = this.afs.options.get("styles") || this.afs.styleManager.defaultStyles;
|
|
3587
|
-
const sliderStyles = styles.slider || this.afs.styleManager.defaultStyles.slider;
|
|
3588
3996
|
const colors = styles.colors || this.afs.styleManager.defaultStyles.colors;
|
|
3997
|
+
const sliderOptions = this.afs.options.get("slider") || {};
|
|
3589
3998
|
const container = document.createElement("div");
|
|
3590
|
-
container.className = "
|
|
3999
|
+
container.className = "afs-range-container";
|
|
3591
4000
|
const slider = document.createElement("div");
|
|
3592
|
-
slider.className =
|
|
4001
|
+
slider.className = sliderOptions.containerClass;
|
|
3593
4002
|
const track = document.createElement("div");
|
|
3594
|
-
track.className =
|
|
4003
|
+
track.className = sliderOptions.trackClass;
|
|
3595
4004
|
|
|
3596
4005
|
// Only add histogram if enabled in the slider-specific options
|
|
3597
4006
|
if (sliderUiOptions?.showHistogram && histogramData?.counts?.length > 0) {
|
|
@@ -3599,15 +4008,15 @@
|
|
|
3599
4008
|
slider.appendChild(histogram);
|
|
3600
4009
|
}
|
|
3601
4010
|
const selectedRange = document.createElement("div");
|
|
3602
|
-
selectedRange.className =
|
|
4011
|
+
selectedRange.className = sliderOptions.selectedClass;
|
|
3603
4012
|
const minThumb = document.createElement("div");
|
|
3604
|
-
minThumb.className =
|
|
4013
|
+
minThumb.className = sliderOptions.thumbClass;
|
|
3605
4014
|
const maxThumb = document.createElement("div");
|
|
3606
|
-
maxThumb.className =
|
|
4015
|
+
maxThumb.className = sliderOptions.thumbClass;
|
|
3607
4016
|
const minValue = document.createElement("div");
|
|
3608
|
-
minValue.className =
|
|
4017
|
+
minValue.className = sliderOptions.valueClass;
|
|
3609
4018
|
const maxValue = document.createElement("div");
|
|
3610
|
-
maxValue.className =
|
|
4019
|
+
maxValue.className = sliderOptions.valueClass;
|
|
3611
4020
|
|
|
3612
4021
|
// Build the slider
|
|
3613
4022
|
slider.appendChild(track);
|
|
@@ -4327,7 +4736,7 @@
|
|
|
4327
4736
|
*/
|
|
4328
4737
|
|
|
4329
4738
|
// Version
|
|
4330
|
-
const VERSION = '1.0.
|
|
4739
|
+
const VERSION = '1.0.9';
|
|
4331
4740
|
class AFS extends EventEmitter {
|
|
4332
4741
|
/**
|
|
4333
4742
|
* @param {Object} options - Configuration options
|
|
@@ -4390,6 +4799,7 @@
|
|
|
4390
4799
|
this.urlManager = new URLManager(this);
|
|
4391
4800
|
this.dateFilter = new DateFilter(this);
|
|
4392
4801
|
this.pagination = new Pagination(this);
|
|
4802
|
+
this.inputRangeFilter = new InputRangeFilter(this);
|
|
4393
4803
|
|
|
4394
4804
|
// Apply styles
|
|
4395
4805
|
this.styleManager.applyStyles();
|