tyrell-components 1.0.0-TC54 → 1.0.0-TC56
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 +53 -53
- package/css/tyrell-theme.css +7 -2
- package/css/tyrell.css +6 -15
- package/dist/tyrell-theme.css +1 -1
- package/dist/tyrell.css +1 -1
- package/dist/tyrell.js +1 -1
- package/lib/base/ty-component.d.ts +14 -0
- package/lib/base/ty-component.d.ts.map +1 -0
- package/lib/base/ty-component.js +27 -0
- package/lib/base/ty-component.js.map +1 -0
- package/lib/components/button.d.ts.map +1 -0
- package/lib/components/button.js +7 -0
- package/lib/components/button.js.map +1 -0
- package/lib/components/calendar-month.d.ts.map +1 -0
- package/lib/components/calendar-month.js +20 -6
- package/lib/components/calendar-month.js.map +1 -0
- package/lib/components/calendar-navigation.d.ts +11 -0
- package/lib/components/calendar-navigation.d.ts.map +1 -0
- package/lib/components/calendar-navigation.js +51 -40
- package/lib/components/calendar-navigation.js.map +1 -0
- package/lib/components/calendar.d.ts +31 -3
- package/lib/components/calendar.d.ts.map +1 -0
- package/lib/components/calendar.js +197 -18
- package/lib/components/calendar.js.map +1 -0
- package/lib/components/checkbox.d.ts.map +1 -0
- package/lib/components/checkbox.js +3 -3
- package/lib/components/checkbox.js.map +1 -0
- package/lib/components/copy.d.ts.map +1 -0
- package/lib/components/copy.js +14 -6
- package/lib/components/copy.js.map +1 -0
- package/lib/components/date-picker.d.ts +15 -9
- package/lib/components/date-picker.d.ts.map +1 -0
- package/lib/components/date-picker.js +187 -236
- package/lib/components/date-picker.js.map +1 -0
- package/lib/components/dropdown.d.ts +403 -0
- package/lib/components/dropdown.d.ts.map +1 -0
- package/lib/components/dropdown.js +1315 -0
- package/lib/components/dropdown.js.map +1 -0
- package/lib/components/file-upload.d.ts +4 -0
- package/lib/components/file-upload.js +14 -0
- package/lib/components/icon.d.ts.map +1 -0
- package/lib/components/icon.js.map +1 -0
- package/lib/components/input.d.ts.map +1 -0
- package/lib/components/input.js +3 -3
- package/lib/components/input.js.map +1 -0
- package/lib/components/modal.d.ts +2 -8
- package/lib/components/modal.d.ts.map +1 -0
- package/lib/components/modal.js +8 -18
- package/lib/components/modal.js.map +1 -0
- package/lib/components/multiselect.d.ts +389 -0
- package/lib/components/multiselect.d.ts.map +1 -0
- package/lib/components/multiselect.js +1301 -0
- package/lib/components/multiselect.js.map +1 -0
- package/lib/components/option.d.ts.map +1 -0
- package/lib/components/option.js +1 -1
- package/lib/components/option.js.map +1 -0
- package/lib/components/popup.d.ts.map +1 -0
- package/lib/components/popup.js +4 -1
- package/lib/components/popup.js.map +1 -0
- package/lib/components/radio.d.ts +15 -0
- package/lib/components/radio.js +34 -4
- package/lib/components/resize-observer.d.ts.map +1 -0
- package/lib/components/resize-observer.js.map +1 -0
- package/lib/components/scroll-container.d.ts +3 -2
- package/lib/components/scroll-container.d.ts.map +1 -0
- package/lib/components/scroll-container.js +14 -19
- package/lib/components/scroll-container.js.map +1 -0
- package/lib/components/select.d.ts +52 -16
- package/lib/components/select.js +170 -67
- package/lib/components/step.d.ts.map +1 -0
- package/lib/components/step.js.map +1 -0
- package/lib/components/switch.js +3 -3
- package/lib/components/tab.d.ts +49 -1
- package/lib/components/tab.d.ts.map +1 -0
- package/lib/components/tab.js +151 -10
- package/lib/components/tab.js.map +1 -0
- package/lib/components/tabs.d.ts +14 -2
- package/lib/components/tabs.d.ts.map +1 -0
- package/lib/components/tabs.js +186 -130
- package/lib/components/tabs.js.map +1 -0
- package/lib/components/tag.d.ts +4 -7
- package/lib/components/tag.d.ts.map +1 -0
- package/lib/components/tag.js +6 -7
- package/lib/components/tag.js.map +1 -0
- package/lib/components/textarea.d.ts +4 -3
- package/lib/components/textarea.d.ts.map +1 -0
- package/lib/components/textarea.js +16 -15
- package/lib/components/textarea.js.map +1 -0
- package/lib/components/tooltip.d.ts +4 -3
- package/lib/components/tooltip.d.ts.map +1 -0
- package/lib/components/tooltip.js +34 -24
- package/lib/components/tooltip.js.map +1 -0
- package/lib/components/wizard.d.ts +5 -4
- package/lib/components/wizard.d.ts.map +1 -0
- package/lib/components/wizard.js +120 -156
- package/lib/components/wizard.js.map +1 -0
- package/lib/icons/fontawesome/brands.d.ts.map +1 -0
- package/lib/icons/fontawesome/brands.js.map +1 -0
- package/lib/icons/fontawesome/regular.d.ts.map +1 -0
- package/lib/icons/fontawesome/regular.js.map +1 -0
- package/lib/icons/fontawesome/solid.d.ts.map +1 -0
- package/lib/icons/fontawesome/solid.js.map +1 -0
- package/lib/icons/heroicons/micro.d.ts.map +1 -0
- package/lib/icons/heroicons/micro.js.map +1 -0
- package/lib/icons/heroicons/mini.d.ts.map +1 -0
- package/lib/icons/heroicons/mini.js.map +1 -0
- package/lib/icons/heroicons/outline.d.ts.map +1 -0
- package/lib/icons/heroicons/outline.js.map +1 -0
- package/lib/icons/heroicons/solid.d.ts.map +1 -0
- package/lib/icons/heroicons/solid.js.map +1 -0
- package/lib/icons/lucide.d.ts.map +1 -0
- package/lib/icons/lucide.js.map +1 -0
- package/lib/icons/material/filled.d.ts.map +1 -0
- package/lib/icons/material/filled.js.map +1 -0
- package/lib/icons/material/outlined.d.ts.map +1 -0
- package/lib/icons/material/outlined.js.map +1 -0
- package/lib/icons/material/round.d.ts.map +1 -0
- package/lib/icons/material/round.js.map +1 -0
- package/lib/icons/material/sharp.d.ts.map +1 -0
- package/lib/icons/material/sharp.js.map +1 -0
- package/lib/icons/material/two-tone.d.ts.map +1 -0
- package/lib/icons/material/two-tone.js.map +1 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js.map +1 -0
- package/lib/styles/button.d.ts.map +1 -0
- package/lib/styles/button.js +68 -58
- package/lib/styles/button.js.map +1 -0
- package/lib/styles/calendar-month.d.ts +3 -0
- package/lib/styles/calendar-month.d.ts.map +1 -0
- package/lib/styles/calendar-month.js +47 -31
- package/lib/styles/calendar-month.js.map +1 -0
- package/lib/styles/calendar-navigation.d.ts +1 -1
- package/lib/styles/calendar-navigation.d.ts.map +1 -0
- package/lib/styles/calendar-navigation.js +55 -22
- package/lib/styles/calendar-navigation.js.map +1 -0
- package/lib/styles/calendar.d.ts +3 -2
- package/lib/styles/calendar.d.ts.map +1 -0
- package/lib/styles/calendar.js +75 -0
- package/lib/styles/calendar.js.map +1 -0
- package/lib/styles/checkbox.js +22 -10
- package/lib/styles/copy.d.ts.map +1 -0
- package/lib/styles/copy.js +5 -1
- package/lib/styles/copy.js.map +1 -0
- package/lib/styles/date-picker.d.ts.map +1 -0
- package/lib/styles/date-picker.js +52 -22
- package/lib/styles/date-picker.js.map +1 -0
- package/lib/styles/dropdown.d.ts +12 -0
- package/lib/styles/dropdown.d.ts.map +1 -0
- package/lib/styles/dropdown.js +725 -0
- package/lib/styles/dropdown.js.map +1 -0
- package/lib/styles/icon.d.ts.map +1 -0
- package/lib/styles/icon.js.map +1 -0
- package/lib/styles/input.d.ts.map +1 -0
- package/lib/styles/input.js.map +1 -0
- package/lib/styles/modal.d.ts.map +1 -0
- package/lib/styles/modal.js.map +1 -0
- package/lib/styles/multiselect.d.ts +6 -0
- package/lib/styles/multiselect.d.ts.map +1 -0
- package/lib/styles/multiselect.js +568 -0
- package/lib/styles/multiselect.js.map +1 -0
- package/lib/styles/option.d.ts +1 -1
- package/lib/styles/option.d.ts.map +1 -0
- package/lib/styles/option.js +3 -3
- package/lib/styles/option.js.map +1 -0
- package/lib/styles/popup.d.ts +1 -1
- package/lib/styles/popup.d.ts.map +1 -0
- package/lib/styles/popup.js +8 -5
- package/lib/styles/popup.js.map +1 -0
- package/lib/styles/radio.js +8 -2
- package/lib/styles/resize-observer.d.ts.map +1 -0
- package/lib/styles/resize-observer.js.map +1 -0
- package/lib/styles/scroll-container.d.ts +1 -1
- package/lib/styles/scroll-container.d.ts.map +1 -0
- package/lib/styles/scroll-container.js +1 -1
- package/lib/styles/scroll-container.js.map +1 -0
- package/lib/styles/select-base.js +81 -14
- package/lib/styles/select.d.ts +1 -1
- package/lib/styles/select.js +6 -0
- package/lib/styles/step.d.ts +1 -1
- package/lib/styles/step.d.ts.map +1 -0
- package/lib/styles/step.js +1 -9
- package/lib/styles/step.js.map +1 -0
- package/lib/styles/switch.js +6 -3
- package/lib/styles/tab.d.ts +1 -1
- package/lib/styles/tab.d.ts.map +1 -0
- package/lib/styles/tab.js +67 -3
- package/lib/styles/tab.js.map +1 -0
- package/lib/styles/tabs.d.ts +1 -1
- package/lib/styles/tabs.d.ts.map +1 -0
- package/lib/styles/tabs.js +7 -3
- package/lib/styles/tabs.js.map +1 -0
- package/lib/styles/tag.d.ts.map +1 -0
- package/lib/styles/tag.js +1 -2
- package/lib/styles/tag.js.map +1 -0
- package/lib/styles/textarea.d.ts.map +1 -0
- package/lib/styles/textarea.js.map +1 -0
- package/lib/styles/tooltip.d.ts.map +1 -0
- package/lib/styles/tooltip.js.map +1 -0
- package/lib/styles/wizard.d.ts +9 -5
- package/lib/styles/wizard.d.ts.map +1 -0
- package/lib/styles/wizard.js +211 -99
- package/lib/styles/wizard.js.map +1 -0
- package/lib/types/common.d.ts +2 -2
- package/lib/types/common.d.ts.map +1 -0
- package/lib/types/common.js.map +1 -0
- package/lib/utils/calendar-utils.d.ts.map +1 -0
- package/lib/utils/calendar-utils.js.map +1 -0
- package/lib/utils/icon-registry.d.ts.map +1 -0
- package/lib/utils/icon-registry.js.map +1 -0
- package/lib/utils/locale.d.ts.map +1 -0
- package/lib/utils/locale.js.map +1 -0
- package/lib/utils/number-format.d.ts.map +1 -0
- package/lib/utils/number-format.js.map +1 -0
- package/lib/utils/parse-boolean.d.ts +39 -0
- package/lib/utils/parse-boolean.d.ts.map +1 -0
- package/lib/utils/parse-boolean.js +23 -0
- package/lib/utils/parse-boolean.js.map +1 -0
- package/lib/utils/positioning.d.ts.map +1 -0
- package/lib/utils/positioning.js.map +1 -0
- package/lib/utils/property-capture.d.ts.map +1 -0
- package/lib/utils/property-capture.js.map +1 -0
- package/lib/utils/property-manager.d.ts +1 -1
- package/lib/utils/property-manager.d.ts.map +1 -0
- package/lib/utils/property-manager.js +2 -0
- package/lib/utils/property-manager.js.map +1 -0
- package/lib/utils/resize-observer.d.ts.map +1 -0
- package/lib/utils/resize-observer.js.map +1 -0
- package/lib/utils/scroll-lock.d.ts.map +1 -0
- package/lib/utils/scroll-lock.js.map +1 -0
- package/lib/utils/styles.d.ts.map +1 -0
- package/lib/utils/styles.js.map +1 -0
- package/lib/utils/validity.d.ts +26 -0
- package/lib/utils/validity.js +53 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.d.ts.map +1 -0
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -0
- package/package.json +25 -4
package/lib/components/select.js
CHANGED
|
@@ -20,10 +20,10 @@ elementIds.set(element, id);
|
|
|
20
20
|
return id;
|
|
21
21
|
}
|
|
22
22
|
import { REQUIRED_ICON_SVG } from "../utils/icons.js";
|
|
23
|
+
const SEARCH_AUTO_THRESHOLD = 7;
|
|
23
24
|
const CHEVRON_DOWN_SVG = `<svg viewBox="0 0 20 20" fill="currentColor">
|
|
24
25
|
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
|
|
25
26
|
</svg>`;
|
|
26
|
-
const SEARCH_AUTO_THRESHOLD = 7;
|
|
27
27
|
function slugify(text) {
|
|
28
28
|
return text
|
|
29
29
|
.trim()
|
|
@@ -55,11 +55,12 @@ this._clearable = true;
|
|
|
55
55
|
this._externalSearch = false;
|
|
56
56
|
this._allowCreate = false;
|
|
57
57
|
this._createTransform = "none";
|
|
58
|
-
this.
|
|
58
|
+
this._notSearchable = false;
|
|
59
59
|
this._loading = false;
|
|
60
60
|
this._scrollLockId = null;
|
|
61
61
|
this._size = DEFAULT_SIZE;
|
|
62
62
|
this._availableLabel = "Available";
|
|
63
|
+
this._selectedLabel = "Selected";
|
|
63
64
|
this._noOptionsMessage = "No options available";
|
|
64
65
|
this._state = {
|
|
65
66
|
open: false,
|
|
@@ -177,16 +178,16 @@ break;
|
|
|
177
178
|
case "required":
|
|
178
179
|
this._required = newValue;
|
|
179
180
|
break;
|
|
180
|
-
case "
|
|
181
|
-
this._clearable = newValue;
|
|
181
|
+
case "noClear":
|
|
182
|
+
this._clearable = !newValue;
|
|
182
183
|
if (this.isConnected && this.shadowRoot)
|
|
183
184
|
this.updateSelectionDisplay();
|
|
184
185
|
break;
|
|
185
186
|
case "externalSearch":
|
|
186
187
|
this._externalSearch = newValue;
|
|
187
188
|
break;
|
|
188
|
-
case "
|
|
189
|
-
this.
|
|
189
|
+
case "notSearchable":
|
|
190
|
+
this._notSearchable = newValue;
|
|
190
191
|
if (this.isConnected && this.shadowRoot)
|
|
191
192
|
this.updateSearchVisibility();
|
|
192
193
|
break;
|
|
@@ -207,6 +208,9 @@ break;
|
|
|
207
208
|
case "available-label":
|
|
208
209
|
this._availableLabel = newValue || "Available";
|
|
209
210
|
break;
|
|
211
|
+
case "selected-label":
|
|
212
|
+
this._selectedLabel = newValue || "Selected";
|
|
213
|
+
break;
|
|
210
214
|
case "no-options-message":
|
|
211
215
|
this._noOptionsMessage = newValue || "No options available";
|
|
212
216
|
break;
|
|
@@ -698,6 +702,8 @@ e.stopPropagation();
|
|
|
698
702
|
e.preventDefault();
|
|
699
703
|
}
|
|
700
704
|
handleSearchInput(e) {
|
|
705
|
+
if (this._state.mode === "mobile")
|
|
706
|
+
this.expandMobileSection("available");
|
|
701
707
|
const target = e.target;
|
|
702
708
|
const query = target.value;
|
|
703
709
|
this._state.search = query;
|
|
@@ -730,7 +736,12 @@ switch (e.key) {
|
|
|
730
736
|
case "Escape":
|
|
731
737
|
e.preventDefault();
|
|
732
738
|
e.stopPropagation();
|
|
739
|
+
if (this._state.mode === "mobile") {
|
|
740
|
+
this.closeMobileModal();
|
|
741
|
+
}
|
|
742
|
+
else {
|
|
733
743
|
this.closeDropdown();
|
|
744
|
+
}
|
|
734
745
|
break;
|
|
735
746
|
case "Enter":
|
|
736
747
|
e.preventDefault();
|
|
@@ -746,43 +757,33 @@ break;
|
|
|
746
757
|
case "ArrowUp":
|
|
747
758
|
e.preventDefault();
|
|
748
759
|
e.stopPropagation();
|
|
749
|
-
|
|
750
|
-
if (tagsCount === 0) {
|
|
751
|
-
newIndexUp = -1;
|
|
752
|
-
}
|
|
753
|
-
else if (currentHighlightedIndex === -1) {
|
|
754
|
-
newIndexUp = tagsCount - 1;
|
|
755
|
-
}
|
|
756
|
-
else if (currentHighlightedIndex === 0) {
|
|
757
|
-
newIndexUp = tagsCount - 1;
|
|
758
|
-
}
|
|
759
|
-
else {
|
|
760
|
-
newIndexUp = currentHighlightedIndex - 1;
|
|
761
|
-
}
|
|
760
|
+
const newIndexUp = this.nextEnabledTagIndex(filteredTags, currentHighlightedIndex, -1);
|
|
762
761
|
this._state.highlightedIndex = newIndexUp;
|
|
763
762
|
this.highlightTag(filteredTags, newIndexUp);
|
|
764
763
|
break;
|
|
765
764
|
case "ArrowDown":
|
|
766
765
|
e.preventDefault();
|
|
767
766
|
e.stopPropagation();
|
|
768
|
-
|
|
769
|
-
if (tagsCount === 0) {
|
|
770
|
-
newIndexDown = -1;
|
|
771
|
-
}
|
|
772
|
-
else if (currentHighlightedIndex === -1) {
|
|
773
|
-
newIndexDown = 0;
|
|
774
|
-
}
|
|
775
|
-
else if (currentHighlightedIndex === tagsCount - 1) {
|
|
776
|
-
newIndexDown = 0;
|
|
777
|
-
}
|
|
778
|
-
else {
|
|
779
|
-
newIndexDown = currentHighlightedIndex + 1;
|
|
780
|
-
}
|
|
767
|
+
const newIndexDown = this.nextEnabledTagIndex(filteredTags, currentHighlightedIndex, 1);
|
|
781
768
|
this._state.highlightedIndex = newIndexDown;
|
|
782
769
|
this.highlightTag(filteredTags, newIndexDown);
|
|
783
770
|
break;
|
|
784
771
|
}
|
|
785
772
|
}
|
|
773
|
+
nextEnabledTagIndex(tags, fromIndex, direction) {
|
|
774
|
+
const count = tags.length;
|
|
775
|
+
if (count === 0)
|
|
776
|
+
return -1;
|
|
777
|
+
let index = fromIndex === -1
|
|
778
|
+
? (direction === 1 ? 0 : count - 1)
|
|
779
|
+
: (fromIndex + direction + count) % count;
|
|
780
|
+
for (let i = 0; i < count; i++) {
|
|
781
|
+
if (!tags[index].element.hasAttribute("disabled"))
|
|
782
|
+
return index;
|
|
783
|
+
index = (index + direction + count) % count;
|
|
784
|
+
}
|
|
785
|
+
return -1;
|
|
786
|
+
}
|
|
786
787
|
filterTags(tags, query) {
|
|
787
788
|
if (!query || query.trim() === "") {
|
|
788
789
|
return tags;
|
|
@@ -880,19 +881,58 @@ this.renderDesktop();
|
|
|
880
881
|
}
|
|
881
882
|
this.updateSearchVisibility();
|
|
882
883
|
this.applyLoadingState();
|
|
884
|
+
this.syncFieldChrome();
|
|
883
885
|
this.updateValidity();
|
|
884
886
|
}
|
|
887
|
+
syncFieldChrome() {
|
|
888
|
+
const shadow = this.shadowRoot;
|
|
889
|
+
const container = shadow?.querySelector(".select-container");
|
|
890
|
+
if (!shadow || !container)
|
|
891
|
+
return;
|
|
892
|
+
const labelId = `select-label-${getElementHash(this)}`;
|
|
893
|
+
let label = container.querySelector(":scope > .ty-field-label");
|
|
894
|
+
if (this._label) {
|
|
895
|
+
if (!label) {
|
|
896
|
+
label = document.createElement("label");
|
|
897
|
+
label.className = "ty-field-label";
|
|
898
|
+
label.id = labelId;
|
|
899
|
+
container.prepend(label);
|
|
900
|
+
}
|
|
901
|
+
label.innerHTML = `${this._label}${this._required ? `<span class="required-icon">${REQUIRED_ICON_SVG}</span>` : ""}`;
|
|
902
|
+
}
|
|
903
|
+
else {
|
|
904
|
+
label?.remove();
|
|
905
|
+
}
|
|
906
|
+
const stub = shadow.querySelector(".select-stub");
|
|
907
|
+
if (stub) {
|
|
908
|
+
stub.classList.toggle("disabled", this._disabled);
|
|
909
|
+
stub.classList.toggle("compact", this._compact);
|
|
910
|
+
stub.tabIndex = this._disabled ? -1 : 0;
|
|
911
|
+
stub.toggleAttribute("disabled", this._disabled);
|
|
912
|
+
if (this._disabled)
|
|
913
|
+
stub.setAttribute("aria-disabled", "true");
|
|
914
|
+
else
|
|
915
|
+
stub.removeAttribute("aria-disabled");
|
|
916
|
+
if (this._label)
|
|
917
|
+
stub.setAttribute("aria-labelledby", labelId);
|
|
918
|
+
else
|
|
919
|
+
stub.removeAttribute("aria-labelledby");
|
|
920
|
+
}
|
|
921
|
+
shadow
|
|
922
|
+
.querySelectorAll(".dropdown-search-input, .mobile-search-input")
|
|
923
|
+
.forEach((input) => (input.disabled = this._disabled));
|
|
924
|
+
}
|
|
885
925
|
updateValidity() {
|
|
886
926
|
if (this.disabled) {
|
|
887
|
-
this.
|
|
927
|
+
this.applyValidity({});
|
|
888
928
|
return;
|
|
889
929
|
}
|
|
890
930
|
if (this.required && this.getSelectedValues().length === 0) {
|
|
891
931
|
const stub = this.shadowRoot?.querySelector(".select-stub");
|
|
892
|
-
this.
|
|
932
|
+
this.applyValidity({ valueMissing: true }, "Please select a value", stub ?? undefined);
|
|
893
933
|
}
|
|
894
934
|
else {
|
|
895
|
-
this.
|
|
935
|
+
this.applyValidity({});
|
|
896
936
|
}
|
|
897
937
|
}
|
|
898
938
|
setupTriggerSlot() {
|
|
@@ -1098,12 +1138,21 @@ ${CHEVRON_DOWN_SVG}
|
|
|
1098
1138
|
<!-- HEADER (matches dropdown.ts) -->
|
|
1099
1139
|
${searchHeaderHtml}
|
|
1100
1140
|
<!-- BODY: options list with toggleable selected state -->
|
|
1101
|
-
<div class="mobile-body">
|
|
1141
|
+
<div class="mobile-body" data-expanded="available">
|
|
1142
|
+
<!-- SELECTED STRIP (pinned above the list, collapses when empty) -->
|
|
1143
|
+
<div class="mobile-selected-section" data-empty="true">
|
|
1144
|
+
<button class="section-header" type="button" data-section="selected" aria-expanded="false">
|
|
1145
|
+
<span class="section-title">${this._selectedLabel} <span class="section-count">(0)</span></span>
|
|
1146
|
+
${CHEVRON_DOWN_SVG}
|
|
1147
|
+
</button>
|
|
1148
|
+
<div class="section-content mobile-selected-chips"></div>
|
|
1149
|
+
</div>
|
|
1102
1150
|
<!-- AVAILABLE LIST (always visible, takes remaining space) -->
|
|
1103
1151
|
<div class="mobile-available-section" data-empty="false">
|
|
1104
|
-
<
|
|
1105
|
-
<span class="section-title">${this._availableLabel}
|
|
1106
|
-
|
|
1152
|
+
<button class="section-header" type="button" data-section="available" aria-expanded="true">
|
|
1153
|
+
<span class="section-title">${this._availableLabel} <span class="section-count"></span></span>
|
|
1154
|
+
${CHEVRON_DOWN_SVG}
|
|
1155
|
+
</button>
|
|
1107
1156
|
<div class="section-content dropdown-options-wrapper" id="${listboxId}" role="listbox" ${this._multiple ? 'aria-multiselectable="true"' : ""}>
|
|
1108
1157
|
<slot id="options-slot"></slot>
|
|
1109
1158
|
<div class="empty-state">${this._noOptionsMessage}</div>
|
|
@@ -1126,6 +1175,10 @@ this.setupMobileEventListeners();
|
|
|
1126
1175
|
this.updateSelectionDisplay();
|
|
1127
1176
|
}
|
|
1128
1177
|
setupMobileEventListeners() {
|
|
1178
|
+
if (!this._keyboardHandler) {
|
|
1179
|
+
this._keyboardHandler = this.handleKeyboard.bind(this);
|
|
1180
|
+
document.addEventListener("keydown", this._keyboardHandler);
|
|
1181
|
+
}
|
|
1129
1182
|
const shadow = this.shadowRoot;
|
|
1130
1183
|
const stub = shadow.querySelector(".select-stub");
|
|
1131
1184
|
const optionsSlot = shadow.querySelector("#options-slot");
|
|
@@ -1145,6 +1198,9 @@ optionsSlot.addEventListener("click", (e) => this.handleMobileTagClick(e));
|
|
|
1145
1198
|
if (searchInput) {
|
|
1146
1199
|
searchInput.addEventListener("input", (e) => this.handleSearchInput(e));
|
|
1147
1200
|
}
|
|
1201
|
+
shadow.querySelectorAll(".mobile-body .section-header").forEach((header) => {
|
|
1202
|
+
header.addEventListener("click", () => this.expandMobileSection(header.dataset.section === "selected" ? "selected" : "available"));
|
|
1203
|
+
});
|
|
1148
1204
|
if (closeButton) {
|
|
1149
1205
|
closeButton.addEventListener("click", () => this.closeMobileModal());
|
|
1150
1206
|
}
|
|
@@ -1183,24 +1239,74 @@ updateMobileSelectedState() {
|
|
|
1183
1239
|
if (this._state.mode !== "mobile")
|
|
1184
1240
|
return;
|
|
1185
1241
|
const shadow = this.shadowRoot;
|
|
1242
|
+
this.renderMobileSelectedChips();
|
|
1186
1243
|
const availableSection = shadow.querySelector(".mobile-available-section");
|
|
1187
1244
|
if (availableSection) {
|
|
1188
|
-
const visibleAvailable = this.getTagElements().filter((tag) => !tag.hasAttribute("hidden")).length;
|
|
1245
|
+
const visibleAvailable = this.getTagElements().filter((tag) => !tag.hasAttribute("hidden") && !tag.hasAttribute("selected")).length;
|
|
1189
1246
|
availableSection.setAttribute("data-empty", String(visibleAvailable === 0));
|
|
1190
|
-
|
|
1191
|
-
if (availableTitleSpan) {
|
|
1192
|
-
availableTitleSpan.textContent = `${this._availableLabel} (${visibleAvailable})`;
|
|
1247
|
+
this.setMobileSectionTitle(availableSection, this._availableLabel, visibleAvailable);
|
|
1193
1248
|
}
|
|
1194
1249
|
}
|
|
1250
|
+
setMobileSectionTitle(section, label, n) {
|
|
1251
|
+
const title = section.querySelector(".section-title");
|
|
1252
|
+
if (!title)
|
|
1253
|
+
return;
|
|
1254
|
+
const count = document.createElement("span");
|
|
1255
|
+
count.className = "section-count";
|
|
1256
|
+
count.textContent = `(${n})`;
|
|
1257
|
+
title.replaceChildren(`${label} `, count);
|
|
1258
|
+
}
|
|
1259
|
+
expandMobileSection(section) {
|
|
1260
|
+
const shadow = this.shadowRoot;
|
|
1261
|
+
const body = shadow?.querySelector(".mobile-body");
|
|
1262
|
+
if (!body)
|
|
1263
|
+
return;
|
|
1264
|
+
if (section === "selected" && this._state.selectedValues.length === 0)
|
|
1265
|
+
return;
|
|
1266
|
+
body.dataset.expanded = section;
|
|
1267
|
+
shadow.querySelectorAll(".mobile-body .section-header").forEach((header) => {
|
|
1268
|
+
const owns = header.dataset.section === section;
|
|
1269
|
+
header.setAttribute("aria-expanded", String(owns));
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1272
|
+
renderMobileSelectedChips() {
|
|
1273
|
+
const shadow = this.shadowRoot;
|
|
1274
|
+
const section = shadow.querySelector(".mobile-selected-section");
|
|
1275
|
+
const host = shadow.querySelector(".mobile-selected-chips");
|
|
1276
|
+
if (!section || !host)
|
|
1277
|
+
return;
|
|
1278
|
+
const selected = this._state.selectedValues;
|
|
1279
|
+
section.setAttribute("data-empty", String(selected.length === 0));
|
|
1280
|
+
this.setMobileSectionTitle(section, this._selectedLabel, selected.length);
|
|
1281
|
+
if (selected.length === 0)
|
|
1282
|
+
this.expandMobileSection("available");
|
|
1283
|
+
const labelFor = (value) => {
|
|
1284
|
+
const option = this.getTagElements().find((tag) => this.getTagData(tag).value === value);
|
|
1285
|
+
return option ? this.getTagData(option).text : value;
|
|
1286
|
+
};
|
|
1287
|
+
host.textContent = "";
|
|
1288
|
+
for (const value of selected) {
|
|
1289
|
+
const chip = document.createElement("button");
|
|
1290
|
+
chip.type = "button";
|
|
1291
|
+
chip.className = "mobile-selected-chip";
|
|
1292
|
+
chip.dataset.value = value;
|
|
1293
|
+
chip.setAttribute("aria-label", `Remove ${labelFor(value)}`);
|
|
1294
|
+
chip.innerHTML = `<span class="chip-label"></span>${CLEAR_ICON_SVG}`;
|
|
1295
|
+
chip.querySelector(".chip-label").textContent = labelFor(value);
|
|
1296
|
+
chip.addEventListener("click", (e) => {
|
|
1297
|
+
e.preventDefault();
|
|
1298
|
+
e.stopPropagation();
|
|
1299
|
+
this.deselectValue(value);
|
|
1300
|
+
});
|
|
1301
|
+
host.appendChild(chip);
|
|
1302
|
+
}
|
|
1195
1303
|
}
|
|
1196
1304
|
shouldShowSearch() {
|
|
1197
1305
|
if (this._externalSearch)
|
|
1198
1306
|
return true;
|
|
1199
1307
|
if (this._allowCreate)
|
|
1200
1308
|
return true;
|
|
1201
|
-
if (this.
|
|
1202
|
-
return true;
|
|
1203
|
-
if (this._searchable === "never")
|
|
1309
|
+
if (this._notSearchable)
|
|
1204
1310
|
return false;
|
|
1205
1311
|
return this.getTagElements().length > SEARCH_AUTO_THRESHOLD;
|
|
1206
1312
|
}
|
|
@@ -1359,11 +1465,11 @@ return this.getProperty("readonly");
|
|
|
1359
1465
|
set readonly(value) {
|
|
1360
1466
|
this.setProperty("readonly", value);
|
|
1361
1467
|
}
|
|
1362
|
-
get
|
|
1363
|
-
return this.getProperty("
|
|
1468
|
+
get noClear() {
|
|
1469
|
+
return this.getProperty("noClear");
|
|
1364
1470
|
}
|
|
1365
|
-
set
|
|
1366
|
-
this.setProperty("
|
|
1471
|
+
set noClear(value) {
|
|
1472
|
+
this.setProperty("noClear", value);
|
|
1367
1473
|
}
|
|
1368
1474
|
get required() {
|
|
1369
1475
|
return this.getProperty("required");
|
|
@@ -1371,11 +1477,11 @@ return this.getProperty("required");
|
|
|
1371
1477
|
set required(value) {
|
|
1372
1478
|
this.setProperty("required", value);
|
|
1373
1479
|
}
|
|
1374
|
-
get
|
|
1375
|
-
return this.getProperty("
|
|
1480
|
+
get notSearchable() {
|
|
1481
|
+
return this.getProperty("notSearchable");
|
|
1376
1482
|
}
|
|
1377
|
-
set
|
|
1378
|
-
this.setProperty("
|
|
1483
|
+
set notSearchable(value) {
|
|
1484
|
+
this.setProperty("notSearchable", value);
|
|
1379
1485
|
}
|
|
1380
1486
|
get externalSearch() {
|
|
1381
1487
|
return this.getProperty("externalSearch");
|
|
@@ -1474,11 +1580,10 @@ type: "boolean",
|
|
|
1474
1580
|
visual: true,
|
|
1475
1581
|
default: false,
|
|
1476
1582
|
},
|
|
1477
|
-
|
|
1583
|
+
noClear: {
|
|
1478
1584
|
type: "boolean",
|
|
1479
1585
|
visual: true,
|
|
1480
|
-
default:
|
|
1481
|
-
aliases: { "not-clearable": false },
|
|
1586
|
+
default: false,
|
|
1482
1587
|
},
|
|
1483
1588
|
externalSearch: {
|
|
1484
1589
|
type: "boolean",
|
|
@@ -1499,17 +1604,10 @@ default: "none",
|
|
|
1499
1604
|
aliases: { "create-transform": true },
|
|
1500
1605
|
coerce: (v) => (v === "slug" ? "slug" : "none"),
|
|
1501
1606
|
},
|
|
1502
|
-
|
|
1503
|
-
type: "
|
|
1607
|
+
notSearchable: {
|
|
1608
|
+
type: "boolean",
|
|
1504
1609
|
visual: true,
|
|
1505
|
-
default:
|
|
1506
|
-
coerce: (v) => {
|
|
1507
|
-
if (v === true || v === "" || v === "true")
|
|
1508
|
-
return "always";
|
|
1509
|
-
if (v === false || v === "false")
|
|
1510
|
-
return "never";
|
|
1511
|
-
return "auto";
|
|
1512
|
-
},
|
|
1610
|
+
default: false,
|
|
1513
1611
|
},
|
|
1514
1612
|
align: {
|
|
1515
1613
|
type: "string",
|
|
@@ -1552,6 +1650,11 @@ type: "string",
|
|
|
1552
1650
|
visual: true,
|
|
1553
1651
|
default: "Available",
|
|
1554
1652
|
},
|
|
1653
|
+
"selected-label": {
|
|
1654
|
+
type: "string",
|
|
1655
|
+
visual: true,
|
|
1656
|
+
default: "Selected",
|
|
1657
|
+
},
|
|
1555
1658
|
"no-options-message": {
|
|
1556
1659
|
type: "string",
|
|
1557
1660
|
visual: true,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step.d.ts","sourceRoot":"","sources":["../../src/components/step.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;CAC3B;AAiED;;GAEG;AACH,qBAAa,MAAO,SAAQ,WAAW;IACrC,0BAA0B;IAC1B,MAAM,KAAK,kBAAkB,aAE5B;;IAOD,iBAAiB;IAIjB,oBAAoB;IAIpB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;CAG3F"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step.js","sourceRoot":"","sources":["../../src/components/step.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAsB/C,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E;;GAEG;AACH,SAAS,iBAAiB,CAAC,EAAU;IACnC,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,aAAa,GAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAEhF,OAAO;QACL,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;QACzB,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC;QAC/B,WAAW,EAAE,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC;QAC3C,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC;QACrC,MAAM,EAAE,UAAU,IAAI,aAAa,CAAC,QAAQ,CAAC,UAAwB,CAAC;YACpE,CAAC,CAAE,UAAyB;YAC5B,CAAC,CAAC,IAAI;KACT,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E;;;GAGG;AACH,SAAS,MAAM,CAAC,EAAU;IACxB,MAAM,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC;IACjC,IAAI,CAAC,UAAU;QAAE,OAAO;IAExB,MAAM,EAAE,EAAE,EAAE,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAErC,2BAA2B;IAC3B,YAAY,CAAC,UAAU,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAE7D,mEAAmE;IACnE,4EAA4E;IAC5E,UAAU,CAAC,SAAS,GAAG;;;WAGd,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE;WAC5B,EAAE,CAAC,CAAC,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE;;;;GAIhD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,OAAO,CAAC,GAAW;IAC1B,6BAA6B;AAC/B,CAAC;AAED,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;GAEG;AACH,MAAM,OAAO,MAAO,SAAQ,WAAW;IACrC,0BAA0B;IAC1B,MAAM,KAAK,kBAAkB;QAC3B,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC9D,CAAC;IAED;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,CAAC;IAED,iBAAiB;QACf,MAAM,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,oBAAoB;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IAED,wBAAwB,CAAC,KAAa,EAAE,SAAwB,EAAE,SAAwB;QACxF,MAAM,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;CACF;AAED,8BAA8B;AAC9B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;IACnC,cAAc,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC"}
|
package/lib/components/switch.js
CHANGED
|
@@ -148,14 +148,14 @@ this.updateValidity();
|
|
|
148
148
|
updateValidity() {
|
|
149
149
|
const anchor = this.shadowRoot?.querySelector(".switch-container");
|
|
150
150
|
if (this.disabled) {
|
|
151
|
-
this.
|
|
151
|
+
this.applyValidity({});
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
154
154
|
if (this.required && !this.checked) {
|
|
155
|
-
this.
|
|
155
|
+
this.applyValidity({ valueMissing: true }, "Please turn this on", anchor ?? undefined);
|
|
156
156
|
}
|
|
157
157
|
else {
|
|
158
|
-
this.
|
|
158
|
+
this.applyValidity({});
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
get checked() { return this.getProperty("checked"); }
|
package/lib/components/tab.d.ts
CHANGED
|
@@ -3,15 +3,63 @@ export interface TabAttributes {
|
|
|
3
3
|
id: string | null;
|
|
4
4
|
label: string | null;
|
|
5
5
|
disabled: boolean;
|
|
6
|
+
lazy: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* `ty-tab-load`: a lazy tab with no content was shown. Fired on the ty-tab
|
|
10
|
+
* and doesn't bubble, so a lazy tab nested in another doesn't trigger the
|
|
11
|
+
* outer one's listener. Listen on the tab, or on ty-tabs with capture.
|
|
12
|
+
*/
|
|
13
|
+
export interface TabLoadDetail {
|
|
14
|
+
id: string;
|
|
15
|
+
index: number;
|
|
6
16
|
}
|
|
7
17
|
export declare class TyTab extends HTMLElement {
|
|
8
18
|
private _scrollbar;
|
|
19
|
+
private _panelLabel;
|
|
20
|
+
private _shown;
|
|
21
|
+
private _load;
|
|
22
|
+
private _contentObserver;
|
|
23
|
+
private _contentChanged;
|
|
9
24
|
static get observedAttributes(): string[];
|
|
10
25
|
constructor();
|
|
11
26
|
connectedCallback(): void;
|
|
27
|
+
/** Accessible name. Set by ty-tabs, which also knows rich `label-{id}` slots. */
|
|
28
|
+
setPanelLabel(label: string): void;
|
|
29
|
+
/** Set by ty-tabs: a panel that isn't shown is inert. */
|
|
30
|
+
setShown(shown: boolean): void;
|
|
12
31
|
disconnectedCallback(): void;
|
|
13
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Called by ty-tabs when this tab becomes the shown one — never for the
|
|
34
|
+
* tab shown first, whose content the page is expected to carry. A lazy
|
|
35
|
+
* tab with no content (or whose load failed) asks for it.
|
|
36
|
+
*/
|
|
37
|
+
_requestLoad(index: number): void;
|
|
38
|
+
/**
|
|
39
|
+
* Report that loading this tab's content failed: shows `slot="error"`
|
|
40
|
+
* (default "Couldn't load.") with a Retry button. Retry, or showing the
|
|
41
|
+
* tab again, fires `ty-tab-load` once more. Content arriving clears it.
|
|
42
|
+
*/
|
|
43
|
+
loadFailed(): void;
|
|
44
|
+
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
14
45
|
private _render;
|
|
46
|
+
/** Lazy tabs track whether they have content; others don't watch. */
|
|
47
|
+
private _watchContent;
|
|
48
|
+
private _hasContent;
|
|
49
|
+
/**
|
|
50
|
+
* `mutated`: content changed under a connected tab. Content that goes away
|
|
51
|
+
* (a morph with the server's empty markup) loads again — right away when
|
|
52
|
+
* this tab is the one shown, otherwise the next time it's shown.
|
|
53
|
+
*/
|
|
54
|
+
private _checkContent;
|
|
55
|
+
private _fireLoad;
|
|
56
|
+
/**
|
|
57
|
+
* Placeholder and error, built the first time a tab loads: tabs that never
|
|
58
|
+
* do carry no hidden "Couldn't load / Retry" text.
|
|
59
|
+
*/
|
|
60
|
+
private _ensureStatus;
|
|
61
|
+
private _setLoad;
|
|
62
|
+
private _syncPanel;
|
|
15
63
|
private _setupScrollbar;
|
|
16
64
|
private _destroyScrollbar;
|
|
17
65
|
resetScroll(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab.d.ts","sourceRoot":"","sources":["../../src/components/tab.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;CACnB;AA0DD;;GAEG;AACH,qBAAa,KAAM,SAAQ,WAAW;IACpC,0BAA0B;IAC1B,MAAM,KAAK,kBAAkB,aAE5B;;IAOD,iBAAiB;IAIjB,oBAAoB;IAIpB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;CAG3F"}
|