sonner-wc 0.1.2 → 0.3.0
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/README.md +59 -2
- package/dist/constants.d.ts +0 -2
- package/dist/icons.d.ts +0 -1
- package/dist/sonner-toast.d.ts +1 -2
- package/dist/sonner-toaster.d.ts +1 -2
- package/dist/sonner-wc.bundle.js +39 -25
- package/dist/sonner-wc.bundle.js.map +8 -7
- package/dist/sonner-wc.js +201 -141
- package/dist/sonner-wc.js.map +8 -7
- package/dist/ssr.d.ts +1 -0
- package/package.json +1 -1
package/dist/sonner-wc.js
CHANGED
|
@@ -14,8 +14,6 @@ var WARNING_ICON = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
|
|
|
14
14
|
var INFO_ICON = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" height="20" width="20"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z" clip-rule="evenodd"/></svg>';
|
|
15
15
|
var ERROR_ICON = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" height="20" width="20"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/></svg>';
|
|
16
16
|
var CLOSE_ICON = '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>';
|
|
17
|
-
var SPINNER_BARS = Array.from({ length: 12 }, () => '<div class="sonner-loading-bar"></div>').join("");
|
|
18
|
-
var LOADING_SPINNER = '<div class="sonner-loading-wrapper" data-visible="true"><div class="sonner-spinner">' + SPINNER_BARS + "</div></div>";
|
|
19
17
|
function getTypeIcon(type) {
|
|
20
18
|
switch (type) {
|
|
21
19
|
case "success":
|
|
@@ -68,6 +66,10 @@ function dismissAllToasts() {
|
|
|
68
66
|
t.dismissAll();
|
|
69
67
|
}
|
|
70
68
|
|
|
69
|
+
// src/ssr.ts
|
|
70
|
+
var HTMLElementCtor = typeof HTMLElement !== "undefined" ? HTMLElement : class {
|
|
71
|
+
};
|
|
72
|
+
|
|
71
73
|
// src/styles/toaster.css
|
|
72
74
|
var toaster_default = `:host {
|
|
73
75
|
position: fixed;
|
|
@@ -119,15 +121,30 @@ var toaster_default = `:host {
|
|
|
119
121
|
--toast-close-button-start: 0;
|
|
120
122
|
--toast-close-button-end: unset;
|
|
121
123
|
--toast-close-button-transform: translate(-35%, -35%);
|
|
124
|
+
inset: unset;
|
|
125
|
+
border: none;
|
|
126
|
+
overflow: visible;
|
|
127
|
+
background: transparent;
|
|
122
128
|
box-sizing: border-box;
|
|
123
129
|
padding: 0;
|
|
124
130
|
margin: 0;
|
|
125
131
|
outline: none;
|
|
132
|
+
contain: layout style;
|
|
126
133
|
z-index: 999999999;
|
|
127
134
|
transition: transform 400ms ease;
|
|
128
135
|
display: block;
|
|
129
136
|
}
|
|
130
137
|
|
|
138
|
+
::backdrop {
|
|
139
|
+
display: none;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
:host(:focus-visible) {
|
|
143
|
+
outline: 2px solid var(--gray9);
|
|
144
|
+
outline-offset: 4px;
|
|
145
|
+
border-radius: var(--border-radius);
|
|
146
|
+
}
|
|
147
|
+
|
|
131
148
|
[data-frame] {
|
|
132
149
|
display: block;
|
|
133
150
|
width: 100%;
|
|
@@ -245,6 +262,8 @@ var toast_default = `:host {
|
|
|
245
262
|
position: absolute;
|
|
246
263
|
opacity: 0;
|
|
247
264
|
transform: var(--y);
|
|
265
|
+
contain: layout style;
|
|
266
|
+
will-change: transform, opacity;
|
|
248
267
|
touch-action: none;
|
|
249
268
|
transition:
|
|
250
269
|
transform 400ms,
|
|
@@ -399,16 +418,14 @@ var toast_default = `:host {
|
|
|
399
418
|
animation: sonner-fade-in 300ms ease forwards;
|
|
400
419
|
}
|
|
401
420
|
|
|
402
|
-
[data-button]
|
|
403
|
-
::slotted(button[slot='action']),
|
|
404
|
-
::slotted(button[slot='cancel']) {
|
|
421
|
+
[data-button] {
|
|
405
422
|
border-radius: 4px;
|
|
406
423
|
padding-left: 8px;
|
|
407
424
|
padding-right: 8px;
|
|
408
425
|
height: 24px;
|
|
409
426
|
font-size: 12px;
|
|
410
427
|
background: var(--normal-text);
|
|
411
|
-
color:
|
|
428
|
+
color: var(--normal-bg);
|
|
412
429
|
margin-left: var(--toast-button-margin-start);
|
|
413
430
|
margin-right: var(--toast-button-margin-end);
|
|
414
431
|
border: none;
|
|
@@ -426,8 +443,7 @@ var toast_default = `:host {
|
|
|
426
443
|
[data-button]:focus-visible {
|
|
427
444
|
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.4);
|
|
428
445
|
}
|
|
429
|
-
[data-cancel]
|
|
430
|
-
::slotted(button[slot='cancel']) {
|
|
446
|
+
[data-cancel] {
|
|
431
447
|
color: var(--normal-text);
|
|
432
448
|
background: var(--cancel-bg, rgba(0, 0, 0, 0.08));
|
|
433
449
|
}
|
|
@@ -814,16 +830,34 @@ function getToastSheet() {
|
|
|
814
830
|
}
|
|
815
831
|
|
|
816
832
|
// src/sonner-toast.ts
|
|
817
|
-
var HTMLElementCtor = typeof HTMLElement !== "undefined" ? HTMLElement : class {
|
|
818
|
-
};
|
|
819
833
|
function isUrgentType(type) {
|
|
820
834
|
return type === "error" || type === "warning";
|
|
821
835
|
}
|
|
822
|
-
function
|
|
836
|
+
function boolAttr(host, name) {
|
|
837
|
+
return host.hasAttribute(name) && host.getAttribute(name) !== "false";
|
|
838
|
+
}
|
|
839
|
+
function toggleAttr(host, name, on) {
|
|
840
|
+
if (on)
|
|
841
|
+
host.setAttribute(name, "");
|
|
842
|
+
else
|
|
843
|
+
host.removeAttribute(name);
|
|
844
|
+
}
|
|
845
|
+
function clearSlot(host, slotName) {
|
|
823
846
|
for (const child of Array.from(host.children)) {
|
|
824
847
|
if (child.getAttribute("slot") === slotName)
|
|
825
848
|
host.removeChild(child);
|
|
826
849
|
}
|
|
850
|
+
}
|
|
851
|
+
function slotElementFromHTML(html, slotName) {
|
|
852
|
+
const tpl = document.createElement("template");
|
|
853
|
+
tpl.innerHTML = html;
|
|
854
|
+
const el = tpl.content.firstElementChild;
|
|
855
|
+
if (el)
|
|
856
|
+
el.setAttribute("slot", slotName);
|
|
857
|
+
return el;
|
|
858
|
+
}
|
|
859
|
+
function setContent(host, slotName, value) {
|
|
860
|
+
clearSlot(host, slotName);
|
|
827
861
|
if (value == null || value === "")
|
|
828
862
|
return;
|
|
829
863
|
const resolved = typeof value === "function" ? value() : value;
|
|
@@ -838,10 +872,14 @@ function setContent(host, slotName, value) {
|
|
|
838
872
|
host.appendChild(span);
|
|
839
873
|
}
|
|
840
874
|
}
|
|
841
|
-
function setButtonSlot(host, slotName, value, defaultCloseHandler) {
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
875
|
+
function setButtonSlot(host, shadow, slotName, value, defaultCloseHandler) {
|
|
876
|
+
clearSlot(host, slotName);
|
|
877
|
+
const container = shadow.querySelector(`[data-${slotName}-host]`);
|
|
878
|
+
if (container) {
|
|
879
|
+
for (const child of Array.from(container.children)) {
|
|
880
|
+
if (child.tagName === "BUTTON")
|
|
881
|
+
container.removeChild(child);
|
|
882
|
+
}
|
|
845
883
|
}
|
|
846
884
|
if (!value)
|
|
847
885
|
return;
|
|
@@ -850,13 +888,12 @@ function setButtonSlot(host, slotName, value, defaultCloseHandler) {
|
|
|
850
888
|
host.appendChild(value);
|
|
851
889
|
return;
|
|
852
890
|
}
|
|
891
|
+
if (!container)
|
|
892
|
+
return;
|
|
853
893
|
const btn = document.createElement("button");
|
|
854
|
-
btn.setAttribute("slot", slotName);
|
|
855
894
|
btn.setAttribute("type", "button");
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
else
|
|
859
|
-
btn.setAttribute("data-action", "");
|
|
895
|
+
btn.setAttribute("data-button", "");
|
|
896
|
+
btn.setAttribute(slotName === "cancel" ? "data-cancel" : "data-action", "");
|
|
860
897
|
btn.textContent = value.label;
|
|
861
898
|
btn.addEventListener("click", (e) => {
|
|
862
899
|
value.onClick?.(e);
|
|
@@ -864,27 +901,33 @@ function setButtonSlot(host, slotName, value, defaultCloseHandler) {
|
|
|
864
901
|
return;
|
|
865
902
|
defaultCloseHandler();
|
|
866
903
|
});
|
|
867
|
-
|
|
904
|
+
container.appendChild(btn);
|
|
868
905
|
}
|
|
869
906
|
var SPINNER_BARS_HTML = Array.from({ length: 12 }, () => '<div class="sonner-loading-bar"></div>').join("");
|
|
870
|
-
var SHADOW_TEMPLATE =
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
907
|
+
var SHADOW_TEMPLATE = (() => {
|
|
908
|
+
if (typeof document === "undefined")
|
|
909
|
+
return null;
|
|
910
|
+
const tpl = document.createElement("template");
|
|
911
|
+
tpl.innerHTML = `
|
|
912
|
+
<div data-frame part="frame">
|
|
913
|
+
<button type="button" data-close-button part="close-button" hidden aria-label="Close toast"></button>
|
|
914
|
+
<div data-icon part="icon">
|
|
915
|
+
<slot name="icon"></slot>
|
|
916
|
+
<div class="sonner-loading-wrapper" aria-hidden="true">
|
|
917
|
+
<div class="sonner-spinner">${SPINNER_BARS_HTML}</div>
|
|
918
|
+
</div>
|
|
877
919
|
</div>
|
|
920
|
+
<div data-content part="content">
|
|
921
|
+
<div data-title part="title"><slot name="title"></slot></div>
|
|
922
|
+
<div data-description part="description"><slot name="description"></slot></div>
|
|
923
|
+
</div>
|
|
924
|
+
<div data-cancel-host part="cancel"><slot name="cancel"></slot></div>
|
|
925
|
+
<div data-action-host part="action"><slot name="action"></slot></div>
|
|
926
|
+
<slot part="custom"></slot>
|
|
878
927
|
</div>
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
</div>
|
|
883
|
-
<slot name="cancel"></slot>
|
|
884
|
-
<slot name="action"></slot>
|
|
885
|
-
<slot part="custom"></slot>
|
|
886
|
-
</div>
|
|
887
|
-
`;
|
|
928
|
+
`;
|
|
929
|
+
return tpl;
|
|
930
|
+
})();
|
|
888
931
|
|
|
889
932
|
class SonnerToast extends HTMLElementCtor {
|
|
890
933
|
static get observedAttributes() {
|
|
@@ -916,9 +959,7 @@ class SonnerToast extends HTMLElementCtor {
|
|
|
916
959
|
super();
|
|
917
960
|
this.#shadow = this.attachShadow({ mode: "open" });
|
|
918
961
|
this.#shadow.adoptedStyleSheets = [getToastSheet()];
|
|
919
|
-
|
|
920
|
-
tpl.innerHTML = SHADOW_TEMPLATE;
|
|
921
|
-
this.#shadow.appendChild(tpl.content.cloneNode(true));
|
|
962
|
+
this.#shadow.appendChild(SHADOW_TEMPLATE.content.cloneNode(true));
|
|
922
963
|
this.#closeBtn = this.#shadow.querySelector("[data-close-button]");
|
|
923
964
|
this.#iconWrap = this.#shadow.querySelector("[data-icon]");
|
|
924
965
|
this.#titleWrap = this.#shadow.querySelector("[data-title]");
|
|
@@ -1061,32 +1102,16 @@ class SonnerToast extends HTMLElementCtor {
|
|
|
1061
1102
|
this.#remainingTime = 0;
|
|
1062
1103
|
timerNeedsReset = true;
|
|
1063
1104
|
}
|
|
1064
|
-
if (options.dismissible !== undefined)
|
|
1065
|
-
|
|
1066
|
-
this.setAttribute("dismissible", "");
|
|
1067
|
-
else
|
|
1068
|
-
this.removeAttribute("dismissible");
|
|
1069
|
-
}
|
|
1105
|
+
if (options.dismissible !== undefined)
|
|
1106
|
+
toggleAttr(this, "dismissible", options.dismissible);
|
|
1070
1107
|
if (options.position !== undefined)
|
|
1071
1108
|
this.setAttribute("position", options.position);
|
|
1072
|
-
if (options.closeButton !== undefined)
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
if (options.richColors !== undefined) {
|
|
1079
|
-
if (options.richColors)
|
|
1080
|
-
this.setAttribute("rich-colors", "");
|
|
1081
|
-
else
|
|
1082
|
-
this.removeAttribute("rich-colors");
|
|
1083
|
-
}
|
|
1084
|
-
if (options.invert !== undefined) {
|
|
1085
|
-
if (options.invert)
|
|
1086
|
-
this.setAttribute("invert", "");
|
|
1087
|
-
else
|
|
1088
|
-
this.removeAttribute("invert");
|
|
1089
|
-
}
|
|
1109
|
+
if (options.closeButton !== undefined)
|
|
1110
|
+
toggleAttr(this, "close-button", options.closeButton);
|
|
1111
|
+
if (options.richColors !== undefined)
|
|
1112
|
+
toggleAttr(this, "rich-colors", options.richColors);
|
|
1113
|
+
if (options.invert !== undefined)
|
|
1114
|
+
toggleAttr(this, "invert", options.invert);
|
|
1090
1115
|
if (options.icon !== undefined)
|
|
1091
1116
|
this.setIcon(options.icon);
|
|
1092
1117
|
if (options.title !== undefined)
|
|
@@ -1094,10 +1119,10 @@ class SonnerToast extends HTMLElementCtor {
|
|
|
1094
1119
|
if (options.description !== undefined)
|
|
1095
1120
|
this.setDescription(options.description);
|
|
1096
1121
|
if (options.action !== undefined) {
|
|
1097
|
-
setButtonSlot(this, "action", options.action, () => this.dismiss());
|
|
1122
|
+
setButtonSlot(this, this.#shadow, "action", options.action, () => this.dismiss());
|
|
1098
1123
|
}
|
|
1099
1124
|
if (options.cancel !== undefined) {
|
|
1100
|
-
setButtonSlot(this, "cancel", options.cancel, () => this.dismiss());
|
|
1125
|
+
setButtonSlot(this, this.#shadow, "cancel", options.cancel, () => this.dismiss());
|
|
1101
1126
|
}
|
|
1102
1127
|
if (options.className)
|
|
1103
1128
|
this.className = options.className;
|
|
@@ -1114,8 +1139,7 @@ class SonnerToast extends HTMLElementCtor {
|
|
|
1114
1139
|
if (timerNeedsReset)
|
|
1115
1140
|
this.#resetTimer();
|
|
1116
1141
|
if (this.#mounted && typeChanged && !wasUrgent && isUrgentType(this.toastType)) {
|
|
1117
|
-
const
|
|
1118
|
-
const text = titleEl?.textContent?.trim();
|
|
1142
|
+
const text = this.#getTitleText();
|
|
1119
1143
|
if (text) {
|
|
1120
1144
|
const toaster = this.closest("sonner-toaster");
|
|
1121
1145
|
toaster?.announceUrgent(text);
|
|
@@ -1127,23 +1151,23 @@ class SonnerToast extends HTMLElementCtor {
|
|
|
1127
1151
|
setContent(this, "title", value);
|
|
1128
1152
|
this.#applyCloseButtonAriaLabel();
|
|
1129
1153
|
}
|
|
1154
|
+
#getTitleText() {
|
|
1155
|
+
const titleEl = Array.from(this.children).find((c) => c.getAttribute("slot") === "title");
|
|
1156
|
+
return titleEl?.textContent?.trim() ?? "";
|
|
1157
|
+
}
|
|
1130
1158
|
#applyCloseButtonAriaLabel() {
|
|
1131
1159
|
if (this.#closeButtonAriaLabel) {
|
|
1132
1160
|
this.#closeBtn.setAttribute("aria-label", this.#closeButtonAriaLabel);
|
|
1133
1161
|
return;
|
|
1134
1162
|
}
|
|
1135
|
-
const
|
|
1136
|
-
const text = titleEl?.textContent?.trim();
|
|
1163
|
+
const text = this.#getTitleText();
|
|
1137
1164
|
this.#closeBtn.setAttribute("aria-label", text ? `Close: ${text}` : "Close toast");
|
|
1138
1165
|
}
|
|
1139
1166
|
setDescription(value) {
|
|
1140
1167
|
setContent(this, "description", value);
|
|
1141
1168
|
}
|
|
1142
1169
|
setIcon(value) {
|
|
1143
|
-
|
|
1144
|
-
if (child.getAttribute("slot") === "icon")
|
|
1145
|
-
this.removeChild(child);
|
|
1146
|
-
}
|
|
1170
|
+
clearSlot(this, "icon");
|
|
1147
1171
|
if (value == null)
|
|
1148
1172
|
return;
|
|
1149
1173
|
if (value instanceof Node) {
|
|
@@ -1151,13 +1175,9 @@ class SonnerToast extends HTMLElementCtor {
|
|
|
1151
1175
|
value.setAttribute("slot", "icon");
|
|
1152
1176
|
this.appendChild(value);
|
|
1153
1177
|
} else {
|
|
1154
|
-
const
|
|
1155
|
-
|
|
1156
|
-
const el = tpl.content.firstElementChild;
|
|
1157
|
-
if (el) {
|
|
1158
|
-
el.setAttribute("slot", "icon");
|
|
1178
|
+
const el = slotElementFromHTML(value, "icon");
|
|
1179
|
+
if (el)
|
|
1159
1180
|
this.appendChild(el);
|
|
1160
|
-
}
|
|
1161
1181
|
}
|
|
1162
1182
|
}
|
|
1163
1183
|
setHandlers(handlers) {
|
|
@@ -1183,36 +1203,25 @@ class SonnerToast extends HTMLElementCtor {
|
|
|
1183
1203
|
const urgent = isUrgentType(type);
|
|
1184
1204
|
this.setAttribute("role", urgent ? "alert" : "status");
|
|
1185
1205
|
this.setAttribute("aria-live", urgent ? "assertive" : "polite");
|
|
1206
|
+
for (const c of Array.from(this.children)) {
|
|
1207
|
+
if (c.getAttribute("slot") === "icon" && c.hasAttribute("data-sonner-default-icon"))
|
|
1208
|
+
this.removeChild(c);
|
|
1209
|
+
}
|
|
1186
1210
|
if (type === "loading") {
|
|
1187
1211
|
this.setAttribute("data-promise", "true");
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
if (c.getAttribute("slot") === "icon" && c.hasAttribute("data-sonner-default-icon"))
|
|
1202
|
-
this.removeChild(c);
|
|
1203
|
-
}
|
|
1204
|
-
const builtin = getTypeIcon(type);
|
|
1205
|
-
if (builtin) {
|
|
1206
|
-
const tpl = document.createElement("template");
|
|
1207
|
-
tpl.innerHTML = builtin;
|
|
1208
|
-
const el = tpl.content.firstElementChild;
|
|
1209
|
-
if (el) {
|
|
1210
|
-
el.setAttribute("slot", "icon");
|
|
1211
|
-
el.setAttribute("data-sonner-default-icon", "");
|
|
1212
|
-
this.appendChild(el);
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1214
|
+
this.removeAttribute("data-promise");
|
|
1215
|
+
const hasUserIcon = Array.from(this.children).some((c) => c.getAttribute("slot") === "icon");
|
|
1216
|
+
if (hasUserIcon)
|
|
1217
|
+
return;
|
|
1218
|
+
const builtin = getTypeIcon(type);
|
|
1219
|
+
if (!builtin)
|
|
1220
|
+
return;
|
|
1221
|
+
const el = slotElementFromHTML(builtin, "icon");
|
|
1222
|
+
if (el) {
|
|
1223
|
+
el.setAttribute("data-sonner-default-icon", "");
|
|
1224
|
+
this.appendChild(el);
|
|
1216
1225
|
}
|
|
1217
1226
|
}
|
|
1218
1227
|
#applyDismissible() {
|
|
@@ -1230,16 +1239,13 @@ class SonnerToast extends HTMLElementCtor {
|
|
|
1230
1239
|
this.setAttribute("data-x-position", x);
|
|
1231
1240
|
}
|
|
1232
1241
|
#applyCloseButton() {
|
|
1233
|
-
|
|
1234
|
-
this.#closeBtn.hidden = !show;
|
|
1242
|
+
this.#closeBtn.hidden = !boolAttr(this, "close-button");
|
|
1235
1243
|
}
|
|
1236
1244
|
#applyRichColors() {
|
|
1237
|
-
|
|
1238
|
-
this.setAttribute("data-rich-colors", String(rich));
|
|
1245
|
+
this.setAttribute("data-rich-colors", String(boolAttr(this, "rich-colors")));
|
|
1239
1246
|
}
|
|
1240
1247
|
#applyInvert() {
|
|
1241
|
-
|
|
1242
|
-
this.setAttribute("data-invert", String(invert));
|
|
1248
|
+
this.setAttribute("data-invert", String(boolAttr(this, "invert")));
|
|
1243
1249
|
}
|
|
1244
1250
|
#readDuration() {
|
|
1245
1251
|
const raw = this.getAttribute("duration");
|
|
@@ -1248,7 +1254,7 @@ class SonnerToast extends HTMLElementCtor {
|
|
|
1248
1254
|
if (raw === "Infinity")
|
|
1249
1255
|
return Infinity;
|
|
1250
1256
|
const n = Number(raw);
|
|
1251
|
-
return Number.isFinite(n)
|
|
1257
|
+
return Number.isFinite(n) ? n : null;
|
|
1252
1258
|
}
|
|
1253
1259
|
#effectiveDuration() {
|
|
1254
1260
|
const explicit = this.#duration ?? this.#readDuration();
|
|
@@ -1410,8 +1416,6 @@ if (typeof customElements !== "undefined" && !customElements.get("sonner-toast")
|
|
|
1410
1416
|
customElements.define("sonner-toast", SonnerToast);
|
|
1411
1417
|
}
|
|
1412
1418
|
// src/sonner-toaster.ts
|
|
1413
|
-
var HTMLElementCtor2 = typeof HTMLElement !== "undefined" ? HTMLElement : class {
|
|
1414
|
-
};
|
|
1415
1419
|
function parseOffsetValue(v, fallback) {
|
|
1416
1420
|
if (v == null)
|
|
1417
1421
|
return fallback;
|
|
@@ -1432,7 +1436,7 @@ function applyOffsetVars(host, opts, prefix, fallback) {
|
|
|
1432
1436
|
}
|
|
1433
1437
|
}
|
|
1434
1438
|
|
|
1435
|
-
class SonnerToaster extends
|
|
1439
|
+
class SonnerToaster extends HTMLElementCtor {
|
|
1436
1440
|
static get observedAttributes() {
|
|
1437
1441
|
return [
|
|
1438
1442
|
"position",
|
|
@@ -1501,12 +1505,18 @@ class SonnerToaster extends HTMLElementCtor2 {
|
|
|
1501
1505
|
this.addEventListener("sonner-toast-mounted", () => this.#reflow({ remeasure: true }));
|
|
1502
1506
|
}
|
|
1503
1507
|
connectedCallback() {
|
|
1508
|
+
if (typeof this.showPopover === "function") {
|
|
1509
|
+
if (!this.hasAttribute("popover"))
|
|
1510
|
+
this.setAttribute("popover", "manual");
|
|
1511
|
+
this.showPopover();
|
|
1512
|
+
}
|
|
1504
1513
|
if (!this.hasAttribute("tabindex"))
|
|
1505
1514
|
this.tabIndex = -1;
|
|
1506
1515
|
if (!this.hasAttribute("role"))
|
|
1507
1516
|
this.setAttribute("role", "region");
|
|
1508
1517
|
if (!this.hasAttribute("aria-label"))
|
|
1509
1518
|
this.setAttribute("aria-label", this.getAttribute("container-aria-label") ?? "Notifications");
|
|
1519
|
+
this.#applyHotkeyHints();
|
|
1510
1520
|
this.setAttribute("data-sonner-toaster", "");
|
|
1511
1521
|
this.#applyPosition();
|
|
1512
1522
|
this.#applyTheme();
|
|
@@ -1528,6 +1538,11 @@ class SonnerToaster extends HTMLElementCtor2 {
|
|
|
1528
1538
|
this.#reflow({ remeasure: true });
|
|
1529
1539
|
}
|
|
1530
1540
|
disconnectedCallback() {
|
|
1541
|
+
if (typeof this.hidePopover === "function") {
|
|
1542
|
+
try {
|
|
1543
|
+
this.hidePopover();
|
|
1544
|
+
} catch {}
|
|
1545
|
+
}
|
|
1531
1546
|
this.#childObserver.disconnect();
|
|
1532
1547
|
this.#resizeObserver.disconnect();
|
|
1533
1548
|
document.removeEventListener("keydown", this.#onKeyDown);
|
|
@@ -1577,6 +1592,9 @@ class SonnerToaster extends HTMLElementCtor2 {
|
|
|
1577
1592
|
case "container-aria-label":
|
|
1578
1593
|
this.setAttribute("aria-label", this.getAttribute("container-aria-label") ?? "Notifications");
|
|
1579
1594
|
break;
|
|
1595
|
+
case "hotkey":
|
|
1596
|
+
this.#applyHotkeyHints();
|
|
1597
|
+
break;
|
|
1580
1598
|
}
|
|
1581
1599
|
}
|
|
1582
1600
|
addToast(el) {
|
|
@@ -1598,12 +1616,15 @@ class SonnerToaster extends HTMLElementCtor2 {
|
|
|
1598
1616
|
#getPosition() {
|
|
1599
1617
|
return this.getAttribute("position") || "bottom-right";
|
|
1600
1618
|
}
|
|
1601
|
-
#
|
|
1619
|
+
#applyPositionTo(target) {
|
|
1602
1620
|
const [y, x] = this.#getPosition().split("-");
|
|
1603
1621
|
if (y)
|
|
1604
|
-
|
|
1622
|
+
target.setAttribute("data-y-position", y);
|
|
1605
1623
|
if (x)
|
|
1606
|
-
|
|
1624
|
+
target.setAttribute("data-x-position", x);
|
|
1625
|
+
}
|
|
1626
|
+
#applyPosition() {
|
|
1627
|
+
this.#applyPositionTo(this);
|
|
1607
1628
|
}
|
|
1608
1629
|
#applyTheme() {
|
|
1609
1630
|
if (this.#themeMql && this.#themeMqlHandler) {
|
|
@@ -1647,13 +1668,8 @@ class SonnerToaster extends HTMLElementCtor2 {
|
|
|
1647
1668
|
}
|
|
1648
1669
|
#applyToastPositions() {
|
|
1649
1670
|
for (const t of this.#toasts) {
|
|
1650
|
-
if (!t.hasAttribute("position"))
|
|
1651
|
-
|
|
1652
|
-
if (y)
|
|
1653
|
-
t.setAttribute("data-y-position", y);
|
|
1654
|
-
if (x)
|
|
1655
|
-
t.setAttribute("data-x-position", x);
|
|
1656
|
-
}
|
|
1671
|
+
if (!t.hasAttribute("position"))
|
|
1672
|
+
this.#applyPositionTo(t);
|
|
1657
1673
|
}
|
|
1658
1674
|
}
|
|
1659
1675
|
#propagateBoolean(attr) {
|
|
@@ -1668,13 +1684,8 @@ class SonnerToaster extends HTMLElementCtor2 {
|
|
|
1668
1684
|
}
|
|
1669
1685
|
}
|
|
1670
1686
|
#decorateToast(toast) {
|
|
1671
|
-
if (!toast.hasAttribute("position"))
|
|
1672
|
-
|
|
1673
|
-
if (y)
|
|
1674
|
-
toast.setAttribute("data-y-position", y);
|
|
1675
|
-
if (x)
|
|
1676
|
-
toast.setAttribute("data-x-position", x);
|
|
1677
|
-
}
|
|
1687
|
+
if (!toast.hasAttribute("position"))
|
|
1688
|
+
this.#applyPositionTo(toast);
|
|
1678
1689
|
if (!toast.hasAttribute("duration")) {
|
|
1679
1690
|
const inherit = this.getAttribute("duration");
|
|
1680
1691
|
if (inherit)
|
|
@@ -1765,6 +1776,8 @@ class SonnerToaster extends HTMLElementCtor2 {
|
|
|
1765
1776
|
};
|
|
1766
1777
|
#onWindowResize = () => this.#reflow({ remeasure: true });
|
|
1767
1778
|
#onKeyDown = (event) => {
|
|
1779
|
+
if (event.defaultPrevented)
|
|
1780
|
+
return;
|
|
1768
1781
|
const target = event.target;
|
|
1769
1782
|
if (target) {
|
|
1770
1783
|
const tag = target.tagName;
|
|
@@ -1773,12 +1786,13 @@ class SonnerToaster extends HTMLElementCtor2 {
|
|
|
1773
1786
|
}
|
|
1774
1787
|
}
|
|
1775
1788
|
const hotkey = this.#hotkey();
|
|
1776
|
-
const
|
|
1777
|
-
|
|
1789
|
+
const allModifiers = ["altKey", "ctrlKey", "shiftKey", "metaKey"];
|
|
1790
|
+
const matches = hotkey.length > 0 && hotkey.every((key) => {
|
|
1791
|
+
if (allModifiers.includes(key)) {
|
|
1778
1792
|
return event[key];
|
|
1779
1793
|
}
|
|
1780
1794
|
return event.code === key;
|
|
1781
|
-
});
|
|
1795
|
+
}) && allModifiers.every((m) => hotkey.includes(m) || !event[m]);
|
|
1782
1796
|
if (matches) {
|
|
1783
1797
|
this.#expanded = true;
|
|
1784
1798
|
for (const t of this.#toasts)
|
|
@@ -1796,10 +1810,56 @@ class SonnerToaster extends HTMLElementCtor2 {
|
|
|
1796
1810
|
};
|
|
1797
1811
|
#hotkey() {
|
|
1798
1812
|
const raw = this.getAttribute("hotkey");
|
|
1799
|
-
if (
|
|
1813
|
+
if (raw === null)
|
|
1800
1814
|
return DEFAULT_HOTKEY;
|
|
1801
|
-
|
|
1815
|
+
const trimmed = raw.trim();
|
|
1816
|
+
if (trimmed === "" || trimmed.toLowerCase() === "none")
|
|
1817
|
+
return [];
|
|
1818
|
+
return trimmed.split("+").map((s) => s.trim());
|
|
1819
|
+
}
|
|
1820
|
+
#applyHotkeyHints() {
|
|
1821
|
+
const formatted = formatHotkeyForAria(this.#hotkey());
|
|
1822
|
+
if (!formatted) {
|
|
1823
|
+
if (this.#ownsAriaKeyshortcuts) {
|
|
1824
|
+
this.removeAttribute("aria-keyshortcuts");
|
|
1825
|
+
this.#ownsAriaKeyshortcuts = false;
|
|
1826
|
+
}
|
|
1827
|
+
if (this.#ownsTitle) {
|
|
1828
|
+
this.removeAttribute("title");
|
|
1829
|
+
this.#ownsTitle = false;
|
|
1830
|
+
}
|
|
1831
|
+
return;
|
|
1832
|
+
}
|
|
1833
|
+
if (!this.hasAttribute("aria-keyshortcuts") || this.#ownsAriaKeyshortcuts) {
|
|
1834
|
+
this.setAttribute("aria-keyshortcuts", formatted);
|
|
1835
|
+
this.#ownsAriaKeyshortcuts = true;
|
|
1836
|
+
}
|
|
1837
|
+
if (!this.hasAttribute("title") || this.#ownsTitle) {
|
|
1838
|
+
this.setAttribute("title", `Press ${formatted} to expand notifications`);
|
|
1839
|
+
this.#ownsTitle = true;
|
|
1840
|
+
}
|
|
1802
1841
|
}
|
|
1842
|
+
#ownsAriaKeyshortcuts = false;
|
|
1843
|
+
#ownsTitle = false;
|
|
1844
|
+
}
|
|
1845
|
+
function formatHotkeyForAria(tokens) {
|
|
1846
|
+
if (tokens.length === 0)
|
|
1847
|
+
return "";
|
|
1848
|
+
return tokens.map((t) => {
|
|
1849
|
+
if (t === "altKey")
|
|
1850
|
+
return "Alt";
|
|
1851
|
+
if (t === "ctrlKey")
|
|
1852
|
+
return "Control";
|
|
1853
|
+
if (t === "shiftKey")
|
|
1854
|
+
return "Shift";
|
|
1855
|
+
if (t === "metaKey")
|
|
1856
|
+
return "Meta";
|
|
1857
|
+
if (/^Key[A-Z]$/.test(t))
|
|
1858
|
+
return t.slice(3);
|
|
1859
|
+
if (/^Digit[0-9]$/.test(t))
|
|
1860
|
+
return t.slice(5);
|
|
1861
|
+
return t;
|
|
1862
|
+
}).join("+");
|
|
1803
1863
|
}
|
|
1804
1864
|
if (typeof customElements !== "undefined" && !customElements.get("sonner-toaster")) {
|
|
1805
1865
|
customElements.define("sonner-toaster", SonnerToaster);
|
|
@@ -1958,5 +2018,5 @@ export {
|
|
|
1958
2018
|
SonnerToast
|
|
1959
2019
|
};
|
|
1960
2020
|
|
|
1961
|
-
//# debugId=
|
|
2021
|
+
//# debugId=6DA0059CEA8E1A6464756E2164756E21
|
|
1962
2022
|
//# sourceMappingURL=sonner-wc.js.map
|