basecoat-cli 0.3.10-beta.1 → 0.3.10-beta.2
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/dist/assets/jinja/select.html.jinja +15 -23
- package/dist/assets/js/all.js +146 -145
- package/dist/assets/js/all.min.js +1 -1
- package/dist/assets/js/select.js +146 -145
- package/dist/assets/js/select.min.js +1 -1
- package/dist/assets/nunjucks/select.njk +16 -24
- package/package.json +1 -1
|
@@ -31,7 +31,13 @@
|
|
|
31
31
|
) %}
|
|
32
32
|
{% set id = id or ("select-" + (range(100000, 999999) | random | string)) %}
|
|
33
33
|
|
|
34
|
-
{%
|
|
34
|
+
{% if selected is defined and selected is iterable and selected is not string %}
|
|
35
|
+
{% set selectedArray = selected %}
|
|
36
|
+
{% elif selected is defined %}
|
|
37
|
+
{% set selectedArray = [selected] %}
|
|
38
|
+
{% else %}
|
|
39
|
+
{% set selectedArray = [] %}
|
|
40
|
+
{% endif %}
|
|
35
41
|
{% set first_option = namespace(item=None) %}
|
|
36
42
|
{% set selected_options = namespace(items=[]) %}
|
|
37
43
|
|
|
@@ -135,28 +141,14 @@
|
|
|
135
141
|
{% endif %}
|
|
136
142
|
</div>
|
|
137
143
|
</div>
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
{% if loop.index0 > 0 %}id="{{ id }}-value-{{ loop.index0 }}"{% endif %}
|
|
145
|
-
{% for key, value in input_attrs.items() %}
|
|
146
|
-
{% if key != 'name' and key != 'value' %}{{ key }}="{{ value }}"{% endif %}
|
|
147
|
-
{% endfor %}
|
|
148
|
-
>
|
|
144
|
+
<input
|
|
145
|
+
type="hidden"
|
|
146
|
+
name="{{ name or id ~ '-value' }}"
|
|
147
|
+
value="{% if multiple %}{{ selectedArray | tojson }}{% else %}{{ (default_option.value if default_option) or '' }}{% endif %}"
|
|
148
|
+
{% for key, value in input_attrs.items() %}
|
|
149
|
+
{% if key != 'name' and key != 'value' %}{{ key }}="{{ value }}"{% endif %}
|
|
149
150
|
{% endfor %}
|
|
150
|
-
|
|
151
|
-
<input
|
|
152
|
-
type="hidden"
|
|
153
|
-
name="{{ name or id ~ '-value' }}"
|
|
154
|
-
value="{{ (default_option.value if default_option) or '' }}"
|
|
155
|
-
{% for key, value in input_attrs.items() %}
|
|
156
|
-
{% if key != 'name' and key != 'value' %}{{ key }}="{{ value }}"{% endif %}
|
|
157
|
-
{% endfor %}
|
|
158
|
-
>
|
|
159
|
-
{% endif %}
|
|
151
|
+
>
|
|
160
152
|
</div>
|
|
161
153
|
{% endmacro %}
|
|
162
154
|
|
|
@@ -189,7 +181,7 @@
|
|
|
189
181
|
<div
|
|
190
182
|
id="{{ item_id }}"
|
|
191
183
|
role="option"
|
|
192
|
-
data-value="{{ item.value }}"
|
|
184
|
+
{% if item.value is defined and item.value is not none %}data-value="{{ item.value }}"{% endif %}
|
|
193
185
|
{% if item.value in selectedArray %}aria-selected="true"{% endif %}
|
|
194
186
|
{% if item.attrs %}
|
|
195
187
|
{% for key, value in item.attrs.items() %}
|
package/dist/assets/js/all.js
CHANGED
|
@@ -527,20 +527,18 @@
|
|
|
527
527
|
let visibleOptions = [...options];
|
|
528
528
|
let activeIndex = -1;
|
|
529
529
|
const isMultiple = listbox.getAttribute('aria-multiselectable') === 'true';
|
|
530
|
-
|
|
531
|
-
|
|
530
|
+
const selectedOptions = isMultiple ? new Set() : null;
|
|
531
|
+
const placeholder = isMultiple ? (selectComponent.dataset.placeholder || '') : null;
|
|
532
532
|
|
|
533
|
-
|
|
534
|
-
placeholder = selectComponent.dataset.placeholder || '';
|
|
535
|
-
}
|
|
533
|
+
const getValue = (opt) => opt.dataset.value ?? opt.textContent.trim();
|
|
536
534
|
|
|
537
535
|
const setActiveOption = (index) => {
|
|
538
536
|
if (activeIndex > -1 && options[activeIndex]) {
|
|
539
537
|
options[activeIndex].classList.remove('active');
|
|
540
538
|
}
|
|
541
|
-
|
|
539
|
+
|
|
542
540
|
activeIndex = index;
|
|
543
|
-
|
|
541
|
+
|
|
544
542
|
if (activeIndex > -1) {
|
|
545
543
|
const activeOption = options[activeIndex];
|
|
546
544
|
activeOption.classList.add('active');
|
|
@@ -559,70 +557,43 @@
|
|
|
559
557
|
return parseFloat(style.transitionDuration) > 0 || parseFloat(style.transitionDelay) > 0;
|
|
560
558
|
};
|
|
561
559
|
|
|
562
|
-
const syncMultipleInputs = () => {
|
|
563
|
-
if (!isMultiple) return;
|
|
564
|
-
const values = Array.from(selectedValues);
|
|
565
|
-
const inputs = Array.from(selectComponent.querySelectorAll(':scope > input[type="hidden"]'));
|
|
566
|
-
inputs.slice(1).forEach(inp => inp.remove());
|
|
567
|
-
|
|
568
|
-
if (values.length === 0) {
|
|
569
|
-
input.value = '';
|
|
570
|
-
} else {
|
|
571
|
-
input.value = values[0];
|
|
572
|
-
let insertAfter = input;
|
|
573
|
-
for (let i = 1; i < values.length; i++) {
|
|
574
|
-
const clone = input.cloneNode(true);
|
|
575
|
-
clone.removeAttribute('id');
|
|
576
|
-
clone.value = values[i];
|
|
577
|
-
insertAfter.after(clone);
|
|
578
|
-
insertAfter = clone;
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
};
|
|
582
|
-
|
|
583
|
-
const updateMultipleLabel = () => {
|
|
584
|
-
if (!isMultiple) return;
|
|
585
|
-
const selected = options.filter(opt => selectedValues.has(opt.dataset.value));
|
|
586
|
-
if (selected.length === 0) {
|
|
587
|
-
selectedLabel.textContent = placeholder;
|
|
588
|
-
selectedLabel.classList.add('text-muted-foreground');
|
|
589
|
-
} else {
|
|
590
|
-
selectedLabel.textContent = selected.map(opt => opt.dataset.label || opt.textContent.trim()).join(', ');
|
|
591
|
-
selectedLabel.classList.remove('text-muted-foreground');
|
|
592
|
-
}
|
|
593
|
-
};
|
|
594
|
-
|
|
595
560
|
const updateValue = (optionOrOptions, triggerEvent = true) => {
|
|
596
561
|
let value;
|
|
597
562
|
|
|
598
563
|
if (isMultiple) {
|
|
599
564
|
const opts = Array.isArray(optionOrOptions) ? optionOrOptions : [];
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
565
|
+
selectedOptions.clear();
|
|
566
|
+
opts.forEach(opt => selectedOptions.add(opt));
|
|
567
|
+
|
|
568
|
+
// Get selected options in DOM order
|
|
569
|
+
const selected = options.filter(opt => selectedOptions.has(opt));
|
|
570
|
+
if (selected.length === 0) {
|
|
571
|
+
selectedLabel.textContent = placeholder;
|
|
572
|
+
selectedLabel.classList.add('text-muted-foreground');
|
|
573
|
+
} else {
|
|
574
|
+
selectedLabel.textContent = selected.map(opt => opt.dataset.label || opt.textContent.trim()).join(', ');
|
|
575
|
+
selectedLabel.classList.remove('text-muted-foreground');
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
value = selected.map(getValue);
|
|
579
|
+
input.value = JSON.stringify(value);
|
|
611
580
|
} else {
|
|
612
581
|
const option = optionOrOptions;
|
|
613
582
|
if (!option) return;
|
|
614
583
|
selectedLabel.innerHTML = option.innerHTML;
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
if (opt === option) {
|
|
618
|
-
opt.setAttribute('aria-selected', 'true');
|
|
619
|
-
} else {
|
|
620
|
-
opt.removeAttribute('aria-selected');
|
|
621
|
-
}
|
|
622
|
-
});
|
|
623
|
-
value = option.dataset.value;
|
|
584
|
+
value = getValue(option);
|
|
585
|
+
input.value = value;
|
|
624
586
|
}
|
|
625
587
|
|
|
588
|
+
options.forEach(opt => {
|
|
589
|
+
const isSelected = isMultiple ? selectedOptions.has(opt) : opt === optionOrOptions;
|
|
590
|
+
if (isSelected) {
|
|
591
|
+
opt.setAttribute('aria-selected', 'true');
|
|
592
|
+
} else {
|
|
593
|
+
opt.removeAttribute('aria-selected');
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
|
|
626
597
|
if (triggerEvent) {
|
|
627
598
|
selectComponent.dispatchEvent(new CustomEvent('change', {
|
|
628
599
|
detail: { value },
|
|
@@ -631,85 +602,73 @@
|
|
|
631
602
|
}
|
|
632
603
|
};
|
|
633
604
|
|
|
634
|
-
const toggleMultipleValue = (value, triggerEvent = true) => {
|
|
635
|
-
if (!isMultiple || value == null) return;
|
|
636
|
-
|
|
637
|
-
const newValues = new Set(selectedValues);
|
|
638
|
-
if (newValues.has(value)) {
|
|
639
|
-
newValues.delete(value);
|
|
640
|
-
} else {
|
|
641
|
-
newValues.add(value);
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
const selectedOptions = options.filter(opt => newValues.has(opt.dataset.value));
|
|
645
|
-
updateValue(selectedOptions, triggerEvent);
|
|
646
|
-
};
|
|
647
|
-
|
|
648
605
|
const closePopover = (focusOnTrigger = true) => {
|
|
649
606
|
if (popover.getAttribute('aria-hidden') === 'true') return;
|
|
650
|
-
|
|
607
|
+
|
|
651
608
|
if (filter) {
|
|
652
609
|
const resetFilter = () => {
|
|
653
610
|
filter.value = '';
|
|
654
611
|
visibleOptions = [...options];
|
|
655
612
|
allOptions.forEach(opt => opt.setAttribute('aria-hidden', 'false'));
|
|
656
613
|
};
|
|
657
|
-
|
|
614
|
+
|
|
658
615
|
if (hasTransition()) {
|
|
659
616
|
popover.addEventListener('transitionend', resetFilter, { once: true });
|
|
660
617
|
} else {
|
|
661
618
|
resetFilter();
|
|
662
619
|
}
|
|
663
620
|
}
|
|
664
|
-
|
|
621
|
+
|
|
665
622
|
if (focusOnTrigger) trigger.focus();
|
|
666
623
|
popover.setAttribute('aria-hidden', 'true');
|
|
667
624
|
trigger.setAttribute('aria-expanded', 'false');
|
|
668
625
|
setActiveOption(-1);
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
const selectOption = (option) => {
|
|
672
|
-
if (!option) return;
|
|
673
|
-
|
|
674
|
-
const oldValue = input.value;
|
|
675
|
-
const newValue = option.dataset.value;
|
|
626
|
+
};
|
|
676
627
|
|
|
677
|
-
|
|
678
|
-
|
|
628
|
+
const toggleMultipleValue = (option) => {
|
|
629
|
+
if (selectedOptions.has(option)) {
|
|
630
|
+
selectedOptions.delete(option);
|
|
631
|
+
} else {
|
|
632
|
+
selectedOptions.add(option);
|
|
679
633
|
}
|
|
680
|
-
|
|
681
|
-
closePopover();
|
|
634
|
+
updateValue(options.filter(opt => selectedOptions.has(opt)));
|
|
682
635
|
};
|
|
683
636
|
|
|
684
|
-
const
|
|
685
|
-
const option = options.find(opt => opt.dataset.value === value);
|
|
637
|
+
const select = (value) => {
|
|
686
638
|
if (isMultiple) {
|
|
687
|
-
|
|
688
|
-
if (option
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
const selectedOptions = options.filter(opt => newValues.has(opt.dataset.value));
|
|
692
|
-
updateValue(selectedOptions);
|
|
693
|
-
}
|
|
639
|
+
const option = options.find(opt => getValue(opt) === value && !selectedOptions.has(opt));
|
|
640
|
+
if (!option) return;
|
|
641
|
+
selectedOptions.add(option);
|
|
642
|
+
updateValue(options.filter(opt => selectedOptions.has(opt)));
|
|
694
643
|
} else {
|
|
695
|
-
|
|
644
|
+
const option = options.find(opt => getValue(opt) === value);
|
|
645
|
+
if (!option) return;
|
|
646
|
+
if (input.value !== value) {
|
|
647
|
+
updateValue(option);
|
|
648
|
+
}
|
|
649
|
+
closePopover();
|
|
696
650
|
}
|
|
697
651
|
};
|
|
698
652
|
|
|
699
|
-
const
|
|
653
|
+
const deselect = (value) => {
|
|
700
654
|
if (!isMultiple) return;
|
|
701
|
-
|
|
655
|
+
const option = options.find(opt => getValue(opt) === value && selectedOptions.has(opt));
|
|
656
|
+
if (!option) return;
|
|
657
|
+
selectedOptions.delete(option);
|
|
658
|
+
updateValue(options.filter(opt => selectedOptions.has(opt)));
|
|
702
659
|
};
|
|
703
660
|
|
|
704
|
-
const
|
|
661
|
+
const toggle = (value) => {
|
|
705
662
|
if (!isMultiple) return;
|
|
706
|
-
|
|
663
|
+
const option = options.find(opt => getValue(opt) === value);
|
|
664
|
+
if (!option) return;
|
|
665
|
+
toggleMultipleValue(option);
|
|
707
666
|
};
|
|
708
667
|
|
|
709
668
|
if (filter) {
|
|
710
669
|
const filterOptions = () => {
|
|
711
670
|
const searchTerm = filter.value.trim().toLowerCase();
|
|
712
|
-
|
|
671
|
+
|
|
713
672
|
setActiveOption(-1);
|
|
714
673
|
|
|
715
674
|
visibleOptions = [];
|
|
@@ -735,35 +694,36 @@
|
|
|
735
694
|
}
|
|
736
695
|
});
|
|
737
696
|
};
|
|
738
|
-
|
|
697
|
+
|
|
739
698
|
filter.addEventListener('input', filterOptions);
|
|
740
699
|
}
|
|
741
700
|
|
|
701
|
+
// Initialization
|
|
742
702
|
if (isMultiple) {
|
|
743
|
-
const
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
.map(
|
|
747
|
-
.filter(v =>
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
if (!initialOption) {
|
|
761
|
-
initialOption = options.find(opt => opt.dataset.value !== undefined) ?? options[0];
|
|
762
|
-
}
|
|
703
|
+
const ariaSelected = options.filter(opt => opt.getAttribute('aria-selected') === 'true');
|
|
704
|
+
try {
|
|
705
|
+
const parsed = JSON.parse(input.value || '[]');
|
|
706
|
+
const validValues = new Set(options.map(getValue));
|
|
707
|
+
const initialValues = Array.isArray(parsed) ? parsed.filter(v => validValues.has(v)) : [];
|
|
708
|
+
|
|
709
|
+
const initialOptions = [];
|
|
710
|
+
if (initialValues.length > 0) {
|
|
711
|
+
// Match values to options in order, allowing duplicates
|
|
712
|
+
initialValues.forEach(val => {
|
|
713
|
+
const opt = options.find(o => getValue(o) === val && !initialOptions.includes(o));
|
|
714
|
+
if (opt) initialOptions.push(opt);
|
|
715
|
+
});
|
|
716
|
+
} else {
|
|
717
|
+
initialOptions.push(...ariaSelected);
|
|
718
|
+
}
|
|
763
719
|
|
|
764
|
-
|
|
765
|
-
|
|
720
|
+
updateValue(initialOptions, false);
|
|
721
|
+
} catch (e) {
|
|
722
|
+
updateValue(ariaSelected, false);
|
|
766
723
|
}
|
|
724
|
+
} else {
|
|
725
|
+
const initialOption = options.find(opt => getValue(opt) === input.value) || options[0];
|
|
726
|
+
if (initialOption) updateValue(initialOption, false);
|
|
767
727
|
}
|
|
768
728
|
|
|
769
729
|
const handleKeyNavigation = (event) => {
|
|
@@ -780,20 +740,24 @@
|
|
|
780
740
|
}
|
|
781
741
|
return;
|
|
782
742
|
}
|
|
783
|
-
|
|
743
|
+
|
|
784
744
|
event.preventDefault();
|
|
785
745
|
|
|
786
746
|
if (event.key === 'Escape') {
|
|
787
747
|
closePopover();
|
|
788
748
|
return;
|
|
789
749
|
}
|
|
790
|
-
|
|
750
|
+
|
|
791
751
|
if (event.key === 'Enter') {
|
|
792
752
|
if (activeIndex > -1) {
|
|
753
|
+
const option = options[activeIndex];
|
|
793
754
|
if (isMultiple) {
|
|
794
|
-
toggleMultipleValue(
|
|
755
|
+
toggleMultipleValue(option);
|
|
795
756
|
} else {
|
|
796
|
-
|
|
757
|
+
if (input.value !== getValue(option)) {
|
|
758
|
+
updateValue(option);
|
|
759
|
+
}
|
|
760
|
+
closePopover();
|
|
797
761
|
}
|
|
798
762
|
}
|
|
799
763
|
return;
|
|
@@ -860,7 +824,7 @@
|
|
|
860
824
|
document.dispatchEvent(new CustomEvent('basecoat:popover', {
|
|
861
825
|
detail: { source: selectComponent }
|
|
862
826
|
}));
|
|
863
|
-
|
|
827
|
+
|
|
864
828
|
if (filter) {
|
|
865
829
|
if (hasTransition()) {
|
|
866
830
|
popover.addEventListener('transitionend', () => {
|
|
@@ -873,7 +837,7 @@
|
|
|
873
837
|
|
|
874
838
|
popover.setAttribute('aria-hidden', 'false');
|
|
875
839
|
trigger.setAttribute('aria-expanded', 'true');
|
|
876
|
-
|
|
840
|
+
|
|
877
841
|
const selectedOption = listbox.querySelector('[role="option"][aria-selected="true"]');
|
|
878
842
|
if (selectedOption) {
|
|
879
843
|
setActiveOption(options.indexOf(selectedOption));
|
|
@@ -892,18 +856,24 @@
|
|
|
892
856
|
|
|
893
857
|
listbox.addEventListener('click', (event) => {
|
|
894
858
|
const clickedOption = event.target.closest('[role="option"]');
|
|
895
|
-
if (clickedOption)
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
859
|
+
if (!clickedOption) return;
|
|
860
|
+
|
|
861
|
+
const option = options.find(opt => opt === clickedOption);
|
|
862
|
+
if (!option) return;
|
|
863
|
+
|
|
864
|
+
if (isMultiple) {
|
|
865
|
+
toggleMultipleValue(option);
|
|
866
|
+
setActiveOption(options.indexOf(option));
|
|
867
|
+
if (filter) {
|
|
868
|
+
filter.focus();
|
|
904
869
|
} else {
|
|
905
|
-
|
|
870
|
+
trigger.focus();
|
|
906
871
|
}
|
|
872
|
+
} else {
|
|
873
|
+
if (input.value !== getValue(option)) {
|
|
874
|
+
updateValue(option);
|
|
875
|
+
}
|
|
876
|
+
closePopover();
|
|
907
877
|
}
|
|
908
878
|
});
|
|
909
879
|
|
|
@@ -921,10 +891,41 @@
|
|
|
921
891
|
|
|
922
892
|
popover.setAttribute('aria-hidden', 'true');
|
|
923
893
|
|
|
924
|
-
|
|
894
|
+
// Public API
|
|
895
|
+
Object.defineProperty(selectComponent, 'value', {
|
|
896
|
+
get: () => {
|
|
897
|
+
if (isMultiple) {
|
|
898
|
+
return options.filter(opt => selectedOptions.has(opt)).map(getValue);
|
|
899
|
+
} else {
|
|
900
|
+
return input.value;
|
|
901
|
+
}
|
|
902
|
+
},
|
|
903
|
+
set: (val) => {
|
|
904
|
+
if (isMultiple) {
|
|
905
|
+
const values = Array.isArray(val) ? val : (val != null ? [val] : []);
|
|
906
|
+
const opts = [];
|
|
907
|
+
values.forEach(v => {
|
|
908
|
+
const opt = options.find(o => getValue(o) === v && !opts.includes(o));
|
|
909
|
+
if (opt) opts.push(opt);
|
|
910
|
+
});
|
|
911
|
+
updateValue(opts);
|
|
912
|
+
} else {
|
|
913
|
+
const option = options.find(opt => getValue(opt) === val);
|
|
914
|
+
if (option) {
|
|
915
|
+
updateValue(option);
|
|
916
|
+
closePopover();
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
selectComponent.select = select;
|
|
923
|
+
selectComponent.selectByValue = select; // Backward compatibility alias
|
|
925
924
|
if (isMultiple) {
|
|
926
|
-
selectComponent.
|
|
927
|
-
selectComponent.
|
|
925
|
+
selectComponent.deselect = deselect;
|
|
926
|
+
selectComponent.toggle = toggle;
|
|
927
|
+
selectComponent.selectAll = () => updateValue(options);
|
|
928
|
+
selectComponent.selectNone = () => updateValue([]);
|
|
928
929
|
}
|
|
929
930
|
selectComponent.dataset.selectInitialized = true;
|
|
930
931
|
selectComponent.dispatchEvent(new CustomEvent('basecoat:initialized'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{const e={};let t=null;const n=()=>{Object.entries(e).forEach((([e,{selector:t,init:n}])=>{document.querySelectorAll(t).forEach(n)}))},a=t=>{t.nodeType===Node.ELEMENT_NODE&&Object.entries(e).forEach((([e,{selector:n,init:a}])=>{t.matches(n)&&a(t),t.querySelectorAll(n).forEach(a)}))},i=()=>{t||(t=new MutationObserver((e=>{e.forEach((e=>{e.addedNodes.forEach(a)}))})),t.observe(document.body,{childList:!0,subtree:!0}))};window.basecoat={register:(t,n,a)=>{e[t]={selector:n,init:a}},init:t=>{const n=e[t];if(!n)return void console.warn(`Component '${t}' not found in registry`);const a=`data-${t}-initialized`;document.querySelectorAll(`[${a}]`).forEach((e=>{e.removeAttribute(a)})),document.querySelectorAll(n.selector).forEach(n.init)},initAll:()=>{Object.entries(e).forEach((([e,{selector:t}])=>{const n=`data-${e}-initialized`;document.querySelectorAll(`[${n}]`).forEach((e=>{e.removeAttribute(n)}))})),n()},start:i,stop:()=>{t&&(t.disconnect(),t=null)}},document.addEventListener("DOMContentLoaded",(()=>{n(),i()}))})(),(()=>{const e=e=>{const t=e.querySelector("header input"),n=e.querySelector('[role="menu"]');if(!t||!n){const a=[];return t||a.push("input"),n||a.push("menu"),void console.error(`Command component initialization failed. Missing element(s): ${a.join(", ")}`,e)}const a=Array.from(n.querySelectorAll('[role="menuitem"]')),i=a.filter((e=>!e.hasAttribute("disabled")&&"true"!==e.getAttribute("aria-disabled")));let r=[...i],o=-1;const s=e=>{if(o>-1&&i[o]&&i[o].classList.remove("active"),o=e,o>-1){const e=i[o];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")};t.addEventListener("input",(()=>{const e=t.value.trim().toLowerCase();s(-1),r=[],a.forEach((t=>{if(t.hasAttribute("data-force"))return t.setAttribute("aria-hidden","false"),void(i.includes(t)&&r.push(t));const n=(t.dataset.filter||t.textContent).trim().toLowerCase(),a=(t.dataset.keywords||"").toLowerCase().split(/[\s,]+/).filter(Boolean).some((t=>t.includes(e))),o=n.includes(e)||a;t.setAttribute("aria-hidden",String(!o)),o&&i.includes(t)&&r.push(t)})),r.length>0&&(s(i.indexOf(r[0])),r[0].scrollIntoView({block:"nearest"}))}));n.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="menuitem"]');if(t&&r.includes(t)){const e=i.indexOf(t);e!==o&&s(e)}})),n.addEventListener("click",(t=>{const n=t.target.closest('[role="menuitem"]');if(n&&r.includes(n)){const t=e.closest("dialog.command-dialog");t&&!n.hasAttribute("data-keep-command-open")&&t.close()}})),t.addEventListener("keydown",(e=>{if(!["ArrowDown","ArrowUp","Enter","Home","End"].includes(e.key))return;if("Enter"===e.key)return e.preventDefault(),void(o>-1&&i[o]?.click());if(0===r.length)return;e.preventDefault();const t=o>-1?r.indexOf(i[o]):-1;let n=t;switch(e.key){case"ArrowDown":t<r.length-1&&(n=t+1);break;case"ArrowUp":t>0?n=t-1:-1===t&&(n=0);break;case"Home":n=0;break;case"End":n=r.length-1}if(n!==t){const e=r[n];s(i.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}})),r.length>0&&(s(i.indexOf(r[0])),r[0].scrollIntoView({block:"nearest"})),e.dataset.commandInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("command",".command:not([data-command-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector(":scope > button"),n=e.querySelector(":scope > [data-popover]"),a=n.querySelector('[role="menu"]');if(!t||!a||!n){const i=[];return t||i.push("trigger"),a||i.push("menu"),n||i.push("popover"),void console.error(`Dropdown menu initialisation failed. Missing element(s): ${i.join(", ")}`,e)}let i=[],r=-1;const o=(e=!0)=>{"false"!==t.getAttribute("aria-expanded")&&(t.setAttribute("aria-expanded","false"),t.removeAttribute("aria-activedescendant"),n.setAttribute("aria-hidden","true"),e&&t.focus(),d(-1))},s=(r=!1)=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),t.setAttribute("aria-expanded","true"),n.setAttribute("aria-hidden","false"),i=Array.from(a.querySelectorAll('[role^="menuitem"]')).filter((e=>!e.hasAttribute("disabled")&&"true"!==e.getAttribute("aria-disabled"))),i.length>0&&r&&("first"===r?d(0):"last"===r&&d(i.length-1))},d=e=>{if(r>-1&&i[r]&&i[r].classList.remove("active"),r=e,r>-1&&i[r]){const e=i[r];e.classList.add("active"),t.setAttribute("aria-activedescendant",e.id)}else t.removeAttribute("aria-activedescendant")};t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?o():s(!1)})),e.addEventListener("keydown",(e=>{const n="true"===t.getAttribute("aria-expanded");if("Escape"===e.key)return void(n&&o());if(!n)return void(["Enter"," "].includes(e.key)?(e.preventDefault(),s(!1)):"ArrowDown"===e.key?(e.preventDefault(),s("first")):"ArrowUp"===e.key&&(e.preventDefault(),s("last")));if(0===i.length)return;let a=r;switch(e.key){case"ArrowDown":e.preventDefault(),a=-1===r?0:Math.min(r+1,i.length-1);break;case"ArrowUp":e.preventDefault(),a=-1===r?i.length-1:Math.max(r-1,0);break;case"Home":e.preventDefault(),a=0;break;case"End":e.preventDefault(),a=i.length-1;break;case"Enter":case" ":return e.preventDefault(),i[r]?.click(),void o()}a!==r&&d(a)})),a.addEventListener("mousemove",(e=>{const t=e.target.closest('[role^="menuitem"]');if(t&&i.includes(t)){const e=i.indexOf(t);e!==r&&d(e)}})),a.addEventListener("mouseleave",(()=>{d(-1)})),a.addEventListener("click",(e=>{e.target.closest('[role^="menuitem"]')&&o()})),document.addEventListener("click",(t=>{e.contains(t.target)||o()})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&o(!1)})),e.dataset.dropdownMenuInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("dropdown-menu",".dropdown-menu:not([data-dropdown-menu-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector(":scope > button"),n=e.querySelector(":scope > [data-popover]");if(!t||!n){const a=[];return t||a.push("trigger"),n||a.push("content"),void console.error(`Popover initialisation failed. Missing element(s): ${a.join(", ")}`,e)}const a=(e=!0)=>{"false"!==t.getAttribute("aria-expanded")&&(t.setAttribute("aria-expanded","false"),n.setAttribute("aria-hidden","true"),e&&t.focus())};t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?a():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}}));const a=n.querySelector("[autofocus]");a&&n.addEventListener("transitionend",(()=>{a.focus()}),{once:!0}),t.setAttribute("aria-expanded","true"),n.setAttribute("aria-hidden","false")})()})),e.addEventListener("keydown",(e=>{"Escape"===e.key&&a()})),document.addEventListener("click",(t=>{e.contains(t.target)||a()})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&a(!1)})),e.dataset.popoverInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("popover",".popover:not([data-popover-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector(":scope > button"),n=t.querySelector(":scope > span"),a=e.querySelector(":scope > [data-popover]"),i=a?a.querySelector('[role="listbox"]'):null,r=e.querySelector(':scope > input[type="hidden"]'),o=e.querySelector('header input[type="text"]');if(!(t&&a&&i&&r)){const n=[];return t||n.push("trigger"),a||n.push("popover"),i||n.push("listbox"),r||n.push("input"),void console.error(`Select component initialisation failed. Missing element(s): ${n.join(", ")}`,e)}const s=Array.from(i.querySelectorAll('[role="option"]')),d=s.filter((e=>"true"!==e.getAttribute("aria-disabled")));let c=[...d],l=-1;const u="true"===i.getAttribute("aria-multiselectable");let v=u?new Set:null,p=null;u&&(p=e.dataset.placeholder||"");const m=e=>{if(l>-1&&d[l]&&d[l].classList.remove("active"),l=e,l>-1){const e=d[l];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")},f=()=>{const e=getComputedStyle(a);return parseFloat(e.transitionDuration)>0||parseFloat(e.transitionDelay)>0},h=(t,a=!0)=>{let i;if(u){const a=Array.isArray(t)?t:[];v=new Set(a.map((e=>e.dataset.value))),d.forEach((e=>{v.has(e.dataset.value)?e.setAttribute("aria-selected","true"):e.removeAttribute("aria-selected")})),(()=>{if(!u)return;const e=d.filter((e=>v.has(e.dataset.value)));0===e.length?(n.textContent=p,n.classList.add("text-muted-foreground")):(n.textContent=e.map((e=>e.dataset.label||e.textContent.trim())).join(", "),n.classList.remove("text-muted-foreground"))})(),(()=>{if(!u)return;const t=Array.from(v);if(Array.from(e.querySelectorAll(':scope > input[type="hidden"]')).slice(1).forEach((e=>e.remove())),0===t.length)r.value="";else{r.value=t[0];let e=r;for(let n=1;n<t.length;n++){const a=r.cloneNode(!0);a.removeAttribute("id"),a.value=t[n],e.after(a),e=a}}})(),i=Array.from(v)}else{const e=t;if(!e)return;n.innerHTML=e.innerHTML,r.value=e.dataset.value,d.forEach((t=>{t===e?t.setAttribute("aria-selected","true"):t.removeAttribute("aria-selected")})),i=e.dataset.value}a&&e.dispatchEvent(new CustomEvent("change",{detail:{value:i},bubbles:!0}))},b=(e,t=!0)=>{if(!u||null==e)return;const n=new Set(v);n.has(e)?n.delete(e):n.add(e);const a=d.filter((e=>n.has(e.dataset.value)));h(a,t)},w=(e=!0)=>{if("true"!==a.getAttribute("aria-hidden")){if(o){const e=()=>{o.value="",c=[...d],s.forEach((e=>e.setAttribute("aria-hidden","false")))};f()?a.addEventListener("transitionend",e,{once:!0}):e()}e&&t.focus(),a.setAttribute("aria-hidden","true"),t.setAttribute("aria-expanded","false"),m(-1)}},g=e=>{if(!e)return;const t=r.value,n=e.dataset.value;null!=n&&n!==t&&h(e),w()},E=()=>{u&&h(d.filter((e=>null!=e.dataset.value)))},A=()=>{u&&h([])};if(o){const e=()=>{const e=o.value.trim().toLowerCase();m(-1),c=[],s.forEach((t=>{if(t.hasAttribute("data-force"))return t.setAttribute("aria-hidden","false"),void(d.includes(t)&&c.push(t));const n=(t.dataset.filter||t.textContent).trim().toLowerCase(),a=(t.dataset.keywords||"").toLowerCase().split(/[\s,]+/).filter(Boolean).some((t=>t.includes(e))),i=n.includes(e)||a;t.setAttribute("aria-hidden",String(!i)),i&&d.includes(t)&&c.push(t)}))};o.addEventListener("input",e)}if(u){const t=new Set(d.map((e=>e.dataset.value)).filter((e=>null!=e))),n=Array.from(e.querySelectorAll(':scope > input[type="hidden"]')).map((e=>e.value)).filter((e=>null!=e&&t.has(e)));let a;a=n.length>0?d.filter((e=>n.includes(e.dataset.value))):d.filter((e=>"true"===e.getAttribute("aria-selected"))),h(a,!1)}else{let e=d.find((e=>e.dataset.value===r.value));e||(e=d.find((e=>void 0!==e.dataset.value))??d[0]),e&&h(e,!1)}const y=e=>{const n="false"===a.getAttribute("aria-hidden");if(!["ArrowDown","ArrowUp","Enter","Home","End","Escape"].includes(e.key))return;if(!n)return void("Enter"!==e.key&&"Escape"!==e.key&&(e.preventDefault(),t.click()));if(e.preventDefault(),"Escape"===e.key)return void w();if("Enter"===e.key)return void(l>-1&&(u?b(d[l].dataset.value):g(d[l])));if(0===c.length)return;const i=l>-1?c.indexOf(d[l]):-1;let r=i;switch(e.key){case"ArrowDown":i<c.length-1&&(r=i+1);break;case"ArrowUp":i>0?r=i-1:-1===i&&(r=0);break;case"Home":r=0;break;case"End":r=c.length-1}if(r!==i){const e=c[r];m(d.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}};i.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="option"]');if(t&&c.includes(t)){const e=d.indexOf(t);e!==l&&m(e)}})),i.addEventListener("mouseleave",(()=>{const e=i.querySelector('[role="option"][aria-selected="true"]');m(e?d.indexOf(e):-1)})),t.addEventListener("keydown",y),o&&o.addEventListener("keydown",y);t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?w():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),o&&(f()?a.addEventListener("transitionend",(()=>{o.focus()}),{once:!0}):o.focus()),a.setAttribute("aria-hidden","false"),t.setAttribute("aria-expanded","true");const n=i.querySelector('[role="option"][aria-selected="true"]');n&&(m(d.indexOf(n)),n.scrollIntoView({block:"nearest"}))})()})),i.addEventListener("click",(e=>{const n=e.target.closest('[role="option"]');n&&(u?(b(n.dataset.value),m(d.indexOf(n)),o?o.focus():t.focus()):g(n))})),document.addEventListener("click",(t=>{e.contains(t.target)||w(!1)})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&w(!1)})),a.setAttribute("aria-hidden","true"),e.selectByValue=e=>{const t=d.find((t=>t.dataset.value===e));if(u){if(null!=e&&v.has(e))return;if(t&&null!=e){const t=new Set(v);t.add(e);const n=d.filter((e=>t.has(e.dataset.value)));h(n)}}else g(t)},u&&(e.selectAll=E,e.selectNone=A),e.dataset.selectInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("select","div.select:not([data-select-initialized])",e)})(),(()=>{if(!window.history.__basecoatPatched){const e=window.history.pushState;window.history.pushState=function(...t){e.apply(this,t),window.dispatchEvent(new Event("basecoat:locationchange"))};const t=window.history.replaceState;window.history.replaceState=function(...e){t.apply(this,e),window.dispatchEvent(new Event("basecoat:locationchange"))},window.history.__basecoatPatched=!0}const e=e=>{const t="false"!==e.dataset.initialOpen,n="true"===e.dataset.initialMobileOpen,a=parseInt(e.dataset.breakpoint)||768;let i=a>0?window.innerWidth>=a?t:n:t;const r=()=>{const t=window.location.pathname.replace(/\/$/,"");e.querySelectorAll("a").forEach((e=>{if(e.hasAttribute("data-ignore-current"))return;new URL(e.href).pathname.replace(/\/$/,"")===t?e.setAttribute("aria-current","page"):e.removeAttribute("aria-current")}))},o=()=>{e.setAttribute("aria-hidden",!i),i?e.removeAttribute("inert"):e.setAttribute("inert","")},s=e=>{i=e,o()},d=e.id;document.addEventListener("basecoat:sidebar",(e=>{if(!e.detail?.id||e.detail.id===d)switch(e.detail?.action){case"open":s(!0);break;case"close":s(!1);break;default:s(!i)}})),e.addEventListener("click",(t=>{const n=t.target,i=e.querySelector("nav");if(window.innerWidth<a&&n.closest("a, button")&&!n.closest("[data-keep-mobile-sidebar-open]"))return document.activeElement&&document.activeElement.blur(),void s(!1);(n===e||i&&!i.contains(n))&&(document.activeElement&&document.activeElement.blur(),s(!1))})),window.addEventListener("popstate",r),window.addEventListener("basecoat:locationchange",r),o(),r(),e.dataset.sidebarInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("sidebar",".sidebar:not([data-sidebar-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector('[role="tablist"]');if(!t)return;const n=Array.from(t.querySelectorAll('[role="tab"]')),a=n.map((e=>document.getElementById(e.getAttribute("aria-controls")))).filter(Boolean),i=e=>{n.forEach(((e,t)=>{e.setAttribute("aria-selected","false"),e.setAttribute("tabindex","-1"),a[t]&&(a[t].hidden=!0)})),e.setAttribute("aria-selected","true"),e.setAttribute("tabindex","0");const t=document.getElementById(e.getAttribute("aria-controls"));t&&(t.hidden=!1)};t.addEventListener("click",(e=>{const t=e.target.closest('[role="tab"]');t&&i(t)})),t.addEventListener("keydown",(e=>{const t=e.target;if(!n.includes(t))return;let a;const r=n.indexOf(t);switch(e.key){case"ArrowRight":a=n[(r+1)%n.length];break;case"ArrowLeft":a=n[(r-1+n.length)%n.length];break;case"Home":a=n[0];break;case"End":a=n[n.length-1];break;default:return}e.preventDefault(),i(a),a.focus()})),e.dataset.tabsInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("tabs",".tabs:not([data-tabs-initialized])",e)})(),(()=>{let e;const t=new WeakMap;let n=!1;const a={success:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>',error:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>',info:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>',warning:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>'};function i(e){if(e.dataset.toastInitialized)return;const a=parseInt(e.dataset.duration),i=-1!==a?a||("error"===e.dataset.category?5e3:3e3):-1,r={remainingTime:i,timeoutId:null,startTime:null};-1!==i&&(n?r.timeoutId=null:(r.startTime=Date.now(),r.timeoutId=setTimeout((()=>s(e)),i))),t.set(e,r),e.dataset.toastInitialized="true"}function r(){n||(n=!0,e.querySelectorAll('.toast:not([aria-hidden="true"])').forEach((e=>{if(!t.has(e))return;const n=t.get(e);n.timeoutId&&(clearTimeout(n.timeoutId),n.timeoutId=null,n.remainingTime-=Date.now()-n.startTime)})))}function o(){n&&(n=!1,e.querySelectorAll('.toast:not([aria-hidden="true"])').forEach((e=>{if(!t.has(e))return;const n=t.get(e);-1===n.remainingTime||n.timeoutId||(n.remainingTime>0?(n.startTime=Date.now(),n.timeoutId=setTimeout((()=>s(e)),n.remainingTime)):s(e))})))}function s(e){if(!t.has(e))return;const n=t.get(e);clearTimeout(n.timeoutId),t.delete(e),e.contains(document.activeElement)&&document.activeElement.blur(),e.setAttribute("aria-hidden","true"),e.addEventListener("transitionend",(()=>e.remove()),{once:!0})}document.addEventListener("basecoat:toast",(t=>{if(!e)return void console.error("Cannot create toast: toaster container not found on page.");const n=function(e){const{category:t="info",title:n,description:i,action:r,cancel:o,duration:s,icon:d}=e,c=d||t&&a[t]||"",l=n?`<h2>${n}</h2>`:"",u=i?`<p>${i}</p>`:"",v=r?.href?`<a href="${r.href}" class="btn" data-toast-action>${r.label}</a>`:r?.onclick?`<button type="button" class="btn" data-toast-action onclick="${r.onclick}">${r.label}</button>`:"",p=o?`<button type="button" class="btn-outline h-6 text-xs px-2.5 rounded-sm" data-toast-cancel onclick="${o?.onclick}">${o.label}</button>`:"",m=`\n <div\n class="toast"\n role="${"error"===t?"alert":"status"}"\n aria-atomic="true"\n ${t?`data-category="${t}"`:""}\n ${void 0!==s?`data-duration="${s}"`:""}\n >\n <div class="toast-content">\n ${c}\n <section>\n ${l}\n ${u}\n </section>\n ${v||p?`<footer>${v}${p}</footer>`:""}\n </div>\n </div>\n </div>\n `,f=document.createElement("template");return f.innerHTML=m.trim(),f.content.firstChild}(t.detail?.config||{});e.appendChild(n)})),window.basecoat&&(window.basecoat.register("toaster","#toaster:not([data-toaster-initialized])",(function(t){t.dataset.toasterInitialized||(e=t,e.addEventListener("mouseenter",r),e.addEventListener("mouseleave",o),e.addEventListener("click",(e=>{const t=e.target.closest(".toast footer a"),n=e.target.closest(".toast footer button");(t||n)&&s(e.target.closest(".toast"))})),e.querySelectorAll(".toast:not([data-toast-initialized])").forEach(i),e.dataset.toasterInitialized="true",e.dispatchEvent(new CustomEvent("basecoat:initialized")))})),window.basecoat.register("toast",".toast:not([data-toast-initialized])",i))})();
|
|
1
|
+
(()=>{const e={};let t=null;const n=()=>{Object.entries(e).forEach((([e,{selector:t,init:n}])=>{document.querySelectorAll(t).forEach(n)}))},i=t=>{t.nodeType===Node.ELEMENT_NODE&&Object.entries(e).forEach((([e,{selector:n,init:i}])=>{t.matches(n)&&i(t),t.querySelectorAll(n).forEach(i)}))},a=()=>{t||(t=new MutationObserver((e=>{e.forEach((e=>{e.addedNodes.forEach(i)}))})),t.observe(document.body,{childList:!0,subtree:!0}))};window.basecoat={register:(t,n,i)=>{e[t]={selector:n,init:i}},init:t=>{const n=e[t];if(!n)return void console.warn(`Component '${t}' not found in registry`);const i=`data-${t}-initialized`;document.querySelectorAll(`[${i}]`).forEach((e=>{e.removeAttribute(i)})),document.querySelectorAll(n.selector).forEach(n.init)},initAll:()=>{Object.entries(e).forEach((([e,{selector:t}])=>{const n=`data-${e}-initialized`;document.querySelectorAll(`[${n}]`).forEach((e=>{e.removeAttribute(n)}))})),n()},start:a,stop:()=>{t&&(t.disconnect(),t=null)}},document.addEventListener("DOMContentLoaded",(()=>{n(),a()}))})(),(()=>{const e=e=>{const t=e.querySelector("header input"),n=e.querySelector('[role="menu"]');if(!t||!n){const i=[];return t||i.push("input"),n||i.push("menu"),void console.error(`Command component initialization failed. Missing element(s): ${i.join(", ")}`,e)}const i=Array.from(n.querySelectorAll('[role="menuitem"]')),a=i.filter((e=>!e.hasAttribute("disabled")&&"true"!==e.getAttribute("aria-disabled")));let r=[...a],o=-1;const s=e=>{if(o>-1&&a[o]&&a[o].classList.remove("active"),o=e,o>-1){const e=a[o];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")};t.addEventListener("input",(()=>{const e=t.value.trim().toLowerCase();s(-1),r=[],i.forEach((t=>{if(t.hasAttribute("data-force"))return t.setAttribute("aria-hidden","false"),void(a.includes(t)&&r.push(t));const n=(t.dataset.filter||t.textContent).trim().toLowerCase(),i=(t.dataset.keywords||"").toLowerCase().split(/[\s,]+/).filter(Boolean).some((t=>t.includes(e))),o=n.includes(e)||i;t.setAttribute("aria-hidden",String(!o)),o&&a.includes(t)&&r.push(t)})),r.length>0&&(s(a.indexOf(r[0])),r[0].scrollIntoView({block:"nearest"}))}));n.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="menuitem"]');if(t&&r.includes(t)){const e=a.indexOf(t);e!==o&&s(e)}})),n.addEventListener("click",(t=>{const n=t.target.closest('[role="menuitem"]');if(n&&r.includes(n)){const t=e.closest("dialog.command-dialog");t&&!n.hasAttribute("data-keep-command-open")&&t.close()}})),t.addEventListener("keydown",(e=>{if(!["ArrowDown","ArrowUp","Enter","Home","End"].includes(e.key))return;if("Enter"===e.key)return e.preventDefault(),void(o>-1&&a[o]?.click());if(0===r.length)return;e.preventDefault();const t=o>-1?r.indexOf(a[o]):-1;let n=t;switch(e.key){case"ArrowDown":t<r.length-1&&(n=t+1);break;case"ArrowUp":t>0?n=t-1:-1===t&&(n=0);break;case"Home":n=0;break;case"End":n=r.length-1}if(n!==t){const e=r[n];s(a.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}})),r.length>0&&(s(a.indexOf(r[0])),r[0].scrollIntoView({block:"nearest"})),e.dataset.commandInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("command",".command:not([data-command-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector(":scope > button"),n=e.querySelector(":scope > [data-popover]"),i=n.querySelector('[role="menu"]');if(!t||!i||!n){const a=[];return t||a.push("trigger"),i||a.push("menu"),n||a.push("popover"),void console.error(`Dropdown menu initialisation failed. Missing element(s): ${a.join(", ")}`,e)}let a=[],r=-1;const o=(e=!0)=>{"false"!==t.getAttribute("aria-expanded")&&(t.setAttribute("aria-expanded","false"),t.removeAttribute("aria-activedescendant"),n.setAttribute("aria-hidden","true"),e&&t.focus(),d(-1))},s=(r=!1)=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),t.setAttribute("aria-expanded","true"),n.setAttribute("aria-hidden","false"),a=Array.from(i.querySelectorAll('[role^="menuitem"]')).filter((e=>!e.hasAttribute("disabled")&&"true"!==e.getAttribute("aria-disabled"))),a.length>0&&r&&("first"===r?d(0):"last"===r&&d(a.length-1))},d=e=>{if(r>-1&&a[r]&&a[r].classList.remove("active"),r=e,r>-1&&a[r]){const e=a[r];e.classList.add("active"),t.setAttribute("aria-activedescendant",e.id)}else t.removeAttribute("aria-activedescendant")};t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?o():s(!1)})),e.addEventListener("keydown",(e=>{const n="true"===t.getAttribute("aria-expanded");if("Escape"===e.key)return void(n&&o());if(!n)return void(["Enter"," "].includes(e.key)?(e.preventDefault(),s(!1)):"ArrowDown"===e.key?(e.preventDefault(),s("first")):"ArrowUp"===e.key&&(e.preventDefault(),s("last")));if(0===a.length)return;let i=r;switch(e.key){case"ArrowDown":e.preventDefault(),i=-1===r?0:Math.min(r+1,a.length-1);break;case"ArrowUp":e.preventDefault(),i=-1===r?a.length-1:Math.max(r-1,0);break;case"Home":e.preventDefault(),i=0;break;case"End":e.preventDefault(),i=a.length-1;break;case"Enter":case" ":return e.preventDefault(),a[r]?.click(),void o()}i!==r&&d(i)})),i.addEventListener("mousemove",(e=>{const t=e.target.closest('[role^="menuitem"]');if(t&&a.includes(t)){const e=a.indexOf(t);e!==r&&d(e)}})),i.addEventListener("mouseleave",(()=>{d(-1)})),i.addEventListener("click",(e=>{e.target.closest('[role^="menuitem"]')&&o()})),document.addEventListener("click",(t=>{e.contains(t.target)||o()})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&o(!1)})),e.dataset.dropdownMenuInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("dropdown-menu",".dropdown-menu:not([data-dropdown-menu-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector(":scope > button"),n=e.querySelector(":scope > [data-popover]");if(!t||!n){const i=[];return t||i.push("trigger"),n||i.push("content"),void console.error(`Popover initialisation failed. Missing element(s): ${i.join(", ")}`,e)}const i=(e=!0)=>{"false"!==t.getAttribute("aria-expanded")&&(t.setAttribute("aria-expanded","false"),n.setAttribute("aria-hidden","true"),e&&t.focus())};t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?i():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}}));const i=n.querySelector("[autofocus]");i&&n.addEventListener("transitionend",(()=>{i.focus()}),{once:!0}),t.setAttribute("aria-expanded","true"),n.setAttribute("aria-hidden","false")})()})),e.addEventListener("keydown",(e=>{"Escape"===e.key&&i()})),document.addEventListener("click",(t=>{e.contains(t.target)||i()})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&i(!1)})),e.dataset.popoverInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("popover",".popover:not([data-popover-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector(":scope > button"),n=t.querySelector(":scope > span"),i=e.querySelector(":scope > [data-popover]"),a=i?i.querySelector('[role="listbox"]'):null,r=e.querySelector(':scope > input[type="hidden"]'),o=e.querySelector('header input[type="text"]');if(!(t&&i&&a&&r)){const n=[];return t||n.push("trigger"),i||n.push("popover"),a||n.push("listbox"),r||n.push("input"),void console.error(`Select component initialisation failed. Missing element(s): ${n.join(", ")}`,e)}const s=Array.from(a.querySelectorAll('[role="option"]')),d=s.filter((e=>"true"!==e.getAttribute("aria-disabled")));let c=[...d],l=-1;const u="true"===a.getAttribute("aria-multiselectable"),p=u?new Set:null,v=u?e.dataset.placeholder||"":null,h=e=>e.dataset.value??e.textContent.trim(),f=e=>{if(l>-1&&d[l]&&d[l].classList.remove("active"),l=e,l>-1){const e=d[l];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")},m=()=>{const e=getComputedStyle(i);return parseFloat(e.transitionDuration)>0||parseFloat(e.transitionDelay)>0},b=(t,i=!0)=>{let a;if(u){const e=Array.isArray(t)?t:[];p.clear(),e.forEach((e=>p.add(e)));const i=d.filter((e=>p.has(e)));0===i.length?(n.textContent=v,n.classList.add("text-muted-foreground")):(n.textContent=i.map((e=>e.dataset.label||e.textContent.trim())).join(", "),n.classList.remove("text-muted-foreground")),a=i.map(h),r.value=JSON.stringify(a)}else{const e=t;if(!e)return;n.innerHTML=e.innerHTML,a=h(e),r.value=a}d.forEach((e=>{(u?p.has(e):e===t)?e.setAttribute("aria-selected","true"):e.removeAttribute("aria-selected")})),i&&e.dispatchEvent(new CustomEvent("change",{detail:{value:a},bubbles:!0}))},w=(e=!0)=>{if("true"!==i.getAttribute("aria-hidden")){if(o){const e=()=>{o.value="",c=[...d],s.forEach((e=>e.setAttribute("aria-hidden","false")))};m()?i.addEventListener("transitionend",e,{once:!0}):e()}e&&t.focus(),i.setAttribute("aria-hidden","true"),t.setAttribute("aria-expanded","false"),f(-1)}},g=e=>{p.has(e)?p.delete(e):p.add(e),b(d.filter((e=>p.has(e))))},E=e=>{if(u){const t=d.find((t=>h(t)===e&&!p.has(t)));if(!t)return;p.add(t),b(d.filter((e=>p.has(e))))}else{const t=d.find((t=>h(t)===e));if(!t)return;r.value!==e&&b(t),w()}},A=e=>{if(!u)return;const t=d.find((t=>h(t)===e&&p.has(t)));t&&(p.delete(t),b(d.filter((e=>p.has(e)))))},y=e=>{if(!u)return;const t=d.find((t=>h(t)===e));t&&g(t)};if(o){const e=()=>{const e=o.value.trim().toLowerCase();f(-1),c=[],s.forEach((t=>{if(t.hasAttribute("data-force"))return t.setAttribute("aria-hidden","false"),void(d.includes(t)&&c.push(t));const n=(t.dataset.filter||t.textContent).trim().toLowerCase(),i=(t.dataset.keywords||"").toLowerCase().split(/[\s,]+/).filter(Boolean).some((t=>t.includes(e))),a=n.includes(e)||i;t.setAttribute("aria-hidden",String(!a)),a&&d.includes(t)&&c.push(t)}))};o.addEventListener("input",e)}if(u){const e=d.filter((e=>"true"===e.getAttribute("aria-selected")));try{const t=JSON.parse(r.value||"[]"),n=new Set(d.map(h)),i=Array.isArray(t)?t.filter((e=>n.has(e))):[],a=[];i.length>0?i.forEach((e=>{const t=d.find((t=>h(t)===e&&!a.includes(t)));t&&a.push(t)})):a.push(...e),b(a,!1)}catch(t){b(e,!1)}}else{const e=d.find((e=>h(e)===r.value))||d[0];e&&b(e,!1)}const k=e=>{const n="false"===i.getAttribute("aria-hidden");if(!["ArrowDown","ArrowUp","Enter","Home","End","Escape"].includes(e.key))return;if(!n)return void("Enter"!==e.key&&"Escape"!==e.key&&(e.preventDefault(),t.click()));if(e.preventDefault(),"Escape"===e.key)return void w();if("Enter"===e.key){if(l>-1){const e=d[l];u?g(e):(r.value!==h(e)&&b(e),w())}return}if(0===c.length)return;const a=l>-1?c.indexOf(d[l]):-1;let o=a;switch(e.key){case"ArrowDown":a<c.length-1&&(o=a+1);break;case"ArrowUp":a>0?o=a-1:-1===a&&(o=0);break;case"Home":o=0;break;case"End":o=c.length-1}if(o!==a){const e=c[o];f(d.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}};a.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="option"]');if(t&&c.includes(t)){const e=d.indexOf(t);e!==l&&f(e)}})),a.addEventListener("mouseleave",(()=>{const e=a.querySelector('[role="option"][aria-selected="true"]');f(e?d.indexOf(e):-1)})),t.addEventListener("keydown",k),o&&o.addEventListener("keydown",k);t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?w():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),o&&(m()?i.addEventListener("transitionend",(()=>{o.focus()}),{once:!0}):o.focus()),i.setAttribute("aria-hidden","false"),t.setAttribute("aria-expanded","true");const n=a.querySelector('[role="option"][aria-selected="true"]');n&&(f(d.indexOf(n)),n.scrollIntoView({block:"nearest"}))})()})),a.addEventListener("click",(e=>{const n=e.target.closest('[role="option"]');if(!n)return;const i=d.find((e=>e===n));i&&(u?(g(i),f(d.indexOf(i)),o?o.focus():t.focus()):(r.value!==h(i)&&b(i),w()))})),document.addEventListener("click",(t=>{e.contains(t.target)||w(!1)})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&w(!1)})),i.setAttribute("aria-hidden","true"),Object.defineProperty(e,"value",{get:()=>u?d.filter((e=>p.has(e))).map(h):r.value,set:e=>{if(u){const t=Array.isArray(e)?e:null!=e?[e]:[],n=[];t.forEach((e=>{const t=d.find((t=>h(t)===e&&!n.includes(t)));t&&n.push(t)})),b(n)}else{const t=d.find((t=>h(t)===e));t&&(b(t),w())}}}),e.select=E,e.selectByValue=E,u&&(e.deselect=A,e.toggle=y,e.selectAll=()=>b(d),e.selectNone=()=>b([])),e.dataset.selectInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("select","div.select:not([data-select-initialized])",e)})(),(()=>{if(!window.history.__basecoatPatched){const e=window.history.pushState;window.history.pushState=function(...t){e.apply(this,t),window.dispatchEvent(new Event("basecoat:locationchange"))};const t=window.history.replaceState;window.history.replaceState=function(...e){t.apply(this,e),window.dispatchEvent(new Event("basecoat:locationchange"))},window.history.__basecoatPatched=!0}const e=e=>{const t="false"!==e.dataset.initialOpen,n="true"===e.dataset.initialMobileOpen,i=parseInt(e.dataset.breakpoint)||768;let a=i>0?window.innerWidth>=i?t:n:t;const r=()=>{const t=window.location.pathname.replace(/\/$/,"");e.querySelectorAll("a").forEach((e=>{if(e.hasAttribute("data-ignore-current"))return;new URL(e.href).pathname.replace(/\/$/,"")===t?e.setAttribute("aria-current","page"):e.removeAttribute("aria-current")}))},o=()=>{e.setAttribute("aria-hidden",!a),a?e.removeAttribute("inert"):e.setAttribute("inert","")},s=e=>{a=e,o()},d=e.id;document.addEventListener("basecoat:sidebar",(e=>{if(!e.detail?.id||e.detail.id===d)switch(e.detail?.action){case"open":s(!0);break;case"close":s(!1);break;default:s(!a)}})),e.addEventListener("click",(t=>{const n=t.target,a=e.querySelector("nav");if(window.innerWidth<i&&n.closest("a, button")&&!n.closest("[data-keep-mobile-sidebar-open]"))return document.activeElement&&document.activeElement.blur(),void s(!1);(n===e||a&&!a.contains(n))&&(document.activeElement&&document.activeElement.blur(),s(!1))})),window.addEventListener("popstate",r),window.addEventListener("basecoat:locationchange",r),o(),r(),e.dataset.sidebarInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("sidebar",".sidebar:not([data-sidebar-initialized])",e)})(),(()=>{const e=e=>{const t=e.querySelector('[role="tablist"]');if(!t)return;const n=Array.from(t.querySelectorAll('[role="tab"]')),i=n.map((e=>document.getElementById(e.getAttribute("aria-controls")))).filter(Boolean),a=e=>{n.forEach(((e,t)=>{e.setAttribute("aria-selected","false"),e.setAttribute("tabindex","-1"),i[t]&&(i[t].hidden=!0)})),e.setAttribute("aria-selected","true"),e.setAttribute("tabindex","0");const t=document.getElementById(e.getAttribute("aria-controls"));t&&(t.hidden=!1)};t.addEventListener("click",(e=>{const t=e.target.closest('[role="tab"]');t&&a(t)})),t.addEventListener("keydown",(e=>{const t=e.target;if(!n.includes(t))return;let i;const r=n.indexOf(t);switch(e.key){case"ArrowRight":i=n[(r+1)%n.length];break;case"ArrowLeft":i=n[(r-1+n.length)%n.length];break;case"Home":i=n[0];break;case"End":i=n[n.length-1];break;default:return}e.preventDefault(),a(i),i.focus()})),e.dataset.tabsInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("tabs",".tabs:not([data-tabs-initialized])",e)})(),(()=>{let e;const t=new WeakMap;let n=!1;const i={success:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>',error:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>',info:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>',warning:'<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>'};function a(e){if(e.dataset.toastInitialized)return;const i=parseInt(e.dataset.duration),a=-1!==i?i||("error"===e.dataset.category?5e3:3e3):-1,r={remainingTime:a,timeoutId:null,startTime:null};-1!==a&&(n?r.timeoutId=null:(r.startTime=Date.now(),r.timeoutId=setTimeout((()=>s(e)),a))),t.set(e,r),e.dataset.toastInitialized="true"}function r(){n||(n=!0,e.querySelectorAll('.toast:not([aria-hidden="true"])').forEach((e=>{if(!t.has(e))return;const n=t.get(e);n.timeoutId&&(clearTimeout(n.timeoutId),n.timeoutId=null,n.remainingTime-=Date.now()-n.startTime)})))}function o(){n&&(n=!1,e.querySelectorAll('.toast:not([aria-hidden="true"])').forEach((e=>{if(!t.has(e))return;const n=t.get(e);-1===n.remainingTime||n.timeoutId||(n.remainingTime>0?(n.startTime=Date.now(),n.timeoutId=setTimeout((()=>s(e)),n.remainingTime)):s(e))})))}function s(e){if(!t.has(e))return;const n=t.get(e);clearTimeout(n.timeoutId),t.delete(e),e.contains(document.activeElement)&&document.activeElement.blur(),e.setAttribute("aria-hidden","true"),e.addEventListener("transitionend",(()=>e.remove()),{once:!0})}document.addEventListener("basecoat:toast",(t=>{if(!e)return void console.error("Cannot create toast: toaster container not found on page.");const n=function(e){const{category:t="info",title:n,description:a,action:r,cancel:o,duration:s,icon:d}=e,c=d||t&&i[t]||"",l=n?`<h2>${n}</h2>`:"",u=a?`<p>${a}</p>`:"",p=r?.href?`<a href="${r.href}" class="btn" data-toast-action>${r.label}</a>`:r?.onclick?`<button type="button" class="btn" data-toast-action onclick="${r.onclick}">${r.label}</button>`:"",v=o?`<button type="button" class="btn-outline h-6 text-xs px-2.5 rounded-sm" data-toast-cancel onclick="${o?.onclick}">${o.label}</button>`:"",h=`\n <div\n class="toast"\n role="${"error"===t?"alert":"status"}"\n aria-atomic="true"\n ${t?`data-category="${t}"`:""}\n ${void 0!==s?`data-duration="${s}"`:""}\n >\n <div class="toast-content">\n ${c}\n <section>\n ${l}\n ${u}\n </section>\n ${p||v?`<footer>${p}${v}</footer>`:""}\n </div>\n </div>\n </div>\n `,f=document.createElement("template");return f.innerHTML=h.trim(),f.content.firstChild}(t.detail?.config||{});e.appendChild(n)})),window.basecoat&&(window.basecoat.register("toaster","#toaster:not([data-toaster-initialized])",(function(t){t.dataset.toasterInitialized||(e=t,e.addEventListener("mouseenter",r),e.addEventListener("mouseleave",o),e.addEventListener("click",(e=>{const t=e.target.closest(".toast footer a"),n=e.target.closest(".toast footer button");(t||n)&&s(e.target.closest(".toast"))})),e.querySelectorAll(".toast:not([data-toast-initialized])").forEach(a),e.dataset.toasterInitialized="true",e.dispatchEvent(new CustomEvent("basecoat:initialized")))})),window.basecoat.register("toast",".toast:not([data-toast-initialized])",a))})();
|
package/dist/assets/js/select.js
CHANGED
|
@@ -22,20 +22,18 @@
|
|
|
22
22
|
let visibleOptions = [...options];
|
|
23
23
|
let activeIndex = -1;
|
|
24
24
|
const isMultiple = listbox.getAttribute('aria-multiselectable') === 'true';
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const selectedOptions = isMultiple ? new Set() : null;
|
|
26
|
+
const placeholder = isMultiple ? (selectComponent.dataset.placeholder || '') : null;
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
placeholder = selectComponent.dataset.placeholder || '';
|
|
30
|
-
}
|
|
28
|
+
const getValue = (opt) => opt.dataset.value ?? opt.textContent.trim();
|
|
31
29
|
|
|
32
30
|
const setActiveOption = (index) => {
|
|
33
31
|
if (activeIndex > -1 && options[activeIndex]) {
|
|
34
32
|
options[activeIndex].classList.remove('active');
|
|
35
33
|
}
|
|
36
|
-
|
|
34
|
+
|
|
37
35
|
activeIndex = index;
|
|
38
|
-
|
|
36
|
+
|
|
39
37
|
if (activeIndex > -1) {
|
|
40
38
|
const activeOption = options[activeIndex];
|
|
41
39
|
activeOption.classList.add('active');
|
|
@@ -54,70 +52,43 @@
|
|
|
54
52
|
return parseFloat(style.transitionDuration) > 0 || parseFloat(style.transitionDelay) > 0;
|
|
55
53
|
};
|
|
56
54
|
|
|
57
|
-
const syncMultipleInputs = () => {
|
|
58
|
-
if (!isMultiple) return;
|
|
59
|
-
const values = Array.from(selectedValues);
|
|
60
|
-
const inputs = Array.from(selectComponent.querySelectorAll(':scope > input[type="hidden"]'));
|
|
61
|
-
inputs.slice(1).forEach(inp => inp.remove());
|
|
62
|
-
|
|
63
|
-
if (values.length === 0) {
|
|
64
|
-
input.value = '';
|
|
65
|
-
} else {
|
|
66
|
-
input.value = values[0];
|
|
67
|
-
let insertAfter = input;
|
|
68
|
-
for (let i = 1; i < values.length; i++) {
|
|
69
|
-
const clone = input.cloneNode(true);
|
|
70
|
-
clone.removeAttribute('id');
|
|
71
|
-
clone.value = values[i];
|
|
72
|
-
insertAfter.after(clone);
|
|
73
|
-
insertAfter = clone;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const updateMultipleLabel = () => {
|
|
79
|
-
if (!isMultiple) return;
|
|
80
|
-
const selected = options.filter(opt => selectedValues.has(opt.dataset.value));
|
|
81
|
-
if (selected.length === 0) {
|
|
82
|
-
selectedLabel.textContent = placeholder;
|
|
83
|
-
selectedLabel.classList.add('text-muted-foreground');
|
|
84
|
-
} else {
|
|
85
|
-
selectedLabel.textContent = selected.map(opt => opt.dataset.label || opt.textContent.trim()).join(', ');
|
|
86
|
-
selectedLabel.classList.remove('text-muted-foreground');
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
|
|
90
55
|
const updateValue = (optionOrOptions, triggerEvent = true) => {
|
|
91
56
|
let value;
|
|
92
57
|
|
|
93
58
|
if (isMultiple) {
|
|
94
59
|
const opts = Array.isArray(optionOrOptions) ? optionOrOptions : [];
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
60
|
+
selectedOptions.clear();
|
|
61
|
+
opts.forEach(opt => selectedOptions.add(opt));
|
|
62
|
+
|
|
63
|
+
// Get selected options in DOM order
|
|
64
|
+
const selected = options.filter(opt => selectedOptions.has(opt));
|
|
65
|
+
if (selected.length === 0) {
|
|
66
|
+
selectedLabel.textContent = placeholder;
|
|
67
|
+
selectedLabel.classList.add('text-muted-foreground');
|
|
68
|
+
} else {
|
|
69
|
+
selectedLabel.textContent = selected.map(opt => opt.dataset.label || opt.textContent.trim()).join(', ');
|
|
70
|
+
selectedLabel.classList.remove('text-muted-foreground');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
value = selected.map(getValue);
|
|
74
|
+
input.value = JSON.stringify(value);
|
|
106
75
|
} else {
|
|
107
76
|
const option = optionOrOptions;
|
|
108
77
|
if (!option) return;
|
|
109
78
|
selectedLabel.innerHTML = option.innerHTML;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (opt === option) {
|
|
113
|
-
opt.setAttribute('aria-selected', 'true');
|
|
114
|
-
} else {
|
|
115
|
-
opt.removeAttribute('aria-selected');
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
value = option.dataset.value;
|
|
79
|
+
value = getValue(option);
|
|
80
|
+
input.value = value;
|
|
119
81
|
}
|
|
120
82
|
|
|
83
|
+
options.forEach(opt => {
|
|
84
|
+
const isSelected = isMultiple ? selectedOptions.has(opt) : opt === optionOrOptions;
|
|
85
|
+
if (isSelected) {
|
|
86
|
+
opt.setAttribute('aria-selected', 'true');
|
|
87
|
+
} else {
|
|
88
|
+
opt.removeAttribute('aria-selected');
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
121
92
|
if (triggerEvent) {
|
|
122
93
|
selectComponent.dispatchEvent(new CustomEvent('change', {
|
|
123
94
|
detail: { value },
|
|
@@ -126,85 +97,73 @@
|
|
|
126
97
|
}
|
|
127
98
|
};
|
|
128
99
|
|
|
129
|
-
const toggleMultipleValue = (value, triggerEvent = true) => {
|
|
130
|
-
if (!isMultiple || value == null) return;
|
|
131
|
-
|
|
132
|
-
const newValues = new Set(selectedValues);
|
|
133
|
-
if (newValues.has(value)) {
|
|
134
|
-
newValues.delete(value);
|
|
135
|
-
} else {
|
|
136
|
-
newValues.add(value);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const selectedOptions = options.filter(opt => newValues.has(opt.dataset.value));
|
|
140
|
-
updateValue(selectedOptions, triggerEvent);
|
|
141
|
-
};
|
|
142
|
-
|
|
143
100
|
const closePopover = (focusOnTrigger = true) => {
|
|
144
101
|
if (popover.getAttribute('aria-hidden') === 'true') return;
|
|
145
|
-
|
|
102
|
+
|
|
146
103
|
if (filter) {
|
|
147
104
|
const resetFilter = () => {
|
|
148
105
|
filter.value = '';
|
|
149
106
|
visibleOptions = [...options];
|
|
150
107
|
allOptions.forEach(opt => opt.setAttribute('aria-hidden', 'false'));
|
|
151
108
|
};
|
|
152
|
-
|
|
109
|
+
|
|
153
110
|
if (hasTransition()) {
|
|
154
111
|
popover.addEventListener('transitionend', resetFilter, { once: true });
|
|
155
112
|
} else {
|
|
156
113
|
resetFilter();
|
|
157
114
|
}
|
|
158
115
|
}
|
|
159
|
-
|
|
116
|
+
|
|
160
117
|
if (focusOnTrigger) trigger.focus();
|
|
161
118
|
popover.setAttribute('aria-hidden', 'true');
|
|
162
119
|
trigger.setAttribute('aria-expanded', 'false');
|
|
163
120
|
setActiveOption(-1);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const selectOption = (option) => {
|
|
167
|
-
if (!option) return;
|
|
168
|
-
|
|
169
|
-
const oldValue = input.value;
|
|
170
|
-
const newValue = option.dataset.value;
|
|
121
|
+
};
|
|
171
122
|
|
|
172
|
-
|
|
173
|
-
|
|
123
|
+
const toggleMultipleValue = (option) => {
|
|
124
|
+
if (selectedOptions.has(option)) {
|
|
125
|
+
selectedOptions.delete(option);
|
|
126
|
+
} else {
|
|
127
|
+
selectedOptions.add(option);
|
|
174
128
|
}
|
|
175
|
-
|
|
176
|
-
closePopover();
|
|
129
|
+
updateValue(options.filter(opt => selectedOptions.has(opt)));
|
|
177
130
|
};
|
|
178
131
|
|
|
179
|
-
const
|
|
180
|
-
const option = options.find(opt => opt.dataset.value === value);
|
|
132
|
+
const select = (value) => {
|
|
181
133
|
if (isMultiple) {
|
|
182
|
-
|
|
183
|
-
if (option
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const selectedOptions = options.filter(opt => newValues.has(opt.dataset.value));
|
|
187
|
-
updateValue(selectedOptions);
|
|
188
|
-
}
|
|
134
|
+
const option = options.find(opt => getValue(opt) === value && !selectedOptions.has(opt));
|
|
135
|
+
if (!option) return;
|
|
136
|
+
selectedOptions.add(option);
|
|
137
|
+
updateValue(options.filter(opt => selectedOptions.has(opt)));
|
|
189
138
|
} else {
|
|
190
|
-
|
|
139
|
+
const option = options.find(opt => getValue(opt) === value);
|
|
140
|
+
if (!option) return;
|
|
141
|
+
if (input.value !== value) {
|
|
142
|
+
updateValue(option);
|
|
143
|
+
}
|
|
144
|
+
closePopover();
|
|
191
145
|
}
|
|
192
146
|
};
|
|
193
147
|
|
|
194
|
-
const
|
|
148
|
+
const deselect = (value) => {
|
|
195
149
|
if (!isMultiple) return;
|
|
196
|
-
|
|
150
|
+
const option = options.find(opt => getValue(opt) === value && selectedOptions.has(opt));
|
|
151
|
+
if (!option) return;
|
|
152
|
+
selectedOptions.delete(option);
|
|
153
|
+
updateValue(options.filter(opt => selectedOptions.has(opt)));
|
|
197
154
|
};
|
|
198
155
|
|
|
199
|
-
const
|
|
156
|
+
const toggle = (value) => {
|
|
200
157
|
if (!isMultiple) return;
|
|
201
|
-
|
|
158
|
+
const option = options.find(opt => getValue(opt) === value);
|
|
159
|
+
if (!option) return;
|
|
160
|
+
toggleMultipleValue(option);
|
|
202
161
|
};
|
|
203
162
|
|
|
204
163
|
if (filter) {
|
|
205
164
|
const filterOptions = () => {
|
|
206
165
|
const searchTerm = filter.value.trim().toLowerCase();
|
|
207
|
-
|
|
166
|
+
|
|
208
167
|
setActiveOption(-1);
|
|
209
168
|
|
|
210
169
|
visibleOptions = [];
|
|
@@ -230,35 +189,36 @@
|
|
|
230
189
|
}
|
|
231
190
|
});
|
|
232
191
|
};
|
|
233
|
-
|
|
192
|
+
|
|
234
193
|
filter.addEventListener('input', filterOptions);
|
|
235
194
|
}
|
|
236
195
|
|
|
196
|
+
// Initialization
|
|
237
197
|
if (isMultiple) {
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
.map(
|
|
242
|
-
.filter(v =>
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
if (!initialOption) {
|
|
256
|
-
initialOption = options.find(opt => opt.dataset.value !== undefined) ?? options[0];
|
|
257
|
-
}
|
|
198
|
+
const ariaSelected = options.filter(opt => opt.getAttribute('aria-selected') === 'true');
|
|
199
|
+
try {
|
|
200
|
+
const parsed = JSON.parse(input.value || '[]');
|
|
201
|
+
const validValues = new Set(options.map(getValue));
|
|
202
|
+
const initialValues = Array.isArray(parsed) ? parsed.filter(v => validValues.has(v)) : [];
|
|
203
|
+
|
|
204
|
+
const initialOptions = [];
|
|
205
|
+
if (initialValues.length > 0) {
|
|
206
|
+
// Match values to options in order, allowing duplicates
|
|
207
|
+
initialValues.forEach(val => {
|
|
208
|
+
const opt = options.find(o => getValue(o) === val && !initialOptions.includes(o));
|
|
209
|
+
if (opt) initialOptions.push(opt);
|
|
210
|
+
});
|
|
211
|
+
} else {
|
|
212
|
+
initialOptions.push(...ariaSelected);
|
|
213
|
+
}
|
|
258
214
|
|
|
259
|
-
|
|
260
|
-
|
|
215
|
+
updateValue(initialOptions, false);
|
|
216
|
+
} catch (e) {
|
|
217
|
+
updateValue(ariaSelected, false);
|
|
261
218
|
}
|
|
219
|
+
} else {
|
|
220
|
+
const initialOption = options.find(opt => getValue(opt) === input.value) || options[0];
|
|
221
|
+
if (initialOption) updateValue(initialOption, false);
|
|
262
222
|
}
|
|
263
223
|
|
|
264
224
|
const handleKeyNavigation = (event) => {
|
|
@@ -275,20 +235,24 @@
|
|
|
275
235
|
}
|
|
276
236
|
return;
|
|
277
237
|
}
|
|
278
|
-
|
|
238
|
+
|
|
279
239
|
event.preventDefault();
|
|
280
240
|
|
|
281
241
|
if (event.key === 'Escape') {
|
|
282
242
|
closePopover();
|
|
283
243
|
return;
|
|
284
244
|
}
|
|
285
|
-
|
|
245
|
+
|
|
286
246
|
if (event.key === 'Enter') {
|
|
287
247
|
if (activeIndex > -1) {
|
|
248
|
+
const option = options[activeIndex];
|
|
288
249
|
if (isMultiple) {
|
|
289
|
-
toggleMultipleValue(
|
|
250
|
+
toggleMultipleValue(option);
|
|
290
251
|
} else {
|
|
291
|
-
|
|
252
|
+
if (input.value !== getValue(option)) {
|
|
253
|
+
updateValue(option);
|
|
254
|
+
}
|
|
255
|
+
closePopover();
|
|
292
256
|
}
|
|
293
257
|
}
|
|
294
258
|
return;
|
|
@@ -355,7 +319,7 @@
|
|
|
355
319
|
document.dispatchEvent(new CustomEvent('basecoat:popover', {
|
|
356
320
|
detail: { source: selectComponent }
|
|
357
321
|
}));
|
|
358
|
-
|
|
322
|
+
|
|
359
323
|
if (filter) {
|
|
360
324
|
if (hasTransition()) {
|
|
361
325
|
popover.addEventListener('transitionend', () => {
|
|
@@ -368,7 +332,7 @@
|
|
|
368
332
|
|
|
369
333
|
popover.setAttribute('aria-hidden', 'false');
|
|
370
334
|
trigger.setAttribute('aria-expanded', 'true');
|
|
371
|
-
|
|
335
|
+
|
|
372
336
|
const selectedOption = listbox.querySelector('[role="option"][aria-selected="true"]');
|
|
373
337
|
if (selectedOption) {
|
|
374
338
|
setActiveOption(options.indexOf(selectedOption));
|
|
@@ -387,18 +351,24 @@
|
|
|
387
351
|
|
|
388
352
|
listbox.addEventListener('click', (event) => {
|
|
389
353
|
const clickedOption = event.target.closest('[role="option"]');
|
|
390
|
-
if (clickedOption)
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
354
|
+
if (!clickedOption) return;
|
|
355
|
+
|
|
356
|
+
const option = options.find(opt => opt === clickedOption);
|
|
357
|
+
if (!option) return;
|
|
358
|
+
|
|
359
|
+
if (isMultiple) {
|
|
360
|
+
toggleMultipleValue(option);
|
|
361
|
+
setActiveOption(options.indexOf(option));
|
|
362
|
+
if (filter) {
|
|
363
|
+
filter.focus();
|
|
399
364
|
} else {
|
|
400
|
-
|
|
365
|
+
trigger.focus();
|
|
401
366
|
}
|
|
367
|
+
} else {
|
|
368
|
+
if (input.value !== getValue(option)) {
|
|
369
|
+
updateValue(option);
|
|
370
|
+
}
|
|
371
|
+
closePopover();
|
|
402
372
|
}
|
|
403
373
|
});
|
|
404
374
|
|
|
@@ -416,10 +386,41 @@
|
|
|
416
386
|
|
|
417
387
|
popover.setAttribute('aria-hidden', 'true');
|
|
418
388
|
|
|
419
|
-
|
|
389
|
+
// Public API
|
|
390
|
+
Object.defineProperty(selectComponent, 'value', {
|
|
391
|
+
get: () => {
|
|
392
|
+
if (isMultiple) {
|
|
393
|
+
return options.filter(opt => selectedOptions.has(opt)).map(getValue);
|
|
394
|
+
} else {
|
|
395
|
+
return input.value;
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
set: (val) => {
|
|
399
|
+
if (isMultiple) {
|
|
400
|
+
const values = Array.isArray(val) ? val : (val != null ? [val] : []);
|
|
401
|
+
const opts = [];
|
|
402
|
+
values.forEach(v => {
|
|
403
|
+
const opt = options.find(o => getValue(o) === v && !opts.includes(o));
|
|
404
|
+
if (opt) opts.push(opt);
|
|
405
|
+
});
|
|
406
|
+
updateValue(opts);
|
|
407
|
+
} else {
|
|
408
|
+
const option = options.find(opt => getValue(opt) === val);
|
|
409
|
+
if (option) {
|
|
410
|
+
updateValue(option);
|
|
411
|
+
closePopover();
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
selectComponent.select = select;
|
|
418
|
+
selectComponent.selectByValue = select; // Backward compatibility alias
|
|
420
419
|
if (isMultiple) {
|
|
421
|
-
selectComponent.
|
|
422
|
-
selectComponent.
|
|
420
|
+
selectComponent.deselect = deselect;
|
|
421
|
+
selectComponent.toggle = toggle;
|
|
422
|
+
selectComponent.selectAll = () => updateValue(options);
|
|
423
|
+
selectComponent.selectNone = () => updateValue([]);
|
|
423
424
|
}
|
|
424
425
|
selectComponent.dataset.selectInitialized = true;
|
|
425
426
|
selectComponent.dispatchEvent(new CustomEvent('basecoat:initialized'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{const e=e=>{const t=e.querySelector(":scope > button"),
|
|
1
|
+
(()=>{const e=e=>{const t=e.querySelector(":scope > button"),r=t.querySelector(":scope > span"),n=e.querySelector(":scope > [data-popover]"),i=n?n.querySelector('[role="listbox"]'):null,a=e.querySelector(':scope > input[type="hidden"]'),s=e.querySelector('header input[type="text"]');if(!(t&&n&&i&&a)){const r=[];return t||r.push("trigger"),n||r.push("popover"),i||r.push("listbox"),a||r.push("input"),void console.error(`Select component initialisation failed. Missing element(s): ${r.join(", ")}`,e)}const o=Array.from(i.querySelectorAll('[role="option"]')),c=o.filter((e=>"true"!==e.getAttribute("aria-disabled")));let l=[...c],d=-1;const u="true"===i.getAttribute("aria-multiselectable"),f=u?new Set:null,p=u?e.dataset.placeholder||"":null,v=e=>e.dataset.value??e.textContent.trim(),h=e=>{if(d>-1&&c[d]&&c[d].classList.remove("active"),d=e,d>-1){const e=c[d];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")},b=()=>{const e=getComputedStyle(n);return parseFloat(e.transitionDuration)>0||parseFloat(e.transitionDelay)>0},m=(t,n=!0)=>{let i;if(u){const e=Array.isArray(t)?t:[];f.clear(),e.forEach((e=>f.add(e)));const n=c.filter((e=>f.has(e)));0===n.length?(r.textContent=p,r.classList.add("text-muted-foreground")):(r.textContent=n.map((e=>e.dataset.label||e.textContent.trim())).join(", "),r.classList.remove("text-muted-foreground")),i=n.map(v),a.value=JSON.stringify(i)}else{const e=t;if(!e)return;r.innerHTML=e.innerHTML,i=v(e),a.value=i}c.forEach((e=>{(u?f.has(e):e===t)?e.setAttribute("aria-selected","true"):e.removeAttribute("aria-selected")})),n&&e.dispatchEvent(new CustomEvent("change",{detail:{value:i},bubbles:!0}))},y=(e=!0)=>{if("true"!==n.getAttribute("aria-hidden")){if(s){const e=()=>{s.value="",l=[...c],o.forEach((e=>e.setAttribute("aria-hidden","false")))};b()?n.addEventListener("transitionend",e,{once:!0}):e()}e&&t.focus(),n.setAttribute("aria-hidden","true"),t.setAttribute("aria-expanded","false"),h(-1)}},A=e=>{f.has(e)?f.delete(e):f.add(e),m(c.filter((e=>f.has(e))))},E=e=>{if(u){const t=c.find((t=>v(t)===e&&!f.has(t)));if(!t)return;f.add(t),m(c.filter((e=>f.has(e))))}else{const t=c.find((t=>v(t)===e));if(!t)return;a.value!==e&&m(t),y()}},g=e=>{if(!u)return;const t=c.find((t=>v(t)===e&&f.has(t)));t&&(f.delete(t),m(c.filter((e=>f.has(e)))))},w=e=>{if(!u)return;const t=c.find((t=>v(t)===e));t&&A(t)};if(s){const e=()=>{const e=s.value.trim().toLowerCase();h(-1),l=[],o.forEach((t=>{if(t.hasAttribute("data-force"))return t.setAttribute("aria-hidden","false"),void(c.includes(t)&&l.push(t));const r=(t.dataset.filter||t.textContent).trim().toLowerCase(),n=(t.dataset.keywords||"").toLowerCase().split(/[\s,]+/).filter(Boolean).some((t=>t.includes(e))),i=r.includes(e)||n;t.setAttribute("aria-hidden",String(!i)),i&&c.includes(t)&&l.push(t)}))};s.addEventListener("input",e)}if(u){const e=c.filter((e=>"true"===e.getAttribute("aria-selected")));try{const t=JSON.parse(a.value||"[]"),r=new Set(c.map(v)),n=Array.isArray(t)?t.filter((e=>r.has(e))):[],i=[];n.length>0?n.forEach((e=>{const t=c.find((t=>v(t)===e&&!i.includes(t)));t&&i.push(t)})):i.push(...e),m(i,!1)}catch(t){m(e,!1)}}else{const e=c.find((e=>v(e)===a.value))||c[0];e&&m(e,!1)}const L=e=>{const r="false"===n.getAttribute("aria-hidden");if(!["ArrowDown","ArrowUp","Enter","Home","End","Escape"].includes(e.key))return;if(!r)return void("Enter"!==e.key&&"Escape"!==e.key&&(e.preventDefault(),t.click()));if(e.preventDefault(),"Escape"===e.key)return void y();if("Enter"===e.key){if(d>-1){const e=c[d];u?A(e):(a.value!==v(e)&&m(e),y())}return}if(0===l.length)return;const i=d>-1?l.indexOf(c[d]):-1;let s=i;switch(e.key){case"ArrowDown":i<l.length-1&&(s=i+1);break;case"ArrowUp":i>0?s=i-1:-1===i&&(s=0);break;case"Home":s=0;break;case"End":s=l.length-1}if(s!==i){const e=l[s];h(c.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}};i.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="option"]');if(t&&l.includes(t)){const e=c.indexOf(t);e!==d&&h(e)}})),i.addEventListener("mouseleave",(()=>{const e=i.querySelector('[role="option"][aria-selected="true"]');h(e?c.indexOf(e):-1)})),t.addEventListener("keydown",L),s&&s.addEventListener("keydown",L);t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?y():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),s&&(b()?n.addEventListener("transitionend",(()=>{s.focus()}),{once:!0}):s.focus()),n.setAttribute("aria-hidden","false"),t.setAttribute("aria-expanded","true");const r=i.querySelector('[role="option"][aria-selected="true"]');r&&(h(c.indexOf(r)),r.scrollIntoView({block:"nearest"}))})()})),i.addEventListener("click",(e=>{const r=e.target.closest('[role="option"]');if(!r)return;const n=c.find((e=>e===r));n&&(u?(A(n),h(c.indexOf(n)),s?s.focus():t.focus()):(a.value!==v(n)&&m(n),y()))})),document.addEventListener("click",(t=>{e.contains(t.target)||y(!1)})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&y(!1)})),n.setAttribute("aria-hidden","true"),Object.defineProperty(e,"value",{get:()=>u?c.filter((e=>f.has(e))).map(v):a.value,set:e=>{if(u){const t=Array.isArray(e)?e:null!=e?[e]:[],r=[];t.forEach((e=>{const t=c.find((t=>v(t)===e&&!r.includes(t)));t&&r.push(t)})),m(r)}else{const t=c.find((t=>v(t)===e));t&&(m(t),y())}}}),e.select=E,e.selectByValue=E,u&&(e.deselect=g,e.toggle=w,e.selectAll=()=>m(c),e.selectNone=()=>m([])),e.dataset.selectInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("select","div.select:not([data-select-initialized])",e)})();
|
|
@@ -31,7 +31,13 @@
|
|
|
31
31
|
) %}
|
|
32
32
|
{% set id = id or ("select-" + (range(100000, 999999) | random | string)) %}
|
|
33
33
|
|
|
34
|
-
{%
|
|
34
|
+
{% if selected is defined and selected is iterable and selected is not string %}
|
|
35
|
+
{% set selectedArray = selected %}
|
|
36
|
+
{% elif selected is defined %}
|
|
37
|
+
{% set selectedArray = [selected] %}
|
|
38
|
+
{% else %}
|
|
39
|
+
{% set selectedArray = [] %}
|
|
40
|
+
{% endif %}
|
|
35
41
|
{% set first_option = [] %}
|
|
36
42
|
{% set selected_options = [] %}
|
|
37
43
|
|
|
@@ -135,28 +141,14 @@
|
|
|
135
141
|
{% endif %}
|
|
136
142
|
</div>
|
|
137
143
|
</div>
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
{% if loop.index0 > 0 %}id="{{ id }}-value-{{ loop.index0 }}"{% endif %}
|
|
145
|
-
{% for key, value in input_attrs %}
|
|
146
|
-
{% if key != 'name' and key != 'value' %}{{ key }}="{{ value }}"{% endif %}
|
|
147
|
-
{% endfor %}
|
|
148
|
-
>
|
|
144
|
+
<input
|
|
145
|
+
type="hidden"
|
|
146
|
+
name="{{ name or id ~ '-value' }}"
|
|
147
|
+
value="{% if multiple %}{{ selectedArray | dump }}{% else %}{{ (default_option.value if default_option) or '' }}{% endif %}"
|
|
148
|
+
{% for key, value in input_attrs %}
|
|
149
|
+
{% if key != 'name' and key != 'value' %}{{ key }}="{{ value }}"{% endif %}
|
|
149
150
|
{% endfor %}
|
|
150
|
-
|
|
151
|
-
<input
|
|
152
|
-
type="hidden"
|
|
153
|
-
name="{{ name or id ~ '-value' }}"
|
|
154
|
-
value="{{ (default_option.value if default_option) or '' }}"
|
|
155
|
-
{% for key, value in input_attrs %}
|
|
156
|
-
{% if key != 'name' and key != 'value' %}{{ key }}="{{ value }}"{% endif %}
|
|
157
|
-
{% endfor %}
|
|
158
|
-
>
|
|
159
|
-
{% endif %}
|
|
151
|
+
>
|
|
160
152
|
</div>
|
|
161
153
|
{% endmacro %}
|
|
162
154
|
|
|
@@ -189,7 +181,7 @@
|
|
|
189
181
|
<div
|
|
190
182
|
id="{{ item_id }}"
|
|
191
183
|
role="option"
|
|
192
|
-
data-value="{{ item.value }}"
|
|
184
|
+
{% if item.value is defined and item.value is not none %}data-value="{{ item.value }}"{% endif %}
|
|
193
185
|
{% if item.value in selectedArray %}aria-selected="true"{% endif %}
|
|
194
186
|
{% if item.attrs %}
|
|
195
187
|
{% for key, value in item.attrs %}
|
|
@@ -201,4 +193,4 @@
|
|
|
201
193
|
</div>
|
|
202
194
|
{% endif %}
|
|
203
195
|
{% endfor %}
|
|
204
|
-
{% endmacro %}
|
|
196
|
+
{% endmacro %}
|