@watermarkinsights/ripple 5.7.0-1 → 5.7.0-11
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-d996c674.js → global-0515f81a.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 +39 -20
- 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 +77 -32
- package/dist/cjs/wm-optgroup.cjs.entry.js +7 -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 +31 -6
- package/dist/collection/components/selects/priv-option-list/priv-option-list.js +65 -35
- package/dist/collection/components/selects/wm-nested-select/wm-nested-select.css +11 -5
- package/dist/collection/components/selects/wm-nested-select/wm-nested-select.js +107 -36
- package/dist/collection/components/selects/wm-optgroup/wm-optgroup.js +24 -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-dcf80bdb.js → global-a9138d5f.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 +39 -20
- 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 +78 -33
- package/dist/esm/wm-optgroup.entry.js +7 -1
- package/dist/esm/wm-option_2.entry.js +10 -12
- package/dist/esm-es5/global-a9138d5f.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-225f55fa.system.js +1 -0
- package/dist/ripple/p-226fe4e0.entry.js +1 -0
- package/dist/ripple/p-5fbe6e5e.system.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-aecf9a22.entry.js +1 -0
- package/dist/ripple/p-bf7d98d8.entry.js +1 -0
- package/dist/ripple/p-bfae6907.js +1 -0
- package/dist/ripple/p-c1714e14.system.entry.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-54d9e467.system.entry.js → p-f4bcee58.system.entry.js} +1 -1
- 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 +1 -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 +98 -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-dcf80bdb.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-0c259c1a.system.entry.js +0 -1
- package/dist/ripple/p-13f51c06.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-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-618300c1.entry.js +0 -1
- package/dist/ripple/p-76ff5d91.entry.js +0 -1
- package/dist/ripple/p-84603f1f.system.entry.js +0 -1
- package/dist/ripple/p-99058787.entry.js +0 -1
- package/dist/ripple/p-b176c143.system.entry.js +0 -1
- package/dist/ripple/p-c6a336d6.system.js +0 -1
- package/dist/ripple/p-e209a933.js +0 -1
- package/dist/ripple/p-ee4fee7d.system.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);
|
|
@@ -243,6 +282,12 @@ export class NestedSelect {
|
|
|
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
|
}
|
|
@@ -282,14 +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)
|
|
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) => {
|
|
286
331
|
return (h("button", { class: `menuitem group-btn ${optgroupEl.disabled ? "disabled" : ""}`, role: "menuitem", "data-label": optgroupEl.label, tabindex: -1, "aria-disabled": optgroupEl.disabled, onClick: () => {
|
|
287
332
|
if (!optgroupEl.disabled) {
|
|
288
333
|
optgroupEl.isExpanded = !optgroupEl.isExpanded;
|
|
289
334
|
forceUpdate(this.el);
|
|
290
335
|
}
|
|
291
336
|
}, onKeyDown: (ev) => this.handleMenuitemKeydown(ev) }, h("span", null, optgroupEl.label), this.renderSelectionCount(optgroupEl), optgroupEl.disabled && h("div", { class: "disabled-indication" }, "Disabled")));
|
|
292
|
-
})), 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)))));
|
|
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)));
|
|
293
338
|
}
|
|
294
339
|
static get is() { return "wm-nested-select"; }
|
|
295
340
|
static get encapsulation() { return "shadow"; }
|
|
@@ -329,17 +374,18 @@ export class NestedSelect {
|
|
|
329
374
|
"mutable": false,
|
|
330
375
|
"complexType": {
|
|
331
376
|
"original": "string",
|
|
332
|
-
"resolved": "string
|
|
377
|
+
"resolved": "string",
|
|
333
378
|
"references": {}
|
|
334
379
|
},
|
|
335
380
|
"required": false,
|
|
336
|
-
"optional":
|
|
381
|
+
"optional": false,
|
|
337
382
|
"docs": {
|
|
338
383
|
"tags": [],
|
|
339
384
|
"text": ""
|
|
340
385
|
},
|
|
341
386
|
"attribute": "max-height",
|
|
342
|
-
"reflect": false
|
|
387
|
+
"reflect": false,
|
|
388
|
+
"defaultValue": "\"200px\""
|
|
343
389
|
},
|
|
344
390
|
"label": {
|
|
345
391
|
"type": "string",
|
|
@@ -518,13 +564,32 @@ export class NestedSelect {
|
|
|
518
564
|
"attribute": "all-selected-message",
|
|
519
565
|
"reflect": false,
|
|
520
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"
|
|
521
585
|
}
|
|
522
586
|
};
|
|
523
587
|
}
|
|
524
588
|
static get states() {
|
|
525
589
|
return {
|
|
526
590
|
"isExpanded": {},
|
|
527
|
-
"showClearSelectionButton": {}
|
|
591
|
+
"showClearSelectionButton": {},
|
|
592
|
+
"announcement": {}
|
|
528
593
|
};
|
|
529
594
|
}
|
|
530
595
|
static get events() {
|
|
@@ -565,6 +630,12 @@ export class NestedSelect {
|
|
|
565
630
|
"target": undefined,
|
|
566
631
|
"capture": false,
|
|
567
632
|
"passive": false
|
|
633
|
+
}, {
|
|
634
|
+
"name": "keydown",
|
|
635
|
+
"method": "handleKeyDown",
|
|
636
|
+
"target": undefined,
|
|
637
|
+
"capture": false,
|
|
638
|
+
"passive": false
|
|
568
639
|
}, {
|
|
569
640
|
"name": "click",
|
|
570
641
|
"method": "handleClick",
|
|
@@ -31,10 +31,16 @@ export class Optgroup {
|
|
|
31
31
|
this.el.classList.remove("visible");
|
|
32
32
|
}, 250);
|
|
33
33
|
}
|
|
34
|
+
if (this.parentNestedSelect.multiple) {
|
|
35
|
+
this.optionListEl.updateOptionVisibility();
|
|
36
|
+
}
|
|
34
37
|
}
|
|
35
38
|
async emitDeselection() {
|
|
36
39
|
this.wmOptgroupAllDeselected.emit();
|
|
37
40
|
}
|
|
41
|
+
async handleChildChange() {
|
|
42
|
+
this.optionListEl.handleChildChange();
|
|
43
|
+
}
|
|
38
44
|
handleOptionKeyLeft() {
|
|
39
45
|
this.isExpanded = false;
|
|
40
46
|
}
|
|
@@ -42,7 +48,7 @@ export class Optgroup {
|
|
|
42
48
|
handleDisabledAttribute(this.el, this.isDisabled);
|
|
43
49
|
}
|
|
44
50
|
render() {
|
|
45
|
-
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)))));
|
|
46
52
|
}
|
|
47
53
|
static get is() { return "wm-optgroup"; }
|
|
48
54
|
static get encapsulation() { return "shadow"; }
|
|
@@ -213,6 +219,23 @@ export class Optgroup {
|
|
|
213
219
|
"text": "",
|
|
214
220
|
"tags": []
|
|
215
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
|
+
}
|
|
216
239
|
}
|
|
217
240
|
};
|
|
218
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
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { h } from "@stencil/core";
|
|
2
|
+
export class ModalFooter {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.secondaryText = "";
|
|
5
|
+
this.primaryText = "";
|
|
6
|
+
this.infoText = "";
|
|
7
|
+
this.primaryActionDisabled = false;
|
|
8
|
+
this.deleteStyle = false;
|
|
9
|
+
}
|
|
10
|
+
componentWillLoad() {
|
|
11
|
+
this.uid = this.el.parentElement.uid;
|
|
12
|
+
// Trap focus when user shift+tabs past first element in modal
|
|
13
|
+
// NB @Listen doesn't allow to listen on a specific element (the parent modal)
|
|
14
|
+
// if we listen to the whole doc each modal on the page reacts to every event
|
|
15
|
+
this.el.parentElement.addEventListener("focusLastElement", () => {
|
|
16
|
+
this.lastElement.focus();
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
emitParentPrimaryEvent() {
|
|
20
|
+
const parentModal = this.el.parentElement;
|
|
21
|
+
//@ts-ignore
|
|
22
|
+
parentModal.emitPrimaryEvent();
|
|
23
|
+
}
|
|
24
|
+
emitParentSecondaryEvent() {
|
|
25
|
+
const parentModal = this.el.parentElement;
|
|
26
|
+
//@ts-ignore
|
|
27
|
+
parentModal.emitSecondaryEvent();
|
|
28
|
+
}
|
|
29
|
+
render() {
|
|
30
|
+
return (h("div", { class: `wm-wrapper ${this.infoText ? " footer-text" : ""}` }, h("div", { class: "wm-info", "aria-live": "polite" }, this.infoText), h("div", { class: "wm-button-collection" }, this.secondaryText && (h("wm-button", { onClick: () => this.emitParentSecondaryEvent(), id: `wm-secondary-${this.uid}`, ref: (el) => (this.primaryActionDisabled ? (this.lastElement = el) : null) }, this.secondaryText)), h("wm-button", { "button-type": this.deleteStyle ? "secondary" : "primary", "permanently-delete": this.deleteStyle, onClick: () => this.emitParentPrimaryEvent(), disabled: this.primaryActionDisabled, id: `wm-primary-${this.uid}`, ref: (el) => (!this.primaryActionDisabled ? (this.lastElement = el) : null) }, this.primaryText))));
|
|
31
|
+
}
|
|
32
|
+
static get is() { return "wm-modal-pss-footer"; }
|
|
33
|
+
static get originalStyleUrls() {
|
|
34
|
+
return {
|
|
35
|
+
"$": ["wm-modal-pss-footer.scss"]
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
static get styleUrls() {
|
|
39
|
+
return {
|
|
40
|
+
"$": ["wm-modal-pss-footer.css"]
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
static get properties() {
|
|
44
|
+
return {
|
|
45
|
+
"secondaryText": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"mutable": false,
|
|
48
|
+
"complexType": {
|
|
49
|
+
"original": "string",
|
|
50
|
+
"resolved": "string | undefined",
|
|
51
|
+
"references": {}
|
|
52
|
+
},
|
|
53
|
+
"required": false,
|
|
54
|
+
"optional": true,
|
|
55
|
+
"docs": {
|
|
56
|
+
"tags": [],
|
|
57
|
+
"text": ""
|
|
58
|
+
},
|
|
59
|
+
"attribute": "secondary-text",
|
|
60
|
+
"reflect": false,
|
|
61
|
+
"defaultValue": "\"\""
|
|
62
|
+
},
|
|
63
|
+
"primaryText": {
|
|
64
|
+
"type": "string",
|
|
65
|
+
"mutable": false,
|
|
66
|
+
"complexType": {
|
|
67
|
+
"original": "string",
|
|
68
|
+
"resolved": "string | undefined",
|
|
69
|
+
"references": {}
|
|
70
|
+
},
|
|
71
|
+
"required": false,
|
|
72
|
+
"optional": true,
|
|
73
|
+
"docs": {
|
|
74
|
+
"tags": [],
|
|
75
|
+
"text": ""
|
|
76
|
+
},
|
|
77
|
+
"attribute": "primary-text",
|
|
78
|
+
"reflect": false,
|
|
79
|
+
"defaultValue": "\"\""
|
|
80
|
+
},
|
|
81
|
+
"infoText": {
|
|
82
|
+
"type": "string",
|
|
83
|
+
"mutable": false,
|
|
84
|
+
"complexType": {
|
|
85
|
+
"original": "string",
|
|
86
|
+
"resolved": "string | undefined",
|
|
87
|
+
"references": {}
|
|
88
|
+
},
|
|
89
|
+
"required": false,
|
|
90
|
+
"optional": true,
|
|
91
|
+
"docs": {
|
|
92
|
+
"tags": [],
|
|
93
|
+
"text": ""
|
|
94
|
+
},
|
|
95
|
+
"attribute": "info-text",
|
|
96
|
+
"reflect": false,
|
|
97
|
+
"defaultValue": "\"\""
|
|
98
|
+
},
|
|
99
|
+
"primaryActionDisabled": {
|
|
100
|
+
"type": "boolean",
|
|
101
|
+
"mutable": false,
|
|
102
|
+
"complexType": {
|
|
103
|
+
"original": "boolean",
|
|
104
|
+
"resolved": "boolean",
|
|
105
|
+
"references": {}
|
|
106
|
+
},
|
|
107
|
+
"required": false,
|
|
108
|
+
"optional": false,
|
|
109
|
+
"docs": {
|
|
110
|
+
"tags": [],
|
|
111
|
+
"text": ""
|
|
112
|
+
},
|
|
113
|
+
"attribute": "primary-action-disabled",
|
|
114
|
+
"reflect": false,
|
|
115
|
+
"defaultValue": "false"
|
|
116
|
+
},
|
|
117
|
+
"deleteStyle": {
|
|
118
|
+
"type": "boolean",
|
|
119
|
+
"mutable": false,
|
|
120
|
+
"complexType": {
|
|
121
|
+
"original": "boolean",
|
|
122
|
+
"resolved": "boolean",
|
|
123
|
+
"references": {}
|
|
124
|
+
},
|
|
125
|
+
"required": false,
|
|
126
|
+
"optional": false,
|
|
127
|
+
"docs": {
|
|
128
|
+
"tags": [],
|
|
129
|
+
"text": ""
|
|
130
|
+
},
|
|
131
|
+
"attribute": "delete-style",
|
|
132
|
+
"reflect": false,
|
|
133
|
+
"defaultValue": "false"
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
static get elementRef() { return "el"; }
|
|
138
|
+
}
|