@cedx/base 0.20.0 → 0.21.1

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.
@@ -3,10 +3,6 @@ import { Context } from "../Context.js";
3
3
  * Represents a notification.
4
4
  */
5
5
  export interface IToast {
6
- /**
7
- * Value indicating whether to apply a transition.
8
- */
9
- animation?: boolean;
10
6
  /**
11
7
  * Value indicating whether to automatically hide the toast.
12
8
  */
@@ -31,6 +27,10 @@ export interface IToast {
31
27
  * The delay, in milliseconds, to hide the toast.
32
28
  */
33
29
  delay?: number;
30
+ /**
31
+ * Value indicating whether to apply a transition.
32
+ */
33
+ fade?: boolean;
34
34
  /**
35
35
  * The icon displayed next to the caption.
36
36
  */
@@ -45,11 +45,6 @@ export declare class Toast extends HTMLElement {
45
45
  * The list of observed attributes.
46
46
  */
47
47
  static readonly observedAttributes: string[];
48
- /**
49
- * Value indicating whether to apply a transition.
50
- */
51
- get animation(): boolean;
52
- set animation(value: boolean);
53
48
  /**
54
49
  * Value indicating whether to automatically hide this toast.
55
50
  */
@@ -83,13 +78,18 @@ export declare class Toast extends HTMLElement {
83
78
  * The time elapsed since this component was initially shown, in milliseconds.
84
79
  */
85
80
  get elapsedTime(): number;
81
+ /**
82
+ * Value indicating whether to apply a transition.
83
+ */
84
+ get fade(): boolean;
85
+ set fade(value: boolean);
86
86
  /**
87
87
  * The icon displayed next to the caption.
88
88
  */
89
89
  get icon(): string | null;
90
90
  set icon(value: string | null);
91
91
  /**
92
- * Value indicating whether to initially show this toast.
92
+ * Value indicating whether to initially show this component.
93
93
  */
94
94
  get open(): boolean;
95
95
  set open(value: boolean);
@@ -1 +1 @@
1
- {"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/Toast.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAiB,MAAM,eAAe,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,MAAM;IAEtB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,IAAI,EAAE,gBAAgB,CAAC;IAEvB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,GAAC,IAAI,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,KAAM,SAAQ,WAAW;;IAErC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAA+E;IAkCjH;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IACD,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,EAE3B;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED;;OAEG;IACH,IAAI,IAAI,CAAC,KAAK,EAAE,gBAAgB,EAE/B;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,CAEpB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,EAExB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAGrB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM,CAGzB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAE7B;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAGlB;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,GAAC,IAAI,CAGtB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAC,IAAI,EAG1B;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,GAAG,IAAI;IAa/F;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,iBAAiB,IAAI,IAAI;IASzB;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAK5B;;OAEG;IACH,IAAI,IAAI,IAAI;CAwFZ;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,cAAc,EAAE,KAAK,CAAC;KACtB;CACD"}
1
+ {"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/Toast.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAiB,MAAM,eAAe,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,MAAM;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,IAAI,EAAE,gBAAgB,CAAC;IAEvB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,GAAC,IAAI,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,KAAM,SAAQ,WAAW;;IAErC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAA0E;IAkC5G;;OAEG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED;;OAEG;IACH,IAAI,IAAI,CAAC,KAAK,EAAE,gBAAgB,EAE/B;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,CAEpB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,EAExB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAGrB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM,CAGzB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAE7B;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAGlB;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,GAAC,IAAI,CAGtB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAC,IAAI,EAG1B;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,GAAG,IAAI;IAa/F;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,iBAAiB,IAAI,IAAI;IASzB;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAK5B;;OAEG;IACH,IAAI,IAAI,IAAI;CAwFZ;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,cAAc,EAAE,KAAK,CAAC;KACtB;CACD"}
@@ -7,7 +7,7 @@ export class Toast extends HTMLElement {
7
7
  /**
8
8
  * The list of observed attributes.
9
9
  */
10
- static observedAttributes = ["animation", "autohide", "caption", "context", "culture", "delay", "icon"];
10
+ static observedAttributes = ["autohide", "caption", "context", "culture", "delay", "fade", "icon"];
11
11
  /**
12
12
  * The time units.
13
13
  */
@@ -34,15 +34,6 @@ export class Toast extends HTMLElement {
34
34
  static {
35
35
  customElements.define("toaster-item", this);
36
36
  }
37
- /**
38
- * Value indicating whether to apply a transition.
39
- */
40
- get animation() {
41
- return this.hasAttribute("animation");
42
- }
43
- set animation(value) {
44
- this.toggleAttribute("animation", value);
45
- }
46
37
  /**
47
38
  * Value indicating whether to automatically hide this toast.
48
39
  */
@@ -103,6 +94,15 @@ export class Toast extends HTMLElement {
103
94
  get elapsedTime() {
104
95
  return Date.now() - this.#initialTime;
105
96
  }
97
+ /**
98
+ * Value indicating whether to apply a transition.
99
+ */
100
+ get fade() {
101
+ return this.hasAttribute("fade");
102
+ }
103
+ set fade(value) {
104
+ this.toggleAttribute("fade", value);
105
+ }
106
106
  /**
107
107
  * The icon displayed next to the caption.
108
108
  */
@@ -117,7 +117,7 @@ export class Toast extends HTMLElement {
117
117
  this.removeAttribute("icon");
118
118
  }
119
119
  /**
120
- * Value indicating whether to initially show this toast.
120
+ * Value indicating whether to initially show this component.
121
121
  */
122
122
  get open() {
123
123
  return this.hasAttribute("open");
@@ -134,9 +134,6 @@ export class Toast extends HTMLElement {
134
134
  attributeChangedCallback(attribute, oldValue, newValue) {
135
135
  if (newValue != oldValue)
136
136
  switch (attribute) {
137
- case "animation":
138
- this.#updateAnimation(newValue != null);
139
- break;
140
137
  case "autohide":
141
138
  this.#updateAutoHide(newValue != null);
142
139
  break;
@@ -152,6 +149,9 @@ export class Toast extends HTMLElement {
152
149
  case "delay":
153
150
  this.#updateDelay(Number(newValue));
154
151
  break;
152
+ case "fade":
153
+ this.#updateFade(newValue != null);
154
+ break;
155
155
  case "icon":
156
156
  this.#updateIcon(newValue);
157
157
  break;
@@ -205,13 +205,6 @@ export class Toast extends HTMLElement {
205
205
  }
206
206
  return this.#formatter.format(Math.ceil(-elapsed), Toast.#timeUnits[index]);
207
207
  }
208
- /**
209
- * Updates the value indicating whether to apply a transition.
210
- * @param value The new value.
211
- */
212
- #updateAnimation(value) {
213
- this.firstElementChild.dataset.bsAnimation = value ? "true" : "false";
214
- }
215
208
  /**
216
209
  * Updates the value indicating whether to automatically hide this toast.
217
210
  * @param value The new value.
@@ -254,6 +247,13 @@ export class Toast extends HTMLElement {
254
247
  const { elapsedTime } = this;
255
248
  this.querySelector(".toast-header small").textContent = elapsedTime > 0 ? this.#formatTime(elapsedTime / 1_000) : "";
256
249
  };
250
+ /**
251
+ * Updates the value indicating whether to apply a transition.
252
+ * @param value The new value.
253
+ */
254
+ #updateFade(value) {
255
+ this.firstElementChild.dataset.bsAnimation = value ? "true" : "false";
256
+ }
257
257
  /**
258
258
  * Updates the icon displayed next to the caption.
259
259
  * @param value The new value.
@@ -14,11 +14,6 @@ export declare class Toaster extends HTMLElement {
14
14
  * Creates a new toaster.
15
15
  */
16
16
  constructor();
17
- /**
18
- * Value indicating whether to apply a transition.
19
- */
20
- get animation(): boolean;
21
- set animation(value: boolean);
22
17
  /**
23
18
  * Value indicating whether to automatically hide the toasts.
24
19
  */
@@ -39,6 +34,11 @@ export declare class Toaster extends HTMLElement {
39
34
  */
40
35
  get delay(): number;
41
36
  set delay(value: number);
37
+ /**
38
+ * Value indicating whether to apply a transition.
39
+ */
40
+ get fade(): boolean;
41
+ set fade(value: boolean);
42
42
  /**
43
43
  * The default icon displayed next to the captions.
44
44
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Toaster.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/Toaster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AACtC,OAAO,EAAC,QAAQ,EAAQ,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,YAAY,CAAC;AAEvC;;GAEG;AACH,qBAAa,OAAQ,SAAQ,WAAW;;IAEvC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAAgB;IAOlD;;OAEG;;IAaH;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IACD,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,EAE3B;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAGrB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM,CAGzB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAE7B;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAGlB;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,GAAC,IAAI,CAGtB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAC,IAAI,EAG1B;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,QAAQ,CAGvB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAE3B;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,GAAG,IAAI;IAO/F;;;;;OAKG;IACH,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAErE;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAsCzB;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,mBAAmB,EAAE,OAAO,CAAC;KAC7B;CACD"}
1
+ {"version":3,"file":"Toaster.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/Toaster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AACtC,OAAO,EAAC,QAAQ,EAAQ,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,YAAY,CAAC;AAEvC;;GAEG;AACH,qBAAa,OAAQ,SAAQ,WAAW;;IAEvC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAAgB;IAOlD;;OAEG;;IAaH;;OAEG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAGrB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM,CAGzB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAE7B;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAGlB;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,GAAC,IAAI,CAGtB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAC,IAAI,EAG1B;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,QAAQ,CAGvB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAE3B;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,GAAG,IAAI;IAO/F;;;;;OAKG;IACH,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAErE;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAsCzB;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,mBAAmB,EAAE,OAAO,CAAC;KAC7B;CACD"}
@@ -26,15 +26,6 @@ export class Toaster extends HTMLElement {
26
26
  static {
27
27
  customElements.define("toaster-container", this);
28
28
  }
29
- /**
30
- * Value indicating whether to apply a transition.
31
- */
32
- get animation() {
33
- return this.hasAttribute("animation");
34
- }
35
- set animation(value) {
36
- this.toggleAttribute("animation", value);
37
- }
38
29
  /**
39
30
  * Value indicating whether to automatically hide the toasts.
40
31
  */
@@ -74,6 +65,15 @@ export class Toaster extends HTMLElement {
74
65
  set delay(value) {
75
66
  this.setAttribute("delay", value.toString());
76
67
  }
68
+ /**
69
+ * Value indicating whether to apply a transition.
70
+ */
71
+ get fade() {
72
+ return this.hasAttribute("fade");
73
+ }
74
+ set fade(value) {
75
+ this.toggleAttribute("fade", value);
76
+ }
77
77
  /**
78
78
  * The default icon displayed next to the captions.
79
79
  */
@@ -125,13 +125,13 @@ export class Toaster extends HTMLElement {
125
125
  const childContent = this.#toastTemplate.cloneNode(true).querySelector(".toast");
126
126
  childContent.addEventListener("hidden.bs.toast", () => item.remove());
127
127
  item.appendChild(childContent);
128
- item.animation = toast.animation ?? this.animation;
129
128
  item.autoHide = toast.autoHide ?? this.autoHide;
130
129
  item.body = toast.body;
131
130
  item.caption = toast.caption;
132
131
  item.context = toast.context ?? this.context;
133
132
  item.culture = toast.culture ?? this.culture;
134
133
  item.delay = toast.delay ?? this.delay;
134
+ item.fade = toast.fade ?? this.fade;
135
135
  item.icon = toast.icon ?? this.icon;
136
136
  this.firstElementChild.appendChild(item);
137
137
  item.show();
package/lib/UI/Tag.js CHANGED
@@ -24,8 +24,9 @@ export function html(fragments, ...values) {
24
24
  * @returns The CSS string corresponding to the specified value.
25
25
  */
26
26
  function stringFromCss(value) {
27
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
27
28
  if (!(value instanceof CSSStyleSheet))
28
- return String(value);
29
+ return value === null || typeof value == "undefined" ? "" : String(value);
29
30
  return Array.from(value.cssRules).map(cssRule => cssRule.cssText).join("\n");
30
31
  }
31
32
  /**
@@ -34,8 +35,9 @@ function stringFromCss(value) {
34
35
  * @returns The HTML string corresponding to the specified value.
35
36
  */
36
37
  function stringFromHtml(value) {
38
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
37
39
  if (!(value instanceof DocumentFragment))
38
- return String(value);
40
+ return value === null || typeof value == "undefined" ? "" : String(value);
39
41
  const element = document.createElement("div");
40
42
  element.appendChild(value);
41
43
  return element.innerHTML;
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "name": "@cedx/base",
8
8
  "repository": "cedx/base",
9
9
  "type": "module",
10
- "version": "0.20.0",
10
+ "version": "0.21.1",
11
11
  "devDependencies": {
12
12
  "@playwright/browser-chromium": "^1.55.0",
13
13
  "@types/bootstrap": "^5.2.10",
@@ -1,6 +1,7 @@
1
1
  import {Modal} from "bootstrap";
2
- import {Context, getIcon, toCss} from "../Context.js";
2
+ import {type Context, getIcon, toCss} from "../Context.js";
3
3
  import {DialogResult} from "../DialogResult.js";
4
+ import {html} from "../Tag.js";
4
5
  import {Variant} from "../Variant.js";
5
6
  import type {DialogButton, IDialogButton} from "./DialogButton.js";
6
7
 
@@ -9,11 +10,6 @@ import type {DialogButton, IDialogButton} from "./DialogButton.js";
9
10
  */
10
11
  export interface IMessage {
11
12
 
12
- /**
13
- * Value indicating whether to apply a transition.
14
- */
15
- animation?: boolean;
16
-
17
13
  /**
18
14
  * The child content displayed in the body.
19
15
  */
@@ -24,41 +20,21 @@ export interface IMessage {
24
20
  */
25
21
  caption: string;
26
22
 
27
- /**
28
- * Value indicating whether to vertically center this message box.
29
- */
30
- centered?: boolean;
31
-
32
- /**
33
- * A contextual modifier.
34
- */
35
- context?: Context;
36
-
37
23
  /**
38
24
  * The child content displayed in the footer.
39
25
  */
40
26
  footer?: DocumentFragment;
41
-
42
- /**
43
- * The icon displayed next to the body.
44
- */
45
- icon?: string|null;
46
-
47
- /**
48
- * Value indicating whether the body is scrollable.
49
- */
50
- scrollable?: boolean;
51
27
  }
52
28
 
53
29
  /**
54
- * Displays a message window, also known as dialog box, which presents a message to the user.
30
+ * Displays a dialog box, which presents a message to the user.
55
31
  */
56
- export class MessageBox extends HTMLElement {
32
+ export class DialogBox extends HTMLElement {
57
33
 
58
34
  /**
59
35
  * The list of observed attributes.
60
36
  */
61
- static readonly observedAttributes = ["animation", "caption", "centered", "context", "icon", "modal", "scrollable"];
37
+ static readonly observedAttributes = ["caption", "centered", "fade", "modal", "scrollable"];
62
38
 
63
39
  /**
64
40
  * The template for a button.
@@ -81,7 +57,7 @@ export class MessageBox extends HTMLElement {
81
57
  #result: DialogResult = DialogResult.None;
82
58
 
83
59
  /**
84
- * Creates a new message box.
60
+ * Creates a new dialog box.
85
61
  */
86
62
  constructor() {
87
63
  super();
@@ -94,24 +70,14 @@ export class MessageBox extends HTMLElement {
94
70
  * Registers the component.
95
71
  */
96
72
  static {
97
- customElements.define("message-box", this);
98
- }
99
-
100
- /**
101
- * Value indicating whether to apply a transition.
102
- */
103
- get animation(): boolean {
104
- return this.hasAttribute("animation");
105
- }
106
- set animation(value: boolean) {
107
- this.toggleAttribute("animation", value);
73
+ customElements.define("dialog-box", this);
108
74
  }
109
75
 
110
76
  /**
111
77
  * The child content displayed in the body.
112
78
  */
113
79
  set body(value: DocumentFragment) { // eslint-disable-line accessor-pairs
114
- this.querySelector(".modal-body > div")!.replaceChildren(...value.childNodes);
80
+ this.querySelector(".modal-body")!.replaceChildren(...value.childNodes);
115
81
  }
116
82
 
117
83
  /**
@@ -125,7 +91,7 @@ export class MessageBox extends HTMLElement {
125
91
  }
126
92
 
127
93
  /**
128
- * Value indicating whether to vertically center this message box.
94
+ * Value indicating whether to vertically center this dialog box.
129
95
  */
130
96
  get centered(): boolean {
131
97
  return this.hasAttribute("centered");
@@ -135,14 +101,13 @@ export class MessageBox extends HTMLElement {
135
101
  }
136
102
 
137
103
  /**
138
- * A contextual modifier.
104
+ * Value indicating whether to apply a transition.
139
105
  */
140
- get context(): Context {
141
- const value = this.getAttribute("context") as Context;
142
- return Object.values(Context).includes(value) ? value : Context.Info;
106
+ get fade(): boolean {
107
+ return this.hasAttribute("fade");
143
108
  }
144
- set context(value: Context) {
145
- this.setAttribute("context", value);
109
+ set fade(value: boolean) {
110
+ this.toggleAttribute("fade", value);
146
111
  }
147
112
 
148
113
  /**
@@ -155,18 +120,7 @@ export class MessageBox extends HTMLElement {
155
120
  }
156
121
 
157
122
  /**
158
- * The icon displayed next to the body.
159
- */
160
- get icon(): string|null {
161
- const value = this.getAttribute("icon") ?? "";
162
- return value.trim() || null;
163
- }
164
- set icon(value: string|null) {
165
- this.toggleAttribute("icon", Boolean(value));
166
- }
167
-
168
- /**
169
- * Value indicating whether to this message box will not close when clicking outside of it.
123
+ * Value indicating whether to this dialog box will not close when clicking outside of it.
170
124
  */
171
125
  get modal(): boolean {
172
126
  return this.hasAttribute("modal");
@@ -176,7 +130,7 @@ export class MessageBox extends HTMLElement {
176
130
  }
177
131
 
178
132
  /**
179
- * Value indicating whether to initially show this message box.
133
+ * Value indicating whether to initially show this component.
180
134
  */
181
135
  get open(): boolean {
182
136
  return this.hasAttribute("open");
@@ -203,13 +157,11 @@ export class MessageBox extends HTMLElement {
203
157
  */
204
158
  attributeChangedCallback(attribute: string, oldValue: string|null, newValue: string|null): void {
205
159
  if (newValue != oldValue) switch (attribute) {
206
- case "animation": this.#updateAnimation(newValue != null); break;
207
160
  case "caption": this.#updateCaption(newValue ?? ""); break;
208
161
  case "centered": this.#updateCentered(newValue != null); break;
209
- case "context": this.#updateContext(Object.values(Context).includes(newValue as Context) ? newValue as Context : Context.Info); break;
210
- case "icon": this.#updateIcon(newValue); break;
211
162
  case "modal": this.#updateModal(newValue != null); break;
212
- case "scrollable": this.#updateScrolling(newValue != null); break;
163
+ case "fade": this.#updateFade(newValue != null); break;
164
+ case "scrollable": this.#updateScrollable(newValue != null); break;
213
165
  // No default
214
166
  }
215
167
  }
@@ -221,14 +173,14 @@ export class MessageBox extends HTMLElement {
221
173
  * @param body The child content displayed in the body.
222
174
  * @returns The dialog box result.
223
175
  */
224
- async alert(context: Context, caption: string, body: DocumentFragment): Promise<DialogResult> {
225
- return await this.show(context, caption, body, [
176
+ alert(context: Context, caption: string, body: DocumentFragment): Promise<DialogResult> {
177
+ return this.show(context, caption, this.#getBodyTemplate(context, body), [
226
178
  {label: "OK", value: DialogResult.OK, variant: Variant.Primary}
227
179
  ]);
228
180
  }
229
181
 
230
182
  /**
231
- * Closes this message box.
183
+ * Closes this dialog box.
232
184
  * @param result The dialog box result.
233
185
  */
234
186
  close(result: DialogResult = DialogResult.None): void {
@@ -243,8 +195,8 @@ export class MessageBox extends HTMLElement {
243
195
  * @param body The child content displayed in the body.
244
196
  * @returns The dialog box result.
245
197
  */
246
- async confirm(context: Context, caption: string, body: DocumentFragment): Promise<DialogResult> {
247
- return await this.show(context, caption, body, [
198
+ confirm(context: Context, caption: string, body: DocumentFragment): Promise<DialogResult> {
199
+ return this.show(context, caption, this.#getBodyTemplate(context, body), [
248
200
  {label: "OK", value: DialogResult.OK, variant: Variant.Primary},
249
201
  {label: "Annuler", value: DialogResult.Cancel, variant: Variant.Secondary}
250
202
  ]);
@@ -294,17 +246,14 @@ export class MessageBox extends HTMLElement {
294
246
  if (typeof message == "string") {
295
247
  const footer = document.createDocumentFragment();
296
248
  footer.append(...buttons.map(button => this.#createButton(button)));
297
- message = {context: message, caption, body, footer};
249
+ message = {body, caption, footer};
298
250
  }
299
251
 
300
- if (typeof message == "object" && message) {
301
- this.body = message.body;
302
- this.caption = message.caption;
303
- this.context = message.context ?? Context.Info;
304
- this.icon = message.icon ?? getIcon(this.context);
305
-
252
+ if (message) {
306
253
  const footer = message.footer ?? document.createDocumentFragment();
307
254
  for (const button of footer.querySelectorAll("button")) button.addEventListener("click", this.#close);
255
+ this.body = message.body;
256
+ this.caption = message.caption;
308
257
  this.footer = footer;
309
258
  }
310
259
 
@@ -316,7 +265,7 @@ export class MessageBox extends HTMLElement {
316
265
  }
317
266
 
318
267
  /**
319
- * Closes this message box.
268
+ * Closes this dialog box.
320
269
  * @param event The dispatched event.
321
270
  */
322
271
  readonly #close: (event: Event) => void = event => {
@@ -344,11 +293,18 @@ export class MessageBox extends HTMLElement {
344
293
  }
345
294
 
346
295
  /**
347
- * Updates the message box animation.
348
- * @param value The new value.
296
+ * Gets the body template corresponding to the specified context and message.
297
+ * @param context The contextual modifier.
298
+ * @param message The child content displayed in the body.
299
+ * @returns The body template corresponding to the specified context and message.
349
300
  */
350
- #updateAnimation(value: boolean): void {
351
- this.firstElementChild!.classList.toggle("fade", value);
301
+ #getBodyTemplate(context: Context, message: DocumentFragment): DocumentFragment {
302
+ return html`
303
+ <div class="d-flex gap-2">
304
+ <i class="icon icon-fill fs-1 text-${toCss(context)}"> ${getIcon(context)}</i>
305
+ <div class="flex-grow-1">${message}</div>
306
+ </div>
307
+ `;
352
308
  }
353
309
 
354
310
  /**
@@ -360,7 +316,7 @@ export class MessageBox extends HTMLElement {
360
316
  }
361
317
 
362
318
  /**
363
- * Updates the value indicating whether to vertically center this message box.
319
+ * Updates the value indicating whether to vertically center this dialog box.
364
320
  * @param value The new value.
365
321
  */
366
322
  #updateCentered(value: boolean): void {
@@ -368,25 +324,15 @@ export class MessageBox extends HTMLElement {
368
324
  }
369
325
 
370
326
  /**
371
- * Updates the contextual modifier.
372
- * @param value The new value.
373
- */
374
- #updateContext(value: Context): void {
375
- const {classList} = this.querySelector(".modal-body > .icon")!;
376
- classList.remove(...Object.values(Context).map(context => `text-${toCss(context)}`));
377
- classList.add(`text-${toCss(value)}`);
378
- }
379
-
380
- /**
381
- * Updates the icon displayed next to the body.
327
+ * Updates the value indicating whether to apply a transition.
382
328
  * @param value The new value.
383
329
  */
384
- #updateIcon(value: string|null): void {
385
- this.querySelector(".modal-body > .icon")!.textContent = (value ?? "").trim() || getIcon(this.context);
330
+ #updateFade(value: boolean): void {
331
+ this.firstElementChild!.classList.toggle("fade", value);
386
332
  }
387
333
 
388
334
  /**
389
- * Updates the value indicating whether to this message box will not close when clicking outside of it.
335
+ * Updates the value indicating whether to this dialog box will not close when clicking outside of it.
390
336
  * @param value The new value.
391
337
  */
392
338
  #updateModal(value: boolean): void {
@@ -394,10 +340,10 @@ export class MessageBox extends HTMLElement {
394
340
  }
395
341
 
396
342
  /**
397
- * Updates the body scrolling.
343
+ * Updates the value indicating whether the body is scrollable.
398
344
  * @param value The new value.
399
345
  */
400
- #updateScrolling(value: boolean): void {
346
+ #updateScrollable(value: boolean): void {
401
347
  this.querySelector(".modal-dialog")!.classList.toggle("modal-dialog-scrollable", value);
402
348
  }
403
349
  }
@@ -411,6 +357,6 @@ declare global {
411
357
  * The map of HTML tag names.
412
358
  */
413
359
  interface HTMLElementTagNameMap {
414
- "message-box": MessageBox;
360
+ "dialog-box": DialogBox;
415
361
  }
416
362
  }
@@ -6,7 +6,7 @@ export class LoadingIndicator extends HTMLElement {
6
6
  /**
7
7
  * The list of observed attributes.
8
8
  */
9
- static readonly observedAttributes = ["animation"];
9
+ static readonly observedAttributes = ["fade"];
10
10
 
11
11
  /**
12
12
  * The number of concurrent HTTP requests.
@@ -23,11 +23,21 @@ export class LoadingIndicator extends HTMLElement {
23
23
  /**
24
24
  * Value indicating whether to apply a transition.
25
25
  */
26
- get animation(): boolean {
27
- return this.hasAttribute("animation");
26
+ get fade(): boolean {
27
+ return this.hasAttribute("fade");
28
28
  }
29
- set animation(value: boolean) {
30
- this.toggleAttribute("animation", value);
29
+ set fade(value: boolean) {
30
+ this.toggleAttribute("fade", value);
31
+ }
32
+
33
+ /**
34
+ * Value indicating whether to initially show this component.
35
+ */
36
+ get open(): boolean {
37
+ return this.hasAttribute("open");
38
+ }
39
+ set open(value: boolean) {
40
+ this.toggleAttribute("open", value);
31
41
  }
32
42
 
33
43
  /**
@@ -38,13 +48,20 @@ export class LoadingIndicator extends HTMLElement {
38
48
  */
39
49
  attributeChangedCallback(attribute: string, oldValue: string|null, newValue: string|null): void {
40
50
  if (newValue != oldValue) switch (attribute) {
41
- case "animation": this.#updateAnimation(newValue != null); break;
51
+ case "fade": this.#updateFade(newValue != null); break;
42
52
  // No default
43
53
  }
44
54
  }
45
55
 
46
56
  /**
47
- * Hides the loading indicator.
57
+ * Method invoked when this component is connected.
58
+ */
59
+ connectedCallback(): void {
60
+ if (this.open) this.show();
61
+ }
62
+
63
+ /**
64
+ * Hides this loading indicator.
48
65
  * @param options Value indicating whether to force the loading indicator to hide.
49
66
  */
50
67
  hide(options: {force?: boolean} = {}): void {
@@ -58,7 +75,7 @@ export class LoadingIndicator extends HTMLElement {
58
75
  }
59
76
 
60
77
  /**
61
- * Shows the loading indicator.
78
+ * Shows this loading indicator.
62
79
  */
63
80
  show(): void {
64
81
  this.#requestCount++;
@@ -71,7 +88,7 @@ export class LoadingIndicator extends HTMLElement {
71
88
  * Updates the value indicating whether to apply a transition.
72
89
  * @param value The new value.
73
90
  */
74
- #updateAnimation(value: boolean): void {
91
+ #updateFade(value: boolean): void {
75
92
  this.classList.toggle("fade", value);
76
93
  }
77
94
  }