@watermarkinsights/ripple 3.12.0 → 3.13.0-9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{chartFunctions-44ae2eee.js → chartFunctions-34fdd3ce.js} +1 -1
- package/dist/cjs/{functions-1a67b971.js → functions-120449cf.js} +245 -32
- package/dist/cjs/{global-122fc638.js → global-1d1d0ab3.js} +7 -5
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/priv-chart-popover.cjs.entry.js +1 -1
- package/dist/cjs/priv-datepicker.cjs.entry.js +1 -1
- package/dist/cjs/ripple.cjs.js +2 -2
- package/dist/cjs/wm-action-menu_2.cjs.entry.js +1 -1
- package/dist/cjs/wm-button.cjs.entry.js +50 -38
- package/dist/cjs/wm-chart.cjs.entry.js +2 -2
- package/dist/cjs/wm-datepicker.cjs.entry.js +1 -1
- package/dist/cjs/wm-input.cjs.entry.js +1 -1
- package/dist/cjs/wm-modal-footer.cjs.entry.js +1 -1
- package/dist/cjs/wm-modal-header.cjs.entry.js +1 -1
- package/dist/cjs/wm-modal.cjs.entry.js +1 -1
- package/dist/cjs/wm-navigation_3.cjs.entry.js +1 -1
- package/dist/cjs/wm-navigator.cjs.entry.js +1 -1
- package/dist/cjs/wm-network-uploader.cjs.entry.js +6 -4
- package/dist/cjs/wm-option_2.cjs.entry.js +345 -122
- package/dist/cjs/wm-pagination.cjs.entry.js +1 -1
- package/dist/cjs/wm-progress-indicator_3.cjs.entry.js +2 -2
- package/dist/cjs/wm-search.cjs.entry.js +1 -1
- package/dist/cjs/wm-snackbar.cjs.entry.js +1 -1
- package/dist/cjs/wm-tab-item_3.cjs.entry.js +1 -1
- package/dist/cjs/wm-tag-input.cjs.entry.js +1 -1
- package/dist/cjs/wm-timepicker.cjs.entry.js +1 -1
- package/dist/cjs/wm-toggletip.cjs.entry.js +4 -4
- package/dist/cjs/wm-uploader.cjs.entry.js +9 -11
- package/dist/collection/components/wm-button/wm-button.css +1 -0
- package/dist/collection/components/wm-button/wm-button.js +50 -40
- package/dist/collection/components/wm-modal/wm-modal-footer.js +1 -1
- package/dist/collection/components/wm-option/wm-option.css +12 -0
- package/dist/collection/components/wm-option/wm-option.js +34 -29
- package/dist/collection/components/wm-select/wm-select.css +76 -23
- package/dist/collection/components/wm-select/wm-select.js +385 -125
- package/dist/collection/components/wm-toggletip/wm-toggletip.js +5 -5
- package/dist/collection/components/wm-uploader/wm-network-uploader/wm-network-uploader.css +0 -3
- package/dist/collection/components/wm-uploader/wm-network-uploader/wm-network-uploader.js +4 -2
- package/dist/collection/components/wm-uploader/wm-uploader.css +1 -5
- package/dist/collection/components/wm-uploader/wm-uploader.js +7 -9
- package/dist/collection/global/__mocks__/functions.js +9 -0
- package/dist/collection/global/functions.js +1 -28
- package/dist/collection/global/global.js +6 -4
- package/dist/esm/{chartFunctions-8fa800a6.js → chartFunctions-20f05eb5.js} +1 -1
- package/dist/esm/{functions-61c7bb1f.js → functions-036af8dc.js} +245 -32
- package/dist/esm/{global-5902ef31.js → global-590c515d.js} +7 -5
- package/dist/esm/loader.js +2 -2
- package/dist/esm/priv-chart-popover.entry.js +1 -1
- package/dist/esm/priv-datepicker.entry.js +1 -1
- package/dist/esm/ripple.js +2 -2
- package/dist/esm/wm-action-menu_2.entry.js +1 -1
- package/dist/esm/wm-button.entry.js +51 -39
- package/dist/esm/wm-chart.entry.js +2 -2
- package/dist/esm/wm-datepicker.entry.js +1 -1
- package/dist/esm/wm-input.entry.js +1 -1
- package/dist/esm/wm-modal-footer.entry.js +1 -1
- package/dist/esm/wm-modal-header.entry.js +1 -1
- package/dist/esm/wm-modal.entry.js +1 -1
- package/dist/esm/wm-navigation_3.entry.js +1 -1
- package/dist/esm/wm-navigator.entry.js +1 -1
- package/dist/esm/wm-network-uploader.entry.js +6 -4
- package/dist/esm/wm-option_2.entry.js +345 -122
- package/dist/esm/wm-pagination.entry.js +1 -1
- package/dist/esm/wm-progress-indicator_3.entry.js +2 -2
- package/dist/esm/wm-search.entry.js +1 -1
- package/dist/esm/wm-snackbar.entry.js +1 -1
- package/dist/esm/wm-tab-item_3.entry.js +1 -1
- package/dist/esm/wm-tag-input.entry.js +1 -1
- package/dist/esm/wm-timepicker.entry.js +1 -1
- package/dist/esm/wm-toggletip.entry.js +4 -4
- package/dist/esm/wm-uploader.entry.js +9 -11
- package/dist/esm-es5/{chartFunctions-8fa800a6.js → chartFunctions-20f05eb5.js} +1 -1
- package/dist/esm-es5/{functions-61c7bb1f.js → functions-036af8dc.js} +2 -2
- package/dist/esm-es5/global-590c515d.js +1 -0
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/priv-chart-popover.entry.js +1 -1
- package/dist/esm-es5/priv-datepicker.entry.js +1 -1
- package/dist/esm-es5/ripple.js +1 -1
- package/dist/esm-es5/wm-action-menu_2.entry.js +1 -1
- package/dist/esm-es5/wm-button.entry.js +1 -1
- package/dist/esm-es5/wm-chart.entry.js +1 -1
- package/dist/esm-es5/wm-datepicker.entry.js +1 -1
- package/dist/esm-es5/wm-input.entry.js +1 -1
- package/dist/esm-es5/wm-modal-footer.entry.js +1 -1
- package/dist/esm-es5/wm-modal-header.entry.js +1 -1
- package/dist/esm-es5/wm-modal.entry.js +1 -1
- package/dist/esm-es5/wm-navigation_3.entry.js +1 -1
- package/dist/esm-es5/wm-navigator.entry.js +1 -1
- package/dist/esm-es5/wm-network-uploader.entry.js +1 -1
- package/dist/esm-es5/wm-option_2.entry.js +1 -1
- package/dist/esm-es5/wm-pagination.entry.js +1 -1
- package/dist/esm-es5/wm-progress-indicator_3.entry.js +1 -1
- package/dist/esm-es5/wm-search.entry.js +1 -1
- package/dist/esm-es5/wm-snackbar.entry.js +1 -1
- package/dist/esm-es5/wm-tab-item_3.entry.js +1 -1
- package/dist/esm-es5/wm-tag-input.entry.js +1 -1
- package/dist/esm-es5/wm-timepicker.entry.js +1 -1
- package/dist/esm-es5/wm-toggletip.entry.js +1 -1
- package/dist/esm-es5/wm-uploader.entry.js +1 -1
- package/dist/ripple/{p-28bf6a2e.system.js → p-04d8b674.system.js} +1 -1
- package/dist/ripple/{p-d3ed8b65.system.entry.js → p-04e44b30.system.entry.js} +1 -1
- package/dist/ripple/{p-fdc4a599.system.entry.js → p-0556279c.system.entry.js} +1 -1
- package/dist/ripple/{p-1242752c.system.entry.js → p-06adbeb9.system.entry.js} +1 -1
- package/dist/ripple/{p-42aa51fe.system.entry.js → p-0e9ccc6f.system.entry.js} +1 -1
- package/dist/ripple/{p-520b0f54.entry.js → p-17ceb8c1.entry.js} +1 -1
- package/dist/ripple/{p-8caae464.entry.js → p-1887286e.entry.js} +1 -1
- package/dist/ripple/{p-c873b490.system.entry.js → p-1ccd994d.system.entry.js} +1 -1
- package/dist/ripple/p-1d795f42.entry.js +1 -0
- package/dist/ripple/p-2996bfe6.entry.js +1 -0
- package/dist/ripple/{p-30745db6.entry.js → p-2f860b24.entry.js} +1 -1
- package/dist/ripple/p-3489b502.js +1 -0
- package/dist/ripple/{p-cd4fda75.entry.js → p-3680b55d.entry.js} +1 -1
- package/dist/ripple/p-3745c620.system.js +1 -0
- package/dist/ripple/{p-f12a510f.entry.js → p-3a1d6fc4.entry.js} +1 -1
- package/dist/ripple/p-42337590.entry.js +1 -0
- package/dist/ripple/{p-68155230.system.entry.js → p-49fd7ede.system.entry.js} +1 -1
- package/dist/ripple/{p-8aa9f811.js → p-4ecd3430.js} +1 -1
- package/dist/ripple/{p-5471864e.system.entry.js → p-62eac2d6.system.entry.js} +1 -1
- package/dist/ripple/{p-5e041c35.entry.js → p-6aa6a818.entry.js} +1 -1
- package/dist/ripple/{p-487f7419.system.entry.js → p-6bf5cbf4.system.entry.js} +1 -1
- package/dist/ripple/{p-e180001c.system.entry.js → p-7173b0a7.system.entry.js} +1 -1
- package/dist/ripple/p-726c979a.system.js +15 -0
- package/dist/ripple/{p-eacd33cc.system.entry.js → p-752da0fb.system.entry.js} +1 -1
- package/dist/ripple/{p-f36b74bf.entry.js → p-7ae1a630.entry.js} +1 -1
- package/dist/ripple/{p-8d347cd5.entry.js → p-7ecbf258.entry.js} +1 -1
- package/dist/ripple/{p-75ef731b.system.entry.js → p-7ef6a7cf.system.entry.js} +1 -1
- package/dist/ripple/p-8612829b.system.entry.js +1 -0
- package/dist/ripple/{p-398b2486.system.entry.js → p-895f5ec5.system.entry.js} +1 -1
- package/dist/ripple/{p-d3603def.entry.js → p-8de546e8.entry.js} +1 -1
- package/dist/ripple/{p-35cfcf9f.entry.js → p-93dee724.entry.js} +1 -1
- package/dist/ripple/{p-0f33461d.entry.js → p-97c2b06f.entry.js} +1 -1
- package/dist/ripple/{p-9f12284b.system.entry.js → p-995ba16f.system.entry.js} +1 -1
- package/dist/ripple/p-9c92c93f.entry.js +1 -0
- package/dist/ripple/p-9e09d7a1.entry.js +1 -0
- package/dist/ripple/{p-f0656464.entry.js → p-a04ba6c8.entry.js} +1 -1
- package/dist/ripple/{p-44035b02.system.entry.js → p-af3ce4fc.system.entry.js} +1 -1
- package/dist/ripple/p-bbcafbd6.system.entry.js +1 -0
- package/dist/ripple/{p-eee347b4.system.entry.js → p-c1443a0e.system.entry.js} +1 -1
- package/dist/ripple/{p-212aac05.system.entry.js → p-ca383a43.system.entry.js} +1 -1
- package/dist/ripple/{p-ca2fbd1b.system.js → p-cc247ee1.system.js} +1 -1
- package/dist/ripple/{p-73d66b0a.system.entry.js → p-cd3d74d1.system.entry.js} +1 -1
- package/dist/ripple/p-d1ac96e1.system.entry.js +1 -0
- package/dist/ripple/{p-3f1d8211.system.entry.js → p-d48c56c7.system.entry.js} +1 -1
- package/dist/ripple/{p-15b1c11b.js → p-de3367ee.js} +2 -2
- package/dist/ripple/{p-e748e22b.entry.js → p-e083fca6.entry.js} +1 -1
- package/dist/ripple/{p-3e6498ea.system.entry.js → p-e4439bc3.system.entry.js} +1 -1
- package/dist/ripple/{p-e49b9a96.entry.js → p-e524d462.entry.js} +1 -1
- package/dist/ripple/{p-92226595.entry.js → p-e8d39f68.entry.js} +1 -1
- package/dist/ripple/{p-00fa3d4b.entry.js → p-ed91be1a.entry.js} +1 -1
- package/dist/ripple/{p-d81a4e7c.system.entry.js → p-f23b3986.system.entry.js} +1 -1
- package/dist/ripple/{p-e75e75e0.entry.js → p-fda61e7e.entry.js} +1 -1
- package/dist/ripple/p-fe952112.entry.js +1 -0
- package/dist/ripple/ripple.esm.js +1 -1
- package/dist/ripple/ripple.js +1 -1
- package/dist/types/components/wm-button/wm-button.d.ts +4 -4
- package/dist/types/components/wm-option/wm-option.d.ts +5 -2
- package/dist/types/components/wm-select/wm-select.d.ts +39 -12
- package/dist/types/components/wm-toggletip/wm-toggletip.d.ts +2 -2
- package/dist/types/components.d.ts +10 -6
- package/dist/types/global/__mocks__/functions.d.ts +1 -0
- package/dist/types/global/functions.d.ts +2 -2
- package/dist/types/global/interfaces.d.ts +1 -1
- package/package.json +1 -1
- package/dist/esm-es5/global-5902ef31.js +0 -1
- package/dist/ripple/p-1b058a44.entry.js +0 -1
- package/dist/ripple/p-2077203e.system.js +0 -1
- package/dist/ripple/p-379b125b.entry.js +0 -1
- package/dist/ripple/p-49bf0b81.js +0 -1
- package/dist/ripple/p-584fef7f.system.entry.js +0 -1
- package/dist/ripple/p-72eb5064.system.entry.js +0 -1
- package/dist/ripple/p-76ca7498.system.js +0 -15
- package/dist/ripple/p-9fe64cec.entry.js +0 -1
- package/dist/ripple/p-a82d37d8.entry.js +0 -1
- package/dist/ripple/p-ac2485a6.system.entry.js +0 -1
- package/dist/ripple/p-ba168596.entry.js +0 -1
- package/dist/ripple/p-ed657559.entry.js +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { h, Component, Element, Event, Listen, Prop, State, Watch, Host } from "@stencil/core";
|
|
2
2
|
import { forceUpdate } from "@stencil/core";
|
|
3
|
-
import { generateId, getTextDir, shouldOpenUp, intl } from "../../global/functions";
|
|
3
|
+
import { generateId, getTextDir, shouldOpenUp, intl, debounce } from "../../global/functions";
|
|
4
4
|
export class Select {
|
|
5
5
|
constructor() {
|
|
6
6
|
this.disabled = false;
|
|
@@ -9,11 +9,17 @@ export class Select {
|
|
|
9
9
|
this.requiredField = false;
|
|
10
10
|
this.errorMessage = "";
|
|
11
11
|
this.multiple = false;
|
|
12
|
+
this.search = false;
|
|
12
13
|
this.placeholder = intl.formatMessage({
|
|
13
14
|
id: "select.multiPlaceholder",
|
|
14
15
|
defaultMessage: "Make a selection",
|
|
15
16
|
description: "Placeholder text. Use imperative",
|
|
16
17
|
});
|
|
18
|
+
this.searchPlaceholder = intl.formatMessage({
|
|
19
|
+
id: "select.searchPlaceholder",
|
|
20
|
+
defaultMessage: "Search",
|
|
21
|
+
description: "Placeholder text. Use imperative",
|
|
22
|
+
});
|
|
17
23
|
this.allSelectedMessage = intl.formatMessage({
|
|
18
24
|
id: "select.allSelected",
|
|
19
25
|
defaultMessage: "All selected",
|
|
@@ -25,21 +31,68 @@ export class Select {
|
|
|
25
31
|
});
|
|
26
32
|
this.isTabbing = false;
|
|
27
33
|
this.isExpanded = false;
|
|
34
|
+
this.announcement = "";
|
|
28
35
|
this.keysSoFar = "";
|
|
29
36
|
this.searchIndex = 0;
|
|
30
37
|
this.keyClear = null;
|
|
31
38
|
this.openUp = false;
|
|
39
|
+
//////////////////////////////////////
|
|
40
|
+
//////////////////////////////////////
|
|
32
41
|
// for multiselect button text
|
|
33
42
|
this.overflowCount = 0;
|
|
34
|
-
this.
|
|
35
|
-
this.
|
|
43
|
+
this.displayedOptions = [];
|
|
44
|
+
this.debouncedSearch = debounce(() => {
|
|
45
|
+
this.wmSelectSearchChanged.emit({ searchTerm: this.searchTerm });
|
|
46
|
+
if (this.filteredOptions.length) {
|
|
47
|
+
this.announce(this.resultsFoundMessage);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
this.announce(this.noResultsFoundMessage);
|
|
51
|
+
}
|
|
52
|
+
}, 150);
|
|
36
53
|
}
|
|
37
|
-
get
|
|
54
|
+
get childOptions() {
|
|
38
55
|
return Array.from(this.el.querySelectorAll("wm-option"));
|
|
39
56
|
}
|
|
40
|
-
get
|
|
57
|
+
get duplicateOptions() {
|
|
58
|
+
return Array.from(this.el.shadowRoot.querySelectorAll("wm-option"));
|
|
59
|
+
}
|
|
60
|
+
get allOptionEls() {
|
|
61
|
+
// this includes both slotted wm-options and internally created wm-options
|
|
62
|
+
return this.duplicateOptions.concat(this.childOptions);
|
|
63
|
+
}
|
|
64
|
+
get visibleOptionEls() {
|
|
65
|
+
return this.allOptionEls.filter((option) => !option.classList.contains("hidden") && !option.classList.contains("filtered-out"));
|
|
66
|
+
}
|
|
67
|
+
//////////////////////////////////////
|
|
68
|
+
// for search variants
|
|
69
|
+
get searchTerm() {
|
|
70
|
+
return this.searchFieldEl ? this.searchFieldEl.value : "";
|
|
71
|
+
}
|
|
72
|
+
get filteredOptions() {
|
|
73
|
+
return this.childOptions.filter((option) => { var _a; return (_a = option.textContent) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(this.searchTerm); });
|
|
74
|
+
}
|
|
75
|
+
get selectedOptions() {
|
|
41
76
|
return Array.from(this.el.querySelectorAll("wm-option")).filter((x) => x.selected);
|
|
42
77
|
}
|
|
78
|
+
get allSelected() {
|
|
79
|
+
return this.childOptions.filter((option) => option.selected).length === this.childOptions.length;
|
|
80
|
+
}
|
|
81
|
+
//////////////////////////////////////
|
|
82
|
+
get resultsFoundMessage() {
|
|
83
|
+
return intl.formatMessage({
|
|
84
|
+
id: "select.searchResultsFound",
|
|
85
|
+
defaultMessage: "{numResults, plural, one {1 option found} other {# options found}}",
|
|
86
|
+
description: "The message read by the screen reader, indicating how many results a search returned",
|
|
87
|
+
}, { numResults: this.filteredOptions.length });
|
|
88
|
+
}
|
|
89
|
+
get noResultsFoundMessage() {
|
|
90
|
+
return intl.formatMessage({
|
|
91
|
+
id: "select.noSearchResults",
|
|
92
|
+
defaultMessage: "No results found. Please try your search again.",
|
|
93
|
+
description: "The message displayed when no options pass the search filter",
|
|
94
|
+
});
|
|
95
|
+
}
|
|
43
96
|
toggleTabbingOn() {
|
|
44
97
|
this.isTabbing = true;
|
|
45
98
|
}
|
|
@@ -48,14 +101,11 @@ export class Select {
|
|
|
48
101
|
}
|
|
49
102
|
handleOptionSelection(ev) {
|
|
50
103
|
if (!this.multiple) {
|
|
51
|
-
// ensure only one option is selected at a time
|
|
52
|
-
this.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
this.focusItem(ev.target);
|
|
58
|
-
this.selectItem(ev.target);
|
|
104
|
+
// ensure only one option is selected at a time, unselect all other options
|
|
105
|
+
this.childOptions.forEach((option) => (option.selected = option === ev.detail));
|
|
106
|
+
}
|
|
107
|
+
this.focusOption(ev.detail);
|
|
108
|
+
this.selectOption(ev.detail);
|
|
59
109
|
if (!this.multiple) {
|
|
60
110
|
this.close();
|
|
61
111
|
}
|
|
@@ -65,28 +115,24 @@ export class Select {
|
|
|
65
115
|
this.close();
|
|
66
116
|
}
|
|
67
117
|
handleChildUp(ev) {
|
|
68
|
-
this.moveUp(ev.
|
|
118
|
+
this.moveUp(ev.detail);
|
|
69
119
|
}
|
|
70
120
|
handleChildDown(ev) {
|
|
71
|
-
this.moveDown(ev.
|
|
72
|
-
}
|
|
73
|
-
moveToFirstItem() {
|
|
74
|
-
this.focusItem(this.childItems[0]);
|
|
121
|
+
this.moveDown(ev.detail);
|
|
75
122
|
}
|
|
76
|
-
|
|
77
|
-
this.
|
|
123
|
+
moveToFirstOption() {
|
|
124
|
+
this.focusOption(this.visibleOptionEls[0]);
|
|
78
125
|
}
|
|
79
|
-
|
|
80
|
-
this.
|
|
126
|
+
moveToLastOption() {
|
|
127
|
+
this.focusOption(this.visibleOptionEls[this.visibleOptionEls.length - 1]);
|
|
81
128
|
}
|
|
82
129
|
closePopupOnEscape() {
|
|
83
130
|
this.close();
|
|
84
131
|
}
|
|
85
132
|
handleOptionBlur(ev) {
|
|
86
|
-
const toElOrChild = ev.detail.relatedTarget === this.el || this.el.contains(ev.detail.relatedTarget);
|
|
87
133
|
// if the Option is blurred to something other than the component emit a blur event with the appropriate relatedTarget
|
|
88
134
|
// keeps our component's blur events accurate, and closes when focusing browser address bar
|
|
89
|
-
if (!
|
|
135
|
+
if (!this.isElOrChild(ev.detail.relatedTarget)) {
|
|
90
136
|
const event = new CustomEvent("blur");
|
|
91
137
|
// @ts-ignore
|
|
92
138
|
event.relatedTarget = ev.detail.relatedTarget;
|
|
@@ -94,18 +140,23 @@ export class Select {
|
|
|
94
140
|
}
|
|
95
141
|
}
|
|
96
142
|
handleClick(ev) {
|
|
97
|
-
|
|
98
|
-
if (!isElOrChild && this.isExpanded) {
|
|
143
|
+
if (!this.isElOrChild(ev.target)) {
|
|
99
144
|
this.close();
|
|
100
145
|
}
|
|
101
146
|
}
|
|
102
147
|
handleButtonBlur(ev) {
|
|
103
|
-
|
|
104
|
-
if (toElOrChild) {
|
|
148
|
+
if (this.isElOrChild(ev.relatedTarget)) {
|
|
105
149
|
// do not emit a blur event when opening the dropdown and focusing the Options
|
|
106
150
|
ev.stopPropagation();
|
|
107
151
|
}
|
|
108
152
|
}
|
|
153
|
+
handleSearchFieldBlur(ev) {
|
|
154
|
+
this.searchFieldWrapperEl.classList.remove("focus");
|
|
155
|
+
if (this.isElOrChild(ev.relatedTarget)) {
|
|
156
|
+
// do not emit a blur event when moving from searchfield to options
|
|
157
|
+
ev.stopPropagation();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
109
160
|
handleKey(ev) {
|
|
110
161
|
switch (ev.key) {
|
|
111
162
|
case "ArrowDown":
|
|
@@ -135,137 +186,236 @@ export class Select {
|
|
|
135
186
|
if (document.body.classList.contains("wmcl-user-is-tabbing")) {
|
|
136
187
|
this.toggleTabbingOn();
|
|
137
188
|
}
|
|
189
|
+
// set initial selections
|
|
190
|
+
if (this.selectedOptions.length > 0) {
|
|
191
|
+
this.selectedOptions.forEach((x) => {
|
|
192
|
+
this.displayedOptions.push(x);
|
|
193
|
+
});
|
|
194
|
+
// single Select only, pre-select if no default option from dev
|
|
195
|
+
}
|
|
196
|
+
else if (!this.multiple) {
|
|
197
|
+
this.selectOption(this.allOptionEls[0]);
|
|
198
|
+
}
|
|
138
199
|
}
|
|
139
200
|
componentDidLoad() {
|
|
140
201
|
this.wmSelectDidLoad.emit();
|
|
141
|
-
if (
|
|
142
|
-
throw new Error("wm-select should have wm-option elements as children.");
|
|
143
|
-
}
|
|
144
|
-
if (this.multiple && this.childItems.filter((x) => x.subinfo).length > 0) {
|
|
202
|
+
if (this.multiple && this.allOptionEls.filter((x) => x.subinfo).length > 0) {
|
|
145
203
|
throw new Error("wm-select with the multiple prop cannot have subinfo options");
|
|
146
204
|
}
|
|
147
205
|
if (this.multiple && !this.placeholder) {
|
|
148
206
|
throw new Error("wm-select with the multiple prop needs to also use the placeholder prop.");
|
|
149
207
|
}
|
|
150
|
-
|
|
151
|
-
if (this.selectedItems.length > 0) {
|
|
152
|
-
this.selectedItems.forEach((x) => this.displayedItems.push(x));
|
|
153
|
-
this.setButtonText();
|
|
154
|
-
// single Select only, pre-select if no default option from dev
|
|
155
|
-
}
|
|
156
|
-
else if (!this.multiple) {
|
|
157
|
-
this.selectItem(this.childItems[0]);
|
|
158
|
-
}
|
|
159
|
-
this.optionsEl.classList.add("hidden");
|
|
208
|
+
this.dropdownEl.classList.add("hidden");
|
|
160
209
|
forceUpdate(this.el);
|
|
161
210
|
// Dev can overwrite the max-height rule set in the Sass file
|
|
162
211
|
if (this.maxHeight) {
|
|
163
|
-
this.
|
|
212
|
+
this.dropdownEl.style.maxHeight = this.maxHeight;
|
|
213
|
+
}
|
|
214
|
+
const mutationObserver = new MutationObserver(() => this.handleSelectedMutation());
|
|
215
|
+
mutationObserver.observe(this.el, {
|
|
216
|
+
attributes: true,
|
|
217
|
+
attributeFilter: ["selected"],
|
|
218
|
+
subtree: true,
|
|
219
|
+
});
|
|
220
|
+
if (this.multiple) {
|
|
221
|
+
this.updateOptionVisibility();
|
|
222
|
+
}
|
|
223
|
+
this.setButtonText();
|
|
224
|
+
}
|
|
225
|
+
componentWillUpdate() {
|
|
226
|
+
if (this.multiple) {
|
|
227
|
+
// find last visible duplicate option and apply .last class
|
|
228
|
+
const visibleDuplicateOptions = this.visibleOptionEls.filter((option) => option.classList.contains("duplicate"));
|
|
229
|
+
visibleDuplicateOptions.forEach((option, idx) => {
|
|
230
|
+
if (idx === visibleDuplicateOptions.length - 1) {
|
|
231
|
+
option.classList.add("last");
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
option.classList.remove("last");
|
|
235
|
+
}
|
|
236
|
+
});
|
|
164
237
|
}
|
|
165
238
|
}
|
|
239
|
+
handleSelectedMutation() {
|
|
240
|
+
// dispatch change event after selected options change
|
|
241
|
+
// mutation observer prevents emitting event when an already selected option is selected again
|
|
242
|
+
const event = new CustomEvent("change");
|
|
243
|
+
// @ts-ignore
|
|
244
|
+
this.el.dispatchEvent(event);
|
|
245
|
+
}
|
|
166
246
|
moveUp(el) {
|
|
167
|
-
const prevEl = el
|
|
247
|
+
const prevEl = this.visibleOptionEls[this.visibleOptionEls.indexOf(el) - 1];
|
|
168
248
|
if (prevEl) {
|
|
169
249
|
// scroll option to top of dropdown if partially obscured / out of view
|
|
170
|
-
if (prevEl.getBoundingClientRect().top < this.
|
|
171
|
-
this.
|
|
172
|
-
prevEl.getBoundingClientRect().top - this.optionsEl.getBoundingClientRect().top + this.optionsEl.scrollTop;
|
|
250
|
+
if (prevEl.getBoundingClientRect().top < this.dropdownEl.getBoundingClientRect().top) {
|
|
251
|
+
this.scrollOptionToTop(prevEl);
|
|
173
252
|
}
|
|
174
|
-
this.
|
|
253
|
+
this.focusOption(prevEl);
|
|
254
|
+
}
|
|
255
|
+
else if (this.search) {
|
|
256
|
+
// if top of list and search variant, focus search field
|
|
257
|
+
this.searchFieldEl.focus();
|
|
175
258
|
}
|
|
176
259
|
else {
|
|
177
|
-
|
|
260
|
+
// if top of list, focus last element
|
|
261
|
+
this.focusOption(this.visibleOptionEls[this.visibleOptionEls.length - 1]);
|
|
178
262
|
}
|
|
179
263
|
}
|
|
180
264
|
moveDown(el) {
|
|
181
|
-
const nextEl = el
|
|
182
|
-
if (nextEl
|
|
265
|
+
const nextEl = this.visibleOptionEls[this.visibleOptionEls.indexOf(el) + 1];
|
|
266
|
+
if (nextEl) {
|
|
183
267
|
// scroll option to bottom of dropdown if partially obscured / out of view
|
|
184
|
-
if (nextEl.getBoundingClientRect().bottom > this.
|
|
185
|
-
this.
|
|
186
|
-
nextEl.getBoundingClientRect().bottom -
|
|
187
|
-
this.optionsEl.getBoundingClientRect().top +
|
|
188
|
-
this.optionsEl.scrollTop -
|
|
189
|
-
this.optionsEl.offsetHeight;
|
|
268
|
+
if (nextEl.getBoundingClientRect().bottom > this.dropdownEl.getBoundingClientRect().bottom) {
|
|
269
|
+
this.scrollOptionToBottom(nextEl);
|
|
190
270
|
}
|
|
191
|
-
this.
|
|
271
|
+
this.focusOption(nextEl);
|
|
192
272
|
}
|
|
193
273
|
else {
|
|
194
|
-
|
|
274
|
+
// if end of list, focus first option in all variants
|
|
275
|
+
this.focusOption(this.visibleOptionEls[0]);
|
|
195
276
|
}
|
|
196
277
|
}
|
|
197
|
-
|
|
278
|
+
scrollOptionToTop(option) {
|
|
279
|
+
this.dropdownEl.scrollTop =
|
|
280
|
+
option.getBoundingClientRect().top - this.dropdownEl.getBoundingClientRect().top + this.dropdownEl.scrollTop;
|
|
281
|
+
}
|
|
282
|
+
scrollOptionToBottom(option) {
|
|
283
|
+
this.dropdownEl.scrollTop =
|
|
284
|
+
option.getBoundingClientRect().bottom -
|
|
285
|
+
this.dropdownEl.getBoundingClientRect().top +
|
|
286
|
+
this.dropdownEl.scrollTop -
|
|
287
|
+
this.dropdownEl.offsetHeight;
|
|
288
|
+
}
|
|
289
|
+
open(optionToSelect) {
|
|
198
290
|
if (!this.disabled) {
|
|
199
291
|
const elHeight = this.el.clientHeight;
|
|
200
292
|
const buttonHeight = this.buttonEl.clientHeight;
|
|
201
|
-
this.openUp = shouldOpenUp(this.el, this.
|
|
293
|
+
this.openUp = shouldOpenUp(this.el, this.dropdownEl,
|
|
202
294
|
// when opening up, dropdown covers both label and button
|
|
203
295
|
elHeight,
|
|
204
296
|
// when opening down, dropdown covers only the button
|
|
205
297
|
buttonHeight);
|
|
206
298
|
this.isExpanded = true;
|
|
207
|
-
this.
|
|
299
|
+
this.dropdownEl.classList.remove("hidden");
|
|
208
300
|
window.requestAnimationFrame(() => {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
301
|
+
switch (optionToSelect) {
|
|
302
|
+
case "next":
|
|
303
|
+
// search variant focuses search field
|
|
304
|
+
// all others focus option "after" last selected option (this can be the first option)
|
|
305
|
+
if (this.search) {
|
|
306
|
+
this.searchFieldEl.focus();
|
|
307
|
+
this.dropdownEl.scrollTop = 0;
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
this.moveDown(this.visibleOptionEls.filter((x) => x.selected).slice(-1)[0]);
|
|
311
|
+
}
|
|
312
|
+
break;
|
|
313
|
+
case "previous":
|
|
314
|
+
// search variant focuses last option
|
|
315
|
+
// all others focus option "above" first selected option (this can be the last option)
|
|
316
|
+
if (this.search) {
|
|
317
|
+
this.focusOption(this.visibleOptionEls[this.visibleOptionEls.length - 1]);
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
this.moveUp(this.visibleOptionEls.filter((x) => x.selected)[0]);
|
|
321
|
+
}
|
|
322
|
+
break;
|
|
323
|
+
default:
|
|
324
|
+
// search variant focuses search field
|
|
325
|
+
// all others focus the selected option
|
|
326
|
+
// if no option is selected (empty multiselect), focuses first option
|
|
327
|
+
if (this.search) {
|
|
328
|
+
this.searchFieldEl.focus();
|
|
329
|
+
this.dropdownEl.scrollTop = 0;
|
|
330
|
+
}
|
|
331
|
+
else if (this.selectedOptions.length > 0) {
|
|
332
|
+
this.focusOption(this.visibleOptionEls.filter((x) => x.selected)[0]);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
this.focusOption(this.visibleOptionEls[0]);
|
|
336
|
+
}
|
|
337
|
+
break;
|
|
222
338
|
}
|
|
223
339
|
});
|
|
224
340
|
}
|
|
225
341
|
}
|
|
226
342
|
close(returnFocus = true) {
|
|
227
|
-
this.isExpanded
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
this.
|
|
343
|
+
if (this.isExpanded) {
|
|
344
|
+
this.isExpanded = false;
|
|
345
|
+
this.allOptionEls.map((i) => (i.focused = false));
|
|
346
|
+
window.setTimeout(() => {
|
|
347
|
+
this.dropdownEl.classList.add("hidden");
|
|
348
|
+
if (this.multiple) {
|
|
349
|
+
this.updateOptionVisibility();
|
|
350
|
+
}
|
|
351
|
+
// clear search field, reset filtered / bolded state of wm-options
|
|
352
|
+
if (this.search) {
|
|
353
|
+
this.searchFieldEl.value = "";
|
|
354
|
+
this.wmSelectSearchChanged.emit({ searchTerm: this.searchTerm });
|
|
355
|
+
}
|
|
356
|
+
// Returns focus to button after popup closes (no need if user is tabbing)
|
|
357
|
+
// Delay is necessary for screenreader to get new expanded state before focus
|
|
358
|
+
// window.requestAnimationFrame is probably enough, but since we are already using setTimeout it may as well be here
|
|
359
|
+
// also UX wise, it makes sense for the button to only be focused after the animation is complete
|
|
360
|
+
if (returnFocus) {
|
|
361
|
+
this.el.focus();
|
|
362
|
+
}
|
|
363
|
+
}, 150);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
updateOptionVisibility() {
|
|
367
|
+
// this runs for search multiselects, where selected options are rendered at the top of the dropdown list
|
|
368
|
+
// slotted wm-options are hidden if selected, and duplicate wm-options are made visible if selected
|
|
369
|
+
this.childOptions.forEach((option, idx) => {
|
|
370
|
+
const duplicateOption = this.duplicateOptions[idx];
|
|
371
|
+
if (option.selected) {
|
|
372
|
+
option.classList.add("hidden");
|
|
373
|
+
duplicateOption.classList.remove("hidden");
|
|
237
374
|
}
|
|
238
|
-
|
|
375
|
+
else {
|
|
376
|
+
option.classList.remove("hidden");
|
|
377
|
+
duplicateOption.classList.add("hidden");
|
|
378
|
+
}
|
|
379
|
+
});
|
|
239
380
|
}
|
|
240
|
-
|
|
241
|
-
this.
|
|
381
|
+
focusOption(option) {
|
|
382
|
+
this.allOptionEls.forEach((i) => (i.focused = i === option));
|
|
383
|
+
option.focus();
|
|
242
384
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
385
|
+
selectOption(option) {
|
|
386
|
+
// this function does not necessarily change an options selected property to true
|
|
387
|
+
// in cases of multiselect, it toggles the selected property
|
|
388
|
+
if (option.classList.contains("duplicate")) {
|
|
389
|
+
// if clicking on a duplicate option, toggle selected property of real one, then rerender
|
|
390
|
+
const correspondingOption = this.findCorrespondingOption(option);
|
|
391
|
+
correspondingOption.selected = !correspondingOption.selected;
|
|
392
|
+
forceUpdate(this.el);
|
|
393
|
+
}
|
|
394
|
+
else if (this.multiple) {
|
|
395
|
+
option.selected = !option.selected;
|
|
246
396
|
}
|
|
247
397
|
else {
|
|
248
|
-
this.
|
|
398
|
+
this.allOptionEls.forEach((x) => (x.selected = x === option));
|
|
249
399
|
}
|
|
250
400
|
this.setButtonText();
|
|
251
401
|
}
|
|
252
|
-
|
|
402
|
+
findAndFocusOption(ev) {
|
|
253
403
|
const character = ev.detail.toUpperCase();
|
|
254
404
|
if (!this.keysSoFar) {
|
|
255
|
-
for (var i = 0; i < this.
|
|
256
|
-
if (this.
|
|
405
|
+
for (var i = 0; i < this.allOptionEls.length; i++) {
|
|
406
|
+
if (this.allOptionEls[i].focused) {
|
|
257
407
|
this.searchIndex = i;
|
|
258
408
|
}
|
|
259
409
|
}
|
|
260
410
|
}
|
|
261
411
|
this.keysSoFar += character;
|
|
262
412
|
this.clearKeysSoFarAfterDelay();
|
|
263
|
-
var nextMatch = this.findMatchInRange(this.
|
|
413
|
+
var nextMatch = this.findMatchInRange(this.allOptionEls, this.searchIndex + 1, this.allOptionEls.length);
|
|
264
414
|
if (!nextMatch) {
|
|
265
|
-
nextMatch = this.findMatchInRange(this.
|
|
415
|
+
nextMatch = this.findMatchInRange(this.allOptionEls, 0, this.searchIndex);
|
|
266
416
|
}
|
|
267
417
|
if (nextMatch) {
|
|
268
|
-
this.
|
|
418
|
+
this.focusOption(nextMatch);
|
|
269
419
|
}
|
|
270
420
|
}
|
|
271
421
|
clearKeysSoFarAfterDelay() {
|
|
@@ -279,8 +429,8 @@ export class Select {
|
|
|
279
429
|
}.bind(this), 500);
|
|
280
430
|
}
|
|
281
431
|
findMatchInRange(list, startIndex, endIndex) {
|
|
282
|
-
// Find the first
|
|
283
|
-
// the specified range of
|
|
432
|
+
// Find the first option starting with the keysSoFar substring, searching in
|
|
433
|
+
// the specified range of options
|
|
284
434
|
for (var n = startIndex; n < endIndex; n++) {
|
|
285
435
|
var label = list[n].textContent;
|
|
286
436
|
if (label && label.toUpperCase().indexOf(this.keysSoFar) === 0) {
|
|
@@ -289,6 +439,19 @@ export class Select {
|
|
|
289
439
|
}
|
|
290
440
|
return null;
|
|
291
441
|
}
|
|
442
|
+
findCorrespondingOption(el) {
|
|
443
|
+
// if duplicate, returns the child wm-option
|
|
444
|
+
// if child wm-option, returns duplicate
|
|
445
|
+
const isDuplicate = el.classList.contains("duplicate");
|
|
446
|
+
return isDuplicate
|
|
447
|
+
? this.childOptions[this.duplicateOptions.indexOf(el)]
|
|
448
|
+
: this.duplicateOptions[this.childOptions.indexOf(el)];
|
|
449
|
+
}
|
|
450
|
+
isElOrChild(el) {
|
|
451
|
+
var _a;
|
|
452
|
+
// determines whether or not the element is the component, a child of the component, or exists within the component's shadowroot
|
|
453
|
+
return el === this.el || this.el.contains(el) || ((_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.contains(el));
|
|
454
|
+
}
|
|
292
455
|
exposeErrors() {
|
|
293
456
|
// When the error changes, a new id is set for the error container and the button's aria-describedby attribute is updated accordingly. This is to make sure the screen reader announces teh updated errors in Firefox. See this longstanding bug: https://bugzilla.mozilla.org/show_bug.cgi?id=493683
|
|
294
457
|
const newId = generateId();
|
|
@@ -306,9 +469,30 @@ export class Select {
|
|
|
306
469
|
this.wmComponentBlurred.emit(); // deprecated
|
|
307
470
|
}
|
|
308
471
|
}
|
|
472
|
+
handleSearchFieldKeyDown(ev) {
|
|
473
|
+
switch (ev.key) {
|
|
474
|
+
case "ArrowDown":
|
|
475
|
+
ev.preventDefault();
|
|
476
|
+
if (this.visibleOptionEls.length) {
|
|
477
|
+
this.focusOption(this.visibleOptionEls[0]);
|
|
478
|
+
}
|
|
479
|
+
break;
|
|
480
|
+
case "ArrowUp":
|
|
481
|
+
ev.preventDefault();
|
|
482
|
+
if (this.visibleOptionEls.length) {
|
|
483
|
+
this.focusOption(this.visibleOptionEls[this.visibleOptionEls.length - 1]);
|
|
484
|
+
}
|
|
485
|
+
break;
|
|
486
|
+
case "Escape":
|
|
487
|
+
ev.preventDefault();
|
|
488
|
+
this.close();
|
|
489
|
+
break;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
309
492
|
setButtonText() {
|
|
310
|
-
this.
|
|
311
|
-
|
|
493
|
+
this.displayedOptions = this.childOptions
|
|
494
|
+
.filter((x) => x.selected)
|
|
495
|
+
.map((y) => (!y.classList.contains("hidden") ? y : this.findCorrespondingOption(y)));
|
|
312
496
|
// handle overflow + counter for multiselect
|
|
313
497
|
if (this.multiple) {
|
|
314
498
|
// this is a fixed measurement accounting for the max width of a 3 character overflow counter
|
|
@@ -318,34 +502,41 @@ export class Select {
|
|
|
318
502
|
const paddingLeft = parseInt(computedStyle.getPropertyValue("padding-left").slice(0, -2));
|
|
319
503
|
const paddingRight = parseInt(computedStyle.getPropertyValue("padding-right").slice(0, -2));
|
|
320
504
|
const availableSpace = this.buttonEl.clientWidth - paddingLeft - paddingRight - overflowCounterWidth;
|
|
321
|
-
let optionsWidths = this.
|
|
505
|
+
let optionsWidths = this.displayedOptions.map((x) => x.shadowRoot.querySelector(".option-wrapper").clientWidth);
|
|
322
506
|
let optionsTotalWidth = optionsWidths.reduce((acc, x) => acc + x, 0);
|
|
323
507
|
this.overflowCount = 0;
|
|
324
|
-
while (optionsTotalWidth > availableSpace && this.
|
|
508
|
+
while (optionsTotalWidth > availableSpace && this.displayedOptions.length > 1) {
|
|
325
509
|
this.overflowCount++;
|
|
326
510
|
optionsTotalWidth -= optionsWidths[optionsWidths.length - 1];
|
|
327
511
|
optionsWidths.pop();
|
|
328
|
-
this.
|
|
512
|
+
this.displayedOptions.pop();
|
|
329
513
|
}
|
|
330
514
|
}
|
|
331
515
|
}
|
|
516
|
+
announce(message) {
|
|
517
|
+
// \u00A0 is a non-breaking space character, which causes the message to be read as a new one
|
|
518
|
+
if (this.liveRegionEl.textContent === message) {
|
|
519
|
+
message += "\u00A0";
|
|
520
|
+
}
|
|
521
|
+
this.announcement = message;
|
|
522
|
+
}
|
|
332
523
|
renderButtonText() {
|
|
333
|
-
if (this.multiple && this.
|
|
524
|
+
if (this.multiple && this.displayedOptions.length < 1) {
|
|
334
525
|
return h("span", null, this.placeholder);
|
|
335
526
|
}
|
|
336
527
|
else if (this.multiple && this.allSelected && this.overflowCount > 0) {
|
|
337
528
|
return this.allSelectedMessage;
|
|
338
529
|
}
|
|
339
530
|
else {
|
|
340
|
-
return this.
|
|
531
|
+
return this.displayedOptions.map((x, idx) => (h("span", null,
|
|
341
532
|
idx > 0 ? ", " : "",
|
|
342
533
|
x.textContent)));
|
|
343
534
|
}
|
|
344
535
|
}
|
|
345
536
|
renderSubinfo() {
|
|
346
537
|
// multiselects cannot have subinfo for options
|
|
347
|
-
if (!this.multiple && this.
|
|
348
|
-
return h("span", { class: "subinfo" }, this.
|
|
538
|
+
if (!this.multiple && this.selectedOptions.length > 0 && this.selectedOptions[0].subinfo) {
|
|
539
|
+
return h("span", { class: "subinfo" }, this.selectedOptions[0].subinfo);
|
|
349
540
|
}
|
|
350
541
|
}
|
|
351
542
|
renderOverflowCount() {
|
|
@@ -356,6 +547,20 @@ export class Select {
|
|
|
356
547
|
this.overflowCount)));
|
|
357
548
|
}
|
|
358
549
|
}
|
|
550
|
+
renderSearchField() {
|
|
551
|
+
return (h("div", { class: "search" },
|
|
552
|
+
h("div", { class: "searchfield-wrapper", ref: (el) => (this.searchFieldWrapperEl = el) },
|
|
553
|
+
h("div", { class: "icon" }),
|
|
554
|
+
h("input", { ref: (el) => (this.searchFieldEl = el), class: "searchfield", role: "combobox", "aria-controls": `list-${this.uid}`, "aria-expanded": this.isExpanded ? "true" : "false", onKeyDown: (ev) => this.handleSearchFieldKeyDown(ev), onFocus: () => this.searchFieldWrapperEl.classList.add("focus"), onBlur: (ev) => this.handleSearchFieldBlur(ev), onInput: () => this.debouncedSearch(), placeholder: this.searchPlaceholder }))));
|
|
555
|
+
}
|
|
556
|
+
renderSearchFailedMessage() {
|
|
557
|
+
return h("div", { class: "search-results-message" }, this.noResultsFoundMessage);
|
|
558
|
+
}
|
|
559
|
+
renderDuplicateOptions() {
|
|
560
|
+
return Array.from(this.el.children).map((option) => {
|
|
561
|
+
return (h("wm-option", { class: "duplicate", selected: option.selected }, option.textContent));
|
|
562
|
+
});
|
|
563
|
+
}
|
|
359
564
|
render() {
|
|
360
565
|
const buttonProps = {
|
|
361
566
|
id: `selectbtn-${this.uid}`,
|
|
@@ -375,17 +580,22 @@ export class Select {
|
|
|
375
580
|
this.requiredField ? (h("span", { class: "required" },
|
|
376
581
|
h("span", { class: "sr-only" }, this.requiredMessage),
|
|
377
582
|
h("span", { "aria-hidden": "true" }, "*"))) : (""))),
|
|
378
|
-
h("div", { class: "
|
|
379
|
-
h("button", Object.assign({}, buttonProps, { class: `displayedoption ${this.isTabbing ? "user-is-tabbing" : ""}`, ref: (el) => (this.buttonEl = el), onBlur: (ev) => this.handleButtonBlur(ev) }),
|
|
380
|
-
h("span", { class: this.
|
|
583
|
+
h("div", { class: "button-wrapper" },
|
|
584
|
+
h("button", Object.assign({}, buttonProps, { class: `displayedoption ${this.isTabbing ? "user-is-tabbing" : ""}`, ref: (el) => (this.buttonEl = el), onBlur: (ev) => this.handleButtonBlur(ev), onFocus: () => this.close() }),
|
|
585
|
+
h("span", { class: this.selectedOptions.length > 0 && this.selectedOptions.filter((x) => x.subinfo).length > 0
|
|
381
586
|
? "overflowcontrol hassubinfo"
|
|
382
587
|
: "overflowcontrol" },
|
|
383
588
|
h("span", { class: "button-text" }, this.renderButtonText()),
|
|
384
589
|
this.renderSubinfo()),
|
|
385
590
|
this.renderOverflowCount()),
|
|
386
|
-
h("div", { class: `
|
|
387
|
-
|
|
388
|
-
|
|
591
|
+
h("div", { class: `dropdown ${this.isExpanded ? "open" : ""} ${this.openUp ? "upwards" : ""}`, ref: (el) => (this.dropdownEl = el) },
|
|
592
|
+
this.search && this.renderSearchField(),
|
|
593
|
+
h("div", { id: `list-${this.uid}`, tabindex: -1, role: "listbox", "aria-multiselectable": this.multiple ? "true" : null, "aria-labelledby": `label-${this.uid}` },
|
|
594
|
+
this.search && this.filteredOptions.length === 0 && this.renderSearchFailedMessage(),
|
|
595
|
+
this.multiple && this.renderDuplicateOptions(),
|
|
596
|
+
h("slot", null))),
|
|
597
|
+
this.renderErrorContainer(),
|
|
598
|
+
h("div", { "aria-live": "polite", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement)))));
|
|
389
599
|
}
|
|
390
600
|
static get is() { return "wm-select"; }
|
|
391
601
|
static get encapsulation() { return "shadow"; }
|
|
@@ -538,6 +748,24 @@ export class Select {
|
|
|
538
748
|
"reflect": false,
|
|
539
749
|
"defaultValue": "false"
|
|
540
750
|
},
|
|
751
|
+
"search": {
|
|
752
|
+
"type": "boolean",
|
|
753
|
+
"mutable": false,
|
|
754
|
+
"complexType": {
|
|
755
|
+
"original": "boolean",
|
|
756
|
+
"resolved": "boolean",
|
|
757
|
+
"references": {}
|
|
758
|
+
},
|
|
759
|
+
"required": false,
|
|
760
|
+
"optional": false,
|
|
761
|
+
"docs": {
|
|
762
|
+
"tags": [],
|
|
763
|
+
"text": ""
|
|
764
|
+
},
|
|
765
|
+
"attribute": "search",
|
|
766
|
+
"reflect": false,
|
|
767
|
+
"defaultValue": "false"
|
|
768
|
+
},
|
|
541
769
|
"placeholder": {
|
|
542
770
|
"type": "string",
|
|
543
771
|
"mutable": false,
|
|
@@ -556,6 +784,24 @@ export class Select {
|
|
|
556
784
|
"reflect": false,
|
|
557
785
|
"defaultValue": "intl.formatMessage({\r\n id: \"select.multiPlaceholder\",\r\n defaultMessage: \"Make a selection\",\r\n description: \"Placeholder text. Use imperative\",\r\n })"
|
|
558
786
|
},
|
|
787
|
+
"searchPlaceholder": {
|
|
788
|
+
"type": "string",
|
|
789
|
+
"mutable": false,
|
|
790
|
+
"complexType": {
|
|
791
|
+
"original": "string",
|
|
792
|
+
"resolved": "string",
|
|
793
|
+
"references": {}
|
|
794
|
+
},
|
|
795
|
+
"required": false,
|
|
796
|
+
"optional": false,
|
|
797
|
+
"docs": {
|
|
798
|
+
"tags": [],
|
|
799
|
+
"text": ""
|
|
800
|
+
},
|
|
801
|
+
"attribute": "search-placeholder",
|
|
802
|
+
"reflect": false,
|
|
803
|
+
"defaultValue": "intl.formatMessage({\r\n id: \"select.searchPlaceholder\",\r\n defaultMessage: \"Search\",\r\n description: \"Placeholder text. Use imperative\",\r\n })"
|
|
804
|
+
},
|
|
559
805
|
"allSelectedMessage": {
|
|
560
806
|
"type": "string",
|
|
561
807
|
"mutable": false,
|
|
@@ -577,7 +823,8 @@ export class Select {
|
|
|
577
823
|
}; }
|
|
578
824
|
static get states() { return {
|
|
579
825
|
"isTabbing": {},
|
|
580
|
-
"isExpanded": {}
|
|
826
|
+
"isExpanded": {},
|
|
827
|
+
"announcement": {}
|
|
581
828
|
}; }
|
|
582
829
|
static get events() { return [{
|
|
583
830
|
"method": "wmSelectDidLoad",
|
|
@@ -624,6 +871,25 @@ export class Select {
|
|
|
624
871
|
"resolved": "void",
|
|
625
872
|
"references": {}
|
|
626
873
|
}
|
|
874
|
+
}, {
|
|
875
|
+
"method": "wmSelectSearchChanged",
|
|
876
|
+
"name": "wmSelectSearchChanged",
|
|
877
|
+
"bubbles": true,
|
|
878
|
+
"cancelable": true,
|
|
879
|
+
"composed": true,
|
|
880
|
+
"docs": {
|
|
881
|
+
"tags": [],
|
|
882
|
+
"text": ""
|
|
883
|
+
},
|
|
884
|
+
"complexType": {
|
|
885
|
+
"original": "Object",
|
|
886
|
+
"resolved": "Object",
|
|
887
|
+
"references": {
|
|
888
|
+
"Object": {
|
|
889
|
+
"location": "global"
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
}
|
|
627
893
|
}]; }
|
|
628
894
|
static get elementRef() { return "el"; }
|
|
629
895
|
static get watchers() { return [{
|
|
@@ -668,19 +934,13 @@ export class Select {
|
|
|
668
934
|
"passive": false
|
|
669
935
|
}, {
|
|
670
936
|
"name": "wmHomeKeyPressed",
|
|
671
|
-
"method": "
|
|
937
|
+
"method": "moveToFirstOption",
|
|
672
938
|
"target": undefined,
|
|
673
939
|
"capture": false,
|
|
674
940
|
"passive": false
|
|
675
941
|
}, {
|
|
676
942
|
"name": "wmEndKeyPressed",
|
|
677
|
-
"method": "
|
|
678
|
-
"target": undefined,
|
|
679
|
-
"capture": false,
|
|
680
|
-
"passive": false
|
|
681
|
-
}, {
|
|
682
|
-
"name": "wmTabKeyPressed",
|
|
683
|
-
"method": "handleTabKey",
|
|
943
|
+
"method": "moveToLastOption",
|
|
684
944
|
"target": undefined,
|
|
685
945
|
"capture": false,
|
|
686
946
|
"passive": false
|
|
@@ -710,7 +970,7 @@ export class Select {
|
|
|
710
970
|
"passive": false
|
|
711
971
|
}, {
|
|
712
972
|
"name": "wmLetterPressed",
|
|
713
|
-
"method": "
|
|
973
|
+
"method": "findAndFocusOption",
|
|
714
974
|
"target": undefined,
|
|
715
975
|
"capture": false,
|
|
716
976
|
"passive": false
|