@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,7 +1,7 @@
|
|
|
1
1
|
import { r as registerInstance, c as createEvent, h, H as Host, g as getElement, f as forceUpdate } from './index-7603f98e.js';
|
|
2
|
-
import { i as intl, g as generateId, l as shouldOpenUp, q as getTextDir } from './functions-
|
|
2
|
+
import { i as intl, d as debounce, g as generateId, l as shouldOpenUp, q as getTextDir } from './functions-036af8dc.js';
|
|
3
3
|
|
|
4
|
-
const wmOptionCss = ":host(:not(:last-child)),wm-option:not(:last-child){border-bottom:2px solid rgba(46, 27, 70, 0.05)}:host,wm-option{display:block;cursor:pointer;position:relative;padding:1.25rem;background:#fff;font-family:inherit;list-style:none;color:#4a4a4a;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}:host:focus,:host.focus,wm-option:focus,wm-option.focus{outline:none;background:#f4f4f4}:host.icon,wm-option.icon{color:#575195}.checkbox:before{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f131\";display:inline;margin-right:0.25rem;color:#575195}:host([aria-selected=true]),wm-option[aria-selected=true]{background:rgba(46, 27, 70, 0.05);font-weight:500}:host([aria-selected=true]) .checkbox:before,wm-option[aria-selected=true] .checkbox:before{content:\"\\f132\"}:host([aria-disabled=true]),wm-option[aria-disabled=true]{font-style:italic;color:#6b6b6b;cursor:default}:host([aria-disabled=true]) .checkbox:before,wm-option[aria-disabled=true] .checkbox:before{color:#6b6b6b}:host(.multi-option),wm-option.multi-option{background:unset}:host(.hassubinfo),wm-option.hassubinfo{display:-ms-flexbox;display:flex}:host(.hassubinfo) .option-wrapper,wm-option.hassubinfo .option-wrapper{-ms-flex:1;flex:1}:host(.hassubinfo) .subinfo,wm-option.hassubinfo .subinfo{-ms-flex:none;flex:none}.subinfo{font-style:italic}.option-wrapper{display:inline-block}::slotted{font-family:inherit}::slotted(i){font-size:0.875rem}::slotted(i):before{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;margin-right:0.625rem;pointer-events:none}:host(:focus),wm-option:focus{outline:none;background:#f4f4f4}:host(:hover){background:#f4f4f4;outline:none}";
|
|
4
|
+
const wmOptionCss = ":host(:not(:last-child)),wm-option:not(:last-child){border-bottom:2px solid rgba(46, 27, 70, 0.05)}:host,wm-option{display:block;cursor:pointer;position:relative;padding:1.25rem;background:#fff;font-family:inherit;list-style:none;color:#4a4a4a;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}:host:focus,:host.focus,wm-option:focus,wm-option.focus{outline:none;background:#f4f4f4}:host.icon,wm-option.icon{color:#575195}.checkbox:before{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f131\";display:inline;margin-right:0.25rem;color:#575195}:host([aria-selected=true]),wm-option[aria-selected=true]{background:rgba(46, 27, 70, 0.05);font-weight:500}:host([aria-selected=true]) .checkbox:before,wm-option[aria-selected=true] .checkbox:before{content:\"\\f132\"}:host([aria-disabled=true]),wm-option[aria-disabled=true]{font-style:italic;color:#6b6b6b;cursor:default}:host([aria-disabled=true]) .checkbox:before,wm-option[aria-disabled=true] .checkbox:before{color:#6b6b6b}:host(.multi-option),wm-option.multi-option{background:unset}:host(.hidden),wm-option.hidden,:host(.filtered-out),wm-option.filtered-out{display:none}:host(.duplicate.last),wm-option.duplicate.last{border-bottom:12px solid rgba(46, 27, 70, 0.05)}:host(.hassubinfo),wm-option.hassubinfo{display:-ms-flexbox;display:flex}:host(.hassubinfo) .option-wrapper,wm-option.hassubinfo .option-wrapper{-ms-flex:1;flex:1}:host(.hassubinfo) .subinfo,wm-option.hassubinfo .subinfo{-ms-flex:none;flex:none}.subinfo{font-style:italic}.option-wrapper{display:inline-block}::slotted{font-family:inherit}::slotted(i){font-size:0.875rem}::slotted(i):before{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;margin-right:0.625rem;pointer-events:none}:host(:focus),wm-option:focus{outline:none;background:#f4f4f4}:host(:hover){background:#f4f4f4;outline:none}";
|
|
5
5
|
|
|
6
6
|
let Option = class {
|
|
7
7
|
constructor(hostRef) {
|
|
@@ -12,7 +12,6 @@ let Option = class {
|
|
|
12
12
|
this.wmEscKeyPressed = createEvent(this, "wmEscKeyPressed", 7);
|
|
13
13
|
this.wmHomeKeyPressed = createEvent(this, "wmHomeKeyPressed", 7);
|
|
14
14
|
this.wmEndKeyPressed = createEvent(this, "wmEndKeyPressed", 7);
|
|
15
|
-
this.wmTabKeyPressed = createEvent(this, "wmTabKeyPressed", 7);
|
|
16
15
|
this.wmEnterKeyPressed = createEvent(this, "wmEnterKeyPressed", 7);
|
|
17
16
|
this.wmLetterPressed = createEvent(this, "wmLetterPressed", 7);
|
|
18
17
|
this.wmOptionBlurred = createEvent(this, "wmOptionBlurred", 7);
|
|
@@ -20,16 +19,32 @@ let Option = class {
|
|
|
20
19
|
this.disabled = false;
|
|
21
20
|
this.selected = false;
|
|
22
21
|
this.focused = false;
|
|
22
|
+
this.searchTerm = "";
|
|
23
23
|
}
|
|
24
|
-
get
|
|
24
|
+
get hostClasses() {
|
|
25
|
+
let classes = [];
|
|
26
|
+
if (this.subinfo) {
|
|
27
|
+
classes.push("hassubinfo");
|
|
28
|
+
}
|
|
29
|
+
if (this.parentSelectEl.multiple) {
|
|
30
|
+
classes.push("multi-option");
|
|
31
|
+
}
|
|
32
|
+
if (!this.el.textContent.toLowerCase().includes(this.searchTerm)) {
|
|
33
|
+
classes.push("filtered-out");
|
|
34
|
+
}
|
|
35
|
+
return classes.join(" ");
|
|
36
|
+
}
|
|
37
|
+
get parentSelectEl() {
|
|
25
38
|
var _a;
|
|
26
|
-
return (_a = this.el.parentElement) === null || _a === void 0 ? void 0 : _a.
|
|
39
|
+
return ((_a = this.el.parentElement) === null || _a === void 0 ? void 0 : _a.nodeName) !== "WM-SELECT"
|
|
40
|
+
? this.el.getRootNode().host
|
|
41
|
+
: this.el.parentElement;
|
|
27
42
|
}
|
|
28
43
|
handleKeydown(ev) {
|
|
29
44
|
switch (ev.key) {
|
|
30
45
|
case "ArrowUp":
|
|
31
46
|
ev.preventDefault();
|
|
32
|
-
this.wmKeyUpPressed.emit();
|
|
47
|
+
this.wmKeyUpPressed.emit(this.el);
|
|
33
48
|
break;
|
|
34
49
|
case "ArrowDown":
|
|
35
50
|
ev.preventDefault();
|
|
@@ -59,16 +74,13 @@ let Option = class {
|
|
|
59
74
|
ev.preventDefault();
|
|
60
75
|
this.wmEndKeyPressed.emit();
|
|
61
76
|
break;
|
|
62
|
-
case "Tab":
|
|
63
|
-
this.wmTabKeyPressed.emit();
|
|
64
|
-
break;
|
|
65
77
|
default:
|
|
66
78
|
this.wmLetterPressed.emit(ev.key);
|
|
67
79
|
}
|
|
68
80
|
}
|
|
69
81
|
handleSelection() {
|
|
70
82
|
if (!this.disabled) {
|
|
71
|
-
this.wmOptionSelected.emit();
|
|
83
|
+
this.wmOptionSelected.emit(this.el);
|
|
72
84
|
// the parent wm-select is in charge of the actual selection
|
|
73
85
|
}
|
|
74
86
|
}
|
|
@@ -96,13 +108,21 @@ let Option = class {
|
|
|
96
108
|
this.el.onclick = this.onClickFunc;
|
|
97
109
|
}
|
|
98
110
|
}
|
|
111
|
+
handleSearch(ev) {
|
|
112
|
+
// filter is case-insensitive, so
|
|
113
|
+
this.searchTerm = ev.detail.searchTerm.toLowerCase();
|
|
114
|
+
const regexp = new RegExp(`${this.searchTerm}`, "gi");
|
|
115
|
+
const boldedText = this.el.textContent.replace(regexp, (match) => `<b>${match}</b>`);
|
|
116
|
+
this.textEl.innerHTML = `<span>${boldedText}</span>`;
|
|
117
|
+
}
|
|
99
118
|
componentWillLoad() {
|
|
100
119
|
this.syncAriaSelected();
|
|
101
120
|
this.syncAriaDisabled();
|
|
102
121
|
this.updateDisabledOnClick();
|
|
122
|
+
this.parentSelectEl.addEventListener("wmSelectSearchChanged", (ev) => this.handleSearch(ev));
|
|
103
123
|
}
|
|
104
124
|
render() {
|
|
105
|
-
return (h(Host, { role: "option", tabindex: this.focused ? 0 : -1, class:
|
|
125
|
+
return (h(Host, { role: "option", tabindex: this.focused ? 0 : -1, class: this.hostClasses }, h("div", { class: `option-wrapper ${this.parentSelectEl.multiple ? "checkbox" : ""}`, ref: (el) => (this.textEl = el) }, h("slot", null)), h("div", { class: "subinfo" }, this.subinfo)));
|
|
106
126
|
}
|
|
107
127
|
get el() { return getElement(this); }
|
|
108
128
|
static get watchers() { return {
|
|
@@ -113,7 +133,7 @@ let Option = class {
|
|
|
113
133
|
};
|
|
114
134
|
Option.style = wmOptionCss;
|
|
115
135
|
|
|
116
|
-
const wmSelectCss = ":host{position:relative;display:block;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:inherit}:host .sr-only{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;border:0 !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;white-space:nowrap !important;margin:-1px !important}.wrapper{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;font-size:0.875rem}.wrapper .label{display:block;line-height:normal;font-weight:600;white-space:nowrap;margin-bottom:0.25rem}.wrapper .label .required{color:#c0392b}.wrapper.label-left{-ms-flex-direction:row;flex-direction:row}.wrapper.label-left .label-wrapper{line-height:2.5rem}.wrapper.label-left .label-wrapper .label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:2.5rem;white-space:normal;margin-bottom:0;margin-right:0.75rem}.wrapper.label-none label{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;border:0 !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;white-space:nowrap !important;margin:-1px !important}.wrapper.invalid .label{color:#c0392b}.wrapper.invalid .label:after{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f026\";margin-left:0.3125rem}[dir=RTL] .wrapper.invalid .label:after{margin-left:0;margin-right:0.3125rem}.wrapper.rtl.label-left .label{margin-right:0;margin-left:0.75rem}.wrapper .
|
|
136
|
+
const wmSelectCss = ":host{position:relative;display:block;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:inherit}:host .sr-only{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;border:0 !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;white-space:nowrap !important;margin:-1px !important}.wrapper{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;font-size:0.875rem}.wrapper .label{display:block;line-height:normal;font-weight:600;white-space:nowrap;margin-bottom:0.25rem}.wrapper .label .required{color:#c0392b}.wrapper.label-left{-ms-flex-direction:row;flex-direction:row}.wrapper.label-left .label-wrapper{line-height:2.5rem}.wrapper.label-left .label-wrapper .label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:2.5rem;white-space:normal;margin-bottom:0;margin-right:0.75rem}.wrapper.label-none label{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;border:0 !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;white-space:nowrap !important;margin:-1px !important}.wrapper.invalid .label{color:#c0392b}.wrapper.invalid .label:after{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f026\";margin-left:0.3125rem}[dir=RTL] .wrapper.invalid .label:after{margin-left:0;margin-right:0.3125rem}.wrapper.rtl.label-left .label{margin-right:0;margin-left:0.75rem}.wrapper .button-wrapper{position:relative;-ms-flex:1;flex:1;font-size:1.125rem;color:#575195;min-width:8.75rem}.wrapper .button-wrapper .displayedoption{-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-wrap:nowrap;flex-wrap:nowrap;background:transparent;width:100%;border:solid 1px rgba(35, 35, 35, 0.6);padding:0 1.875rem 0 0.9375rem;cursor:pointer;height:2.5rem;line-height:normal;font-family:inherit;color:#575195;font-weight:400;font-size:0.875rem;text-transform:none;text-align:left}@media only screen and (max-width: 768px){.wrapper .button-wrapper .displayedoption{height:2.75rem}}.wrapper .button-wrapper .displayedoption:before{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f140\";position:absolute;right:0.5625rem;pointer-events:none}.wrapper .button-wrapper .displayedoption:hover:not(:disabled):not(.-disabled):not(.-raised){background:transparent;text-decoration:none}.wrapper .button-wrapper .displayedoption:active{-ms-transform:scale(1, 1) !important;-webkit-transform:scale(1, 1) !important;transform:scale(1, 1) !important}.wrapper .button-wrapper .displayedoption:focus{outline:none}.wrapper .button-wrapper .displayedoption::-moz-focus-inner{border:0}.wrapper .button-wrapper .displayedoption.user-is-tabbing:focus{-webkit-box-shadow:0 2px 2px 0 rgba(244, 243, 246, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.1), 0 0 4px 3px #61279e;-moz-box-shadow:0 2px 2px 0 rgba(244, 243, 246, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.1), 0 0 4px 3px #61279e;box-shadow:0 2px 2px 0 rgba(244, 243, 246, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.1), 0 0 4px 3px #61279e}.wrapper .button-wrapper .displayedoption.user-is-tabbing:focus::-moz-focus-inner{border:0}.wrapper .button-wrapper .displayedoption .overflowcontrol{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;-ms-flex:1;flex:1}.wrapper .button-wrapper .displayedoption .overflowcontrol.hassubinfo{display:-ms-flexbox;display:flex}.wrapper .button-wrapper .displayedoption .overflowcontrol.hassubinfo .button-text{-ms-flex:1;flex:1;text-overflow:ellipsis;overflow:hidden;min-width:0}.wrapper .button-wrapper .displayedoption .overflowcontrol.hassubinfo .subinfo{-ms-flex:none;flex:none;font-style:italic}.wrapper .button-wrapper .displayedoption .overflow-counter{font-weight:bold;margin-left:0.5rem}.wrapper .button-wrapper>.displayedoption[disabled]{color:#6b6b6b;border-color:#8a8a8a;background:#f0f0f0;cursor:default}.wrapper .button-wrapper>.dropdown{-webkit-overflow-scrolling:touch;overflow:auto;max-height:12.5rem;-webkit-box-shadow:0 4px 15px 0 rgba(0, 0, 0, 0.2);-moz-box-shadow:0 4px 15px 0 rgba(0, 0, 0, 0.2);box-shadow:0 4px 15px 0 rgba(0, 0, 0, 0.2);-ms-transition:transform 0.25s ease;-webkit-transition:transform 0.25s ease;-moz-transition:transform 0.25s ease;-webkit-transition:-webkit-transform 0.25s ease;transition:-webkit-transform 0.25s ease;transition:transform 0.25s ease;transition:transform 0.25s ease, -webkit-transform 0.25s ease;-ms-transform:scale(1, 0);-webkit-transform:scale(1, 0);-moz-transform:scale(1, 0);transform:scale(1, 0);-ms-transform-origin:center top;-webkit-transform-origin:center top;-moz-transform-origin:center top;transform-origin:center top;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;position:absolute;top:0;right:0;background:#fff;z-index:100;width:100%;font-size:0.875rem}.wrapper .button-wrapper>.dropdown.upwards{top:unset;bottom:calc(100% - 2.5rem);-ms-transform-origin:center bottom;-webkit-transform-origin:center bottom;-moz-transform-origin:center bottom;transform-origin:center bottom}.wrapper .button-wrapper>.dropdown.hidden{visibility:hidden}.wrapper .button-wrapper>.dropdown.open{-ms-transform:scale(1, 1);-webkit-transform:scale(1, 1);-moz-transform:scale(1, 1);transform:scale(1, 1)}.wrapper.invalid .button-wrapper .displayedoption{-webkit-box-shadow:0 0 0 1px #c0392b;-moz-box-shadow:0 0 0 1px #c0392b;box-shadow:0 0 0 1px #c0392b;border-color:#c0392b}.wrapper .error-message{color:#c0392b;font-size:0.875rem;margin-top:0.25rem;margin-bottom:0.25rem;display:block;top:100%;left:0;font-style:italic}.search{-webkit-box-sizing:border-box;box-sizing:border-box;border-bottom:2px solid rgba(46, 27, 70, 0.05);padding:1.25rem}.search .searchfield-wrapper{-webkit-box-sizing:border-box;box-sizing:border-box;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;height:2.75rem;width:100%;padding:0 0.75rem;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;border:1px solid #4a4a4a}.search .searchfield-wrapper:focus,.search .searchfield-wrapper.focus{-webkit-box-shadow:0 0 0 1px #20cbd4;-moz-box-shadow:0 0 0 1px #20cbd4;box-shadow:0 0 0 1px #20cbd4;outline:none;border-color:#20cbd4}.search .searchfield{width:100%;border:none;outline:none;font-family:inherit;font-size:0.875rem;margin-left:0.25rem}.search .icon:before{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f349\";color:#6b6b6b;font-size:0.875rem}.search-results-message{padding:1.25rem;color:#4a4a4a;font-size:0.875rem;font-style:italic}.rtl>.dropdown{-ms-transform-origin:left top;-webkit-transform-origin:left top;-moz-transform-origin:left top;transform-origin:left top;left:0;right:auto}.rtl>.dropdown .option{padding-left:3rem;padding-right:1.25rem}.rtl>.displayedoption{padding:0 0.9375rem 0 1.875rem;text-align:right}.rtl>.displayedoption:before{right:auto;left:0.5625rem}";
|
|
117
137
|
|
|
118
138
|
let Select = class {
|
|
119
139
|
constructor(hostRef) {
|
|
@@ -121,17 +141,24 @@ let Select = class {
|
|
|
121
141
|
this.wmSelectDidLoad = createEvent(this, "wmSelectDidLoad", 7);
|
|
122
142
|
this.wmSelectBlurred = createEvent(this, "wmSelectBlurred", 7);
|
|
123
143
|
this.wmComponentBlurred = createEvent(this, "wmComponentBlurred", 7);
|
|
144
|
+
this.wmSelectSearchChanged = createEvent(this, "wmSelectSearchChanged", 7);
|
|
124
145
|
this.disabled = false;
|
|
125
146
|
this.invalid = false;
|
|
126
147
|
this.labelPosition = "top";
|
|
127
148
|
this.requiredField = false;
|
|
128
149
|
this.errorMessage = "";
|
|
129
150
|
this.multiple = false;
|
|
151
|
+
this.search = false;
|
|
130
152
|
this.placeholder = intl.formatMessage({
|
|
131
153
|
id: "select.multiPlaceholder",
|
|
132
154
|
defaultMessage: "Make a selection",
|
|
133
155
|
description: "Placeholder text. Use imperative",
|
|
134
156
|
});
|
|
157
|
+
this.searchPlaceholder = intl.formatMessage({
|
|
158
|
+
id: "select.searchPlaceholder",
|
|
159
|
+
defaultMessage: "Search",
|
|
160
|
+
description: "Placeholder text. Use imperative",
|
|
161
|
+
});
|
|
135
162
|
this.allSelectedMessage = intl.formatMessage({
|
|
136
163
|
id: "select.allSelected",
|
|
137
164
|
defaultMessage: "All selected",
|
|
@@ -143,21 +170,68 @@ let Select = class {
|
|
|
143
170
|
});
|
|
144
171
|
this.isTabbing = false;
|
|
145
172
|
this.isExpanded = false;
|
|
173
|
+
this.announcement = "";
|
|
146
174
|
this.keysSoFar = "";
|
|
147
175
|
this.searchIndex = 0;
|
|
148
176
|
this.keyClear = null;
|
|
149
177
|
this.openUp = false;
|
|
178
|
+
//////////////////////////////////////
|
|
179
|
+
//////////////////////////////////////
|
|
150
180
|
// for multiselect button text
|
|
151
181
|
this.overflowCount = 0;
|
|
152
|
-
this.
|
|
153
|
-
this.
|
|
182
|
+
this.displayedOptions = [];
|
|
183
|
+
this.debouncedSearch = debounce(() => {
|
|
184
|
+
this.wmSelectSearchChanged.emit({ searchTerm: this.searchTerm });
|
|
185
|
+
if (this.filteredOptions.length) {
|
|
186
|
+
this.announce(this.resultsFoundMessage);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
this.announce(this.noResultsFoundMessage);
|
|
190
|
+
}
|
|
191
|
+
}, 150);
|
|
154
192
|
}
|
|
155
|
-
get
|
|
193
|
+
get childOptions() {
|
|
156
194
|
return Array.from(this.el.querySelectorAll("wm-option"));
|
|
157
195
|
}
|
|
158
|
-
get
|
|
196
|
+
get duplicateOptions() {
|
|
197
|
+
return Array.from(this.el.shadowRoot.querySelectorAll("wm-option"));
|
|
198
|
+
}
|
|
199
|
+
get allOptionEls() {
|
|
200
|
+
// this includes both slotted wm-options and internally created wm-options
|
|
201
|
+
return this.duplicateOptions.concat(this.childOptions);
|
|
202
|
+
}
|
|
203
|
+
get visibleOptionEls() {
|
|
204
|
+
return this.allOptionEls.filter((option) => !option.classList.contains("hidden") && !option.classList.contains("filtered-out"));
|
|
205
|
+
}
|
|
206
|
+
//////////////////////////////////////
|
|
207
|
+
// for search variants
|
|
208
|
+
get searchTerm() {
|
|
209
|
+
return this.searchFieldEl ? this.searchFieldEl.value : "";
|
|
210
|
+
}
|
|
211
|
+
get filteredOptions() {
|
|
212
|
+
return this.childOptions.filter((option) => { var _a; return (_a = option.textContent) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(this.searchTerm); });
|
|
213
|
+
}
|
|
214
|
+
get selectedOptions() {
|
|
159
215
|
return Array.from(this.el.querySelectorAll("wm-option")).filter((x) => x.selected);
|
|
160
216
|
}
|
|
217
|
+
get allSelected() {
|
|
218
|
+
return this.childOptions.filter((option) => option.selected).length === this.childOptions.length;
|
|
219
|
+
}
|
|
220
|
+
//////////////////////////////////////
|
|
221
|
+
get resultsFoundMessage() {
|
|
222
|
+
return intl.formatMessage({
|
|
223
|
+
id: "select.searchResultsFound",
|
|
224
|
+
defaultMessage: "{numResults, plural, one {1 option found} other {# options found}}",
|
|
225
|
+
description: "The message read by the screen reader, indicating how many results a search returned",
|
|
226
|
+
}, { numResults: this.filteredOptions.length });
|
|
227
|
+
}
|
|
228
|
+
get noResultsFoundMessage() {
|
|
229
|
+
return intl.formatMessage({
|
|
230
|
+
id: "select.noSearchResults",
|
|
231
|
+
defaultMessage: "No results found. Please try your search again.",
|
|
232
|
+
description: "The message displayed when no options pass the search filter",
|
|
233
|
+
});
|
|
234
|
+
}
|
|
161
235
|
toggleTabbingOn() {
|
|
162
236
|
this.isTabbing = true;
|
|
163
237
|
}
|
|
@@ -166,14 +240,11 @@ let Select = class {
|
|
|
166
240
|
}
|
|
167
241
|
handleOptionSelection(ev) {
|
|
168
242
|
if (!this.multiple) {
|
|
169
|
-
// ensure only one option is selected at a time
|
|
170
|
-
this.
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
this.focusItem(ev.target);
|
|
176
|
-
this.selectItem(ev.target);
|
|
243
|
+
// ensure only one option is selected at a time, unselect all other options
|
|
244
|
+
this.childOptions.forEach((option) => (option.selected = option === ev.detail));
|
|
245
|
+
}
|
|
246
|
+
this.focusOption(ev.detail);
|
|
247
|
+
this.selectOption(ev.detail);
|
|
177
248
|
if (!this.multiple) {
|
|
178
249
|
this.close();
|
|
179
250
|
}
|
|
@@ -183,28 +254,24 @@ let Select = class {
|
|
|
183
254
|
this.close();
|
|
184
255
|
}
|
|
185
256
|
handleChildUp(ev) {
|
|
186
|
-
this.moveUp(ev.
|
|
257
|
+
this.moveUp(ev.detail);
|
|
187
258
|
}
|
|
188
259
|
handleChildDown(ev) {
|
|
189
|
-
this.moveDown(ev.
|
|
260
|
+
this.moveDown(ev.detail);
|
|
190
261
|
}
|
|
191
|
-
|
|
192
|
-
this.
|
|
262
|
+
moveToFirstOption() {
|
|
263
|
+
this.focusOption(this.visibleOptionEls[0]);
|
|
193
264
|
}
|
|
194
|
-
|
|
195
|
-
this.
|
|
196
|
-
}
|
|
197
|
-
handleTabKey() {
|
|
198
|
-
this.close(false);
|
|
265
|
+
moveToLastOption() {
|
|
266
|
+
this.focusOption(this.visibleOptionEls[this.visibleOptionEls.length - 1]);
|
|
199
267
|
}
|
|
200
268
|
closePopupOnEscape() {
|
|
201
269
|
this.close();
|
|
202
270
|
}
|
|
203
271
|
handleOptionBlur(ev) {
|
|
204
|
-
const toElOrChild = ev.detail.relatedTarget === this.el || this.el.contains(ev.detail.relatedTarget);
|
|
205
272
|
// if the Option is blurred to something other than the component emit a blur event with the appropriate relatedTarget
|
|
206
273
|
// keeps our component's blur events accurate, and closes when focusing browser address bar
|
|
207
|
-
if (!
|
|
274
|
+
if (!this.isElOrChild(ev.detail.relatedTarget)) {
|
|
208
275
|
const event = new CustomEvent("blur");
|
|
209
276
|
// @ts-ignore
|
|
210
277
|
event.relatedTarget = ev.detail.relatedTarget;
|
|
@@ -212,18 +279,23 @@ let Select = class {
|
|
|
212
279
|
}
|
|
213
280
|
}
|
|
214
281
|
handleClick(ev) {
|
|
215
|
-
|
|
216
|
-
if (!isElOrChild && this.isExpanded) {
|
|
282
|
+
if (!this.isElOrChild(ev.target)) {
|
|
217
283
|
this.close();
|
|
218
284
|
}
|
|
219
285
|
}
|
|
220
286
|
handleButtonBlur(ev) {
|
|
221
|
-
|
|
222
|
-
if (toElOrChild) {
|
|
287
|
+
if (this.isElOrChild(ev.relatedTarget)) {
|
|
223
288
|
// do not emit a blur event when opening the dropdown and focusing the Options
|
|
224
289
|
ev.stopPropagation();
|
|
225
290
|
}
|
|
226
291
|
}
|
|
292
|
+
handleSearchFieldBlur(ev) {
|
|
293
|
+
this.searchFieldWrapperEl.classList.remove("focus");
|
|
294
|
+
if (this.isElOrChild(ev.relatedTarget)) {
|
|
295
|
+
// do not emit a blur event when moving from searchfield to options
|
|
296
|
+
ev.stopPropagation();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
227
299
|
handleKey(ev) {
|
|
228
300
|
switch (ev.key) {
|
|
229
301
|
case "ArrowDown":
|
|
@@ -253,137 +325,236 @@ let Select = class {
|
|
|
253
325
|
if (document.body.classList.contains("wmcl-user-is-tabbing")) {
|
|
254
326
|
this.toggleTabbingOn();
|
|
255
327
|
}
|
|
328
|
+
// set initial selections
|
|
329
|
+
if (this.selectedOptions.length > 0) {
|
|
330
|
+
this.selectedOptions.forEach((x) => {
|
|
331
|
+
this.displayedOptions.push(x);
|
|
332
|
+
});
|
|
333
|
+
// single Select only, pre-select if no default option from dev
|
|
334
|
+
}
|
|
335
|
+
else if (!this.multiple) {
|
|
336
|
+
this.selectOption(this.allOptionEls[0]);
|
|
337
|
+
}
|
|
256
338
|
}
|
|
257
339
|
componentDidLoad() {
|
|
258
340
|
this.wmSelectDidLoad.emit();
|
|
259
|
-
if (
|
|
260
|
-
throw new Error("wm-select should have wm-option elements as children.");
|
|
261
|
-
}
|
|
262
|
-
if (this.multiple && this.childItems.filter((x) => x.subinfo).length > 0) {
|
|
341
|
+
if (this.multiple && this.allOptionEls.filter((x) => x.subinfo).length > 0) {
|
|
263
342
|
throw new Error("wm-select with the multiple prop cannot have subinfo options");
|
|
264
343
|
}
|
|
265
344
|
if (this.multiple && !this.placeholder) {
|
|
266
345
|
throw new Error("wm-select with the multiple prop needs to also use the placeholder prop.");
|
|
267
346
|
}
|
|
268
|
-
|
|
269
|
-
if (this.selectedItems.length > 0) {
|
|
270
|
-
this.selectedItems.forEach((x) => this.displayedItems.push(x));
|
|
271
|
-
this.setButtonText();
|
|
272
|
-
// single Select only, pre-select if no default option from dev
|
|
273
|
-
}
|
|
274
|
-
else if (!this.multiple) {
|
|
275
|
-
this.selectItem(this.childItems[0]);
|
|
276
|
-
}
|
|
277
|
-
this.optionsEl.classList.add("hidden");
|
|
347
|
+
this.dropdownEl.classList.add("hidden");
|
|
278
348
|
forceUpdate(this.el);
|
|
279
349
|
// Dev can overwrite the max-height rule set in the Sass file
|
|
280
350
|
if (this.maxHeight) {
|
|
281
|
-
this.
|
|
351
|
+
this.dropdownEl.style.maxHeight = this.maxHeight;
|
|
352
|
+
}
|
|
353
|
+
const mutationObserver = new MutationObserver(() => this.handleSelectedMutation());
|
|
354
|
+
mutationObserver.observe(this.el, {
|
|
355
|
+
attributes: true,
|
|
356
|
+
attributeFilter: ["selected"],
|
|
357
|
+
subtree: true,
|
|
358
|
+
});
|
|
359
|
+
if (this.multiple) {
|
|
360
|
+
this.updateOptionVisibility();
|
|
361
|
+
}
|
|
362
|
+
this.setButtonText();
|
|
363
|
+
}
|
|
364
|
+
componentWillUpdate() {
|
|
365
|
+
if (this.multiple) {
|
|
366
|
+
// find last visible duplicate option and apply .last class
|
|
367
|
+
const visibleDuplicateOptions = this.visibleOptionEls.filter((option) => option.classList.contains("duplicate"));
|
|
368
|
+
visibleDuplicateOptions.forEach((option, idx) => {
|
|
369
|
+
if (idx === visibleDuplicateOptions.length - 1) {
|
|
370
|
+
option.classList.add("last");
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
option.classList.remove("last");
|
|
374
|
+
}
|
|
375
|
+
});
|
|
282
376
|
}
|
|
283
377
|
}
|
|
378
|
+
handleSelectedMutation() {
|
|
379
|
+
// dispatch change event after selected options change
|
|
380
|
+
// mutation observer prevents emitting event when an already selected option is selected again
|
|
381
|
+
const event = new CustomEvent("change");
|
|
382
|
+
// @ts-ignore
|
|
383
|
+
this.el.dispatchEvent(event);
|
|
384
|
+
}
|
|
284
385
|
moveUp(el) {
|
|
285
|
-
const prevEl = el
|
|
386
|
+
const prevEl = this.visibleOptionEls[this.visibleOptionEls.indexOf(el) - 1];
|
|
286
387
|
if (prevEl) {
|
|
287
388
|
// scroll option to top of dropdown if partially obscured / out of view
|
|
288
|
-
if (prevEl.getBoundingClientRect().top < this.
|
|
289
|
-
this.
|
|
290
|
-
prevEl.getBoundingClientRect().top - this.optionsEl.getBoundingClientRect().top + this.optionsEl.scrollTop;
|
|
389
|
+
if (prevEl.getBoundingClientRect().top < this.dropdownEl.getBoundingClientRect().top) {
|
|
390
|
+
this.scrollOptionToTop(prevEl);
|
|
291
391
|
}
|
|
292
|
-
this.
|
|
392
|
+
this.focusOption(prevEl);
|
|
393
|
+
}
|
|
394
|
+
else if (this.search) {
|
|
395
|
+
// if top of list and search variant, focus search field
|
|
396
|
+
this.searchFieldEl.focus();
|
|
293
397
|
}
|
|
294
398
|
else {
|
|
295
|
-
|
|
399
|
+
// if top of list, focus last element
|
|
400
|
+
this.focusOption(this.visibleOptionEls[this.visibleOptionEls.length - 1]);
|
|
296
401
|
}
|
|
297
402
|
}
|
|
298
403
|
moveDown(el) {
|
|
299
|
-
const nextEl = el
|
|
300
|
-
if (nextEl
|
|
404
|
+
const nextEl = this.visibleOptionEls[this.visibleOptionEls.indexOf(el) + 1];
|
|
405
|
+
if (nextEl) {
|
|
301
406
|
// scroll option to bottom of dropdown if partially obscured / out of view
|
|
302
|
-
if (nextEl.getBoundingClientRect().bottom > this.
|
|
303
|
-
this.
|
|
304
|
-
nextEl.getBoundingClientRect().bottom -
|
|
305
|
-
this.optionsEl.getBoundingClientRect().top +
|
|
306
|
-
this.optionsEl.scrollTop -
|
|
307
|
-
this.optionsEl.offsetHeight;
|
|
407
|
+
if (nextEl.getBoundingClientRect().bottom > this.dropdownEl.getBoundingClientRect().bottom) {
|
|
408
|
+
this.scrollOptionToBottom(nextEl);
|
|
308
409
|
}
|
|
309
|
-
this.
|
|
410
|
+
this.focusOption(nextEl);
|
|
310
411
|
}
|
|
311
412
|
else {
|
|
312
|
-
|
|
413
|
+
// if end of list, focus first option in all variants
|
|
414
|
+
this.focusOption(this.visibleOptionEls[0]);
|
|
313
415
|
}
|
|
314
416
|
}
|
|
315
|
-
|
|
417
|
+
scrollOptionToTop(option) {
|
|
418
|
+
this.dropdownEl.scrollTop =
|
|
419
|
+
option.getBoundingClientRect().top - this.dropdownEl.getBoundingClientRect().top + this.dropdownEl.scrollTop;
|
|
420
|
+
}
|
|
421
|
+
scrollOptionToBottom(option) {
|
|
422
|
+
this.dropdownEl.scrollTop =
|
|
423
|
+
option.getBoundingClientRect().bottom -
|
|
424
|
+
this.dropdownEl.getBoundingClientRect().top +
|
|
425
|
+
this.dropdownEl.scrollTop -
|
|
426
|
+
this.dropdownEl.offsetHeight;
|
|
427
|
+
}
|
|
428
|
+
open(optionToSelect) {
|
|
316
429
|
if (!this.disabled) {
|
|
317
430
|
const elHeight = this.el.clientHeight;
|
|
318
431
|
const buttonHeight = this.buttonEl.clientHeight;
|
|
319
|
-
this.openUp = shouldOpenUp(this.el, this.
|
|
432
|
+
this.openUp = shouldOpenUp(this.el, this.dropdownEl,
|
|
320
433
|
// when opening up, dropdown covers both label and button
|
|
321
434
|
elHeight,
|
|
322
435
|
// when opening down, dropdown covers only the button
|
|
323
436
|
buttonHeight);
|
|
324
437
|
this.isExpanded = true;
|
|
325
|
-
this.
|
|
438
|
+
this.dropdownEl.classList.remove("hidden");
|
|
326
439
|
window.requestAnimationFrame(() => {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
440
|
+
switch (optionToSelect) {
|
|
441
|
+
case "next":
|
|
442
|
+
// search variant focuses search field
|
|
443
|
+
// all others focus option "after" last selected option (this can be the first option)
|
|
444
|
+
if (this.search) {
|
|
445
|
+
this.searchFieldEl.focus();
|
|
446
|
+
this.dropdownEl.scrollTop = 0;
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
this.moveDown(this.visibleOptionEls.filter((x) => x.selected).slice(-1)[0]);
|
|
450
|
+
}
|
|
451
|
+
break;
|
|
452
|
+
case "previous":
|
|
453
|
+
// search variant focuses last option
|
|
454
|
+
// all others focus option "above" first selected option (this can be the last option)
|
|
455
|
+
if (this.search) {
|
|
456
|
+
this.focusOption(this.visibleOptionEls[this.visibleOptionEls.length - 1]);
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
this.moveUp(this.visibleOptionEls.filter((x) => x.selected)[0]);
|
|
460
|
+
}
|
|
461
|
+
break;
|
|
462
|
+
default:
|
|
463
|
+
// search variant focuses search field
|
|
464
|
+
// all others focus the selected option
|
|
465
|
+
// if no option is selected (empty multiselect), focuses first option
|
|
466
|
+
if (this.search) {
|
|
467
|
+
this.searchFieldEl.focus();
|
|
468
|
+
this.dropdownEl.scrollTop = 0;
|
|
469
|
+
}
|
|
470
|
+
else if (this.selectedOptions.length > 0) {
|
|
471
|
+
this.focusOption(this.visibleOptionEls.filter((x) => x.selected)[0]);
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
this.focusOption(this.visibleOptionEls[0]);
|
|
475
|
+
}
|
|
476
|
+
break;
|
|
340
477
|
}
|
|
341
478
|
});
|
|
342
479
|
}
|
|
343
480
|
}
|
|
344
481
|
close(returnFocus = true) {
|
|
345
|
-
this.isExpanded
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
this.
|
|
482
|
+
if (this.isExpanded) {
|
|
483
|
+
this.isExpanded = false;
|
|
484
|
+
this.allOptionEls.map((i) => (i.focused = false));
|
|
485
|
+
window.setTimeout(() => {
|
|
486
|
+
this.dropdownEl.classList.add("hidden");
|
|
487
|
+
if (this.multiple) {
|
|
488
|
+
this.updateOptionVisibility();
|
|
489
|
+
}
|
|
490
|
+
// clear search field, reset filtered / bolded state of wm-options
|
|
491
|
+
if (this.search) {
|
|
492
|
+
this.searchFieldEl.value = "";
|
|
493
|
+
this.wmSelectSearchChanged.emit({ searchTerm: this.searchTerm });
|
|
494
|
+
}
|
|
495
|
+
// Returns focus to button after popup closes (no need if user is tabbing)
|
|
496
|
+
// Delay is necessary for screenreader to get new expanded state before focus
|
|
497
|
+
// window.requestAnimationFrame is probably enough, but since we are already using setTimeout it may as well be here
|
|
498
|
+
// also UX wise, it makes sense for the button to only be focused after the animation is complete
|
|
499
|
+
if (returnFocus) {
|
|
500
|
+
this.el.focus();
|
|
501
|
+
}
|
|
502
|
+
}, 150);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
updateOptionVisibility() {
|
|
506
|
+
// this runs for search multiselects, where selected options are rendered at the top of the dropdown list
|
|
507
|
+
// slotted wm-options are hidden if selected, and duplicate wm-options are made visible if selected
|
|
508
|
+
this.childOptions.forEach((option, idx) => {
|
|
509
|
+
const duplicateOption = this.duplicateOptions[idx];
|
|
510
|
+
if (option.selected) {
|
|
511
|
+
option.classList.add("hidden");
|
|
512
|
+
duplicateOption.classList.remove("hidden");
|
|
355
513
|
}
|
|
356
|
-
|
|
514
|
+
else {
|
|
515
|
+
option.classList.remove("hidden");
|
|
516
|
+
duplicateOption.classList.add("hidden");
|
|
517
|
+
}
|
|
518
|
+
});
|
|
357
519
|
}
|
|
358
|
-
|
|
359
|
-
this.
|
|
520
|
+
focusOption(option) {
|
|
521
|
+
this.allOptionEls.forEach((i) => (i.focused = i === option));
|
|
522
|
+
option.focus();
|
|
360
523
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
524
|
+
selectOption(option) {
|
|
525
|
+
// this function does not necessarily change an options selected property to true
|
|
526
|
+
// in cases of multiselect, it toggles the selected property
|
|
527
|
+
if (option.classList.contains("duplicate")) {
|
|
528
|
+
// if clicking on a duplicate option, toggle selected property of real one, then rerender
|
|
529
|
+
const correspondingOption = this.findCorrespondingOption(option);
|
|
530
|
+
correspondingOption.selected = !correspondingOption.selected;
|
|
531
|
+
forceUpdate(this.el);
|
|
532
|
+
}
|
|
533
|
+
else if (this.multiple) {
|
|
534
|
+
option.selected = !option.selected;
|
|
364
535
|
}
|
|
365
536
|
else {
|
|
366
|
-
this.
|
|
537
|
+
this.allOptionEls.forEach((x) => (x.selected = x === option));
|
|
367
538
|
}
|
|
368
539
|
this.setButtonText();
|
|
369
540
|
}
|
|
370
|
-
|
|
541
|
+
findAndFocusOption(ev) {
|
|
371
542
|
const character = ev.detail.toUpperCase();
|
|
372
543
|
if (!this.keysSoFar) {
|
|
373
|
-
for (var i = 0; i < this.
|
|
374
|
-
if (this.
|
|
544
|
+
for (var i = 0; i < this.allOptionEls.length; i++) {
|
|
545
|
+
if (this.allOptionEls[i].focused) {
|
|
375
546
|
this.searchIndex = i;
|
|
376
547
|
}
|
|
377
548
|
}
|
|
378
549
|
}
|
|
379
550
|
this.keysSoFar += character;
|
|
380
551
|
this.clearKeysSoFarAfterDelay();
|
|
381
|
-
var nextMatch = this.findMatchInRange(this.
|
|
552
|
+
var nextMatch = this.findMatchInRange(this.allOptionEls, this.searchIndex + 1, this.allOptionEls.length);
|
|
382
553
|
if (!nextMatch) {
|
|
383
|
-
nextMatch = this.findMatchInRange(this.
|
|
554
|
+
nextMatch = this.findMatchInRange(this.allOptionEls, 0, this.searchIndex);
|
|
384
555
|
}
|
|
385
556
|
if (nextMatch) {
|
|
386
|
-
this.
|
|
557
|
+
this.focusOption(nextMatch);
|
|
387
558
|
}
|
|
388
559
|
}
|
|
389
560
|
clearKeysSoFarAfterDelay() {
|
|
@@ -397,8 +568,8 @@ let Select = class {
|
|
|
397
568
|
}.bind(this), 500);
|
|
398
569
|
}
|
|
399
570
|
findMatchInRange(list, startIndex, endIndex) {
|
|
400
|
-
// Find the first
|
|
401
|
-
// the specified range of
|
|
571
|
+
// Find the first option starting with the keysSoFar substring, searching in
|
|
572
|
+
// the specified range of options
|
|
402
573
|
for (var n = startIndex; n < endIndex; n++) {
|
|
403
574
|
var label = list[n].textContent;
|
|
404
575
|
if (label && label.toUpperCase().indexOf(this.keysSoFar) === 0) {
|
|
@@ -407,6 +578,19 @@ let Select = class {
|
|
|
407
578
|
}
|
|
408
579
|
return null;
|
|
409
580
|
}
|
|
581
|
+
findCorrespondingOption(el) {
|
|
582
|
+
// if duplicate, returns the child wm-option
|
|
583
|
+
// if child wm-option, returns duplicate
|
|
584
|
+
const isDuplicate = el.classList.contains("duplicate");
|
|
585
|
+
return isDuplicate
|
|
586
|
+
? this.childOptions[this.duplicateOptions.indexOf(el)]
|
|
587
|
+
: this.duplicateOptions[this.childOptions.indexOf(el)];
|
|
588
|
+
}
|
|
589
|
+
isElOrChild(el) {
|
|
590
|
+
var _a;
|
|
591
|
+
// determines whether or not the element is the component, a child of the component, or exists within the component's shadowroot
|
|
592
|
+
return el === this.el || this.el.contains(el) || ((_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.contains(el));
|
|
593
|
+
}
|
|
410
594
|
exposeErrors() {
|
|
411
595
|
// 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
|
|
412
596
|
const newId = generateId();
|
|
@@ -424,9 +608,30 @@ let Select = class {
|
|
|
424
608
|
this.wmComponentBlurred.emit(); // deprecated
|
|
425
609
|
}
|
|
426
610
|
}
|
|
611
|
+
handleSearchFieldKeyDown(ev) {
|
|
612
|
+
switch (ev.key) {
|
|
613
|
+
case "ArrowDown":
|
|
614
|
+
ev.preventDefault();
|
|
615
|
+
if (this.visibleOptionEls.length) {
|
|
616
|
+
this.focusOption(this.visibleOptionEls[0]);
|
|
617
|
+
}
|
|
618
|
+
break;
|
|
619
|
+
case "ArrowUp":
|
|
620
|
+
ev.preventDefault();
|
|
621
|
+
if (this.visibleOptionEls.length) {
|
|
622
|
+
this.focusOption(this.visibleOptionEls[this.visibleOptionEls.length - 1]);
|
|
623
|
+
}
|
|
624
|
+
break;
|
|
625
|
+
case "Escape":
|
|
626
|
+
ev.preventDefault();
|
|
627
|
+
this.close();
|
|
628
|
+
break;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
427
631
|
setButtonText() {
|
|
428
|
-
this.
|
|
429
|
-
|
|
632
|
+
this.displayedOptions = this.childOptions
|
|
633
|
+
.filter((x) => x.selected)
|
|
634
|
+
.map((y) => (!y.classList.contains("hidden") ? y : this.findCorrespondingOption(y)));
|
|
430
635
|
// handle overflow + counter for multiselect
|
|
431
636
|
if (this.multiple) {
|
|
432
637
|
// this is a fixed measurement accounting for the max width of a 3 character overflow counter
|
|
@@ -436,32 +641,39 @@ let Select = class {
|
|
|
436
641
|
const paddingLeft = parseInt(computedStyle.getPropertyValue("padding-left").slice(0, -2));
|
|
437
642
|
const paddingRight = parseInt(computedStyle.getPropertyValue("padding-right").slice(0, -2));
|
|
438
643
|
const availableSpace = this.buttonEl.clientWidth - paddingLeft - paddingRight - overflowCounterWidth;
|
|
439
|
-
let optionsWidths = this.
|
|
644
|
+
let optionsWidths = this.displayedOptions.map((x) => x.shadowRoot.querySelector(".option-wrapper").clientWidth);
|
|
440
645
|
let optionsTotalWidth = optionsWidths.reduce((acc, x) => acc + x, 0);
|
|
441
646
|
this.overflowCount = 0;
|
|
442
|
-
while (optionsTotalWidth > availableSpace && this.
|
|
647
|
+
while (optionsTotalWidth > availableSpace && this.displayedOptions.length > 1) {
|
|
443
648
|
this.overflowCount++;
|
|
444
649
|
optionsTotalWidth -= optionsWidths[optionsWidths.length - 1];
|
|
445
650
|
optionsWidths.pop();
|
|
446
|
-
this.
|
|
651
|
+
this.displayedOptions.pop();
|
|
447
652
|
}
|
|
448
653
|
}
|
|
449
654
|
}
|
|
655
|
+
announce(message) {
|
|
656
|
+
// \u00A0 is a non-breaking space character, which causes the message to be read as a new one
|
|
657
|
+
if (this.liveRegionEl.textContent === message) {
|
|
658
|
+
message += "\u00A0";
|
|
659
|
+
}
|
|
660
|
+
this.announcement = message;
|
|
661
|
+
}
|
|
450
662
|
renderButtonText() {
|
|
451
|
-
if (this.multiple && this.
|
|
663
|
+
if (this.multiple && this.displayedOptions.length < 1) {
|
|
452
664
|
return h("span", null, this.placeholder);
|
|
453
665
|
}
|
|
454
666
|
else if (this.multiple && this.allSelected && this.overflowCount > 0) {
|
|
455
667
|
return this.allSelectedMessage;
|
|
456
668
|
}
|
|
457
669
|
else {
|
|
458
|
-
return this.
|
|
670
|
+
return this.displayedOptions.map((x, idx) => (h("span", null, idx > 0 ? ", " : "", x.textContent)));
|
|
459
671
|
}
|
|
460
672
|
}
|
|
461
673
|
renderSubinfo() {
|
|
462
674
|
// multiselects cannot have subinfo for options
|
|
463
|
-
if (!this.multiple && this.
|
|
464
|
-
return h("span", { class: "subinfo" }, this.
|
|
675
|
+
if (!this.multiple && this.selectedOptions.length > 0 && this.selectedOptions[0].subinfo) {
|
|
676
|
+
return h("span", { class: "subinfo" }, this.selectedOptions[0].subinfo);
|
|
465
677
|
}
|
|
466
678
|
}
|
|
467
679
|
renderOverflowCount() {
|
|
@@ -469,6 +681,17 @@ let Select = class {
|
|
|
469
681
|
return (h("span", null, h("span", { class: "overflow-counter" }, "+", this.overflowCount)));
|
|
470
682
|
}
|
|
471
683
|
}
|
|
684
|
+
renderSearchField() {
|
|
685
|
+
return (h("div", { class: "search" }, h("div", { class: "searchfield-wrapper", ref: (el) => (this.searchFieldWrapperEl = el) }, h("div", { class: "icon" }), 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 }))));
|
|
686
|
+
}
|
|
687
|
+
renderSearchFailedMessage() {
|
|
688
|
+
return h("div", { class: "search-results-message" }, this.noResultsFoundMessage);
|
|
689
|
+
}
|
|
690
|
+
renderDuplicateOptions() {
|
|
691
|
+
return Array.from(this.el.children).map((option) => {
|
|
692
|
+
return (h("wm-option", { class: "duplicate", selected: option.selected }, option.textContent));
|
|
693
|
+
});
|
|
694
|
+
}
|
|
472
695
|
render() {
|
|
473
696
|
const buttonProps = {
|
|
474
697
|
id: `selectbtn-${this.uid}`,
|
|
@@ -481,9 +704,9 @@ let Select = class {
|
|
|
481
704
|
};
|
|
482
705
|
return (h(Host, { onBlur: (ev) => this.handleComponentBlur(ev) }, h("div", { class: `wrapper ${getTextDir()} label-${this.labelPosition} ${this.invalid || this.errorMessage ? "invalid" : ""}` }, h("div", { class: "label-wrapper" }, h("label", { class: "label", id: `label-${this.uid}`, htmlFor: `selectbtn-${this.uid}` }, this.label,
|
|
483
706
|
// we can't use aria-required or required attributes because it's invalid on the elements we're using (button controlling a listbox)
|
|
484
|
-
this.requiredField ? (h("span", { class: "required" }, h("span", { class: "sr-only" }, this.requiredMessage), h("span", { "aria-hidden": "true" }, "*"))) : (""))), h("div", { class: "
|
|
707
|
+
this.requiredField ? (h("span", { class: "required" }, h("span", { class: "sr-only" }, this.requiredMessage), h("span", { "aria-hidden": "true" }, "*"))) : (""))), h("div", { class: "button-wrapper" }, 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() }), h("span", { class: this.selectedOptions.length > 0 && this.selectedOptions.filter((x) => x.subinfo).length > 0
|
|
485
708
|
? "overflowcontrol hassubinfo"
|
|
486
|
-
: "overflowcontrol" }, h("span", { class: "button-text" }, this.renderButtonText()), this.renderSubinfo()), this.renderOverflowCount()), h("div", { class: `
|
|
709
|
+
: "overflowcontrol" }, h("span", { class: "button-text" }, this.renderButtonText()), this.renderSubinfo()), this.renderOverflowCount()), h("div", { class: `dropdown ${this.isExpanded ? "open" : ""} ${this.openUp ? "upwards" : ""}`, ref: (el) => (this.dropdownEl = el) }, this.search && this.renderSearchField(), h("div", { id: `list-${this.uid}`, tabindex: -1, role: "listbox", "aria-multiselectable": this.multiple ? "true" : null, "aria-labelledby": `label-${this.uid}` }, this.search && this.filteredOptions.length === 0 && this.renderSearchFailedMessage(), this.multiple && this.renderDuplicateOptions(), h("slot", null))), this.renderErrorContainer(), h("div", { "aria-live": "polite", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement)))));
|
|
487
710
|
}
|
|
488
711
|
get el() { return getElement(this); }
|
|
489
712
|
static get watchers() { return {
|