@watermarkinsights/ripple 5.6.0-8 → 5.7.0-0
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/{global-9662b435.js → global-b4e48f66.js} +1 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/priv-option-list.cjs.entry.js +32 -6
- package/dist/cjs/ripple.cjs.js +2 -2
- package/dist/cjs/wm-line-chart.cjs.entry.js +7 -22
- package/dist/cjs/wm-modal.cjs.entry.js +1 -1
- package/dist/cjs/wm-nested-select.cjs.entry.js +45 -34
- package/dist/cjs/wm-optgroup.cjs.entry.js +12 -10
- package/dist/cjs/wm-option_2.cjs.entry.js +9 -9
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/charts/wm-line-chart/wm-line-chart.js +7 -22
- package/dist/collection/components/selects/priv-option-list/priv-option-list.css +32 -5
- package/dist/collection/components/selects/priv-option-list/priv-option-list.js +76 -5
- package/dist/collection/components/selects/wm-nested-select/wm-nested-select.css +16 -4
- package/dist/collection/components/selects/wm-nested-select/wm-nested-select.js +46 -41
- package/dist/collection/components/selects/wm-optgroup/wm-optgroup.css +0 -26
- package/dist/collection/components/selects/wm-optgroup/wm-optgroup.js +20 -9
- package/dist/collection/components/{wm-option → selects/wm-option}/wm-option.css +1 -1
- package/dist/collection/components/{wm-option → selects/wm-option}/wm-option.js +4 -9
- package/dist/collection/components/{wm-option → selects/wm-option}/wm-option.spec.js +1 -1
- package/dist/collection/components/selects/wm-select/wm-select.css +7 -0
- package/dist/collection/components/selects/wm-select/wm-select.js +6 -6
- package/dist/collection/components/selects/wm-select/wm-select.spec.js +1 -1
- package/dist/collection/components/wm-modal/wm-modal.js +1 -1
- package/dist/collection/dev/nested-select.js +31 -57
- package/dist/esm/{global-f1582c2f.js → global-8a4502dd.js} +1 -1
- package/dist/esm/loader.js +2 -2
- package/dist/esm/priv-option-list.entry.js +32 -6
- package/dist/esm/ripple.js +2 -2
- package/dist/esm/wm-line-chart.entry.js +7 -22
- package/dist/esm/wm-modal.entry.js +1 -1
- package/dist/esm/wm-nested-select.entry.js +46 -35
- package/dist/esm/wm-optgroup.entry.js +12 -10
- package/dist/esm/wm-option_2.entry.js +9 -9
- package/dist/esm-es5/{global-f1582c2f.js → global-8a4502dd.js} +1 -1
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/priv-option-list.entry.js +1 -1
- package/dist/esm-es5/ripple.js +1 -1
- package/dist/esm-es5/wm-line-chart.entry.js +1 -1
- package/dist/esm-es5/wm-modal.entry.js +1 -1
- package/dist/esm-es5/wm-nested-select.entry.js +1 -1
- package/dist/esm-es5/wm-optgroup.entry.js +1 -1
- package/dist/esm-es5/wm-option_2.entry.js +1 -1
- package/dist/ripple/p-01addccd.entry.js +1 -0
- package/dist/ripple/{p-bfeb6ef8.system.js → p-01e29a2a.system.js} +1 -1
- package/dist/ripple/p-0c259c1a.system.entry.js +1 -0
- package/dist/ripple/p-1796b85d.entry.js +1 -0
- package/dist/ripple/p-1c170fb3.entry.js +1 -0
- package/dist/ripple/p-3d02b293.system.entry.js +1 -0
- package/dist/ripple/p-45dc49e8.entry.js +1 -0
- package/dist/ripple/p-54f7d3d4.system.entry.js +1 -0
- package/dist/ripple/p-725230dd.system.entry.js +1 -0
- package/dist/ripple/{p-465d44f0.system.entry.js → p-84603f1f.system.entry.js} +1 -1
- package/dist/ripple/p-947f8f0d.system.entry.js +1 -0
- package/dist/ripple/p-99058787.entry.js +1 -0
- package/dist/ripple/p-db9f8841.system.js +1 -0
- package/dist/ripple/{p-cf55659f.js → p-de8f5e92.js} +1 -1
- package/dist/ripple/p-e687176d.entry.js +1 -0
- package/dist/ripple/ripple.esm.js +1 -1
- package/dist/ripple/ripple.js +1 -1
- package/dist/types/components/charts/wm-line-chart/wm-line-chart.d.ts +1 -1
- package/dist/types/components/selects/priv-option-list/priv-option-list.d.ts +73 -0
- package/dist/types/components/selects/wm-nested-select/wm-nested-select.d.ts +58 -0
- package/dist/types/components/selects/wm-optgroup/wm-optgroup.d.ts +17 -0
- package/dist/types/components/selects/wm-option/wm-option.d.ts +40 -0
- package/dist/types/components/selects/wm-select/wm-select.d.ts +1 -0
- package/dist/types/components.d.ts +8 -2
- package/package.json +2 -2
- package/dist/ripple/p-104c0e9b.system.entry.js +0 -1
- package/dist/ripple/p-17c8aac1.system.entry.js +0 -1
- package/dist/ripple/p-24ba754f.entry.js +0 -1
- package/dist/ripple/p-2fb58947.entry.js +0 -1
- package/dist/ripple/p-4564a101.system.entry.js +0 -1
- package/dist/ripple/p-4ca5ed96.entry.js +0 -1
- package/dist/ripple/p-5b9babd9.system.entry.js +0 -1
- package/dist/ripple/p-8835adfb.entry.js +0 -1
- package/dist/ripple/p-885c3527.entry.js +0 -1
- package/dist/ripple/p-ba422994.entry.js +0 -1
- package/dist/ripple/p-cf2121f3.system.entry.js +0 -1
- package/dist/ripple/p-f6fd623f.system.js +0 -1
- /package/dist/collection/components/{wm-option → selects/wm-option}/wm-option.e2e.js +0 -0
|
@@ -38,6 +38,7 @@ export class PrivOptionList {
|
|
|
38
38
|
this.selectAll = false;
|
|
39
39
|
this.searchPlaceholder = undefined;
|
|
40
40
|
this.maxHeight = undefined;
|
|
41
|
+
this.optgroupLabel = undefined;
|
|
41
42
|
this.announcement = "";
|
|
42
43
|
this.searchTerm = "";
|
|
43
44
|
}
|
|
@@ -151,9 +152,11 @@ export class PrivOptionList {
|
|
|
151
152
|
}
|
|
152
153
|
}
|
|
153
154
|
async clearSearch() {
|
|
154
|
-
this.
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
if (this.search) {
|
|
156
|
+
this.searchFieldEl.value = "";
|
|
157
|
+
this.searchTerm = "";
|
|
158
|
+
this.optionListSearchChanged.emit({ searchTerm: this.searchTerm });
|
|
159
|
+
}
|
|
157
160
|
}
|
|
158
161
|
async focusOption(option) {
|
|
159
162
|
this.allOptionEls.forEach((i) => (i.focused = i === option));
|
|
@@ -249,9 +252,16 @@ export class PrivOptionList {
|
|
|
249
252
|
ev.preventDefault();
|
|
250
253
|
this.moveUp(ev.target);
|
|
251
254
|
break;
|
|
255
|
+
case "ArrowLeft":
|
|
256
|
+
// if an optgroupLabel was passed, we are within a Nested Select
|
|
257
|
+
if (!!this.optgroupLabel) {
|
|
258
|
+
ev.preventDefault();
|
|
259
|
+
this.wmKeyLeftPressed.emit();
|
|
260
|
+
}
|
|
261
|
+
break;
|
|
252
262
|
case "Escape":
|
|
253
263
|
ev.preventDefault();
|
|
254
|
-
this.
|
|
264
|
+
this.wmEscKeyPressed.emit();
|
|
255
265
|
break;
|
|
256
266
|
case "Enter":
|
|
257
267
|
if (el === this.selectAllEl) {
|
|
@@ -293,6 +303,10 @@ export class PrivOptionList {
|
|
|
293
303
|
if (this.searchFieldEl) {
|
|
294
304
|
focusableEls.unshift(this.searchFieldEl);
|
|
295
305
|
}
|
|
306
|
+
// if an optgroupLabel was passed, we are is within a Nested Select
|
|
307
|
+
if (!!this.optgroupLabel) {
|
|
308
|
+
focusableEls.unshift(this.returnBtnEl);
|
|
309
|
+
}
|
|
296
310
|
const prevEl = focusableEls[focusableEls.indexOf(el) - 1] || focusableEls[focusableEls.length - 1];
|
|
297
311
|
if (prevEl) {
|
|
298
312
|
this.focusOption(prevEl);
|
|
@@ -306,6 +320,10 @@ export class PrivOptionList {
|
|
|
306
320
|
if (this.searchFieldEl) {
|
|
307
321
|
focusableEls.unshift(this.searchFieldEl);
|
|
308
322
|
}
|
|
323
|
+
// if an optgroupLabel was passed, we are is within a Nested Select
|
|
324
|
+
if (!!this.optgroupLabel) {
|
|
325
|
+
focusableEls.unshift(this.returnBtnEl);
|
|
326
|
+
}
|
|
309
327
|
const nextEl = focusableEls[focusableEls.indexOf(el) + 1] || focusableEls[0];
|
|
310
328
|
if (nextEl) {
|
|
311
329
|
this.focusOption(nextEl);
|
|
@@ -345,6 +363,12 @@ export class PrivOptionList {
|
|
|
345
363
|
}
|
|
346
364
|
this.announcement = message;
|
|
347
365
|
}
|
|
366
|
+
renderReturnBtn() {
|
|
367
|
+
return (h("button", { ref: (el) => (this.returnBtnEl = el), id: "return-btn", class: "return-btn", onKeyDown: (ev) => this.handleKeyDown(ev), onClick: () => {
|
|
368
|
+
//@ts-ignore -- Check out this one weird trick TypeScript doesn't want you to know about
|
|
369
|
+
this.el.getRootNode().host.isExpanded = false;
|
|
370
|
+
} }, this.optgroupLabel));
|
|
371
|
+
}
|
|
348
372
|
renderSearchField() {
|
|
349
373
|
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",
|
|
350
374
|
// aria-expanded={this.isExpanded ? "true" : "false"}
|
|
@@ -363,7 +387,7 @@ export class PrivOptionList {
|
|
|
363
387
|
});
|
|
364
388
|
}
|
|
365
389
|
render() {
|
|
366
|
-
return (h("div", { class: "list-wrapper" }, this.search && this.renderSearchField(), this.visibleSelectAllButton && this.renderSelectAllButton(), h("div", { id: "list", class: "options-wrapper", tabindex: -1, role: "listbox", "aria-multiselectable": this.multiple ? "true" : null, "aria-labelledby": "label", ref: (el) => (this.listboxEl = el) }, this.searchTerm && this.filteredOptions.length === 0 && this.renderSearchFailedMessage(), this.multiple && this.renderCloneOptions(), h("slot", null)), h("div", { id: "optionlist-announcement", "aria-live": "polite", "aria-atomic": "true", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement)));
|
|
390
|
+
return (h("div", { class: "list-wrapper" }, !!this.optgroupLabel && this.renderReturnBtn(), this.search && this.renderSearchField(), this.visibleSelectAllButton && this.renderSelectAllButton(), h("div", { id: "list", class: "options-wrapper", tabindex: -1, role: "listbox", "aria-multiselectable": this.multiple ? "true" : null, "aria-labelledby": "label", ref: (el) => (this.listboxEl = el) }, this.searchTerm && this.filteredOptions.length === 0 && this.renderSearchFailedMessage(), this.multiple && this.renderCloneOptions(), h("slot", null)), h("div", { id: "optionlist-announcement", "aria-live": "polite", "aria-atomic": "true", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement)));
|
|
367
391
|
}
|
|
368
392
|
static get is() { return "priv-option-list"; }
|
|
369
393
|
static get originalStyleUrls() {
|
|
@@ -465,6 +489,23 @@ export class PrivOptionList {
|
|
|
465
489
|
},
|
|
466
490
|
"attribute": "max-height",
|
|
467
491
|
"reflect": false
|
|
492
|
+
},
|
|
493
|
+
"optgroupLabel": {
|
|
494
|
+
"type": "string",
|
|
495
|
+
"mutable": false,
|
|
496
|
+
"complexType": {
|
|
497
|
+
"original": "string",
|
|
498
|
+
"resolved": "string | undefined",
|
|
499
|
+
"references": {}
|
|
500
|
+
},
|
|
501
|
+
"required": false,
|
|
502
|
+
"optional": true,
|
|
503
|
+
"docs": {
|
|
504
|
+
"tags": [],
|
|
505
|
+
"text": ""
|
|
506
|
+
},
|
|
507
|
+
"attribute": "optgroup-label",
|
|
508
|
+
"reflect": false
|
|
468
509
|
}
|
|
469
510
|
};
|
|
470
511
|
}
|
|
@@ -540,6 +581,36 @@ export class PrivOptionList {
|
|
|
540
581
|
"resolved": "any",
|
|
541
582
|
"references": {}
|
|
542
583
|
}
|
|
584
|
+
}, {
|
|
585
|
+
"method": "wmEscKeyPressed",
|
|
586
|
+
"name": "wmEscKeyPressed",
|
|
587
|
+
"bubbles": true,
|
|
588
|
+
"cancelable": true,
|
|
589
|
+
"composed": true,
|
|
590
|
+
"docs": {
|
|
591
|
+
"tags": [],
|
|
592
|
+
"text": ""
|
|
593
|
+
},
|
|
594
|
+
"complexType": {
|
|
595
|
+
"original": "any",
|
|
596
|
+
"resolved": "any",
|
|
597
|
+
"references": {}
|
|
598
|
+
}
|
|
599
|
+
}, {
|
|
600
|
+
"method": "wmKeyLeftPressed",
|
|
601
|
+
"name": "wmKeyLeftPressed",
|
|
602
|
+
"bubbles": true,
|
|
603
|
+
"cancelable": true,
|
|
604
|
+
"composed": true,
|
|
605
|
+
"docs": {
|
|
606
|
+
"tags": [],
|
|
607
|
+
"text": ""
|
|
608
|
+
},
|
|
609
|
+
"complexType": {
|
|
610
|
+
"original": "any",
|
|
611
|
+
"resolved": "any",
|
|
612
|
+
"references": {}
|
|
613
|
+
}
|
|
543
614
|
}];
|
|
544
615
|
}
|
|
545
616
|
static get methods() {
|
|
@@ -172,6 +172,9 @@
|
|
|
172
172
|
pointer-events: none;
|
|
173
173
|
font-size: 1.12rem;
|
|
174
174
|
}
|
|
175
|
+
.button-wrapper .displayedoption.expanded:before {
|
|
176
|
+
content: "\f143";
|
|
177
|
+
}
|
|
175
178
|
.button-wrapper .displayedoption:hover:not(:disabled):not(.-disabled):not(.-raised) {
|
|
176
179
|
background: var(--wmcolor-select-background);
|
|
177
180
|
text-decoration: none;
|
|
@@ -282,7 +285,7 @@
|
|
|
282
285
|
}
|
|
283
286
|
.dropdown.upwards {
|
|
284
287
|
top: unset;
|
|
285
|
-
bottom:
|
|
288
|
+
bottom: 100%;
|
|
286
289
|
-ms-transform-origin: center bottom;
|
|
287
290
|
-webkit-transform-origin: center bottom;
|
|
288
291
|
-moz-transform-origin: center bottom;
|
|
@@ -357,11 +360,20 @@
|
|
|
357
360
|
.option-list-wrapper {
|
|
358
361
|
background: white;
|
|
359
362
|
width: 100%;
|
|
360
|
-
transform: translateX(
|
|
363
|
+
transform: translateX(0%);
|
|
361
364
|
transition: transform 0.2s cubic-bezier(0.04, 0, 0.2, 1);
|
|
362
365
|
}
|
|
363
|
-
.option-list-wrapper.
|
|
364
|
-
transform: translateX(
|
|
366
|
+
.option-list-wrapper.hidden {
|
|
367
|
+
transform: translateX(100%);
|
|
368
|
+
position: absolute;
|
|
369
|
+
top: 0px;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
.measurement-area {
|
|
373
|
+
position: absolute;
|
|
374
|
+
visibility: hidden;
|
|
375
|
+
height: 0px;
|
|
376
|
+
pointer-events: none;
|
|
365
377
|
}
|
|
366
378
|
|
|
367
379
|
.sr-only {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { h, Host, forceUpdate } from "@stencil/core";
|
|
2
|
-
import { getTextDir, intl, isElOrChild, toBool } from "../../../global/functions";
|
|
2
|
+
import { getTextDir, intl, isElOrChild, shouldOpenUp, toBool } from "../../../global/functions";
|
|
3
3
|
import { globalMessages } from "../../../global/intl";
|
|
4
4
|
export class NestedSelect {
|
|
5
5
|
constructor() {
|
|
6
|
+
this.openUp = false;
|
|
6
7
|
this.overflowCount = 0;
|
|
7
8
|
this.displayedOptions = [];
|
|
8
9
|
this.clearSelectionMessage = this.multiple
|
|
@@ -47,7 +48,7 @@ export class NestedSelect {
|
|
|
47
48
|
description: "Text displayed when all options are selected",
|
|
48
49
|
});
|
|
49
50
|
this.isExpanded = false;
|
|
50
|
-
this.
|
|
51
|
+
this.showClearSelectionButton = false;
|
|
51
52
|
}
|
|
52
53
|
get isDisabled() {
|
|
53
54
|
// string "false" needs to be treated as bool False because react wrappers convert bool to string.
|
|
@@ -76,7 +77,6 @@ export class NestedSelect {
|
|
|
76
77
|
}
|
|
77
78
|
componentDidLoad() {
|
|
78
79
|
if (this.maxHeight) {
|
|
79
|
-
// this.listboxEl.style.maxHeight = this.maxHeight;
|
|
80
80
|
this.dropdownEl.style.maxHeight = this.maxHeight;
|
|
81
81
|
}
|
|
82
82
|
}
|
|
@@ -97,14 +97,14 @@ export class NestedSelect {
|
|
|
97
97
|
const paddingLeft = parseInt(computedStyle.getPropertyValue("padding-left").slice(0, -2));
|
|
98
98
|
const paddingRight = parseInt(computedStyle.getPropertyValue("padding-right").slice(0, -2));
|
|
99
99
|
const availableSpace = this.buttonEl.clientWidth - paddingLeft - paddingRight - overflowCounterWidth;
|
|
100
|
-
let optionsWidths = this.displayedOptions.map((x) => x.shadowRoot.querySelector(".option-text").clientWidth);
|
|
101
|
-
let optionsTotalWidth = optionsWidths.reduce((acc, x) => acc + x, 0);
|
|
102
100
|
this.overflowCount = 0;
|
|
101
|
+
this.measurementAreaEl.textContent = this.displayedOptions.map((x) => x.textContent).join(", ");
|
|
102
|
+
let optionsTotalWidth = this.measurementAreaEl.clientWidth;
|
|
103
103
|
while (optionsTotalWidth > availableSpace && this.displayedOptions.length > 1) {
|
|
104
104
|
this.overflowCount++;
|
|
105
|
-
optionsTotalWidth -= optionsWidths[optionsWidths.length - 1];
|
|
106
|
-
optionsWidths.pop();
|
|
107
105
|
this.displayedOptions.pop();
|
|
106
|
+
this.measurementAreaEl.textContent = this.displayedOptions.map((x) => x.textContent).join(", ");
|
|
107
|
+
optionsTotalWidth = this.measurementAreaEl.clientWidth;
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
}
|
|
@@ -124,17 +124,12 @@ export class NestedSelect {
|
|
|
124
124
|
closePopupOnEscape() {
|
|
125
125
|
this.close();
|
|
126
126
|
}
|
|
127
|
-
handleOptionKeyLeft(ev) {
|
|
128
|
-
const parentOptgroup = ev.detail.parentElement;
|
|
129
|
-
parentOptgroup.isExpanded = false;
|
|
130
|
-
this.focusFirstMenuitem();
|
|
131
|
-
}
|
|
132
127
|
close(returnFocus = true) {
|
|
133
128
|
if (this.isExpanded) {
|
|
134
129
|
this.isExpanded = false;
|
|
135
|
-
this.
|
|
130
|
+
this.dropdownEl.classList.remove("open");
|
|
136
131
|
window.setTimeout(() => {
|
|
137
|
-
this.
|
|
132
|
+
this.optgroupEls.forEach((optgroupEl) => (optgroupEl.isExpanded = false));
|
|
138
133
|
if (returnFocus) {
|
|
139
134
|
this.buttonEl.focus();
|
|
140
135
|
}
|
|
@@ -142,12 +137,16 @@ export class NestedSelect {
|
|
|
142
137
|
}
|
|
143
138
|
}
|
|
144
139
|
open() {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
this.
|
|
150
|
-
|
|
140
|
+
if (!this.isDisabled) {
|
|
141
|
+
this.showClearSelectionButton = this.childOptions.some((o) => o.selected);
|
|
142
|
+
this.isExpanded = true;
|
|
143
|
+
this.dropdownEl.classList.add("open");
|
|
144
|
+
const elHeight = this.el.clientHeight;
|
|
145
|
+
this.openUp = shouldOpenUp(this.el, this.dropdownEl.clientHeight, elHeight, 0);
|
|
146
|
+
window.requestAnimationFrame(() => {
|
|
147
|
+
this.focusFirstMenuitem();
|
|
148
|
+
});
|
|
149
|
+
}
|
|
151
150
|
}
|
|
152
151
|
focusFirstMenuitem() {
|
|
153
152
|
if (this.menuitemEls.length > 0) {
|
|
@@ -215,10 +214,16 @@ export class NestedSelect {
|
|
|
215
214
|
}
|
|
216
215
|
}
|
|
217
216
|
handleOptgroupExpanded() {
|
|
218
|
-
this.
|
|
217
|
+
this.menuEl.classList.add("hidden");
|
|
218
|
+
this.optListWrapperEl.classList.remove("hidden");
|
|
219
219
|
}
|
|
220
|
-
handleOptgroupHidden() {
|
|
221
|
-
this.
|
|
220
|
+
handleOptgroupHidden(ev) {
|
|
221
|
+
this.showClearSelectionButton = this.childOptions.some((o) => o.selected);
|
|
222
|
+
this.menuEl.classList.remove("hidden");
|
|
223
|
+
this.optListWrapperEl.classList.add("hidden");
|
|
224
|
+
// focus back to nested select
|
|
225
|
+
const elToFocus = this.el.shadowRoot.querySelector(`button[data-label=${ev.detail}]`);
|
|
226
|
+
elToFocus.focus();
|
|
222
227
|
}
|
|
223
228
|
renderButtonText() {
|
|
224
229
|
if (this.displayedOptions.length < 1) {
|
|
@@ -232,29 +237,35 @@ export class NestedSelect {
|
|
|
232
237
|
}
|
|
233
238
|
}
|
|
234
239
|
renderOverflowCount() {
|
|
235
|
-
// TODO overflow count not appearing due to refactor, in both regular select and nested select
|
|
236
240
|
if (this.overflowCount > 0) {
|
|
237
241
|
return (h("span", null, h("span", { class: "overflow-counter" }, "+", this.overflowCount)));
|
|
238
242
|
}
|
|
239
243
|
}
|
|
240
244
|
handleClearSelection() {
|
|
241
245
|
this.optgroupEls.forEach((optgroupEl) => optgroupEl.emitDeselection());
|
|
246
|
+
if (!this.multiple) {
|
|
247
|
+
this.close();
|
|
248
|
+
}
|
|
242
249
|
}
|
|
243
250
|
renderClearSelectionButton() {
|
|
244
|
-
|
|
245
|
-
if (selectedCount) {
|
|
251
|
+
if (this.showClearSelectionButton) {
|
|
246
252
|
return (h("button", { class: "menuitem", onClick: () => this.handleClearSelection(), tabindex: -1, onKeyDown: (ev) => this.handleMenuitemKeydown(ev) }, this.clearSelectionMessage));
|
|
247
253
|
}
|
|
248
254
|
}
|
|
249
255
|
renderSelectionCount(optgroupEl) {
|
|
250
256
|
const selectionCount = this.countOptgroupSelected(optgroupEl);
|
|
251
257
|
if (selectionCount) {
|
|
252
|
-
const
|
|
253
|
-
id: "select.
|
|
254
|
-
defaultMessage: "
|
|
255
|
-
description: "Text indicating number of selected in a group.",
|
|
258
|
+
const singleSelectionCountMessage = intl.formatMessage({
|
|
259
|
+
id: "select.optgroupSingleSelectionCount",
|
|
260
|
+
defaultMessage: "Item Selected",
|
|
261
|
+
description: "Text indicating number of selected in a group, where only a single selection is possible.",
|
|
262
|
+
}, { numSelected: selectionCount });
|
|
263
|
+
const multipleSelectionCountMessage = intl.formatMessage({
|
|
264
|
+
id: "select.optgroupMultipleSelectionCount",
|
|
265
|
+
defaultMessage: "{numSelected} Selected",
|
|
266
|
+
description: "Text indicating number of selected in a group, where multiple selections are possible.",
|
|
256
267
|
}, { numSelected: selectionCount });
|
|
257
|
-
return (h("div", { class: "selection-count" }, h("span", null,
|
|
268
|
+
return (h("div", { class: "selection-count" }, h("span", null, this.multiple ? multipleSelectionCountMessage : singleSelectionCountMessage)));
|
|
258
269
|
}
|
|
259
270
|
}
|
|
260
271
|
render() {
|
|
@@ -271,12 +282,12 @@ export class NestedSelect {
|
|
|
271
282
|
};
|
|
272
283
|
return (h(Host, { onBlur: (ev) => this.handleComponentBlur(ev) }, h("div", { class: `wrapper ${getTextDir()} label-${this.labelPosition} ${this.errorMessage ? "invalid" : ""}` }, h("div", { class: "label-wrapper" }, h("label", { class: "label", id: "label", htmlFor: "selectbtn" }, this.label,
|
|
273
284
|
// we can't use aria-required or required attributes because it's invalid on the elements we're using (button controlling a listbox)
|
|
274
|
-
this.requiredField ? (h("span", { class: "required" }, h("span", { class: "sr-only" }, globalMessages.requiredField), h("span", { "aria-hidden": "true" }, "*"))) : (""))), h("div", { class: "button-wrapper" }, h("button", Object.assign({}, buttonProps, { class:
|
|
275
|
-
return (h("button", { class: "menuitem group-btn", role: "menuitem", tabindex: -1, onClick: () => {
|
|
285
|
+
this.requiredField ? (h("span", { class: "required" }, h("span", { class: "sr-only" }, globalMessages.requiredField), h("span", { "aria-hidden": "true" }, "*"))) : (""))), h("div", { class: "button-wrapper" }, h("button", Object.assign({}, buttonProps, { class: `displayedoption ${this.isExpanded ? "expanded" : ""}`, ref: (el) => (this.buttonEl = el), onBlur: (ev) => this.handleButtonBlur(ev), onFocus: () => this.close() }), h("span", { class: "overflowcontrol" }, h("span", { class: "button-text" }, this.renderButtonText())), this.renderOverflowCount(), h("div", { ref: (el) => (this.measurementAreaEl = el), class: "measurement-area", "aria-hidden": "true" })), h("div", { class: `dropdown ${this.openUp ? "upwards" : ""}`, ref: (el) => (this.dropdownEl = el) }, h("div", { ref: (el) => (this.menuEl = el), class: "menu" }, this.renderClearSelectionButton(), this.optgroupEls.map((optgroupEl) => {
|
|
286
|
+
return (h("button", { class: "menuitem group-btn", role: "menuitem", "data-label": optgroupEl.label, tabindex: -1, onClick: () => {
|
|
276
287
|
optgroupEl.isExpanded = !optgroupEl.isExpanded;
|
|
277
288
|
forceUpdate(this.el);
|
|
278
289
|
}, onKeyDown: (ev) => this.handleMenuitemKeydown(ev) }, h("span", null, optgroupEl.label), this.renderSelectionCount(optgroupEl)));
|
|
279
|
-
})), h("div", {
|
|
290
|
+
})), h("div", { ref: (el) => (this.optListWrapperEl = el), class: "option-list-wrapper hidden" }, h("slot", null))), h("div", { id: "error", class: this.errorMessage ? "error-message" : "" }, this.errorMessage)))));
|
|
280
291
|
}
|
|
281
292
|
static get is() { return "wm-nested-select"; }
|
|
282
293
|
static get encapsulation() { return "shadow"; }
|
|
@@ -511,7 +522,7 @@ export class NestedSelect {
|
|
|
511
522
|
static get states() {
|
|
512
523
|
return {
|
|
513
524
|
"isExpanded": {},
|
|
514
|
-
"
|
|
525
|
+
"showClearSelectionButton": {}
|
|
515
526
|
};
|
|
516
527
|
}
|
|
517
528
|
static get events() {
|
|
@@ -552,12 +563,6 @@ export class NestedSelect {
|
|
|
552
563
|
"target": undefined,
|
|
553
564
|
"capture": false,
|
|
554
565
|
"passive": false
|
|
555
|
-
}, {
|
|
556
|
-
"name": "wmKeyLeftPressed",
|
|
557
|
-
"method": "handleOptionKeyLeft",
|
|
558
|
-
"target": undefined,
|
|
559
|
-
"capture": false,
|
|
560
|
-
"passive": false
|
|
561
566
|
}, {
|
|
562
567
|
"name": "click",
|
|
563
568
|
"method": "handleClick",
|
|
@@ -48,30 +48,4 @@
|
|
|
48
48
|
|
|
49
49
|
:host(.visible) {
|
|
50
50
|
display: unset;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.return-btn {
|
|
54
|
-
cursor: pointer;
|
|
55
|
-
padding: 1.25rem;
|
|
56
|
-
display: flex;
|
|
57
|
-
align-items: center;
|
|
58
|
-
font-weight: 600;
|
|
59
|
-
font-size: 0.875rem;
|
|
60
|
-
border-bottom: 1px solid #4a4a4a;
|
|
61
|
-
}
|
|
62
|
-
.return-btn:before {
|
|
63
|
-
display: inline-block;
|
|
64
|
-
font: normal normal normal 24px/1 "Material Design Icons";
|
|
65
|
-
font-size: inherit;
|
|
66
|
-
text-rendering: auto;
|
|
67
|
-
line-height: inherit;
|
|
68
|
-
-webkit-font-smoothing: antialiased;
|
|
69
|
-
-moz-osx-font-smoothing: grayscale;
|
|
70
|
-
content: "\f141";
|
|
71
|
-
pointer-events: none;
|
|
72
|
-
font-size: 1.12rem;
|
|
73
|
-
}
|
|
74
|
-
.return-btn:hover {
|
|
75
|
-
background: var(--wmcolor-select-option-background-hover);
|
|
76
|
-
outline: none;
|
|
77
51
|
}
|
|
@@ -10,6 +10,7 @@ export class Optgroup {
|
|
|
10
10
|
}
|
|
11
11
|
isExpandedChanged() {
|
|
12
12
|
if (this.isExpanded) {
|
|
13
|
+
this.el.classList.add("visible");
|
|
13
14
|
this.optgroupExpanded.emit();
|
|
14
15
|
window.setTimeout(() => {
|
|
15
16
|
// wait for slide in animation to complete before assigning focus
|
|
@@ -17,21 +18,22 @@ export class Optgroup {
|
|
|
17
18
|
}, 250);
|
|
18
19
|
}
|
|
19
20
|
else {
|
|
20
|
-
this.optgroupHidden.emit();
|
|
21
|
+
this.optgroupHidden.emit(this.label);
|
|
22
|
+
this.optionListEl.clearSearch();
|
|
23
|
+
window.setTimeout(() => {
|
|
24
|
+
// wait for slide out animation to complete before hiding
|
|
25
|
+
this.el.classList.remove("visible");
|
|
26
|
+
}, 250);
|
|
21
27
|
}
|
|
22
28
|
}
|
|
23
29
|
async emitDeselection() {
|
|
24
30
|
this.wmOptgroupAllDeselected.emit();
|
|
25
31
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
*/
|
|
32
|
+
handleOptionKeyLeft() {
|
|
33
|
+
this.isExpanded = false;
|
|
34
|
+
}
|
|
31
35
|
render() {
|
|
32
|
-
return (h(Host,
|
|
33
|
-
this.isExpanded = false;
|
|
34
|
-
} }, this.label), h("div", { class: `list-wrapper` }, h("priv-option-list", { ref: (el) => (this.optionListEl = el), multiple: this.parentNestedSelect.multiple, search: this.parentNestedSelect.search, searchPlaceholder: this.parentNestedSelect.searchPlaceholder, selectAll: this.parentNestedSelect.selectAll, onOptionListAllSelected: () => this.wmOptgroupAllSelected.emit(), onOptionListAllDeselected: () => this.wmOptgroupAllDeselected.emit() }, h("slot", null)))));
|
|
36
|
+
return (h(Host, null, h("div", { class: `list-wrapper` }, h("priv-option-list", { ref: (el) => (this.optionListEl = el), multiple: this.parentNestedSelect.multiple, search: this.parentNestedSelect.search, searchPlaceholder: this.parentNestedSelect.searchPlaceholder, optgroupLabel: this.label, selectAll: this.parentNestedSelect.selectAll, onOptionListAllSelected: () => this.wmOptgroupAllSelected.emit(), onOptionListAllDeselected: () => this.wmOptgroupAllDeselected.emit() }, h("slot", null)))));
|
|
35
37
|
}
|
|
36
38
|
static get is() { return "wm-optgroup"; }
|
|
37
39
|
static get encapsulation() { return "shadow"; }
|
|
@@ -194,4 +196,13 @@ export class Optgroup {
|
|
|
194
196
|
"methodName": "isExpandedChanged"
|
|
195
197
|
}];
|
|
196
198
|
}
|
|
199
|
+
static get listeners() {
|
|
200
|
+
return [{
|
|
201
|
+
"name": "wmKeyLeftPressed",
|
|
202
|
+
"method": "handleOptionKeyLeft",
|
|
203
|
+
"target": undefined,
|
|
204
|
+
"capture": false,
|
|
205
|
+
"passive": false
|
|
206
|
+
}];
|
|
207
|
+
}
|
|
197
208
|
}
|
|
@@ -61,7 +61,7 @@ export class Option {
|
|
|
61
61
|
break;
|
|
62
62
|
case "ArrowLeft":
|
|
63
63
|
ev.preventDefault();
|
|
64
|
-
this.wmKeyLeftPressed.emit(
|
|
64
|
+
this.wmKeyLeftPressed.emit();
|
|
65
65
|
break;
|
|
66
66
|
default:
|
|
67
67
|
if (ev.key.length === 1) {
|
|
@@ -367,14 +367,9 @@ export class Option {
|
|
|
367
367
|
"text": ""
|
|
368
368
|
},
|
|
369
369
|
"complexType": {
|
|
370
|
-
"original": "
|
|
371
|
-
"resolved": "
|
|
372
|
-
"references": {
|
|
373
|
-
"HTMLWmOptionElement": {
|
|
374
|
-
"location": "global",
|
|
375
|
-
"id": "global::HTMLWmOptionElement"
|
|
376
|
-
}
|
|
377
|
-
}
|
|
370
|
+
"original": "any",
|
|
371
|
+
"resolved": "any",
|
|
372
|
+
"references": {}
|
|
378
373
|
}
|
|
379
374
|
}, {
|
|
380
375
|
"method": "wmEscKeyPressed",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { newSpecPage } from "@stencil/core/testing";
|
|
2
2
|
import { Option } from "./wm-option";
|
|
3
|
-
import { Select } from "../
|
|
3
|
+
import { Select } from "../wm-select/wm-select";
|
|
4
4
|
// mock MutationObserver
|
|
5
5
|
global.MutationObserver = jest.fn().mockImplementation(() => ({
|
|
6
6
|
observe: jest.fn(),
|
|
@@ -302,6 +302,13 @@
|
|
|
302
302
|
overflow: auto;
|
|
303
303
|
}
|
|
304
304
|
|
|
305
|
+
.measurement-area {
|
|
306
|
+
position: absolute;
|
|
307
|
+
visibility: hidden;
|
|
308
|
+
height: 0px;
|
|
309
|
+
pointer-events: none;
|
|
310
|
+
}
|
|
311
|
+
|
|
305
312
|
.rtl > .dropdown {
|
|
306
313
|
-ms-transform-origin: left top;
|
|
307
314
|
-webkit-transform-origin: left top;
|
|
@@ -118,8 +118,8 @@ export class Select {
|
|
|
118
118
|
handleChildChange(_) {
|
|
119
119
|
// on update of children or children selected state, reset button text and rerender
|
|
120
120
|
this.setButtonText();
|
|
121
|
-
forceUpdate(this.el);
|
|
122
121
|
this.optionListEl.handleChildChange(_);
|
|
122
|
+
forceUpdate(this.el);
|
|
123
123
|
}
|
|
124
124
|
componentDidLoad() {
|
|
125
125
|
this.wmSelectDidLoad.emit();
|
|
@@ -197,14 +197,14 @@ export class Select {
|
|
|
197
197
|
const paddingLeft = parseInt(computedStyle.getPropertyValue("padding-left").slice(0, -2));
|
|
198
198
|
const paddingRight = parseInt(computedStyle.getPropertyValue("padding-right").slice(0, -2));
|
|
199
199
|
const availableSpace = this.buttonEl.clientWidth - paddingLeft - paddingRight - overflowCounterWidth;
|
|
200
|
-
let optionsWidths = this.displayedOptions.map((x) => x.shadowRoot.querySelector(".option-text").clientWidth);
|
|
201
|
-
let optionsTotalWidth = optionsWidths.reduce((acc, x) => acc + x, 0);
|
|
202
200
|
this.overflowCount = 0;
|
|
201
|
+
this.measurementAreaEl.textContent = this.displayedOptions.map((x) => x.textContent).join(", ");
|
|
202
|
+
let optionsTotalWidth = this.measurementAreaEl.clientWidth;
|
|
203
203
|
while (optionsTotalWidth > availableSpace && this.displayedOptions.length > 1) {
|
|
204
204
|
this.overflowCount++;
|
|
205
|
-
optionsTotalWidth -= optionsWidths[optionsWidths.length - 1];
|
|
206
|
-
optionsWidths.pop();
|
|
207
205
|
this.displayedOptions.pop();
|
|
206
|
+
this.measurementAreaEl.textContent = this.displayedOptions.map((x) => x.textContent).join(", ");
|
|
207
|
+
optionsTotalWidth = this.measurementAreaEl.clientWidth;
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
210
|
}
|
|
@@ -244,7 +244,7 @@ export class Select {
|
|
|
244
244
|
};
|
|
245
245
|
return (h(Host, { onBlur: (ev) => this.handleComponentBlur(ev) }, h("div", { class: `wrapper ${getTextDir()} label-${this.labelPosition} ${this.errorMessage ? "invalid" : ""}` }, h("div", { class: "label-wrapper" }, h("label", { class: "label", id: "label", htmlFor: "selectbtn" }, this.label,
|
|
246
246
|
// we can't use aria-required or required attributes because it's invalid on the elements we're using (button controlling a listbox)
|
|
247
|
-
this.requiredField ? (h("span", { class: "required" }, h("span", { class: "sr-only" }, globalMessages.requiredField), h("span", { "aria-hidden": "true" }, "*"))) : (""))), h("div", { class: "button-wrapper" }, h("button", Object.assign({}, buttonProps, { class: "displayedoption", ref: (el) => (this.buttonEl = el), onBlur: (ev) => this.handleButtonBlur(ev), onFocus: () => this.close() }), h("span", { class: `overflowcontrol ${showSubinfo ? "hassubinfo" : ""}` }, h("span", { class: "button-text" }, this.renderButtonText()), showSubinfo && h("span", { class: "subinfo" }, this.selectedOptions[0].subinfo)), this.renderOverflowCount()), h("div", { class: `dropdown ${this.isExpanded ? "open" : ""} ${this.openUp ? "upwards" : ""}`, ref: (el) => (this.dropdownEl = el) }, h("priv-option-list", { ref: (el) => (this.optionListEl = el), multiple: this.multiple, search: this.search, selectAll: this.selectAll, searchPlaceholder: this.searchPlaceholder, onOptionListCloseRequested: () => this.close(), onOptionListAllSelected: () => this.wmSelectAllSelected.emit(), onOptionListAllDeselected: () => this.wmSelectAllDeselected.emit() }, h("slot", null))), h("div", { id: "error", class: this.errorMessage ? "error-message" : "" }, this.errorMessage), h("div", { id: "announcement", "aria-live": "polite", "aria-atomic": "true", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement)))));
|
|
247
|
+
this.requiredField ? (h("span", { class: "required" }, h("span", { class: "sr-only" }, globalMessages.requiredField), h("span", { "aria-hidden": "true" }, "*"))) : (""))), h("div", { class: "button-wrapper" }, h("button", Object.assign({}, buttonProps, { class: "displayedoption", ref: (el) => (this.buttonEl = el), onBlur: (ev) => this.handleButtonBlur(ev), onFocus: () => this.close() }), h("span", { class: `overflowcontrol ${showSubinfo ? "hassubinfo" : ""}` }, h("span", { class: "button-text" }, this.renderButtonText()), showSubinfo && h("span", { class: "subinfo" }, this.selectedOptions[0].subinfo)), this.renderOverflowCount(), h("div", { ref: (el) => (this.measurementAreaEl = el), class: "measurement-area", "aria-hidden": "true" })), h("div", { class: `dropdown ${this.isExpanded ? "open" : ""} ${this.openUp ? "upwards" : ""}`, ref: (el) => (this.dropdownEl = el) }, h("priv-option-list", { ref: (el) => (this.optionListEl = el), multiple: this.multiple, search: this.search, selectAll: this.selectAll, searchPlaceholder: this.searchPlaceholder, onOptionListCloseRequested: () => this.close(), onOptionListAllSelected: () => this.wmSelectAllSelected.emit(), onOptionListAllDeselected: () => this.wmSelectAllDeselected.emit() }, h("slot", null))), h("div", { id: "error", class: this.errorMessage ? "error-message" : "" }, this.errorMessage), h("div", { id: "announcement", "aria-live": "polite", "aria-atomic": "true", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement)))));
|
|
248
248
|
}
|
|
249
249
|
static get is() { return "wm-select"; }
|
|
250
250
|
static get encapsulation() { return "shadow"; }
|
|
@@ -2,7 +2,7 @@ import { newSpecPage } from "@stencil/core/testing";
|
|
|
2
2
|
import * as globalFuncs from "../../../global/functions";
|
|
3
3
|
jest.spyOn(globalFuncs, "getTextDir").mockImplementation(() => "rtl");
|
|
4
4
|
import { Select } from "./wm-select";
|
|
5
|
-
import { Option } from "
|
|
5
|
+
import { Option } from "../wm-option/wm-option";
|
|
6
6
|
// mock MutationObserver
|
|
7
7
|
global.MutationObserver = jest.fn().mockImplementation(() => ({
|
|
8
8
|
observe: jest.fn(),
|
|
@@ -65,7 +65,7 @@ export class Modal {
|
|
|
65
65
|
componentWillLoad() {
|
|
66
66
|
if (this.elementToFocus === "primary" || this.elementToFocus === "secondary") {
|
|
67
67
|
if (!this.el.id) {
|
|
68
|
-
console.error("For accessibility purposes you need to set the modal content wrapper's id to 'content-[id of wm-modal].");
|
|
68
|
+
console.error("For accessibility purposes you need to set the modal content wrapper's id to 'content-[id of wm-modal]'.");
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
this.el.focus = () => {
|