@nectary/components 5.38.0 → 5.38.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.
package/bundle.js CHANGED
@@ -15893,7 +15893,7 @@ class Toast extends NectaryElement {
15893
15893
  this.#clearTimeout();
15894
15894
  }
15895
15895
  static get observedAttributes() {
15896
- return ["text", "persistent"];
15896
+ return ["text", "type", "persistent"];
15897
15897
  }
15898
15898
  attributeChangedCallback(name, oldVal, newVal) {
15899
15899
  switch (name) {
@@ -15901,6 +15901,7 @@ class Toast extends NectaryElement {
15901
15901
  updateAttribute(this.#$text, name, newVal);
15902
15902
  break;
15903
15903
  }
15904
+ case "type":
15904
15905
  case "persistent": {
15905
15906
  this.#updateTimeout();
15906
15907
  break;
@@ -15926,7 +15927,8 @@ class Toast extends NectaryElement {
15926
15927
  updateBooleanAttribute(this, "persistent", isPersistent);
15927
15928
  }
15928
15929
  #updateTimeout() {
15929
- if (this.persistent) {
15930
+ const type = getAttribute(this, "type");
15931
+ if (this.persistent || type === "error" || type === "warn") {
15930
15932
  this.#clearTimeout();
15931
15933
  return;
15932
15934
  }
@@ -15950,7 +15952,7 @@ class Toast extends NectaryElement {
15950
15952
  }
15951
15953
  defineCustomElement("sinch-toast", Toast);
15952
15954
  const originValues = ["bottom-right", "top-right"];
15953
- const templateHTML$1 = '<style>:host{display:block}#items{display:block;width:0;height:0;visibility:hidden;overflow:hidden}#list{display:flex;flex-direction:column;position:fixed;z-index:1;bottom:0;right:16px}:host([origin=top-right]) #list{flex-direction:column-reverse;bottom:unset;top:16px}.item-wrapper{height:0;opacity:0;position:relative}.item-wrapper[data-deleting]::after{content:"";position:absolute;top:0;left:0;bottom:0;right:0}</style><slot id="items"></slot><div id="list" aria-live="polite"></div>';
15955
+ const templateHTML$1 = '<style>:host{display:block}#items{display:block;width:0;height:0;visibility:hidden;overflow:hidden}#list{display:flex;flex-direction:column;position:fixed;z-index:1;bottom:0;right:16px}:host([origin=top-right]) #list{flex-direction:column-reverse;bottom:unset;top:16px}.item-wrapper{height:0;opacity:0;position:relative}.item-wrapper[data-deleting]::after{content:"";position:absolute;top:0;left:0;bottom:0;right:0}</style><slot id="items"></slot><div id="list" role="status" aria-live="polite" aria-atomic="false"></div>';
15954
15956
  const DURATION_ADD = 250;
15955
15957
  const DURATION_REMOVE = 250;
15956
15958
  const ITEMS_GAP = 16;
@@ -16061,6 +16063,27 @@ class ToastManager extends NectaryElement {
16061
16063
  this.#onAnimateRemove(item, removeIndex);
16062
16064
  ++removeIndex;
16063
16065
  }
16066
+ let hasNewItems = false;
16067
+ let isAssertive = false;
16068
+ for (const item of slotItems) {
16069
+ if (this.#map.has(item)) {
16070
+ continue;
16071
+ }
16072
+ hasNewItems = true;
16073
+ if (item instanceof Toast) {
16074
+ const type = item.type;
16075
+ if (type === "error" || type === "warn") {
16076
+ isAssertive = true;
16077
+ }
16078
+ }
16079
+ }
16080
+ if (slotItems.length === 0) {
16081
+ this.#$list.setAttribute("role", "status");
16082
+ this.#$list.setAttribute("aria-live", "polite");
16083
+ } else if (hasNewItems) {
16084
+ this.#$list.setAttribute("role", isAssertive ? "alert" : "status");
16085
+ this.#$list.setAttribute("aria-live", isAssertive ? "assertive" : "polite");
16086
+ }
16064
16087
  let addIndex = 0;
16065
16088
  for (const item of slotItems) {
16066
16089
  if (this.#map.has(item)) {
@@ -16069,12 +16092,6 @@ class ToastManager extends NectaryElement {
16069
16092
  const cloned = cloneNode(item, true);
16070
16093
  const rect = item.getBoundingClientRect();
16071
16094
  const wrapper = document.createElement("div");
16072
- if (item instanceof Toast) {
16073
- if (item.hasAttribute("type")) {
16074
- const type = item.type;
16075
- this.#$list.setAttribute("aria-live", type === "error" || type === "warn" ? "assertive" : "polite");
16076
- }
16077
- }
16078
16095
  wrapper.className = "item-wrapper";
16079
16096
  wrapper.appendChild(cloned);
16080
16097
  this.#$list.appendChild(wrapper);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nectary/components",
3
- "version": "5.38.0",
3
+ "version": "5.38.1",
4
4
  "files": [
5
5
  "**/*/*.css",
6
6
  "**/*/*.json",
package/toast/index.js CHANGED
@@ -29,7 +29,7 @@ class Toast extends NectaryElement {
29
29
  this.#clearTimeout();
30
30
  }
31
31
  static get observedAttributes() {
32
- return ["text", "persistent"];
32
+ return ["text", "type", "persistent"];
33
33
  }
34
34
  attributeChangedCallback(name, oldVal, newVal) {
35
35
  switch (name) {
@@ -37,6 +37,7 @@ class Toast extends NectaryElement {
37
37
  updateAttribute(this.#$text, name, newVal);
38
38
  break;
39
39
  }
40
+ case "type":
40
41
  case "persistent": {
41
42
  this.#updateTimeout();
42
43
  break;
@@ -62,7 +63,8 @@ class Toast extends NectaryElement {
62
63
  updateBooleanAttribute(this, "persistent", isPersistent);
63
64
  }
64
65
  #updateTimeout() {
65
- if (this.persistent) {
66
+ const type = getAttribute(this, "type");
67
+ if (this.persistent || type === "error" || type === "warn") {
66
68
  this.#clearTimeout();
67
69
  return;
68
70
  }
package/toast/types.d.ts CHANGED
@@ -5,7 +5,7 @@ export type TSinchToastProps = {
5
5
  type: TSinchToastType;
6
6
  /** Text */
7
7
  text: string;
8
- /** Persistent, i.e. doesn't automatically dissapear after 5s */
8
+ /** Persistent, i.e. doesn't automatically disappear after 5s. Error and warn toasts are always persistent. */
9
9
  persistent?: boolean;
10
10
  };
11
11
  export type TSinchToastEvents = {
@@ -5,7 +5,7 @@ import { shouldReduceMotion, getLiteralAttribute, updateLiteralAttribute, cloneN
5
5
  import { defineCustomElement, NectaryElement } from "../utils/element.js";
6
6
  import { getRect } from "../utils/rect.js";
7
7
  import { originValues } from "./utils.js";
8
- const templateHTML = '<style>:host{display:block}#items{display:block;width:0;height:0;visibility:hidden;overflow:hidden}#list{display:flex;flex-direction:column;position:fixed;z-index:1;bottom:0;right:16px}:host([origin=top-right]) #list{flex-direction:column-reverse;bottom:unset;top:16px}.item-wrapper{height:0;opacity:0;position:relative}.item-wrapper[data-deleting]::after{content:"";position:absolute;top:0;left:0;bottom:0;right:0}</style><slot id="items"></slot><div id="list" aria-live="polite"></div>';
8
+ const templateHTML = '<style>:host{display:block}#items{display:block;width:0;height:0;visibility:hidden;overflow:hidden}#list{display:flex;flex-direction:column;position:fixed;z-index:1;bottom:0;right:16px}:host([origin=top-right]) #list{flex-direction:column-reverse;bottom:unset;top:16px}.item-wrapper{height:0;opacity:0;position:relative}.item-wrapper[data-deleting]::after{content:"";position:absolute;top:0;left:0;bottom:0;right:0}</style><slot id="items"></slot><div id="list" role="status" aria-live="polite" aria-atomic="false"></div>';
9
9
  const DURATION_ADD = 250;
10
10
  const DURATION_REMOVE = 250;
11
11
  const ITEMS_GAP = 16;
@@ -116,6 +116,27 @@ class ToastManager extends NectaryElement {
116
116
  this.#onAnimateRemove(item, removeIndex);
117
117
  ++removeIndex;
118
118
  }
119
+ let hasNewItems = false;
120
+ let isAssertive = false;
121
+ for (const item of slotItems) {
122
+ if (this.#map.has(item)) {
123
+ continue;
124
+ }
125
+ hasNewItems = true;
126
+ if (item instanceof Toast) {
127
+ const type = item.type;
128
+ if (type === "error" || type === "warn") {
129
+ isAssertive = true;
130
+ }
131
+ }
132
+ }
133
+ if (slotItems.length === 0) {
134
+ this.#$list.setAttribute("role", "status");
135
+ this.#$list.setAttribute("aria-live", "polite");
136
+ } else if (hasNewItems) {
137
+ this.#$list.setAttribute("role", isAssertive ? "alert" : "status");
138
+ this.#$list.setAttribute("aria-live", isAssertive ? "assertive" : "polite");
139
+ }
119
140
  let addIndex = 0;
120
141
  for (const item of slotItems) {
121
142
  if (this.#map.has(item)) {
@@ -124,12 +145,6 @@ class ToastManager extends NectaryElement {
124
145
  const cloned = cloneNode(item, true);
125
146
  const rect = item.getBoundingClientRect();
126
147
  const wrapper = document.createElement("div");
127
- if (item instanceof Toast) {
128
- if (item.hasAttribute("type")) {
129
- const type = item.type;
130
- this.#$list.setAttribute("aria-live", type === "error" || type === "warn" ? "assertive" : "polite");
131
- }
132
- }
133
148
  wrapper.className = "item-wrapper";
134
149
  wrapper.appendChild(cloned);
135
150
  this.#$list.appendChild(wrapper);