@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.
Files changed (94) hide show
  1. package/dist/cjs/{global-d996c674.js → global-0515f81a.js} +1 -1
  2. package/dist/cjs/index-e86c28b6.js +8 -12
  3. package/dist/cjs/loader.cjs.js +2 -2
  4. package/dist/cjs/priv-option-list.cjs.entry.js +39 -20
  5. package/dist/cjs/ripple.cjs.js +2 -2
  6. package/dist/cjs/wm-modal-pss_3.cjs.entry.js +213 -0
  7. package/dist/cjs/{wm-modal.cjs.entry.js → wm-modal_3.cjs.entry.js} +73 -0
  8. package/dist/cjs/wm-nested-select.cjs.entry.js +77 -32
  9. package/dist/cjs/wm-optgroup.cjs.entry.js +7 -1
  10. package/dist/cjs/wm-option_2.cjs.entry.js +10 -12
  11. package/dist/collection/collection-manifest.json +17 -5
  12. package/dist/collection/components/selects/priv-option-list/priv-option-list.css +31 -6
  13. package/dist/collection/components/selects/priv-option-list/priv-option-list.js +65 -35
  14. package/dist/collection/components/selects/wm-nested-select/wm-nested-select.css +11 -5
  15. package/dist/collection/components/selects/wm-nested-select/wm-nested-select.js +107 -36
  16. package/dist/collection/components/selects/wm-optgroup/wm-optgroup.js +24 -1
  17. package/dist/collection/components/selects/wm-option/wm-option.css +1 -1
  18. package/dist/collection/components/selects/wm-select/wm-select.css +5 -8
  19. package/dist/collection/components/selects/wm-select/wm-select.js +12 -13
  20. package/dist/collection/components/wm-modal-pss/wm-modal-pss-footer.css +61 -0
  21. package/dist/collection/components/wm-modal-pss/wm-modal-pss-footer.js +138 -0
  22. package/dist/collection/components/wm-modal-pss/wm-modal-pss-header.css +55 -0
  23. package/dist/collection/components/wm-modal-pss/wm-modal-pss-header.js +81 -0
  24. package/dist/collection/components/wm-modal-pss/wm-modal-pss.css +134 -0
  25. package/dist/collection/components/wm-modal-pss/wm-modal-pss.js +361 -0
  26. package/dist/esm/{global-dcf80bdb.js → global-a9138d5f.js} +1 -1
  27. package/dist/esm/index-558b5a82.js +8 -12
  28. package/dist/esm/loader.js +2 -2
  29. package/dist/esm/priv-option-list.entry.js +39 -20
  30. package/dist/esm/ripple.js +2 -2
  31. package/dist/esm/wm-modal-pss_3.entry.js +207 -0
  32. package/dist/esm/{wm-modal.entry.js → wm-modal_3.entry.js} +73 -2
  33. package/dist/esm/wm-nested-select.entry.js +78 -33
  34. package/dist/esm/wm-optgroup.entry.js +7 -1
  35. package/dist/esm/wm-option_2.entry.js +10 -12
  36. package/dist/esm-es5/global-a9138d5f.js +1 -0
  37. package/dist/esm-es5/index-558b5a82.js +1 -1
  38. package/dist/esm-es5/loader.js +1 -1
  39. package/dist/esm-es5/priv-option-list.entry.js +1 -1
  40. package/dist/esm-es5/ripple.js +1 -1
  41. package/dist/esm-es5/wm-modal-pss_3.entry.js +1 -0
  42. package/dist/esm-es5/wm-modal_3.entry.js +1 -0
  43. package/dist/esm-es5/wm-nested-select.entry.js +1 -1
  44. package/dist/esm-es5/wm-optgroup.entry.js +1 -1
  45. package/dist/esm-es5/wm-option_2.entry.js +1 -1
  46. package/dist/ripple/p-012cab20.entry.js +1 -0
  47. package/dist/ripple/p-02deae76.entry.js +1 -0
  48. package/dist/ripple/p-1d18d9d2.system.entry.js +1 -0
  49. package/dist/ripple/p-225f55fa.system.js +1 -0
  50. package/dist/ripple/p-226fe4e0.entry.js +1 -0
  51. package/dist/ripple/p-5fbe6e5e.system.js +1 -0
  52. package/dist/ripple/p-6e725656.system.entry.js +1 -0
  53. package/dist/ripple/p-6fdfe9f4.system.entry.js +1 -0
  54. package/dist/ripple/p-aecf9a22.entry.js +1 -0
  55. package/dist/ripple/p-bf7d98d8.entry.js +1 -0
  56. package/dist/ripple/p-bfae6907.js +1 -0
  57. package/dist/ripple/p-c1714e14.system.entry.js +1 -0
  58. package/dist/ripple/p-cff5d7e9.system.entry.js +1 -0
  59. package/dist/ripple/p-f13b034e.entry.js +1 -0
  60. package/dist/ripple/{p-54d9e467.system.entry.js → p-f4bcee58.system.entry.js} +1 -1
  61. package/dist/ripple/ripple.esm.js +1 -1
  62. package/dist/ripple/ripple.js +1 -1
  63. package/dist/types/components/selects/priv-option-list/priv-option-list.d.ts +6 -2
  64. package/dist/types/components/selects/wm-nested-select/wm-nested-select.d.ts +8 -5
  65. package/dist/types/components/selects/wm-optgroup/wm-optgroup.d.ts +1 -0
  66. package/dist/types/components/selects/wm-select/wm-select.d.ts +2 -2
  67. package/dist/types/components/wm-modal-pss/wm-modal-pss-footer.d.ts +14 -0
  68. package/dist/types/components/wm-modal-pss/wm-modal-pss-header.d.ts +10 -0
  69. package/dist/types/components.d.ts +98 -5
  70. package/package.json +1 -1
  71. package/dist/cjs/wm-modal-footer.cjs.entry.js +0 -47
  72. package/dist/cjs/wm-modal-header.cjs.entry.js +0 -39
  73. package/dist/esm/wm-modal-footer.entry.js +0 -43
  74. package/dist/esm/wm-modal-header.entry.js +0 -35
  75. package/dist/esm-es5/global-dcf80bdb.js +0 -1
  76. package/dist/esm-es5/wm-modal-footer.entry.js +0 -1
  77. package/dist/esm-es5/wm-modal-header.entry.js +0 -1
  78. package/dist/esm-es5/wm-modal.entry.js +0 -1
  79. package/dist/ripple/p-0c259c1a.system.entry.js +0 -1
  80. package/dist/ripple/p-13f51c06.entry.js +0 -1
  81. package/dist/ripple/p-1c170fb3.entry.js +0 -1
  82. package/dist/ripple/p-294b38ca.system.entry.js +0 -1
  83. package/dist/ripple/p-3568472c.entry.js +0 -1
  84. package/dist/ripple/p-45dc49e8.entry.js +0 -1
  85. package/dist/ripple/p-50388b6f.system.entry.js +0 -1
  86. package/dist/ripple/p-54f7d3d4.system.entry.js +0 -1
  87. package/dist/ripple/p-618300c1.entry.js +0 -1
  88. package/dist/ripple/p-76ff5d91.entry.js +0 -1
  89. package/dist/ripple/p-84603f1f.system.entry.js +0 -1
  90. package/dist/ripple/p-99058787.entry.js +0 -1
  91. package/dist/ripple/p-b176c143.system.entry.js +0 -1
  92. package/dist/ripple/p-c6a336d6.system.js +0 -1
  93. package/dist/ripple/p-e209a933.js +0 -1
  94. package/dist/ripple/p-ee4fee7d.system.js +0 -1
@@ -0,0 +1,213 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const index = require('./index-e86c28b6.js');
6
+
7
+ const wmModalPssCss = "wm-modal-pss{--wmcolor-modal-background:var(--wmcolor-background);--wmcolor-modal-border:var(--wmcolor-border);--wmcolor-modal-heading:var(--wmcolor-text);--wmcolor-modal-overlay:var(--wmcolor-overlay);display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;-ms-flex-direction:column;flex-direction:column;position:fixed;top:50%;left:50%;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);z-index:2001;width:80vw;max-width:750px;max-height:80vh;-webkit-box-shadow:0px 11px 15px 0px rgba(0, 0, 0, 0.2), 0px 9px 46px 8px rgba(0, 0, 0, 0.12), 0px 24px 38px 3px rgba(0, 0, 0, 0.14);box-shadow:0px 11px 15px 0px rgba(0, 0, 0, 0.2), 0px 9px 46px 8px rgba(0, 0, 0, 0.12), 0px 24px 38px 3px rgba(0, 0, 0, 0.14)}wm-modal-pss *{-webkit-box-sizing:border-box;box-sizing:border-box}wm-modal-pss>*{width:80vw;max-width:750px;background:var(--wmcolor-modal-background)}wm-modal-pss>*:focus{outline:none}wm-modal-pss wm-modal-pss-header,wm-modal-pss wm-modal-pss-footer{padding:20px 30px}wm-modal-pss wm-modal-pss-header{z-index:2003}wm-modal-pss wm-modal-pss-footer{z-index:2003}wm-modal-pss>:not(wm-modal-pss-header):not(wm-modal-pss-footer){max-height:calc(80vh - 166px);z-index:2002}wm-modal-pss.wm-modal wm-modal-pss-header{border-bottom:1px solid var(--wmcolor-modal-border)}wm-modal-pss.wm-modal wm-modal-pss-footer{border-top:1px solid var(--wmcolor-modal-border)}@media only screen and (max-width: 768px){wm-modal-pss.wm-modal{height:100%;max-height:none;max-width:none;width:100vw}wm-modal-pss.wm-modal>*{max-width:none;width:100vw}wm-modal-pss.wm-modal>*:not(wm-modal-pss-header):not(wm-modal-pss-footer){max-height:none;height:calc(100vh - 166px)}}wm-modal-pss.wm-dialog>:not(wm-modal-pss-header):not(wm-modal-pss-footer){padding:0 30px 20px 30px;font-size:0.875rem;border:none}wm-modal-pss .overlay{width:100vw;height:100vh;max-width:none;max-height:none;position:fixed !important;top:-1;bottom:1;left:-1;right:1;-webkit-transform:translate(0%, 0%);transform:translate(0%, 0%);background-color:var(--wmcolor-modal-overlay);-webkit-transition:opacity 0.5s ease-out;transition:opacity 0.5s ease-out;z-index:2000}wm-modal-pss.hide{visibility:hidden}wm-modal-pss .sr-only{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;border:0 !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;white-space:nowrap !important;margin:-1px !important;top:0;left:0}";
8
+
9
+ const Modal = class {
10
+ constructor(hostRef) {
11
+ index.registerInstance(this, hostRef);
12
+ this.focusLastElement = index.createEvent(this, "focusLastElement", 3);
13
+ this.focusFirstElement = index.createEvent(this, "focusFirstElement", 3);
14
+ this.wmModalCloseTriggered = index.createEvent(this, "wmModalCloseTriggered", 3);
15
+ this.wmModalPrimaryTriggered = index.createEvent(this, "wmModalPrimaryTriggered", 7);
16
+ this.wmModalSecondaryTriggered = index.createEvent(this, "wmModalSecondaryTriggered", 7);
17
+ this.bodyFocusListener = () => this.redirectFocusFromBody();
18
+ this.open = false;
19
+ this.elementToFocus = "";
20
+ this.modalType = "modal";
21
+ this.uid = undefined;
22
+ }
23
+ get focusOnOpenEl() {
24
+ let customElementToFocus = null;
25
+ if (this.elementToFocus === "primary" || this.elementToFocus === "secondary") {
26
+ customElementToFocus = this.el.querySelector(`#wm-${this.elementToFocus}-${this.uid}`);
27
+ }
28
+ else if (this.elementToFocus) {
29
+ customElementToFocus = this.el.querySelector("#" + this.elementToFocus);
30
+ !customElementToFocus &&
31
+ console.warn("Ripple Component Library: The modal component couldn't find an element matching the id you passed for 'elementToFocus'. It will fall back to the default and focus the close button when the modal opens.");
32
+ }
33
+ const closeButtonEl = this.el.querySelector(`#wm-modal-close-${this.uid}`);
34
+ return customElementToFocus ? customElementToFocus : closeButtonEl;
35
+ }
36
+ //App can open modal by toggling the prop
37
+ toggleModal() {
38
+ this.open ? this.showModal() : this.hideModal();
39
+ }
40
+ handleClick(ev) {
41
+ this.open && ev.target === this.overlayEl && this.focusOnOpenEl.focus();
42
+ }
43
+ closeModalOnEscape(ev) {
44
+ if (ev.key === "Escape") {
45
+ // stops propagation prevents nested modal from closing all at once
46
+ ev.stopPropagation();
47
+ this.wmModalCloseTriggered.emit();
48
+ this.open = false;
49
+ }
50
+ }
51
+ showModal() {
52
+ this.setAriaDescribedbyOnModal();
53
+ this.setElToFocusOnClose(); //Record where the user was before the modal opened so that focus can return to it when the modal closes
54
+ document.body.style.overflow = "hidden"; //Keeps the page below the modal from scrolling
55
+ //Focus listeners as a general catch for keeping focus in case of errors in finding element with id passed in by dev (element is removed from DOM, etc.) or other scenarios
56
+ document.body.tabIndex = 0;
57
+ document.body.removeEventListener("focus", this.bodyFocusListener, true);
58
+ document.body.addEventListener("focus", this.bodyFocusListener, true);
59
+ window.requestAnimationFrame(() => {
60
+ // nested requestAnimationFrames allow all elements to become visible on page before assigning focus
61
+ window.requestAnimationFrame(() => this.focusOnOpenEl.focus()); //Bring focus to element inside modal
62
+ });
63
+ }
64
+ //Close the modal and focus the triggering element when the modal buttons emit their events
65
+ hideModal() {
66
+ document.body.style.overflow = "visible";
67
+ document.body.tabIndex = -1;
68
+ document.body.removeEventListener("focus", this.bodyFocusListener, true);
69
+ window.requestAnimationFrame(() => this.focusOnCloseEl.focus()); //Return focus
70
+ }
71
+ componentWillLoad() {
72
+ if (this.elementToFocus === "primary" || this.elementToFocus === "secondary") {
73
+ if (!this.el.id) {
74
+ console.error("For accessibility purposes, you need to set the modal content wrapper's id to 'content-[id of wm-modal-pss]'.");
75
+ }
76
+ }
77
+ this.el.focus = () => {
78
+ this.focusOnOpenEl.focus();
79
+ };
80
+ const generatedId = "wmcl-" + Math.random().toString(36).substr(2, 10);
81
+ this.uid = this.el.id ? this.el.id : generatedId;
82
+ }
83
+ componentDidLoad() {
84
+ if (this.open) {
85
+ this.showModal();
86
+ }
87
+ }
88
+ async emitCloseEvent() {
89
+ this.wmModalCloseTriggered.emit();
90
+ }
91
+ async emitPrimaryEvent() {
92
+ this.wmModalPrimaryTriggered.emit();
93
+ }
94
+ async emitSecondaryEvent() {
95
+ this.wmModalSecondaryTriggered.emit();
96
+ }
97
+ setAriaDescribedbyOnModal() {
98
+ const modalBody = document.getElementById(`content-${this.uid}`);
99
+ if (!modalBody) {
100
+ console.warn("Ripple Component Library: The element containing the body of the modal must include an id in the format 'content-[id of modal]' for accessibility purposes.");
101
+ }
102
+ else {
103
+ this.el.setAttribute("aria-describedby", `wm-modal-heading-text-${this.uid} content-${this.uid}`);
104
+ }
105
+ }
106
+ setElToFocusOnClose() {
107
+ const elToFocus = document.activeElement;
108
+ if (elToFocus.tagName === "WM-MENUITEM") {
109
+ this.focusOnCloseEl = elToFocus.parentElement;
110
+ }
111
+ else {
112
+ let el;
113
+ while (elToFocus && elToFocus.shadowRoot) {
114
+ el = elToFocus.shadowRoot.activeElement;
115
+ }
116
+ if (el) {
117
+ this.focusOnCloseEl = el;
118
+ }
119
+ }
120
+ }
121
+ redirectFocusFromBody() {
122
+ if (document.activeElement.tagName === "BODY") {
123
+ this.focusOnOpenEl.focus();
124
+ }
125
+ }
126
+ render() {
127
+ return (index.h(index.Host, { class: `${this.open ? "" : "hide "}${"wm-" + this.modalType}`, role: "dialog", "aria-describedby": `wm-modal-heading-text-${this.uid}`, "aria-modal": "true", tabindex: this.open ? 0 : null, onFocus: () => {
128
+ this.focusLastElement.emit();
129
+ } }, index.h("div", { class: "overlay", ref: (el) => (this.overlayEl = el) }), index.h("div", { class: "sr-only", tabIndex: 0, onFocus: () => {
130
+ this.focusFirstElement.emit();
131
+ } })));
132
+ }
133
+ get el() { return index.getElement(this); }
134
+ static get watchers() { return {
135
+ "open": ["toggleModal"]
136
+ }; }
137
+ };
138
+ Modal.style = wmModalPssCss;
139
+
140
+ const wmModalPssFooterCss = "wm-modal-pss-footer{border-radius:0px 0px 5px 5px;margin-top:-1px}wm-modal-pss-footer .wm-wrapper{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:center;align-items:center}@media only screen and (max-width: 650px){wm-modal-pss-footer .wm-wrapper.footer-text{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start}}wm-modal-pss-footer .wm-wrapper wm-button+wm-button{margin-left:1rem}wm-modal-pss-footer .wm-wrapper .wm-info{font-size:0.875rem;font-style:italic}@media only screen and (max-width: 650px){wm-modal-pss-footer .wm-wrapper .wm-info{padding-bottom:0.625rem}}wm-modal-pss-footer .wm-wrapper .wm-info:focus{outline:none}";
141
+
142
+ const ModalFooter = class {
143
+ constructor(hostRef) {
144
+ index.registerInstance(this, hostRef);
145
+ this.secondaryText = "";
146
+ this.primaryText = "";
147
+ this.infoText = "";
148
+ this.primaryActionDisabled = false;
149
+ this.deleteStyle = false;
150
+ }
151
+ componentWillLoad() {
152
+ this.uid = this.el.parentElement.uid;
153
+ // Trap focus when user shift+tabs past first element in modal
154
+ // NB @Listen doesn't allow to listen on a specific element (the parent modal)
155
+ // if we listen to the whole doc each modal on the page reacts to every event
156
+ this.el.parentElement.addEventListener("focusLastElement", () => {
157
+ this.lastElement.focus();
158
+ });
159
+ }
160
+ emitParentPrimaryEvent() {
161
+ const parentModal = this.el.parentElement;
162
+ //@ts-ignore
163
+ parentModal.emitPrimaryEvent();
164
+ }
165
+ emitParentSecondaryEvent() {
166
+ const parentModal = this.el.parentElement;
167
+ //@ts-ignore
168
+ parentModal.emitSecondaryEvent();
169
+ }
170
+ render() {
171
+ return (index.h("div", { class: `wm-wrapper ${this.infoText ? " footer-text" : ""}` }, index.h("div", { class: "wm-info", "aria-live": "polite" }, this.infoText), index.h("div", { class: "wm-button-collection" }, this.secondaryText && (index.h("wm-button", { onClick: () => this.emitParentSecondaryEvent(), id: `wm-secondary-${this.uid}`, ref: (el) => (this.primaryActionDisabled ? (this.lastElement = el) : null) }, this.secondaryText)), index.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))));
172
+ }
173
+ get el() { return index.getElement(this); }
174
+ };
175
+ ModalFooter.style = wmModalPssFooterCss;
176
+
177
+ const wmModalPssHeaderCss = "wm-modal-pss-header{border-radius:5px 5px 0 0px;margin-bottom:-1px}wm-modal-pss-header .wm-wrapper{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-align:center;align-items:center}wm-modal-pss-header .wm-wrapper .title{margin:0;font-weight:600;font-size:1.125rem;color:var(--wmcolor-modal-heading);line-height:normal}wm-modal-pss-header .wm-wrapper .title .subtitle{display:block;font-size:0.875rem;font-weight:normal}wm-modal-pss-header .wm-wrapper .title:focus{outline:none}";
178
+
179
+ const ModalHeader = class {
180
+ constructor(hostRef) {
181
+ index.registerInstance(this, hostRef);
182
+ this.heading = "";
183
+ this.subheading = "";
184
+ }
185
+ componentWillLoad() {
186
+ this.uid = this.el.parentElement.uid;
187
+ // Trap focus when user tabs past last element in modal
188
+ // NB @Listen doesn't allow to listen on a specific element (the parent modal)
189
+ // if we listen to the whole doc each modal on the page reacts to every event
190
+ this.el.parentElement.addEventListener("focusFirstElement", () => {
191
+ this.closeButtonEl.focus();
192
+ });
193
+ }
194
+ emitParentCloseEvent() {
195
+ const parentModal = this.el.parentElement;
196
+ //@ts-ignore
197
+ parentModal.emitCloseEvent();
198
+ }
199
+ // @Listen("click")
200
+ // directFocusOnClick() {
201
+ // this.headingElement.tabIndex = 0;
202
+ // this.headingElement.focus();
203
+ // }
204
+ render() {
205
+ return (index.h(index.Host, null, index.h("div", { class: "wm-wrapper" }, index.h("div", null, index.h("h2", { class: "title", id: `wm-modal-heading-text-${this.uid}` }, this.heading, index.h("span", { class: "subtitle" }, this.subheading))), index.h("wm-button", { "button-type": "navigational", icon: "f156", tooltip: "Close", "tooltip-position": "left", id: `wm-modal-close-${this.uid}`, ref: (el) => (this.closeButtonEl = el), onClick: () => this.emitParentCloseEvent() }))));
206
+ }
207
+ get el() { return index.getElement(this); }
208
+ };
209
+ ModalHeader.style = wmModalPssHeaderCss;
210
+
211
+ exports.wm_modal_pss = Modal;
212
+ exports.wm_modal_pss_footer = ModalFooter;
213
+ exports.wm_modal_pss_header = ModalHeader;
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const index = require('./index-e86c28b6.js');
6
6
  const functions = require('./functions-e24249e6.js');
7
+ const intl = require('./intl-5aeba788.js');
7
8
 
8
9
  const wmModalCss = "wm-modal{--wmcolor-modal-background:var(--wmcolor-background);--wmcolor-modal-border:var(--wmcolor-border);--wmcolor-modal-heading:var(--wmcolor-text);--wmcolor-modal-overlay:var(--wmcolor-overlay)}wm-modal *{-webkit-box-sizing:border-box;box-sizing:border-box}wm-modal dialog{color:inherit;padding:0;width:80vw;max-width:750px;max-height:80vh;-webkit-border-radius:5px 5px 5px 5px;-moz-border-radius:5px 5px 5px 5px;-ms-border-radius:5px 5px 5px 5px;border-radius:5px 5px 5px 5px;border:none;background:var(--wmcolor-modal-background)}wm-modal dialog>:not(wm-modal-header):not(wm-modal-footer){max-height:calc(80vh - 166px)}wm-modal dialog::-webkit-backdrop{background:rgba(25, 25, 25, 0.4)}wm-modal dialog::-ms-backdrop{background:rgba(25, 25, 25, 0.4)}wm-modal dialog::backdrop{background:rgba(25, 25, 25, 0.4)}wm-modal dialog[open]{-webkit-box-shadow:0px 11px 15px 0px rgba(0, 0, 0, 0.2), 0px 9px 46px 8px rgba(0, 0, 0, 0.12), 0px 24px 38px 3px rgba(0, 0, 0, 0.14);-moz-box-shadow:0px 11px 15px 0px rgba(0, 0, 0, 0.2), 0px 9px 46px 8px rgba(0, 0, 0, 0.12), 0px 24px 38px 3px rgba(0, 0, 0, 0.14);box-shadow:0px 11px 15px 0px rgba(0, 0, 0, 0.2), 0px 9px 46px 8px rgba(0, 0, 0, 0.12), 0px 24px 38px 3px rgba(0, 0, 0, 0.14)}wm-modal dialog.wm-modal>wm-modal-header{border-bottom:1px solid var(--wmcolor-modal-border)}wm-modal dialog.wm-modal>wm-modal-footer{border-top:1px solid var(--wmcolor-modal-border)}@media only screen and (max-width: 768px){wm-modal dialog.wm-modal{height:100%;max-height:none;max-width:none;width:100vw}wm-modal dialog.wm-modal>*{max-width:none;width:100vw}wm-modal dialog.wm-modal>*:not(wm-modal-header):not(wm-modal-footer){max-height:none;height:calc(100vh - 166px)}}wm-modal dialog.wm-dialog>:not(wm-modal-header):not(wm-modal-footer):not(.wm-tooltip){padding:0 1.875rem 1.25rem 1.875rem;font-size:0.875rem;border:none}wm-modal wm-modal-header,wm-modal wm-modal-footer{padding:1.25rem 1.875rem;width:100%}wm-modal .sr-only{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;border:0 !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;white-space:nowrap !important;margin:-1px !important;top:0;left:0}";
9
10
 
@@ -136,4 +137,76 @@ const Modal = class {
136
137
  };
137
138
  Modal.style = wmModalCss;
138
139
 
140
+ const wmModalFooterCss = "wm-modal-footer{display:block;-webkit-border-radius:0px 0px 5px 5px;-moz-border-radius:0px 0px 5px 5px;-ms-border-radius:0px 0px 5px 5px;border-radius:0px 0px 5px 5px}wm-modal-footer .wm-wrapper{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}@media only screen and (max-width: 650px){wm-modal-footer .wm-wrapper.footer-text{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start}}wm-modal-footer .wm-wrapper wm-button+wm-button{margin-left:1rem}wm-modal-footer .wm-wrapper .wm-info{font-size:0.875rem;font-style:italic}@media only screen and (max-width: 650px){wm-modal-footer .wm-wrapper .wm-info{padding-bottom:0.625rem}}wm-modal-footer .wm-wrapper .wm-info:focus{outline:none}";
141
+
142
+ const ModalFooter = class {
143
+ constructor(hostRef) {
144
+ index.registerInstance(this, hostRef);
145
+ this.secondaryText = "";
146
+ this.primaryText = "";
147
+ this.infoText = "";
148
+ this.primaryActionDisabled = false;
149
+ this.deleteStyle = false;
150
+ }
151
+ componentWillLoad() {
152
+ const parentModal = this.el.closest("wm-modal");
153
+ this.uid = parentModal.uid;
154
+ // Trap focus when user shift+tabs past first element in modal
155
+ // NB @Listen doesn't allow to listen on a specific element (the parent modal)
156
+ // if we listen to the whole doc each modal on the page reacts to every event
157
+ parentModal.addEventListener("focusLastElement", () => {
158
+ this.lastElement.focus();
159
+ });
160
+ }
161
+ emitParentPrimaryEvent() {
162
+ const parentModal = this.el.closest("wm-modal");
163
+ if (parentModal) {
164
+ parentModal.emitPrimaryEvent();
165
+ }
166
+ }
167
+ emitParentSecondaryEvent() {
168
+ const parentModal = this.el.closest("wm-modal");
169
+ if (parentModal) {
170
+ parentModal.emitSecondaryEvent();
171
+ }
172
+ }
173
+ render() {
174
+ return (index.h("div", { class: `wm-wrapper ${this.infoText ? " footer-text" : ""}` }, index.h("div", { class: "wm-info", "aria-live": "polite" }, this.infoText), index.h("div", { class: "wm-button-collection" }, this.secondaryText && (index.h("wm-button", { onClick: () => this.emitParentSecondaryEvent(), id: `wm-secondary-${this.uid}`, ref: (el) => (this.primaryActionDisabled ? (this.lastElement = el) : undefined) }, this.secondaryText)), index.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) : undefined) }, this.primaryText))));
175
+ }
176
+ get el() { return index.getElement(this); }
177
+ };
178
+ ModalFooter.style = wmModalFooterCss;
179
+
180
+ const wmModalHeaderCss = "wm-modal-header{display:block;-webkit-border-radius:5px 5px 0 0px;-moz-border-radius:5px 5px 0 0px;-ms-border-radius:5px 5px 0 0px;border-radius:5px 5px 0 0px}wm-modal-header .wm-wrapper{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}wm-modal-header .wm-wrapper .title{margin:0;font-weight:600;font-size:1.125rem;color:var(--wmcolor-modal-heading);line-height:normal}wm-modal-header .wm-wrapper .title .subtitle{display:block;font-size:0.875rem;font-weight:normal}wm-modal-header .wm-wrapper .title:focus{outline:none}";
181
+
182
+ const ModalHeader = class {
183
+ constructor(hostRef) {
184
+ index.registerInstance(this, hostRef);
185
+ this.heading = "";
186
+ this.subheading = "";
187
+ }
188
+ componentWillLoad() {
189
+ const parentModal = this.el.closest("wm-modal");
190
+ this.uid = parentModal.uid;
191
+ // Trap focus when user tabs past last element in modal
192
+ // NB @Listen doesn't allow to listen on a specific element (the parent modal)
193
+ // if we listen to the whole doc each modal on the page reacts to every event
194
+ parentModal.addEventListener("focusFirstElement", () => {
195
+ this.closeButtonEl.focus();
196
+ });
197
+ }
198
+ emitParentCloseEvent() {
199
+ const parentModal = this.el.closest("wm-modal");
200
+ //@ts-ignore
201
+ parentModal.emitCloseEvent();
202
+ }
203
+ render() {
204
+ return (index.h(index.Host, null, index.h("div", { class: "wm-wrapper" }, index.h("div", null, index.h("h2", { class: "title", id: `wm-modal-heading-text-${this.uid}` }, this.heading, index.h("span", { class: "subtitle" }, this.subheading))), index.h("wm-button", { "button-type": "navigational", icon: "f156", tooltip: intl.globalMessages.close, "tooltip-position": "left", id: `wm-modal-close-${this.uid}`, ref: (el) => (this.closeButtonEl = el), onClick: () => this.emitParentCloseEvent() }))));
205
+ }
206
+ get el() { return index.getElement(this); }
207
+ };
208
+ ModalHeader.style = wmModalHeaderCss;
209
+
139
210
  exports.wm_modal = Modal;
211
+ exports.wm_modal_footer = ModalFooter;
212
+ exports.wm_modal_header = ModalHeader;
@@ -6,7 +6,7 @@ const index = require('./index-e86c28b6.js');
6
6
  const functions = require('./functions-e24249e6.js');
7
7
  const intl = require('./intl-5aeba788.js');
8
8
 
9
- const wmNestedSelectCss = ":host{--wmcolor-select-background:var(--wmcolor-background);--wmcolor-select-border:var(--wmcolor-input-border);--wmcolor-select-option-background-disabled:var(--wmcolor-option-background-disabled);--wmcolor-select-option-background-focus:var(--wmcolor-option-background-focus);--wmcolor-select-option-background-hover:var(--wmcolor-option-background-hover);--wmcolor-select-option-background-selected:var(--wmcolor-option-background-selected);--wmcolor-select-option-background:var(--wmcolor-option-background);--wmcolor-select-option-border:var(--wmcolor-option-border);--wmcolor-select-option-text-disabled:var(--wmcolor-option-text-disabled);--wmcolor-select-option-text:var(--wmcolor-option-text);--wmcolor-select-search-border:var(--wmcolor-input-border);--wmcolor-select-search-icon:var(--wmcolor-icon-accent);--wmcolor-select-searchresults-text:var(--wmcolor-text);--wmcolor-select-selectall-background:var(--wmcolor-select-option-background);--wmcolor-select-selectall-border:var(--wmcolor-select-option-border);--wmcolor-select-selectall-text:var(--wmcolor-interactive);--wmcolor-select-text:var(--wmcolor-interactive);position:relative;display:block;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:inherit}.wrapper{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;font-size:0.875rem}.wrapper .label{display:block;line-height:normal;font-weight:600;white-space:nowrap;margin-bottom:0.25rem}.wrapper .label .required{color:var(--wmcolor-text-required)}.wrapper.label-left{-ms-flex-direction:row;flex-direction:row}.wrapper.label-left .label-wrapper{line-height:2.5rem}.wrapper.label-left .label-wrapper .label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:2.5rem;white-space:normal;margin-bottom:0;margin-right:0.75rem}.wrapper.label-none label{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;border:0 !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;white-space:nowrap !important;margin:-1px !important}.wrapper.invalid .label{color:var(--wmcolor-text-error)}.wrapper.invalid .label:after{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f026\";margin-left:0.3125rem}[dir=RTL] .wrapper.invalid .label:after{margin-left:0;margin-right:0.3125rem}.wrapper.rtl.label-left .label{margin-right:0;margin-left:0.75rem}.button-wrapper{position:relative;-ms-flex:1;flex:1;font-size:1.125rem;color:var(--wmcolor-select-text);min-width:8.75rem}.button-wrapper .displayedoption{-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-wrap:nowrap;flex-wrap:nowrap;background:var(--wmcolor-select-background);width:100%;border:solid 1px;border-color:var(--wmcolor-select-border);padding:0 1.875rem 0 0.9375rem;cursor:pointer;height:2.5rem;line-height:normal;font-family:inherit;color:var(--wmcolor-select-text);font-weight:400;font-size:0.875rem;text-transform:none;text-align:left}@media only screen and (max-width: 768px){.button-wrapper .displayedoption{height:2.75rem}}.button-wrapper .displayedoption:before{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f140\";position:absolute;right:0.5625rem;pointer-events:none;font-size:1.12rem}.button-wrapper .displayedoption.expanded:before{content:\"\\f143\"}.button-wrapper .displayedoption:hover:not(:disabled):not(.-disabled):not(.-raised){background:var(--wmcolor-select-background);text-decoration:none}.button-wrapper .displayedoption:active{-ms-transform:scale(1, 1) !important;-webkit-transform:scale(1, 1) !important;transform:scale(1, 1) !important}.button-wrapper .displayedoption:focus{outline:none}.button-wrapper .displayedoption::-moz-focus-inner{border:0}.button-wrapper .displayedoption:focus-visible{outline:3px solid var(--wmcolor-interactive-focus);outline-offset:2px}.button-wrapper .displayedoption .overflowcontrol{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;-ms-flex:1;flex:1}.button-wrapper .displayedoption .overflowcontrol.hassubinfo{display:-ms-flexbox;display:flex}.button-wrapper .displayedoption .overflowcontrol.hassubinfo .button-text{-ms-flex:1;flex:1;text-overflow:ellipsis;overflow:hidden;min-width:0}.button-wrapper .displayedoption .overflowcontrol.hassubinfo .subinfo{-ms-flex:none;flex:none;font-style:italic}.button-wrapper .displayedoption .overflow-counter{font-weight:bold;margin-left:0.5rem}.button-wrapper>.displayedoption[disabled]{color:#6b6b6b;border-color:#8a8a8a;background:#f0f0f0;cursor:default}.wrapper.invalid .button-wrapper .displayedoption{-webkit-box-shadow:0 0 0 1px var(--wmcolor-input-border-error);-moz-box-shadow:0 0 0 1px var(--wmcolor-input-border-error);box-shadow:0 0 0 1px var(--wmcolor-input-border-error);border-color:var(--wmcolor-input-border-error)}.wrapper .error-message{display:block;font-style:italic;color:var(--wmcolor-text-error);font-size:0.875rem;margin-bottom:0.25rem;top:100%;left:0}.wrapper .error-message:not(:empty){margin-top:0.25rem}.dropdown{overflow-x:hidden;overflow-y:auto;-ms-transition:transform 0.25s ease;-webkit-transition:transform 0.25s ease;-moz-transition:transform 0.25s ease;-webkit-transition:-webkit-transform 0.25s ease;transition:-webkit-transform 0.25s ease;transition:transform 0.25s ease;transition:transform 0.25s ease, -webkit-transform 0.25s ease;-ms-transform-origin:center top;-webkit-transform-origin:center top;-moz-transform-origin:center top;transform-origin:center top;transform:scale(1, 0);-webkit-overflow-scrolling:touch;-webkit-box-shadow:0 4px 15px 0 rgba(0, 0, 0, 0.2);-moz-box-shadow:0 4px 15px 0 rgba(0, 0, 0, 0.2);box-shadow:0 4px 15px 0 rgba(0, 0, 0, 0.2);-ms-transition:transform 0.25s ease;-webkit-transition:transform 0.25s ease;-moz-transition:transform 0.25s ease;transition:transform 0.25s ease;-ms-transform:scale(1, 0);-webkit-transform:scale(1, 0);-moz-transform:scale(1, 0);transform:scale(1, 0);-ms-transform-origin:center top;-webkit-transform-origin:center top;-moz-transform-origin:center top;transform-origin:center top;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;position:absolute;top:40;right:0;background:var(--wmcolor-select-option-background);z-index:100;width:100%;font-size:0.875rem}.dropdown.upwards{top:unset;bottom:100%;-ms-transform-origin:center bottom;-webkit-transform-origin:center bottom;-moz-transform-origin:center bottom;transform-origin:center bottom}.dropdown.hidden{visibility:hidden}.dropdown.open{-ms-transform:scale(1, 1);-webkit-transform:scale(1, 1);-moz-transform:scale(1, 1);transform:scale(1, 1)}.menu{width:100%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.menu.hidden{position:absolute}.menu .menuitem{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;cursor:pointer;position:relative;padding:1.25rem;background:var(--wmcolor-select-option-background);font-family:inherit;list-style:none;color:var(--wmcolor-select-option-text);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:none;font-weight:600}.menu .menuitem:not(:last-child){border-bottom:2px solid;border-color:var(--wmcolor-select-option-border)}.menu .menuitem.disabled{color:var(--wmcolor-select-option-text-disabled);cursor:auto}.menu .menuitem.clear-selection{color:var(--wmcolor-select-text);-ms-flex-pack:start;justify-content:start;-ms-flex-align:center;align-items:center}.menu .menuitem.clear-selection:before{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f156\";pointer-events:none;padding-right:0.5rem;font-size:1.12rem}.menu :focus{outline:none;background:var(--wmcolor-interactive-background-focus)}.menu :hover{background:var(--wmcolor-select-option-background-hover);outline:none}.group-btn:before{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f142\";position:absolute;right:1.25rem;pointer-events:none;font-size:1.12rem}.group-btn.disabled{background:var(--wmcolor-select-option-background-disabled)}.selection-count,.disabled-indication{margin-right:40px;font-weight:400;font-style:italic}.disabled-indication{color:var(--wmcolor-interactive-disabled)}.option-list-wrapper{background:white;width:100%;-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transition:-webkit-transform 0.2s cubic-bezier(0.04, 0, 0.2, 1);transition:-webkit-transform 0.2s cubic-bezier(0.04, 0, 0.2, 1);transition:transform 0.2s cubic-bezier(0.04, 0, 0.2, 1);transition:transform 0.2s cubic-bezier(0.04, 0, 0.2, 1), -webkit-transform 0.2s cubic-bezier(0.04, 0, 0.2, 1)}.option-list-wrapper.hidden{-webkit-transform:translateX(100%);transform:translateX(100%);position:absolute;top:0px}.measurement-area{position:absolute;visibility:hidden;height:0px;pointer-events:none}.sr-only{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;border:0 !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;white-space:nowrap !important;margin:-1px !important}";
9
+ const wmNestedSelectCss = ":host{--wmcolor-select-background:var(--wmcolor-background);--wmcolor-select-border:var(--wmcolor-input-border);--wmcolor-select-option-background-disabled:var(--wmcolor-option-background-disabled);--wmcolor-select-option-background-focus:var(--wmcolor-option-background-focus);--wmcolor-select-option-background-hover:var(--wmcolor-option-background-hover);--wmcolor-select-option-background-selected:var(--wmcolor-option-background-selected);--wmcolor-select-option-background:var(--wmcolor-option-background);--wmcolor-select-option-border:var(--wmcolor-option-border);--wmcolor-select-option-text-disabled:var(--wmcolor-option-text-disabled);--wmcolor-select-option-text:var(--wmcolor-option-text);--wmcolor-select-search-border:var(--wmcolor-input-border);--wmcolor-select-search-icon:var(--wmcolor-icon-accent);--wmcolor-select-searchresults-text:var(--wmcolor-text);--wmcolor-select-selectall-background:var(--wmcolor-select-option-background);--wmcolor-select-selectall-border:var(--wmcolor-select-option-border);--wmcolor-select-selectall-text:var(--wmcolor-interactive);--wmcolor-select-text:var(--wmcolor-interactive);position:relative;display:block;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:inherit}.wrapper{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;font-size:0.875rem}.wrapper .label{display:block;line-height:normal;font-weight:600;white-space:nowrap;margin-bottom:0.25rem}.wrapper .label .required{color:var(--wmcolor-text-required)}.wrapper.label-left{-ms-flex-direction:row;flex-direction:row}.wrapper.label-left .label-wrapper{line-height:2.5rem}.wrapper.label-left .label-wrapper .label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:2.5rem;white-space:normal;margin-bottom:0;margin-right:0.75rem}.wrapper.label-none label{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;border:0 !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;white-space:nowrap !important;margin:-1px !important}.wrapper.invalid .label{color:var(--wmcolor-text-error)}.wrapper.invalid .label:after{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f026\";margin-left:0.3125rem}[dir=RTL] .wrapper.invalid .label:after{margin-left:0;margin-right:0.3125rem}.wrapper.rtl.label-left .label{margin-right:0;margin-left:0.75rem}.button-wrapper{position:relative;-ms-flex:1;flex:1;font-size:1.125rem;color:var(--wmcolor-select-text);min-width:8.75rem}.button-wrapper .displayedoption{-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-wrap:nowrap;flex-wrap:nowrap;background:var(--wmcolor-select-background);width:100%;border:solid 1px;border-color:var(--wmcolor-select-border);padding:0 1.875rem 0 0.9375rem;cursor:pointer;height:2.5rem;line-height:normal;font-family:inherit;color:var(--wmcolor-select-text);font-weight:400;font-size:0.875rem;text-transform:none;text-align:left}@media only screen and (max-width: 768px){.button-wrapper .displayedoption{height:2.75rem}}.button-wrapper .displayedoption:before{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f140\";position:absolute;right:0.5625rem;pointer-events:none;font-size:1.12rem}.button-wrapper .displayedoption.expanded:before{content:\"\\f143\"}.button-wrapper .displayedoption:hover:not(:disabled):not(.-disabled):not(.-raised){background:var(--wmcolor-select-background);text-decoration:none}.button-wrapper .displayedoption:active{-ms-transform:scale(1, 1) !important;-webkit-transform:scale(1, 1) !important;transform:scale(1, 1) !important}.button-wrapper .displayedoption:focus{outline:none}.button-wrapper .displayedoption::-moz-focus-inner{border:0}.button-wrapper .displayedoption:focus-visible{outline:3px solid var(--wmcolor-interactive-focus);outline-offset:2px}.button-wrapper .displayedoption .overflowcontrol{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;-ms-flex:1;flex:1}.button-wrapper .displayedoption .overflowcontrol.hassubinfo{display:-ms-flexbox;display:flex}.button-wrapper .displayedoption .overflowcontrol.hassubinfo .button-text{-ms-flex:1;flex:1;text-overflow:ellipsis;overflow:hidden;min-width:0}.button-wrapper .displayedoption .overflowcontrol.hassubinfo .subinfo{-ms-flex:none;flex:none;font-style:italic}.button-wrapper .displayedoption .overflow-counter{font-weight:bold;margin-left:0.5rem}.button-wrapper>.displayedoption[disabled]{color:var(--wmcolor-select-option-text-disabled);border-color:var(--wmcolor-border-dark);background:var(--wmcolor-select-option-background-disabled);cursor:default}.wrapper.invalid .button-wrapper .displayedoption{-webkit-box-shadow:0 0 0 1px var(--wmcolor-input-border-error);-moz-box-shadow:0 0 0 1px var(--wmcolor-input-border-error);box-shadow:0 0 0 1px var(--wmcolor-input-border-error);border-color:var(--wmcolor-input-border-error)}.wrapper .error-message{display:block;font-style:italic;color:var(--wmcolor-text-error);font-size:0.875rem;margin-bottom:0.25rem;top:100%;left:0}.wrapper .error-message:not(:empty){margin-top:0.25rem}.dropdown{overflow-x:hidden;overflow-y:auto;-ms-transition:transform 0.25s ease;-webkit-transition:transform 0.25s ease;-moz-transition:transform 0.25s ease;-webkit-transition:-webkit-transform 0.25s ease;transition:-webkit-transform 0.25s ease;transition:transform 0.25s ease;transition:transform 0.25s ease, -webkit-transform 0.25s ease;-ms-transform-origin:center top;-webkit-transform-origin:center top;-moz-transform-origin:center top;transform-origin:center top;transform:scale(1, 0);-webkit-overflow-scrolling:touch;-webkit-box-shadow:0 4px 15px 0 rgba(0, 0, 0, 0.2);-moz-box-shadow:0 4px 15px 0 rgba(0, 0, 0, 0.2);box-shadow:0 4px 15px 0 rgba(0, 0, 0, 0.2);-ms-transition:transform 0.25s ease;-webkit-transition:transform 0.25s ease;-moz-transition:transform 0.25s ease;transition:transform 0.25s ease;-ms-transform:scale(1, 0);-webkit-transform:scale(1, 0);-moz-transform:scale(1, 0);transform:scale(1, 0);-ms-transform-origin:center top;-webkit-transform-origin:center top;-moz-transform-origin:center top;transform-origin:center top;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;position:absolute;top:40;right:0;background:var(--wmcolor-select-option-background);z-index:100;width:100%;font-size:0.875rem}.dropdown.upwards{top:unset;bottom:100%;-ms-transform-origin:center bottom;-webkit-transform-origin:center bottom;-moz-transform-origin:center bottom;transform-origin:center bottom}.dropdown.hidden{visibility:hidden}.dropdown.open{-ms-transform:scale(1, 1);-webkit-transform:scale(1, 1);-moz-transform:scale(1, 1);transform:scale(1, 1)}.menu{width:100%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;max-height:var(--max-height);overflow-y:auto}.menu.hidden{position:absolute;max-height:100%;overflow:hidden}.menu .menuitem{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;cursor:pointer;position:relative;padding:1.25rem;background:var(--wmcolor-select-option-background);font-family:inherit;list-style:none;color:var(--wmcolor-select-option-text);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:none;font-weight:600}.menu .menuitem:not(:last-child){border-bottom:2px solid;border-color:var(--wmcolor-select-option-border)}.menu .menuitem.disabled{color:var(--wmcolor-select-option-text-disabled);cursor:auto}.menu .menuitem.clear-selection{color:var(--wmcolor-select-text);-ms-flex-pack:start;justify-content:start;-ms-flex-align:center;align-items:center}.menu .menuitem.clear-selection:before{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f156\";pointer-events:none;padding-right:0.5rem;font-size:1.12rem}.menu .menuitem:focus-visible{outline:none;background:var(--wmcolor-interactive-background-focus)}.menu .menuitem:hover{background:var(--wmcolor-select-option-background-hover);outline:none}.group-btn:before{display:inline-block;font:normal normal normal 24px/1 \"Material Design Icons\";font-size:inherit;text-rendering:auto;line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:\"\\f142\";position:absolute;right:1.25rem;pointer-events:none;font-size:1.12rem}.group-btn.disabled{background:var(--wmcolor-select-option-background-disabled)}.selection-count,.disabled-indication{margin-right:40px;font-weight:400;font-style:italic}.disabled-indication{color:var(--wmcolor-interactive-disabled)}.option-list-wrapper{background:white;width:100%;-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transition:-webkit-transform 0.2s cubic-bezier(0.04, 0, 0.2, 1);transition:-webkit-transform 0.2s cubic-bezier(0.04, 0, 0.2, 1);transition:transform 0.2s cubic-bezier(0.04, 0, 0.2, 1);transition:transform 0.2s cubic-bezier(0.04, 0, 0.2, 1), -webkit-transform 0.2s cubic-bezier(0.04, 0, 0.2, 1)}.option-list-wrapper.hidden{-webkit-transform:translateX(100%);transform:translateX(100%);position:absolute;top:0px;max-height:100%;overflow-y:hidden}.measurement-area{position:absolute;visibility:hidden;height:0px;pointer-events:none}.sr-only{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;border:0 !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;white-space:nowrap !important;margin:-1px !important}";
10
10
 
11
11
  const NestedSelect = class {
12
12
  constructor(hostRef) {
@@ -27,7 +27,7 @@ const NestedSelect = class {
27
27
  description: "Button text to clear selection. Use imperative",
28
28
  });
29
29
  this.disabled = false;
30
- this.maxHeight = undefined;
30
+ this.maxHeight = "200px";
31
31
  this.label = undefined;
32
32
  this.labelPosition = "top";
33
33
  this.requiredField = false;
@@ -58,6 +58,8 @@ const NestedSelect = class {
58
58
  });
59
59
  this.isExpanded = false;
60
60
  this.showClearSelectionButton = false;
61
+ this.announcement = "";
62
+ this.constrainedMaxHeight = this.maxHeight;
61
63
  }
62
64
  get isDisabled() {
63
65
  // string "false" needs to be treated as bool False because react wrappers convert bool to string.
@@ -76,7 +78,7 @@ const NestedSelect = class {
76
78
  return this.childOptions.every((option) => option.selected);
77
79
  }
78
80
  componentWillLoad() {
79
- const mutationObserver = new MutationObserver((mutationRecordList) => mutationRecordList.forEach((mutationRecord) => this.handleChildChange(mutationRecord)));
81
+ const mutationObserver = new MutationObserver((mutationRecordList) => mutationRecordList.forEach((_mutationRecord) => this.handleChildChange()));
80
82
  mutationObserver.observe(this.el, {
81
83
  childList: true,
82
84
  attributes: true,
@@ -84,16 +86,14 @@ const NestedSelect = class {
84
86
  attributeFilter: ["selected"],
85
87
  });
86
88
  }
87
- componentDidLoad() {
88
- if (this.maxHeight) {
89
- this.dropdownEl.style.maxHeight = this.maxHeight;
90
- }
91
- }
92
- handleChildChange(_) {
89
+ handleChildChange() {
93
90
  // on update of children or children selected state, reset button text and rerender
94
91
  this.setButtonText();
95
92
  index.forceUpdate(this.el);
96
- // this.optionListEl.handleChildChange(_);
93
+ if (this.multiple) {
94
+ // update state of clone options
95
+ this.optgroupEls.forEach((optgroupEl) => optgroupEl.handleChildChange());
96
+ }
97
97
  }
98
98
  setButtonText() {
99
99
  this.displayedOptions = this.childOptions.filter((x) => x.selected);
@@ -133,6 +133,28 @@ const NestedSelect = class {
133
133
  closePopupOnEscape() {
134
134
  this.close();
135
135
  }
136
+ handleKeyDown(ev) {
137
+ // when shift tabbing but component is still in focus, close dropdown
138
+ switch (ev.key) {
139
+ case "Tab":
140
+ if (ev.shiftKey) {
141
+ this.close();
142
+ }
143
+ break;
144
+ case "ArrowDown":
145
+ if (this.isExpanded === false) {
146
+ ev.preventDefault();
147
+ this.open();
148
+ }
149
+ break;
150
+ case "ArrowUp":
151
+ if (this.isExpanded === false) {
152
+ ev.preventDefault();
153
+ this.open(true);
154
+ }
155
+ break;
156
+ }
157
+ }
136
158
  close(returnFocus = true) {
137
159
  if (this.isExpanded) {
138
160
  this.isExpanded = false;
@@ -145,40 +167,50 @@ const NestedSelect = class {
145
167
  }, 150);
146
168
  }
147
169
  }
148
- open() {
170
+ open(focusLast = false) {
149
171
  if (!this.isDisabled) {
150
172
  this.showClearSelectionButton = this.childOptions.some((o) => o.selected);
173
+ this.dropdownEl.scrollTop = 0;
151
174
  this.isExpanded = true;
152
175
  this.dropdownEl.classList.add("open");
153
176
  const elHeight = this.el.clientHeight;
154
177
  this.openUp = functions.shouldOpenUp(this.el, this.dropdownEl.clientHeight, elHeight, 0);
155
- window.requestAnimationFrame(() => {
156
- this.focusFirstMenuitem();
178
+ this.constrainedMaxHeight = this.maxHeight;
179
+ const spaceAbove = functions.getContextMeasurements(this.el).spaceAbove;
180
+ if (this.openUp) {
181
+ if (parseInt(getComputedStyle(this.menuEl).getPropertyValue("--max-height").replace("px", "")) > spaceAbove) {
182
+ this.constrainedMaxHeight = spaceAbove.toString() + "px";
183
+ }
184
+ }
185
+ // if opening upwards, set an upwards height limit for the optgroup level
186
+ this.optgroupEls.forEach((o) => {
187
+ o.shadowRoot.querySelector("priv-option-list").upwardsHeightLimit = this.openUp
188
+ ? spaceAbove
189
+ : null;
157
190
  });
158
- }
159
- }
160
- focusFirstMenuitem() {
161
- if (this.menuitemEls.length > 0) {
162
- this.menuitemEls[0].focus();
191
+ // 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))
192
+ // when opening the dropdown, scrollIntoView must be delayed to a point where the browser recognizes content within it as able to be scrolled to
193
+ // 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
194
+ window.setTimeout(() => {
195
+ if (this.menuitemEls.length > 0) {
196
+ const menuitemToFocus = this.menuitemEls[focusLast ? this.menuitemEls.length - 1 : 0];
197
+ menuitemToFocus.scrollIntoView({ block: "nearest" });
198
+ menuitemToFocus.focus();
199
+ }
200
+ }, 60);
163
201
  }
164
202
  }
165
203
  moveDown(menuitemEl) {
166
204
  const currentIndex = this.menuitemEls.indexOf(menuitemEl);
167
- if (currentIndex == this.menuitemEls.length - 1) {
168
- this.menuitemEls[0].focus();
169
- }
170
- else {
171
- this.menuitemEls[currentIndex + 1].focus();
172
- }
205
+ const menuitemToFocus = this.menuitemEls[currentIndex == this.menuitemEls.length - 1 ? 0 : currentIndex + 1];
206
+ menuitemToFocus.scrollIntoView({ block: "nearest" });
207
+ menuitemToFocus.focus();
173
208
  }
174
209
  moveUp(menuitemEl) {
175
210
  const currentIndex = this.menuitemEls.indexOf(menuitemEl);
176
- if (currentIndex == 0) {
177
- this.menuitemEls[this.menuitemEls.length - 1].focus();
178
- }
179
- else {
180
- this.menuitemEls[currentIndex - 1].focus();
181
- }
211
+ const menuitemToFocus = this.menuitemEls[currentIndex == 0 ? this.menuitemEls.length - 1 : currentIndex - 1];
212
+ menuitemToFocus.scrollIntoView({ block: "nearest" });
213
+ menuitemToFocus.focus();
182
214
  }
183
215
  handleButtonBlur(ev) {
184
216
  if (functions.isElOrChild(this.el, ev.relatedTarget)) {
@@ -234,6 +266,13 @@ const NestedSelect = class {
234
266
  const elToFocus = this.el.shadowRoot.querySelector(`button[data-label=${ev.detail}]`);
235
267
  elToFocus.focus();
236
268
  }
269
+ announce(message) {
270
+ // \u00A0 is a non-breaking space character, which causes the message to be read as a new one
271
+ if (this.liveRegionEl.textContent === message) {
272
+ message += "\u00A0";
273
+ }
274
+ this.announcement = message;
275
+ }
237
276
  renderButtonText() {
238
277
  if (this.displayedOptions.length < 1) {
239
278
  return index.h("span", null, this.placeholder);
@@ -252,6 +291,12 @@ const NestedSelect = class {
252
291
  }
253
292
  handleClearSelection() {
254
293
  this.optgroupEls.forEach((optgroupEl) => optgroupEl.emitDeselection());
294
+ const selectionClearedAnnouncement = functions.intl.formatMessage({
295
+ id: "select.selectionCleared",
296
+ defaultMessage: "Selection cleared",
297
+ description: "Screen reader announcement alerting the user they have cleared their selection",
298
+ });
299
+ this.announce(selectionClearedAnnouncement);
255
300
  if (!this.multiple) {
256
301
  this.close();
257
302
  }
@@ -291,14 +336,14 @@ const NestedSelect = class {
291
336
  };
292
337
  return (index.h(index.Host, { onBlur: (ev) => this.handleComponentBlur(ev) }, index.h("div", { class: `wrapper ${functions.getTextDir()} label-${this.labelPosition} ${this.errorMessage ? "invalid" : ""}` }, index.h("div", { class: "label-wrapper" }, index.h("label", { class: "label", id: "label", htmlFor: "selectbtn" }, this.label,
293
338
  // we can't use aria-required or required attributes because it's invalid on the elements we're using (button controlling a listbox)
294
- this.requiredField ? (index.h("span", { class: "required" }, index.h("span", { class: "sr-only" }, intl.globalMessages.requiredField), index.h("span", { "aria-hidden": "true" }, "*"))) : (""))), index.h("div", { class: "button-wrapper" }, index.h("button", Object.assign({}, buttonProps, { class: `displayedoption ${this.isExpanded ? "expanded" : ""}`, ref: (el) => (this.buttonEl = el), onBlur: (ev) => this.handleButtonBlur(ev), onFocus: () => this.close() }), index.h("span", { class: "overflowcontrol" }, index.h("span", { class: "button-text" }, this.renderButtonText())), this.renderOverflowCount(), index.h("div", { ref: (el) => (this.measurementAreaEl = el), class: "measurement-area", "aria-hidden": "true" })), index.h("div", { class: `dropdown ${this.openUp ? "upwards" : ""}`, ref: (el) => (this.dropdownEl = el) }, index.h("div", { ref: (el) => (this.menuEl = el), class: "menu" }, this.renderClearSelectionButton(), this.optgroupEls.map((optgroupEl) => {
339
+ this.requiredField ? (index.h("span", { class: "required" }, index.h("span", { class: "sr-only" }, intl.globalMessages.requiredField), index.h("span", { "aria-hidden": "true" }, "*"))) : (""))), index.h("div", { class: "button-wrapper" }, index.h("button", Object.assign({}, buttonProps, { class: `displayedoption ${this.isExpanded ? "expanded" : ""}`, ref: (el) => (this.buttonEl = el), onBlur: (ev) => this.handleButtonBlur(ev) }), index.h("span", { class: "overflowcontrol" }, index.h("span", { class: "button-text" }, this.renderButtonText())), this.renderOverflowCount(), index.h("div", { ref: (el) => (this.measurementAreaEl = el), class: "measurement-area", "aria-hidden": "true" })), index.h("div", { class: `dropdown ${this.openUp ? "upwards" : ""}`, ref: (el) => (this.dropdownEl = el) }, index.h("div", { ref: (el) => (this.menuEl = el), class: "menu", style: { "--max-height": this.constrainedMaxHeight }, tabIndex: -1 }, this.renderClearSelectionButton(), this.optgroupEls.map((optgroupEl) => {
295
340
  return (index.h("button", { class: `menuitem group-btn ${optgroupEl.disabled ? "disabled" : ""}`, role: "menuitem", "data-label": optgroupEl.label, tabindex: -1, "aria-disabled": optgroupEl.disabled, onClick: () => {
296
341
  if (!optgroupEl.disabled) {
297
342
  optgroupEl.isExpanded = !optgroupEl.isExpanded;
298
343
  index.forceUpdate(this.el);
299
344
  }
300
345
  }, onKeyDown: (ev) => this.handleMenuitemKeydown(ev) }, index.h("span", null, optgroupEl.label), this.renderSelectionCount(optgroupEl), optgroupEl.disabled && index.h("div", { class: "disabled-indication" }, "Disabled")));
301
- })), index.h("div", { ref: (el) => (this.optListWrapperEl = el), class: "option-list-wrapper hidden" }, index.h("slot", null))), index.h("div", { id: "error", class: this.errorMessage ? "error-message" : "" }, this.errorMessage)))));
346
+ })), index.h("div", { ref: (el) => (this.optListWrapperEl = el), class: "option-list-wrapper hidden" }, index.h("slot", null))), index.h("div", { id: "error", class: this.errorMessage ? "error-message" : "" }, this.errorMessage))), index.h("div", { id: "nestedselect-announcement", "aria-live": "assertive", "aria-atomic": "true", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement)));
302
347
  }
303
348
  static get delegatesFocus() { return true; }
304
349
  get el() { return index.getElement(this); }
@@ -43,10 +43,16 @@ const Optgroup = class {
43
43
  this.el.classList.remove("visible");
44
44
  }, 250);
45
45
  }
46
+ if (this.parentNestedSelect.multiple) {
47
+ this.optionListEl.updateOptionVisibility();
48
+ }
46
49
  }
47
50
  async emitDeselection() {
48
51
  this.wmOptgroupAllDeselected.emit();
49
52
  }
53
+ async handleChildChange() {
54
+ this.optionListEl.handleChildChange();
55
+ }
50
56
  handleOptionKeyLeft() {
51
57
  this.isExpanded = false;
52
58
  }
@@ -54,7 +60,7 @@ const Optgroup = class {
54
60
  functions.handleDisabledAttribute(this.el, this.isDisabled);
55
61
  }
56
62
  render() {
57
- return (index.h(index.Host, null, index.h("div", { class: `list-wrapper` }, index.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() }, index.h("slot", null)))));
63
+ return (index.h(index.Host, null, index.h("div", { class: `list-wrapper` }, index.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() }, index.h("slot", null)))));
58
64
  }
59
65
  static get delegatesFocus() { return true; }
60
66
  get el() { return index.getElement(this); }