@proximus/lavender-modal 2.0.0-alpha.22 → 2.0.0-alpha.221

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/Modal.d.ts CHANGED
@@ -6,25 +6,53 @@ import '@proximus/lavender-heading';
6
6
  import '@proximus/lavender-paragraph';
7
7
  import { type ButtonIcon } from '@proximus/lavender-button-icon';
8
8
  import { type Icon } from '@proximus/lavender-icon';
9
+ export declare const statusValues: string[];
9
10
  export declare class Modal extends HTMLElement {
10
- template: string;
11
+ protected static readonly template: HTMLTemplateElement;
12
+ private onOpenClick;
13
+ private onCloseClick;
14
+ private onDialogCancel;
15
+ private commandButtonCleanups;
16
+ private opener;
17
+ private openerElement;
18
+ private closerElement;
11
19
  constructor();
12
20
  connectedCallback(): void;
13
21
  static get observedAttributes(): string[];
14
22
  attributeChangedCallback(attrName: string, oldValue: string, newValue: string): void;
23
+ disconnectedCallback(): void;
24
+ addEventListenersToCommandButtons(): void;
25
+ private removeCommandButtonListeners;
15
26
  handleOpenChange(): void;
16
27
  handleStatusChange(oldStatus: string, newStatus: string): void;
17
28
  getIcon(status: string): "checkmark_fill" | "exclamation_mark_fill" | "minus_fill" | "information_fill";
18
29
  show(): void;
19
30
  close(): void;
20
31
  updateMediaSrc(src: string): void;
21
- get status(): string;
22
- set status(value: string);
32
+ addOpenListener(): void;
33
+ private removeOpenListener;
34
+ addCloseListener(value: string): void;
35
+ private removeCloseListener;
36
+ toggleDescriptionVisibility(): void;
37
+ toggleCloseButtonSafeArea(): void;
38
+ get $slottedCloseButton(): HTMLSlotElement;
39
+ get $slotCloseButton(): HTMLSlotElement | null;
40
+ get $slottedDescription(): HTMLSlotElement;
41
+ get $slotDescription(): HTMLSlotElement | null;
42
+ get $descriptionContainer(): HTMLParagraphElement;
43
+ get $titleContainer(): HTMLHeadingElement;
44
+ get $opener(): HTMLButtonElement;
45
+ get status(): string | null;
46
+ set status(value: string | null);
47
+ get openedby(): string | null;
48
+ set openedby(value: string | null);
49
+ get closedby(): string | null;
50
+ set closedby(value: string | null);
23
51
  get $closeButton(): ButtonIcon;
24
52
  get $statusIcon(): Icon;
25
53
  get $mediaContainer(): HTMLDivElement;
26
- get mediaSrc(): string;
27
- set mediaSrc(value: string);
54
+ get mediaSrc(): string | null;
55
+ set mediaSrc(value: string | null);
28
56
  get $container(): Element;
29
57
  get $iconContainer(): Element;
30
58
  get $dialog(): HTMLDialogElement;
package/dist/index.es.js CHANGED
@@ -4,149 +4,182 @@ import "@proximus/lavender-layout";
4
4
  import "@proximus/lavender-icon";
5
5
  import "@proximus/lavender-heading";
6
6
  import "@proximus/lavender-paragraph";
7
- const n = "*{box-sizing:border-box}#container{width:1080px;display:flex;flex-wrap:nowrap;border-radius:var(--px-radius-main);background-color:var(--px-color-background-surface-default);overflow:hidden}#container.info{border-left:5px var(--px-color-icon-brand-default) solid}#container.success{border-left:5px var(--px-color-icon-purpose-success-default) solid}#container.warning{border-left:5px var(--px-color-icon-purpose-warning-default) solid}#container.error{border-left:5px var(--px-color-icon-purpose-error-default) solid}#content-container{padding:var(--px-padding-m-mobile)}#media-container{display:none}::slotted(px-button-icon){position:absolute;top:var(--px-padding-m-desktop);right:var(--px-padding-m-desktop)}dialog{background:transparent;border-radius:0;box-shadow:none;padding:0;border:0;box-sizing:border-box;transform:scale(.95);animation:modalIn .3s ease-out forwards}::backdrop{background:#0000004d;-webkit-backdrop-filter:saturate(180%) blur(15px);backdrop-filter:saturate(180%) blur(15px)}#content{max-height:12.5em;overflow:auto}@media screen and (max-width: 1081px){#container{width:inherit}#content-container{padding:var(--px-padding-m-mobile)}::slotted(px-button-icon){top:var(--px-padding-m-mobile);right:var(--px-padding-m-mobile)}}@media only screen and (min-width: 48em){::slotted(px-button-icon){position:absolute;top:var(--px-padding-m-tablet);right:var(--px-padding-m-tablet)}#content{max-height:25em}}@media only screen and (min-width: 64.0625em){:host([media-src]) #media-container{display:block;background-size:cover;background-position:center center;background-repeat:no-repeat;flex-basis:25em;flex-shrink:0}}@keyframes modalIn{0%{transform:scale(.95);opacity:0}to{transform:scale(1);opacity:1}}", a = new CSSStyleSheet();
8
- a.replaceSync(n);
9
- const c = "px.lavender.modal.close";
10
- class d extends HTMLElement {
11
- constructor() {
12
- super(), this.template = ` <dialog>
13
- <div id="container">
14
- <div id="content-container">
15
- <px-vstack gap="default" >
16
- <px-hstack id="icon-container" gap="s" align-items="flex-start">
17
- <px-vstack gap="s">
18
- <px-h1 variant="title-l">
19
- <slot name="title"></slot>
20
- </px-h1>
21
- <px-p font-weight="title">
22
- <slot name="description"></slot>
23
- </px-p>
24
- </px-vstack>
25
- </px-hstack>
26
- <div id="content">
27
- <slot></slot>
28
- </div>
29
- <px-separator size="m"></px-separator>
30
- <px-stack
31
- gap="s"
32
- justify-content="flex-end"
33
- align-items="center"
34
- align-items--mobile="stretch"
35
- direction="row"
36
- direction--mobile="column-reverse"
37
- >
38
- <slot name="footer"></slot>
39
- </px-stack>
40
- </px-vstack>
41
- <slot name="close-button"></slot>
42
- </div>
43
- <div id="media-container">
44
- </div>
45
- </div>
46
- </dialog>`, this.attachShadow({ mode: "open" }), this.shadowRoot.innerHTML = this.template, this.shadowRoot.adoptedStyleSheets = [a];
47
- }
48
- connectedCallback() {
49
- if (this.hasAttribute("open") && this.show(), this.hasAttribute("closedby")) {
50
- const t = document.querySelector(
51
- `#${this.getAttribute("closedby")}`
52
- );
53
- t == null || t.addEventListener("click", () => {
54
- this.close();
55
- });
56
- }
57
- if (this.hasAttribute("openedby")) {
58
- const t = document.querySelector(
59
- `px-button#${this.getAttribute("openedby")}`
60
- );
61
- t == null || t.addEventListener("click", () => {
62
- this.show();
63
- });
64
- }
65
- this.hasAttribute("media-src") && this.updateMediaSrc(this.getAttribute("media-src"));
66
- }
67
- static get observedAttributes() {
68
- return ["open", "status", "media-src"];
69
- }
70
- attributeChangedCallback(t, e, i) {
71
- switch (t) {
72
- case "open":
73
- this.handleOpenChange();
74
- break;
75
- case "status":
76
- this.handleStatusChange(e, i);
77
- break;
78
- case "media-src":
79
- this.updateMediaSrc(i);
80
- break;
81
- }
82
- }
83
- handleOpenChange() {
84
- this.hasAttribute("open") ? this.show() : this.close();
85
- }
86
- handleStatusChange(t, e) {
87
- var i, s, r;
88
- if (e === "info" ? this.$container.classList.add("info") : this.$container.classList.remove("info"), e === "success" ? this.$container.classList.add("success") : this.$container.classList.remove("success"), e === "error" ? this.$container.classList.add("error") : this.$container.classList.remove("error"), e === "warning" ? this.$container.classList.add("warning") : this.$container.classList.remove("warning"), e === null && this.$statusIcon)
89
- (i = this.$statusIcon) == null || i.remove();
90
- else if (t === null && e && !this.$statusIcon) {
91
- const o = document.createElement("px-icon");
92
- o.setAttribute("name", this.getIcon(e)), o.setAttribute("from", "lavender"), o.setAttribute("color", `purpose-${e}`), o.setAttribute("size", "l"), this.$iconContainer.prepend(o);
93
- } else
94
- (s = this.$statusIcon) == null || s.setAttribute("name", this.getIcon(e)), (r = this.$statusIcon) == null || r.setAttribute("color", `purpose-${e}`);
95
- }
96
- getIcon(t) {
97
- return t === "success" ? "checkmark_fill" : t === "warning" ? "exclamation_mark_fill" : t === "error" ? "minus_fill" : "information_fill";
98
- }
99
- show() {
100
- this.$dialog.showModal();
101
- }
102
- close() {
103
- this.$dialog.close(), this.dispatchEvent(
104
- new CustomEvent(c, {
105
- bubbles: !0,
106
- composed: !0
107
- })
108
- );
109
- }
110
- updateMediaSrc(t) {
111
- this.$mediaContainer.style.backgroundImage = `url(${t})`;
112
- }
113
- get status() {
114
- return this.getAttribute("status");
115
- }
116
- set status(t) {
117
- this.setAttribute("status", t);
118
- }
119
- get $closeButton() {
120
- return this.shadowRoot.querySelector("px-button-icon");
121
- }
122
- get $statusIcon() {
123
- return this.$iconContainer.querySelector(
124
- "#icon-container > px-icon"
125
- );
126
- }
127
- get $mediaContainer() {
128
- return this.shadowRoot.querySelector("#media-container");
129
- }
130
- get mediaSrc() {
131
- return this.getAttribute("media-src");
132
- }
133
- set mediaSrc(t) {
134
- t === null ? this.removeAttribute("media-src") : this.setAttribute("media-src", t);
135
- }
136
- get $container() {
137
- return this.shadowRoot.querySelector("#container");
138
- }
139
- get $iconContainer() {
140
- return this.shadowRoot.querySelector("#icon-container");
141
- }
142
- get $dialog() {
143
- return this.shadowRoot.querySelector("dialog");
144
- }
145
- get open() {
146
- return this.$dialog.open;
147
- }
148
- }
149
- customElements.get("px-modal") || customElements.define("px-modal", d);
150
- export {
151
- d as Modal
7
+ import { createTemplate as e, propertyToAttributeSetter as t, renderTemplate as n } from "@proximus/lavender-common";
8
+ //#region src/modal.css?inline
9
+ var r = "*{box-sizing:border-box}#container{font-family:var(--px-font-family);font-size:var(--px-font-size-base);color:var(--px-color-text-neutral-default);width:inherit;border-radius:var(--px-radius-main);background-color:var(--px-color-background-surface-default);flex-wrap:nowrap;display:flex;overflow:hidden}#container.info{border-left:5px var(--px-color-icon-brand-default) solid}#container.success{border-left:5px var(--px-color-icon-purpose-success-default) solid}#container.warning{border-left:5px var(--px-color-icon-purpose-warning-default) solid}#container.error{border-left:5px var(--px-color-icon-purpose-error-default) solid}#container.has-close-button #icon-container{max-width:calc(100% - (var(--px-size-m) + var(--px-spacing-s-mobile)))}#content-container{padding:var(--px-padding-m-mobile);flex-grow:1;display:flex}#content-container px-vstack{flex-grow:1;max-height:100%}#media-container{display:none}::slotted(px-button-icon[slot=close-button]){top:var(--px-padding-m-mobile);right:var(--px-padding-m-mobile);position:absolute}dialog{box-shadow:none;box-sizing:border-box;max-width:calc(100% - (var(--px-spacing-s-mobile) * 2));max-height:calc(100% - (var(--px-spacing-s-mobile) * 2));background:0 0;border:0;border-radius:0;padding:0;animation:.3s ease-out forwards modalIn;transform:scale(.95)}dialog[open]{display:flex}::backdrop{-webkit-backdrop-filter:saturate(180%)blur(15px);backdrop-filter:saturate(180%)blur(15px);background:#0000004d}#content{max-height:12.5rem;overflow:auto}@media screen and (width>=48rem){dialog{max-width:calc(100% - (var(--px-spacing-s-tablet) * 2));max-height:calc(100% - (var(--px-spacing-s-tablet) * 2))}#container.has-close-button #icon-container{max-width:calc(100% - (var(--px-size-m) + var(--px-spacing-s-tablet)))}::slotted(px-button-icon[slot=close-button]){top:var(--px-padding-m-tablet);right:var(--px-padding-m-tablet);position:absolute}#content{max-height:25rem}}@media screen and (width>=64.0625rem){dialog{max-width:calc(100% - (var(--px-spacing-s-laptop) * 2));max-height:calc(100% - (var(--px-spacing-s-laptop) * 2))}#container.has-close-button #icon-container{max-width:calc(100% - (var(--px-size-m) + var(--px-spacing-s-laptop)))}::slotted(px-button-icon[slot=close-button]){top:var(--px-padding-m-laptop);right:var(--px-padding-m-laptop)}:host([media-src]) #container.has-close-button #icon-container{max-width:100%}:host([media-src]) #media-container{background-position:50%;background-repeat:no-repeat;background-size:cover;flex-shrink:0;flex-basis:25rem;display:block}}@media screen and (width>=69.875rem){#container{width:1080px}}@media screen and (width>=90.0625rem){dialog{max-width:calc(100% - (var(--px-spacing-s-desktop) * 2));max-height:calc(100% - (var(--px-spacing-s-desktop) * 2))}:host(:not([media-src])) #container.has-close-button #icon-container{max-width:calc(100% - (var(--px-size-m) + var(--px-spacing-s-desktop)))}::slotted(px-button-icon[slot=close-button]){top:var(--px-padding-m-desktop);right:var(--px-padding-m-desktop);position:absolute}}@keyframes modalIn{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}", i = new CSSStyleSheet();
10
+ i.replaceSync(r);
11
+ var a = "px.lavender.modal.close", o = [
12
+ "",
13
+ "info",
14
+ "success",
15
+ "error",
16
+ "warning"
17
+ ], s = class r extends HTMLElement {
18
+ static {
19
+ this.template = e("<dialog><div id=\"container\"><div id=\"content-container\"><px-vstack gap=\"default\" ><px-hstack id=\"icon-container\" gap=\"s\" align-items=\"flex-start\"><px-vstack gap=\"xs\"><px-h1 variant=\"title-l\"><slot name=\"title\"></slot></px-h1><px-p font-weight=\"title\"><slot name=\"description\"></slot></px-p></px-vstack></px-hstack><div id=\"content\"><slot name=\"content\"></slot><slot></slot></div><px-separator size=\"m\"></px-separator><px-stack\n gap=\"s\"\n justify-content=\"flex-end\"\n align-items=\"center\"\n align-items--mobile=\"stretch\"\n direction=\"row\"\n direction--mobile=\"column-reverse\"\n ><slot name=\"footer\"></slot></px-stack></px-vstack><slot name=\"close-button\"></slot></div><div id=\"media-container\"></div></div></dialog>");
20
+ }
21
+ constructor() {
22
+ super(), this.onOpenClick = () => this.show(), this.onCloseClick = () => this.close(), this.onDialogCancel = () => this.close(), this.commandButtonCleanups = [], this.opener = null, this.openerElement = null, this.closerElement = null, this.attachShadow({ mode: "open" }), n(this.shadowRoot, r.template), this.shadowRoot.adoptedStyleSheets = [i];
23
+ }
24
+ connectedCallback() {
25
+ this.$dialog.addEventListener("cancel", this.onDialogCancel), this.addEventListenersToCommandButtons(), this.toggleDescriptionVisibility = this.toggleDescriptionVisibility.bind(this), this.toggleCloseButtonSafeArea = this.toggleCloseButtonSafeArea.bind(this), this.hasAttribute("open") && this.show(), this.hasAttribute("openedby") && this.addOpenListener(), this.hasAttribute("closedby") && this.addCloseListener(this.getAttribute("closedby")), this.toggleDescriptionVisibility(), this.$slotDescription?.addEventListener("slotchange", this.toggleDescriptionVisibility), this.toggleCloseButtonSafeArea(), this.$slotCloseButton?.addEventListener("slotchange", this.toggleCloseButtonSafeArea);
26
+ }
27
+ static get observedAttributes() {
28
+ return [
29
+ "open",
30
+ "status",
31
+ "media-src",
32
+ "openedby",
33
+ "closedby",
34
+ "id"
35
+ ];
36
+ }
37
+ attributeChangedCallback(e, t, n) {
38
+ switch (e) {
39
+ case "open":
40
+ this.isConnected && this.handleOpenChange();
41
+ break;
42
+ case "status":
43
+ this.handleStatusChange(t, n);
44
+ break;
45
+ case "media-src":
46
+ this.updateMediaSrc(n);
47
+ break;
48
+ case "openedby":
49
+ this.isConnected && this.addOpenListener();
50
+ break;
51
+ case "closedby":
52
+ this.isConnected && this.addCloseListener(n);
53
+ break;
54
+ case "id": this.addEventListenersToCommandButtons();
55
+ }
56
+ }
57
+ disconnectedCallback() {
58
+ this.$dialog.removeEventListener("cancel", this.onDialogCancel), this.$slotDescription?.removeEventListener("slotchange", this.toggleDescriptionVisibility), this.$slotCloseButton?.removeEventListener("slotchange", this.toggleCloseButtonSafeArea), this.removeCommandButtonListeners(), this.removeOpenListener(), this.removeCloseListener();
59
+ }
60
+ addEventListenersToCommandButtons() {
61
+ this.removeCommandButtonListeners(), this.id && document.querySelectorAll(`[commandfor="${this.id}"]`).forEach((e) => {
62
+ e.getAttribute("command") === "show-modal" ? (e.addEventListener("click", this.onOpenClick), this.commandButtonCleanups.push(() => e.removeEventListener("click", this.onOpenClick))) : e.getAttribute("command") === "close" && (e.addEventListener("click", this.onCloseClick), this.commandButtonCleanups.push(() => e.removeEventListener("click", this.onCloseClick)));
63
+ });
64
+ }
65
+ removeCommandButtonListeners() {
66
+ this.commandButtonCleanups.forEach((e) => e()), this.commandButtonCleanups = [];
67
+ }
68
+ handleOpenChange() {
69
+ this.hasAttribute("open") ? this.show() : this.close();
70
+ }
71
+ handleStatusChange(e, t) {
72
+ if (o.includes(t) ? this.$titleContainer.setAttribute("color", "neutral") : this.$titleContainer.hasAttribute("color") && this.$titleContainer.removeAttribute("color"), t === "info" ? this.$container.classList.add("info") : this.$container.classList.remove("info"), t === "success" ? this.$container.classList.add("success") : this.$container.classList.remove("success"), t === "error" ? this.$container.classList.add("error") : this.$container.classList.remove("error"), t === "warning" ? this.$container.classList.add("warning") : this.$container.classList.remove("warning"), t === null && this.$statusIcon) this.$statusIcon?.remove();
73
+ else if (e === null && t && !this.$statusIcon) {
74
+ let e = document.createElement("px-icon");
75
+ e.setAttribute("name", this.getIcon(t)), e.setAttribute("from", "lavender"), e.setAttribute("color", `purpose-${t}`), e.setAttribute("size", "l"), this.$iconContainer.prepend(e);
76
+ } else this.$statusIcon?.setAttribute("name", this.getIcon(t)), this.$statusIcon?.setAttribute("color", `purpose-${t}`);
77
+ }
78
+ getIcon(e) {
79
+ return e === "success" ? "checkmark_fill" : e === "warning" ? "exclamation_mark_fill" : e === "error" ? "minus_fill" : "information_fill";
80
+ }
81
+ show() {
82
+ this.$dialog.showModal(), document.body.style.overflow = "hidden";
83
+ }
84
+ close() {
85
+ this.$dialog.close(), document.body.style.overflow = "", this.dispatchEvent(new CustomEvent(a, {
86
+ bubbles: !0,
87
+ composed: !0
88
+ }));
89
+ }
90
+ updateMediaSrc(e) {
91
+ this.$mediaContainer.style.backgroundImage = `url(${e})`;
92
+ }
93
+ addOpenListener() {
94
+ this.removeOpenListener(), this.$opener ? (this.openerElement = this.$opener, this.openerElement.addEventListener("click", this.onOpenClick)) : (this.opener?.disconnect(), this.opener = new MutationObserver(() => {
95
+ this.$opener && (this.opener.disconnect(), this.opener = null, this.addOpenListener());
96
+ }), this.opener.observe(document.body, {
97
+ childList: !0,
98
+ subtree: !0
99
+ }));
100
+ }
101
+ removeOpenListener() {
102
+ this.opener?.disconnect(), this.opener = null, this.openerElement?.removeEventListener("click", this.onOpenClick), this.openerElement = null;
103
+ }
104
+ addCloseListener(e) {
105
+ e === "none" && this.$dialog?.setAttribute("closedby", "none"), this.removeCloseListener(), e && e !== "none" && (this.closerElement = document.querySelector(`#${e}`), this.closerElement?.addEventListener("click", this.onCloseClick));
106
+ }
107
+ removeCloseListener() {
108
+ this.closerElement?.removeEventListener("click", this.onCloseClick), this.closerElement = null;
109
+ }
110
+ toggleDescriptionVisibility() {
111
+ this.$slottedDescription ? this.$descriptionContainer.style.display = "block" : this.$descriptionContainer.style.display = "none";
112
+ }
113
+ toggleCloseButtonSafeArea() {
114
+ this.$slottedCloseButton ? this.$container?.classList.add("has-close-button") : this.$container?.classList.contains("has-close-button") && this.$container?.classList.remove("has-close-button");
115
+ }
116
+ get $slottedCloseButton() {
117
+ return this.querySelector("[slot=\"close-button\"]");
118
+ }
119
+ get $slotCloseButton() {
120
+ return this.shadowRoot.querySelector("slot[name=\"close-button\"]");
121
+ }
122
+ get $slottedDescription() {
123
+ return this.querySelector("[slot=\"description\"]");
124
+ }
125
+ get $slotDescription() {
126
+ return this.shadowRoot.querySelector("slot[name=\"description\"]");
127
+ }
128
+ get $descriptionContainer() {
129
+ return this.shadowRoot.querySelector("px-p[font-weight=\"title\"]");
130
+ }
131
+ get $titleContainer() {
132
+ return this.shadowRoot.querySelector("px-h1");
133
+ }
134
+ get $opener() {
135
+ return document.querySelector(`px-button#${this.getAttribute("openedby")}`);
136
+ }
137
+ get status() {
138
+ return this.getAttribute("status");
139
+ }
140
+ set status(e) {
141
+ t(this, "status", e);
142
+ }
143
+ get openedby() {
144
+ return this.getAttribute("openedby");
145
+ }
146
+ set openedby(e) {
147
+ t(this, "openedby", e);
148
+ }
149
+ get closedby() {
150
+ return this.getAttribute("closedby");
151
+ }
152
+ set closedby(e) {
153
+ t(this, "closedby", e);
154
+ }
155
+ get $closeButton() {
156
+ return this.shadowRoot.querySelector("px-button-icon");
157
+ }
158
+ get $statusIcon() {
159
+ return this.$iconContainer.querySelector("#icon-container > px-icon");
160
+ }
161
+ get $mediaContainer() {
162
+ return this.shadowRoot.querySelector("#media-container");
163
+ }
164
+ get mediaSrc() {
165
+ return this.getAttribute("media-src");
166
+ }
167
+ set mediaSrc(e) {
168
+ t(this, "media-src", e);
169
+ }
170
+ get $container() {
171
+ return this.shadowRoot.querySelector("#container");
172
+ }
173
+ get $iconContainer() {
174
+ return this.shadowRoot.querySelector("#icon-container");
175
+ }
176
+ get $dialog() {
177
+ return this.shadowRoot.querySelector("dialog");
178
+ }
179
+ get open() {
180
+ return this.$dialog.open;
181
+ }
152
182
  };
183
+ customElements.get("px-modal") || customElements.define("px-modal", s);
184
+ //#endregion
185
+ export { s as Modal, o as statusValues };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proximus/lavender-modal",
3
- "version": "2.0.0-alpha.22",
3
+ "version": "2.0.0-alpha.221",
4
4
  "description": "",
5
5
  "main": "dist/index.es.js",
6
6
  "types": "dist/index.d.ts",