@watermarkinsights/ripple 5.7.0-0 → 5.7.0-10
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-b4e48f66.js → global-d1944ab2.js} +1 -1
- package/dist/cjs/index-e86c28b6.js +8 -12
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/priv-option-list.cjs.entry.js +27 -19
- package/dist/cjs/ripple.cjs.js +2 -2
- package/dist/cjs/wm-modal-pss_3.cjs.entry.js +213 -0
- package/dist/cjs/{wm-modal.cjs.entry.js → wm-modal_3.cjs.entry.js} +73 -0
- package/dist/cjs/wm-nested-select.cjs.entry.js +85 -38
- package/dist/cjs/wm-optgroup.cjs.entry.js +16 -1
- package/dist/cjs/wm-option_2.cjs.entry.js +10 -12
- package/dist/collection/collection-manifest.json +17 -5
- package/dist/collection/components/selects/priv-option-list/priv-option-list.css +22 -6
- package/dist/collection/components/selects/priv-option-list/priv-option-list.js +53 -34
- package/dist/collection/components/selects/wm-nested-select/wm-nested-select.css +43 -7
- package/dist/collection/components/selects/wm-nested-select/wm-nested-select.js +115 -42
- package/dist/collection/components/selects/wm-optgroup/wm-optgroup.js +51 -1
- package/dist/collection/components/selects/wm-option/wm-option.css +1 -1
- package/dist/collection/components/selects/wm-select/wm-select.css +5 -8
- package/dist/collection/components/selects/wm-select/wm-select.js +12 -13
- package/dist/collection/components/wm-modal-pss/wm-modal-pss-footer.css +61 -0
- package/dist/collection/components/wm-modal-pss/wm-modal-pss-footer.js +138 -0
- package/dist/collection/components/wm-modal-pss/wm-modal-pss-header.css +55 -0
- package/dist/collection/components/wm-modal-pss/wm-modal-pss-header.js +81 -0
- package/dist/collection/components/wm-modal-pss/wm-modal-pss.css +134 -0
- package/dist/collection/components/wm-modal-pss/wm-modal-pss.js +361 -0
- package/dist/esm/{global-8a4502dd.js → global-687694e4.js} +1 -1
- package/dist/esm/index-558b5a82.js +8 -12
- package/dist/esm/loader.js +2 -2
- package/dist/esm/priv-option-list.entry.js +27 -19
- package/dist/esm/ripple.js +2 -2
- package/dist/esm/wm-modal-pss_3.entry.js +207 -0
- package/dist/esm/{wm-modal.entry.js → wm-modal_3.entry.js} +73 -2
- package/dist/esm/wm-nested-select.entry.js +86 -39
- package/dist/esm/wm-optgroup.entry.js +16 -1
- package/dist/esm/wm-option_2.entry.js +10 -12
- package/dist/esm-es5/global-687694e4.js +1 -0
- package/dist/esm-es5/index-558b5a82.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-modal-pss_3.entry.js +1 -0
- package/dist/esm-es5/wm-modal_3.entry.js +1 -0
- 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-012cab20.entry.js +1 -0
- package/dist/ripple/p-02deae76.entry.js +1 -0
- package/dist/ripple/p-1d18d9d2.system.entry.js +1 -0
- package/dist/ripple/p-226fe4e0.entry.js +1 -0
- package/dist/ripple/p-6e725656.system.entry.js +1 -0
- package/dist/ripple/p-6fdfe9f4.system.entry.js +1 -0
- package/dist/ripple/p-77e48f61.system.entry.js +1 -0
- package/dist/ripple/p-ad1bdcd6.js +1 -0
- package/dist/ripple/p-add3ab3d.system.js +1 -0
- package/dist/ripple/p-bf7d98d8.entry.js +1 -0
- package/dist/ripple/p-ca397ba6.system.js +1 -0
- package/dist/ripple/p-cff5d7e9.system.entry.js +1 -0
- package/dist/ripple/p-f13b034e.entry.js +1 -0
- package/dist/ripple/p-f3f4620c.entry.js +1 -0
- package/dist/ripple/p-f4bcee58.system.entry.js +1 -0
- package/dist/ripple/ripple.esm.js +1 -1
- package/dist/ripple/ripple.js +1 -1
- package/dist/types/components/selects/priv-option-list/priv-option-list.d.ts +6 -2
- package/dist/types/components/selects/wm-nested-select/wm-nested-select.d.ts +8 -5
- package/dist/types/components/selects/wm-optgroup/wm-optgroup.d.ts +4 -0
- package/dist/types/components/selects/wm-select/wm-select.d.ts +2 -2
- package/dist/types/components/wm-modal-pss/wm-modal-pss-footer.d.ts +14 -0
- package/dist/types/components/wm-modal-pss/wm-modal-pss-header.d.ts +10 -0
- package/dist/types/components.d.ts +100 -5
- package/package.json +1 -1
- package/dist/cjs/wm-modal-footer.cjs.entry.js +0 -47
- package/dist/cjs/wm-modal-header.cjs.entry.js +0 -39
- package/dist/esm/wm-modal-footer.entry.js +0 -43
- package/dist/esm/wm-modal-header.entry.js +0 -35
- package/dist/esm-es5/global-8a4502dd.js +0 -1
- package/dist/esm-es5/wm-modal-footer.entry.js +0 -1
- package/dist/esm-es5/wm-modal-header.entry.js +0 -1
- package/dist/esm-es5/wm-modal.entry.js +0 -1
- package/dist/ripple/p-01addccd.entry.js +0 -1
- package/dist/ripple/p-01e29a2a.system.js +0 -1
- package/dist/ripple/p-0c259c1a.system.entry.js +0 -1
- package/dist/ripple/p-13f51c06.entry.js +0 -1
- package/dist/ripple/p-1796b85d.entry.js +0 -1
- package/dist/ripple/p-1c170fb3.entry.js +0 -1
- package/dist/ripple/p-294b38ca.system.entry.js +0 -1
- package/dist/ripple/p-3568472c.entry.js +0 -1
- package/dist/ripple/p-3d02b293.system.entry.js +0 -1
- package/dist/ripple/p-45dc49e8.entry.js +0 -1
- package/dist/ripple/p-50388b6f.system.entry.js +0 -1
- package/dist/ripple/p-54f7d3d4.system.entry.js +0 -1
- package/dist/ripple/p-84603f1f.system.entry.js +0 -1
- package/dist/ripple/p-947f8f0d.system.entry.js +0 -1
- package/dist/ripple/p-99058787.entry.js +0 -1
- package/dist/ripple/p-db9f8841.system.js +0 -1
- package/dist/ripple/p-de8f5e92.js +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { h, Host, forceUpdate } from "@stencil/core";
|
|
2
|
-
import { getTextDir, intl, isElOrChild, shouldOpenUp, toBool } from "../../../global/functions";
|
|
2
|
+
import { getContextMeasurements, getTextDir, intl, isElOrChild, shouldOpenUp, toBool } from "../../../global/functions";
|
|
3
3
|
import { globalMessages } from "../../../global/intl";
|
|
4
4
|
export class NestedSelect {
|
|
5
5
|
constructor() {
|
|
@@ -18,7 +18,7 @@ export class NestedSelect {
|
|
|
18
18
|
description: "Button text to clear selection. Use imperative",
|
|
19
19
|
});
|
|
20
20
|
this.disabled = false;
|
|
21
|
-
this.maxHeight =
|
|
21
|
+
this.maxHeight = "200px";
|
|
22
22
|
this.label = undefined;
|
|
23
23
|
this.labelPosition = "top";
|
|
24
24
|
this.requiredField = false;
|
|
@@ -49,6 +49,8 @@ export class NestedSelect {
|
|
|
49
49
|
});
|
|
50
50
|
this.isExpanded = false;
|
|
51
51
|
this.showClearSelectionButton = false;
|
|
52
|
+
this.announcement = "";
|
|
53
|
+
this.constrainedMaxHeight = this.maxHeight;
|
|
52
54
|
}
|
|
53
55
|
get isDisabled() {
|
|
54
56
|
// string "false" needs to be treated as bool False because react wrappers convert bool to string.
|
|
@@ -67,7 +69,7 @@ export class NestedSelect {
|
|
|
67
69
|
return this.childOptions.every((option) => option.selected);
|
|
68
70
|
}
|
|
69
71
|
componentWillLoad() {
|
|
70
|
-
const mutationObserver = new MutationObserver((mutationRecordList) => mutationRecordList.forEach((
|
|
72
|
+
const mutationObserver = new MutationObserver((mutationRecordList) => mutationRecordList.forEach((_mutationRecord) => this.handleChildChange()));
|
|
71
73
|
mutationObserver.observe(this.el, {
|
|
72
74
|
childList: true,
|
|
73
75
|
attributes: true,
|
|
@@ -75,16 +77,14 @@ export class NestedSelect {
|
|
|
75
77
|
attributeFilter: ["selected"],
|
|
76
78
|
});
|
|
77
79
|
}
|
|
78
|
-
|
|
79
|
-
if (this.maxHeight) {
|
|
80
|
-
this.dropdownEl.style.maxHeight = this.maxHeight;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
handleChildChange(_) {
|
|
80
|
+
handleChildChange() {
|
|
84
81
|
// on update of children or children selected state, reset button text and rerender
|
|
85
82
|
this.setButtonText();
|
|
86
83
|
forceUpdate(this.el);
|
|
87
|
-
|
|
84
|
+
if (this.multiple) {
|
|
85
|
+
// update state of clone options
|
|
86
|
+
this.optgroupEls.forEach((optgroupEl) => optgroupEl.handleChildChange());
|
|
87
|
+
}
|
|
88
88
|
}
|
|
89
89
|
setButtonText() {
|
|
90
90
|
this.displayedOptions = this.childOptions.filter((x) => x.selected);
|
|
@@ -124,6 +124,28 @@ export class NestedSelect {
|
|
|
124
124
|
closePopupOnEscape() {
|
|
125
125
|
this.close();
|
|
126
126
|
}
|
|
127
|
+
handleKeyDown(ev) {
|
|
128
|
+
// when shift tabbing but component is still in focus, close dropdown
|
|
129
|
+
switch (ev.key) {
|
|
130
|
+
case "Tab":
|
|
131
|
+
if (ev.shiftKey) {
|
|
132
|
+
this.close();
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
case "ArrowDown":
|
|
136
|
+
if (this.isExpanded === false) {
|
|
137
|
+
ev.preventDefault();
|
|
138
|
+
this.open();
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
case "ArrowUp":
|
|
142
|
+
if (this.isExpanded === false) {
|
|
143
|
+
ev.preventDefault();
|
|
144
|
+
this.open(true);
|
|
145
|
+
}
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
127
149
|
close(returnFocus = true) {
|
|
128
150
|
if (this.isExpanded) {
|
|
129
151
|
this.isExpanded = false;
|
|
@@ -136,40 +158,50 @@ export class NestedSelect {
|
|
|
136
158
|
}, 150);
|
|
137
159
|
}
|
|
138
160
|
}
|
|
139
|
-
open() {
|
|
161
|
+
open(focusLast = false) {
|
|
140
162
|
if (!this.isDisabled) {
|
|
141
163
|
this.showClearSelectionButton = this.childOptions.some((o) => o.selected);
|
|
164
|
+
this.dropdownEl.scrollTop = 0;
|
|
142
165
|
this.isExpanded = true;
|
|
143
166
|
this.dropdownEl.classList.add("open");
|
|
144
167
|
const elHeight = this.el.clientHeight;
|
|
145
168
|
this.openUp = shouldOpenUp(this.el, this.dropdownEl.clientHeight, elHeight, 0);
|
|
146
|
-
|
|
147
|
-
|
|
169
|
+
this.constrainedMaxHeight = this.maxHeight;
|
|
170
|
+
const spaceAbove = getContextMeasurements(this.el).spaceAbove;
|
|
171
|
+
if (this.openUp) {
|
|
172
|
+
if (parseInt(getComputedStyle(this.menuEl).getPropertyValue("--max-height").replace("px", "")) > spaceAbove) {
|
|
173
|
+
this.constrainedMaxHeight = spaceAbove.toString() + "px";
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// if opening upwards, set an upwards height limit for the optgroup level
|
|
177
|
+
this.optgroupEls.forEach((o) => {
|
|
178
|
+
o.shadowRoot.querySelector("priv-option-list").upwardsHeightLimit = this.openUp
|
|
179
|
+
? spaceAbove
|
|
180
|
+
: null;
|
|
148
181
|
});
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
182
|
+
// scrollIntoView does not work when the container of the element it's called on is not rendered to the page (in our case the dropdown is still closed and has transform: scaleY(0))
|
|
183
|
+
// when opening the dropdown, scrollIntoView must be delayed to a point where the browser recognizes content within it as able to be scrolled to
|
|
184
|
+
// in Safari in particular, the soonest this seems to happen is 20ms. The longest we can wait before any jumping in the open dropdown is noticeable is 60ms
|
|
185
|
+
window.setTimeout(() => {
|
|
186
|
+
if (this.menuitemEls.length > 0) {
|
|
187
|
+
const menuitemToFocus = this.menuitemEls[focusLast ? this.menuitemEls.length - 1 : 0];
|
|
188
|
+
menuitemToFocus.scrollIntoView({ block: "nearest" });
|
|
189
|
+
menuitemToFocus.focus();
|
|
190
|
+
}
|
|
191
|
+
}, 60);
|
|
154
192
|
}
|
|
155
193
|
}
|
|
156
194
|
moveDown(menuitemEl) {
|
|
157
195
|
const currentIndex = this.menuitemEls.indexOf(menuitemEl);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
else {
|
|
162
|
-
this.menuitemEls[currentIndex + 1].focus();
|
|
163
|
-
}
|
|
196
|
+
const menuitemToFocus = this.menuitemEls[currentIndex == this.menuitemEls.length - 1 ? 0 : currentIndex + 1];
|
|
197
|
+
menuitemToFocus.scrollIntoView({ block: "nearest" });
|
|
198
|
+
menuitemToFocus.focus();
|
|
164
199
|
}
|
|
165
200
|
moveUp(menuitemEl) {
|
|
166
201
|
const currentIndex = this.menuitemEls.indexOf(menuitemEl);
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
else {
|
|
171
|
-
this.menuitemEls[currentIndex - 1].focus();
|
|
172
|
-
}
|
|
202
|
+
const menuitemToFocus = this.menuitemEls[currentIndex == 0 ? this.menuitemEls.length - 1 : currentIndex - 1];
|
|
203
|
+
menuitemToFocus.scrollIntoView({ block: "nearest" });
|
|
204
|
+
menuitemToFocus.focus();
|
|
173
205
|
}
|
|
174
206
|
handleButtonBlur(ev) {
|
|
175
207
|
if (isElOrChild(this.el, ev.relatedTarget)) {
|
|
@@ -225,6 +257,13 @@ export class NestedSelect {
|
|
|
225
257
|
const elToFocus = this.el.shadowRoot.querySelector(`button[data-label=${ev.detail}]`);
|
|
226
258
|
elToFocus.focus();
|
|
227
259
|
}
|
|
260
|
+
announce(message) {
|
|
261
|
+
// \u00A0 is a non-breaking space character, which causes the message to be read as a new one
|
|
262
|
+
if (this.liveRegionEl.textContent === message) {
|
|
263
|
+
message += "\u00A0";
|
|
264
|
+
}
|
|
265
|
+
this.announcement = message;
|
|
266
|
+
}
|
|
228
267
|
renderButtonText() {
|
|
229
268
|
if (this.displayedOptions.length < 1) {
|
|
230
269
|
return h("span", null, this.placeholder);
|
|
@@ -237,19 +276,25 @@ export class NestedSelect {
|
|
|
237
276
|
}
|
|
238
277
|
}
|
|
239
278
|
renderOverflowCount() {
|
|
240
|
-
if (this.overflowCount > 0) {
|
|
279
|
+
if (this.overflowCount > 0 && !this.allSelected) {
|
|
241
280
|
return (h("span", null, h("span", { class: "overflow-counter" }, "+", this.overflowCount)));
|
|
242
281
|
}
|
|
243
282
|
}
|
|
244
283
|
handleClearSelection() {
|
|
245
284
|
this.optgroupEls.forEach((optgroupEl) => optgroupEl.emitDeselection());
|
|
285
|
+
const selectionClearedAnnouncement = intl.formatMessage({
|
|
286
|
+
id: "select.selectionCleared",
|
|
287
|
+
defaultMessage: "Selection cleared",
|
|
288
|
+
description: "Screen reader announcement alerting the user they have cleared their selection",
|
|
289
|
+
});
|
|
290
|
+
this.announce(selectionClearedAnnouncement);
|
|
246
291
|
if (!this.multiple) {
|
|
247
292
|
this.close();
|
|
248
293
|
}
|
|
249
294
|
}
|
|
250
295
|
renderClearSelectionButton() {
|
|
251
296
|
if (this.showClearSelectionButton) {
|
|
252
|
-
return (h("button", { class: "menuitem", onClick: () => this.handleClearSelection(), tabindex: -1, onKeyDown: (ev) => this.handleMenuitemKeydown(ev) }, this.clearSelectionMessage));
|
|
297
|
+
return (h("button", { class: "menuitem clear-selection", onClick: () => this.handleClearSelection(), tabindex: -1, onKeyDown: (ev) => this.handleMenuitemKeydown(ev) }, this.clearSelectionMessage));
|
|
253
298
|
}
|
|
254
299
|
}
|
|
255
300
|
renderSelectionCount(optgroupEl) {
|
|
@@ -282,12 +327,14 @@ export class NestedSelect {
|
|
|
282
327
|
};
|
|
283
328
|
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,
|
|
284
329
|
// we can't use aria-required or required attributes because it's invalid on the elements we're using (button controlling a listbox)
|
|
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)
|
|
286
|
-
return (h("button", { class:
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
330
|
+
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) }), 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", style: { "--max-height": this.constrainedMaxHeight }, tabIndex: -1 }, this.renderClearSelectionButton(), this.optgroupEls.map((optgroupEl) => {
|
|
331
|
+
return (h("button", { class: `menuitem group-btn ${optgroupEl.disabled ? "disabled" : ""}`, role: "menuitem", "data-label": optgroupEl.label, tabindex: -1, "aria-disabled": optgroupEl.disabled, onClick: () => {
|
|
332
|
+
if (!optgroupEl.disabled) {
|
|
333
|
+
optgroupEl.isExpanded = !optgroupEl.isExpanded;
|
|
334
|
+
forceUpdate(this.el);
|
|
335
|
+
}
|
|
336
|
+
}, onKeyDown: (ev) => this.handleMenuitemKeydown(ev) }, h("span", null, optgroupEl.label), this.renderSelectionCount(optgroupEl), optgroupEl.disabled && h("div", { class: "disabled-indication" }, "Disabled")));
|
|
337
|
+
})), 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))), h("div", { id: "nestedselect-announcement", "aria-live": "assertive", "aria-atomic": "true", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement)));
|
|
291
338
|
}
|
|
292
339
|
static get is() { return "wm-nested-select"; }
|
|
293
340
|
static get encapsulation() { return "shadow"; }
|
|
@@ -327,17 +374,18 @@ export class NestedSelect {
|
|
|
327
374
|
"mutable": false,
|
|
328
375
|
"complexType": {
|
|
329
376
|
"original": "string",
|
|
330
|
-
"resolved": "string
|
|
377
|
+
"resolved": "string",
|
|
331
378
|
"references": {}
|
|
332
379
|
},
|
|
333
380
|
"required": false,
|
|
334
|
-
"optional":
|
|
381
|
+
"optional": false,
|
|
335
382
|
"docs": {
|
|
336
383
|
"tags": [],
|
|
337
384
|
"text": ""
|
|
338
385
|
},
|
|
339
386
|
"attribute": "max-height",
|
|
340
|
-
"reflect": false
|
|
387
|
+
"reflect": false,
|
|
388
|
+
"defaultValue": "\"200px\""
|
|
341
389
|
},
|
|
342
390
|
"label": {
|
|
343
391
|
"type": "string",
|
|
@@ -516,13 +564,32 @@ export class NestedSelect {
|
|
|
516
564
|
"attribute": "all-selected-message",
|
|
517
565
|
"reflect": false,
|
|
518
566
|
"defaultValue": "intl.formatMessage({\n id: \"select.allSelected\",\n defaultMessage: \"All selected\",\n description: \"Text displayed when all options are selected\",\n })"
|
|
567
|
+
},
|
|
568
|
+
"constrainedMaxHeight": {
|
|
569
|
+
"type": "string",
|
|
570
|
+
"mutable": true,
|
|
571
|
+
"complexType": {
|
|
572
|
+
"original": "string",
|
|
573
|
+
"resolved": "string",
|
|
574
|
+
"references": {}
|
|
575
|
+
},
|
|
576
|
+
"required": false,
|
|
577
|
+
"optional": false,
|
|
578
|
+
"docs": {
|
|
579
|
+
"tags": [],
|
|
580
|
+
"text": ""
|
|
581
|
+
},
|
|
582
|
+
"attribute": "constrained-max-height",
|
|
583
|
+
"reflect": false,
|
|
584
|
+
"defaultValue": "this.maxHeight"
|
|
519
585
|
}
|
|
520
586
|
};
|
|
521
587
|
}
|
|
522
588
|
static get states() {
|
|
523
589
|
return {
|
|
524
590
|
"isExpanded": {},
|
|
525
|
-
"showClearSelectionButton": {}
|
|
591
|
+
"showClearSelectionButton": {},
|
|
592
|
+
"announcement": {}
|
|
526
593
|
};
|
|
527
594
|
}
|
|
528
595
|
static get events() {
|
|
@@ -563,6 +630,12 @@ export class NestedSelect {
|
|
|
563
630
|
"target": undefined,
|
|
564
631
|
"capture": false,
|
|
565
632
|
"passive": false
|
|
633
|
+
}, {
|
|
634
|
+
"name": "keydown",
|
|
635
|
+
"method": "handleKeyDown",
|
|
636
|
+
"target": undefined,
|
|
637
|
+
"capture": false,
|
|
638
|
+
"passive": false
|
|
566
639
|
}, {
|
|
567
640
|
"name": "click",
|
|
568
641
|
"method": "handleClick",
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
|
+
import { handleDisabledAttribute, toBool } from "../../../global/functions";
|
|
2
3
|
export class Optgroup {
|
|
3
4
|
constructor() {
|
|
4
5
|
this.label = undefined;
|
|
5
6
|
this.isExpanded = false;
|
|
6
7
|
this.multiple = false;
|
|
8
|
+
this.disabled = false;
|
|
7
9
|
}
|
|
8
10
|
get parentNestedSelect() {
|
|
9
11
|
return this.el.parentElement;
|
|
10
12
|
}
|
|
13
|
+
get isDisabled() {
|
|
14
|
+
// string "false" needs to be treated as bool False because react wrappers convert bool to string.
|
|
15
|
+
return toBool(this.disabled);
|
|
16
|
+
}
|
|
11
17
|
isExpandedChanged() {
|
|
12
18
|
if (this.isExpanded) {
|
|
13
19
|
this.el.classList.add("visible");
|
|
@@ -25,15 +31,24 @@ export class Optgroup {
|
|
|
25
31
|
this.el.classList.remove("visible");
|
|
26
32
|
}, 250);
|
|
27
33
|
}
|
|
34
|
+
if (this.parentNestedSelect.multiple) {
|
|
35
|
+
this.optionListEl.updateOptionVisibility();
|
|
36
|
+
}
|
|
28
37
|
}
|
|
29
38
|
async emitDeselection() {
|
|
30
39
|
this.wmOptgroupAllDeselected.emit();
|
|
31
40
|
}
|
|
41
|
+
async handleChildChange() {
|
|
42
|
+
this.optionListEl.handleChildChange();
|
|
43
|
+
}
|
|
32
44
|
handleOptionKeyLeft() {
|
|
33
45
|
this.isExpanded = false;
|
|
34
46
|
}
|
|
47
|
+
componentWillLoad() {
|
|
48
|
+
handleDisabledAttribute(this.el, this.isDisabled);
|
|
49
|
+
}
|
|
35
50
|
render() {
|
|
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)))));
|
|
51
|
+
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, maxHeight: this.parentNestedSelect.constrainedMaxHeight, searchPlaceholder: this.parentNestedSelect.searchPlaceholder, optgroupLabel: this.label, selectAll: this.parentNestedSelect.selectAll, onOptionListAllSelected: () => this.wmOptgroupAllSelected.emit(), onOptionListAllDeselected: () => this.wmOptgroupAllDeselected.emit() }, h("slot", null)))));
|
|
37
52
|
}
|
|
38
53
|
static get is() { return "wm-optgroup"; }
|
|
39
54
|
static get encapsulation() { return "shadow"; }
|
|
@@ -102,6 +117,24 @@ export class Optgroup {
|
|
|
102
117
|
"attribute": "multiple",
|
|
103
118
|
"reflect": false,
|
|
104
119
|
"defaultValue": "false"
|
|
120
|
+
},
|
|
121
|
+
"disabled": {
|
|
122
|
+
"type": "boolean",
|
|
123
|
+
"mutable": false,
|
|
124
|
+
"complexType": {
|
|
125
|
+
"original": "boolean",
|
|
126
|
+
"resolved": "boolean",
|
|
127
|
+
"references": {}
|
|
128
|
+
},
|
|
129
|
+
"required": false,
|
|
130
|
+
"optional": false,
|
|
131
|
+
"docs": {
|
|
132
|
+
"tags": [],
|
|
133
|
+
"text": ""
|
|
134
|
+
},
|
|
135
|
+
"attribute": "disabled",
|
|
136
|
+
"reflect": false,
|
|
137
|
+
"defaultValue": "false"
|
|
105
138
|
}
|
|
106
139
|
};
|
|
107
140
|
}
|
|
@@ -186,6 +219,23 @@ export class Optgroup {
|
|
|
186
219
|
"text": "",
|
|
187
220
|
"tags": []
|
|
188
221
|
}
|
|
222
|
+
},
|
|
223
|
+
"handleChildChange": {
|
|
224
|
+
"complexType": {
|
|
225
|
+
"signature": "() => Promise<void>",
|
|
226
|
+
"parameters": [],
|
|
227
|
+
"references": {
|
|
228
|
+
"Promise": {
|
|
229
|
+
"location": "global",
|
|
230
|
+
"id": "global::Promise"
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
"return": "Promise<void>"
|
|
234
|
+
},
|
|
235
|
+
"docs": {
|
|
236
|
+
"text": "",
|
|
237
|
+
"tags": []
|
|
238
|
+
}
|
|
189
239
|
}
|
|
190
240
|
};
|
|
191
241
|
}
|
|
@@ -227,9 +227,9 @@
|
|
|
227
227
|
margin-left: 0.5rem;
|
|
228
228
|
}
|
|
229
229
|
.wrapper .button-wrapper > .displayedoption[disabled] {
|
|
230
|
-
color:
|
|
231
|
-
border-color:
|
|
232
|
-
background:
|
|
230
|
+
color: var(--wmcolor-select-option-text-disabled);
|
|
231
|
+
border-color: var(--wmcolor-border-dark);
|
|
232
|
+
background: var(--wmcolor-select-option-background-disabled);
|
|
233
233
|
cursor: default;
|
|
234
234
|
}
|
|
235
235
|
.wrapper .button-wrapper > .dropdown {
|
|
@@ -260,6 +260,8 @@
|
|
|
260
260
|
z-index: 100;
|
|
261
261
|
width: 100%;
|
|
262
262
|
font-size: 0.875rem;
|
|
263
|
+
max-height: var(--max-height);
|
|
264
|
+
overflow-y: auto;
|
|
263
265
|
}
|
|
264
266
|
.wrapper .button-wrapper > .dropdown.upwards {
|
|
265
267
|
top: unset;
|
|
@@ -297,11 +299,6 @@
|
|
|
297
299
|
margin-top: 0.25rem;
|
|
298
300
|
}
|
|
299
301
|
|
|
300
|
-
.options-wrapper {
|
|
301
|
-
max-height: 12.5rem;
|
|
302
|
-
overflow: auto;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
302
|
.measurement-area {
|
|
306
303
|
position: absolute;
|
|
307
304
|
visibility: hidden;
|
|
@@ -10,7 +10,7 @@ export class Select {
|
|
|
10
10
|
this.overflowCount = 0;
|
|
11
11
|
this.displayedOptions = [];
|
|
12
12
|
this.disabled = false;
|
|
13
|
-
this.maxHeight =
|
|
13
|
+
this.maxHeight = "200px";
|
|
14
14
|
this.label = undefined;
|
|
15
15
|
this.labelPosition = "top";
|
|
16
16
|
this.requiredField = false;
|
|
@@ -107,7 +107,7 @@ export class Select {
|
|
|
107
107
|
console.error("wm-select should have one initial option selected");
|
|
108
108
|
}
|
|
109
109
|
handleDisabledAttribute(this.el, this.isDisabled);
|
|
110
|
-
const mutationObserver = new MutationObserver((mutationRecordList) => mutationRecordList.forEach((
|
|
110
|
+
const mutationObserver = new MutationObserver((mutationRecordList) => mutationRecordList.forEach((_mutationRecord) => this.handleChildChange()));
|
|
111
111
|
mutationObserver.observe(this.el, {
|
|
112
112
|
childList: true,
|
|
113
113
|
attributes: true,
|
|
@@ -115,21 +115,19 @@ export class Select {
|
|
|
115
115
|
attributeFilter: ["selected"],
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
|
-
handleChildChange(
|
|
118
|
+
handleChildChange() {
|
|
119
119
|
// on update of children or children selected state, reset button text and rerender
|
|
120
120
|
this.setButtonText();
|
|
121
|
-
this.optionListEl.handleChildChange(_);
|
|
122
121
|
forceUpdate(this.el);
|
|
122
|
+
if (this.multiple) {
|
|
123
|
+
// update state of clone options
|
|
124
|
+
this.optionListEl.handleChildChange();
|
|
125
|
+
}
|
|
123
126
|
}
|
|
124
127
|
componentDidLoad() {
|
|
125
128
|
this.wmSelectDidLoad.emit();
|
|
126
129
|
this.dropdownEl.classList.add("hidden");
|
|
127
130
|
forceUpdate(this.el);
|
|
128
|
-
// Dev can overwrite the max-height rule set in the Sass file
|
|
129
|
-
if (this.maxHeight) {
|
|
130
|
-
// this.listboxEl.style.maxHeight = this.maxHeight;
|
|
131
|
-
this.dropdownEl.style.maxHeight = this.maxHeight;
|
|
132
|
-
}
|
|
133
131
|
this.setButtonText();
|
|
134
132
|
}
|
|
135
133
|
open(optionToSelect) {
|
|
@@ -244,7 +242,7 @@ export class Select {
|
|
|
244
242
|
};
|
|
245
243
|
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
244
|
// 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", { 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)))));
|
|
245
|
+
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, maxHeight: this.maxHeight, 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
246
|
}
|
|
249
247
|
static get is() { return "wm-select"; }
|
|
250
248
|
static get encapsulation() { return "shadow"; }
|
|
@@ -284,17 +282,18 @@ export class Select {
|
|
|
284
282
|
"mutable": false,
|
|
285
283
|
"complexType": {
|
|
286
284
|
"original": "string",
|
|
287
|
-
"resolved": "string
|
|
285
|
+
"resolved": "string",
|
|
288
286
|
"references": {}
|
|
289
287
|
},
|
|
290
288
|
"required": false,
|
|
291
|
-
"optional":
|
|
289
|
+
"optional": false,
|
|
292
290
|
"docs": {
|
|
293
291
|
"tags": [],
|
|
294
292
|
"text": ""
|
|
295
293
|
},
|
|
296
294
|
"attribute": "max-height",
|
|
297
|
-
"reflect": false
|
|
295
|
+
"reflect": false,
|
|
296
|
+
"defaultValue": "\"200px\""
|
|
298
297
|
},
|
|
299
298
|
"label": {
|
|
300
299
|
"type": "string",
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* --------------------------------------
|
|
2
|
+
1. Box-shadow
|
|
3
|
+
-------------------------------------- */
|
|
4
|
+
/* --------------------------------------
|
|
5
|
+
2. Border-radius
|
|
6
|
+
-------------------------------------- */
|
|
7
|
+
/* --------------------------------------
|
|
8
|
+
3. Transforms
|
|
9
|
+
-------------------------------------- */
|
|
10
|
+
/* --------------------------------------
|
|
11
|
+
4. Button Focus
|
|
12
|
+
-------------------------------------- */
|
|
13
|
+
/* --------------------------------------
|
|
14
|
+
5. Flex
|
|
15
|
+
-------------------------------------- */
|
|
16
|
+
/* --------------------------------------
|
|
17
|
+
7. Screen Reader Only
|
|
18
|
+
-------------------------------------- */
|
|
19
|
+
/* --------------------------------------
|
|
20
|
+
8. Label styles
|
|
21
|
+
this mixin includes all the styles for the label
|
|
22
|
+
+ flex rules on the parent container to switch between top and left position
|
|
23
|
+
+ srOnly when label is hidden
|
|
24
|
+
Assumes the following markup:
|
|
25
|
+
div.wrapper[.label-left.invalid] > div.label-wrapper > label.label > span.required
|
|
26
|
+
.wrapper is for the flex rules
|
|
27
|
+
.label-wrapper is to set the height of the label when positioned left so it's the same height as
|
|
28
|
+
the input. It can't be done directly on .label because of possible line wrapping.
|
|
29
|
+
When the label is on top there's no line wrapping at all to ensure proper alignment of inlined elements
|
|
30
|
+
(they can't be aligned on the baseline because of possible description text and error message)
|
|
31
|
+
-------------------------------------- */
|
|
32
|
+
wm-modal-pss-footer {
|
|
33
|
+
border-radius: 0px 0px 5px 5px;
|
|
34
|
+
margin-top: -1px;
|
|
35
|
+
}
|
|
36
|
+
wm-modal-pss-footer .wm-wrapper {
|
|
37
|
+
display: flex;
|
|
38
|
+
justify-content: space-between;
|
|
39
|
+
align-items: center;
|
|
40
|
+
}
|
|
41
|
+
@media only screen and (max-width: 650px) {
|
|
42
|
+
wm-modal-pss-footer .wm-wrapper.footer-text {
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
align-items: flex-start;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
wm-modal-pss-footer .wm-wrapper wm-button + wm-button {
|
|
48
|
+
margin-left: 1rem;
|
|
49
|
+
}
|
|
50
|
+
wm-modal-pss-footer .wm-wrapper .wm-info {
|
|
51
|
+
font-size: 0.875rem;
|
|
52
|
+
font-style: italic;
|
|
53
|
+
}
|
|
54
|
+
@media only screen and (max-width: 650px) {
|
|
55
|
+
wm-modal-pss-footer .wm-wrapper .wm-info {
|
|
56
|
+
padding-bottom: 0.625rem;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
wm-modal-pss-footer .wm-wrapper .wm-info:focus {
|
|
60
|
+
outline: none;
|
|
61
|
+
}
|