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