@leavepulse/ui 0.72.2 → 0.72.4
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/chunks/{DropzoneLinkField-CvyzXHdc.js → DropzoneLinkField-C-9BCGJn.js} +2 -2
- package/dist/chunks/{FieldWrapper-DeOZzjBM.js → FieldWrapper-CORPzo9s.js} +1 -1
- package/dist/chunks/{LpActionBar-DZP0IpXS.js → LpActionBar-BP1ld7-S.js} +2 -2
- package/dist/chunks/{LpAddressInput-q8Vu3M8z.js → LpAddressInput-Al3HT5ey.js} +3 -3
- package/dist/chunks/{LpAlert-CGeYc3fe.js → LpAlert-n5XPAZfv.js} +2 -2
- package/dist/chunks/{LpAppShell-oB-QWu74.js → LpAppShell-D1-On_5L.js} +4 -4
- package/dist/chunks/{LpBadge-BVDOfrqI.js → LpBadge-wUYLN4U9.js} +1 -1
- package/dist/chunks/{LpBottomNav-w_5LKno0.js → LpBottomNav-CbNQQPuL.js} +1 -1
- package/dist/chunks/{LpBreadcrumbs-DJvcYVPM.js → LpBreadcrumbs-DPdbth-c.js} +1 -1
- package/dist/chunks/{LpButton-Cse4COe7.js → LpButton-CFb44IjC.js} +1 -1
- package/dist/chunks/{LpCard-BoB-UqzE.js → LpCard-r13WRqox.js} +1 -1
- package/dist/chunks/{LpCheckbox-B6lfW2GC.js → LpCheckbox-Cs4SHaHX.js} +1 -1
- package/dist/chunks/{LpCodeBlock-BjptdRIt.js → LpCodeBlock-DRC8VbXW.js} +1 -1
- package/dist/chunks/{LpCodeDisplay-BkVeLcLM.js → LpCodeDisplay-AQx-3nNb.js} +4 -4
- package/dist/chunks/{LpConfirmDialog-DqsrdJSK.js → LpConfirmDialog-DY2VjDji.js} +1 -1
- package/dist/chunks/{LpConfirmHost-BT8iDrWb.js → LpConfirmHost-DvSZTJ4N.js} +1 -1
- package/dist/chunks/{LpCopyButton-DhptBlXE.js → LpCopyButton-xF7wFVoU.js} +1 -1
- package/dist/chunks/{LpCountdown-9QnxUFXk.js → LpCountdown-BxE7stYk.js} +1 -1
- package/dist/chunks/{LpDataList-_D19wjXa.js → LpDataList-Jxyl9H5w.js} +1 -1
- package/dist/chunks/{LpEditable-BdjKjOMG.js → LpEditable-Cy6GLbFx.js} +2 -2
- package/dist/chunks/{LpFileTree-Cnw35H2X.js → LpFileTree-zIFEgo3I.js} +1 -1
- package/dist/chunks/{LpFileTreeNode-DR3YPYFb.js → LpFileTreeNode-cT6BIWvz.js} +3 -3
- package/dist/chunks/{LpFormField-CjnOXjFq.js → LpFormField-Ch69Jd-X.js} +1 -1
- package/dist/chunks/{LpHintLayer-DWWn7Xm2.js → LpHintLayer-CgObdUsM.js} +2 -2
- package/dist/chunks/{LpHints-Ctl4p_tS.js → LpHints-Bz-BlaSl.js} +3 -3
- package/dist/chunks/{LpInfraNode-CZrDvfnL.js → LpInfraNode-46XOCkfq.js} +2 -2
- package/dist/chunks/{LpInput-D9uwTIqP.js → LpInput-Tw-yxT4I.js} +1 -1
- package/dist/chunks/{LpLightbox-DlNPihiz.js → LpLightbox-B95yu22B.js} +2 -2
- package/dist/chunks/{LpLoader-DBVl6KDH.js → LpLoader-DVwkOmt9.js} +1 -1
- package/dist/chunks/{LpLogViewer-By_fmDpN.js → LpLogViewer-D25jM2_I.js} +3 -3
- package/dist/chunks/{LpMapPicker-CmuOTS7N.js → LpMapPicker-DRGgh89B.js} +1 -1
- package/dist/chunks/{LpMediaGallery-Dh5ONZt1.js → LpMediaGallery-Bkram-MO.js} +1 -1
- package/dist/chunks/{LpModalNav-CThPOPAF.js → LpModalNav-CE3iLnxB.js} +2 -2
- package/dist/chunks/{LpNotificationBell-674IgUph.js → LpNotificationBell-3244LUVc.js} +3 -3
- package/dist/chunks/{LpPaletteTheme-hsYXczIM.js → LpPaletteTheme-CdEEMMEF.js} +3 -3
- package/dist/chunks/{LpPasswordInput-DNCvyY6N.js → LpPasswordInput-BkHKQDhM.js} +2 -2
- package/dist/chunks/{LpPie-DCpGXbRS.js → LpPie-Mr3EtFEd.js} +2 -2
- package/dist/chunks/{LpPipeline-wh1SzEHF.js → LpPipeline-B3aOVOkV.js} +2 -2
- package/dist/chunks/{LpRepeater-BnOQXjWo.js → LpRepeater-D7ZmnIYd.js} +2 -2
- package/dist/chunks/{LpScramble-INTKwGsY.js → LpScramble-Bn9OoOtC.js} +1 -1
- package/dist/chunks/{LpSecretField-Ck0Mx6xx.js → LpSecretField-BbmqM9ye.js} +6 -6
- package/dist/chunks/{LpShift-DLU4_TFf.js → LpShift-CCq7dofl.js} +28 -5
- package/dist/chunks/{LpSidebar-DVPinvaL.js → LpSidebar-BciLMBgY.js} +2 -2
- package/dist/chunks/{LpSidebarNav-BBj2_6jV.js → LpSidebarNav-HYcG-ib8.js} +3 -2
- package/dist/chunks/{LpSidebarRow-C81reNEm.js → LpSidebarRow-Di2VYz-Z.js} +19 -6
- package/dist/chunks/{LpStat-tq-f6ZzL.js → LpStat-D6V6Fdfc.js} +1 -1
- package/dist/chunks/{LpStatus-Chbh_JJr.js → LpStatus-DglxttQ7.js} +2 -2
- package/dist/chunks/{LpStepMark-C064WOYG.js → LpStepMark-DpzKVyh8.js} +1 -1
- package/dist/chunks/{LpStepper-B15etK5F.js → LpStepper-DpsocBNJ.js} +1 -1
- package/dist/chunks/{LpSwap-BA5fh77B.js → LpSwap-C96c0LWh.js} +1 -1
- package/dist/chunks/{LpSwitch-ByaxQKEm.js → LpSwitch-BnXd1llc.js} +1 -1
- package/dist/chunks/{LpTabFace-Dcj2cO6x.js → LpTabFace-DPCwKkH2.js} +1 -1
- package/dist/chunks/{LpTableFilter-CT8Xml_m.js → LpTableFilter-CiVBpaq0.js} +3 -3
- package/dist/chunks/{LpTagsInput-CSv62X4B.js → LpTagsInput-C-mDG648.js} +2 -2
- package/dist/chunks/{LpTextarea-Blv8qdz0.js → LpTextarea-TE-yZv2U.js} +1 -1
- package/dist/chunks/{LpThemeStudio-DYQP_qbp.js → LpThemeStudio-BJDKf3_Z.js} +2 -2
- package/dist/chunks/{LpThemeSwitcher-BGIVrM1l.js → LpThemeSwitcher-BDrIJswA.js} +2 -2
- package/dist/chunks/{LpToaster-D5Pj_wc9.js → LpToaster-IwTXjbbU.js} +2 -2
- package/dist/chunks/{LpTopologyCanvas-Bq-k5tgI.js → LpTopologyCanvas-B1gIbS0n.js} +1 -1
- package/dist/chunks/{LpTour-BU4JX3RU.js → LpTour-BZq-mUMv.js} +1 -1
- package/dist/chunks/{LpTruncate-Cb7MDTD7.js → LpTruncate-CflAIwiJ.js} +1 -1
- package/dist/chunks/{LpUptimeBar-Cdq76qi_.js → LpUptimeBar-BtkZRwY0.js} +2 -2
- package/dist/chunks/{RevealToggle-DhL7mi-3.js → RevealToggle-BEit1n6Z.js} +1 -1
- package/dist/chunks/{TourCard-Dvo_vH_P.js → TourCard-DNclH3u_.js} +3 -3
- package/dist/components/DropzoneLinkField.vue.js +1 -1
- package/dist/components/FieldWrapper.vue.js +1 -1
- package/dist/components/LpActionBar.vue.js +1 -1
- package/dist/components/LpAddressInput.vue.js +1 -1
- package/dist/components/LpAlert.vue.js +1 -1
- package/dist/components/LpAppShell.vue.js +1 -1
- package/dist/components/LpBadge.vue.js +1 -1
- package/dist/components/LpBottomNav.vue.js +1 -1
- package/dist/components/LpBreadcrumbs.vue.js +1 -1
- package/dist/components/LpButton.vue.js +1 -1
- package/dist/components/LpCard.vue.js +1 -1
- package/dist/components/LpChart.vue.js +2 -2
- package/dist/components/LpCheckbox.vue.js +1 -1
- package/dist/components/LpCodeBlock.vue.js +1 -1
- package/dist/components/LpCodeDisplay.vue.js +1 -1
- package/dist/components/LpCommandPalette.vue.d.ts +1 -1
- package/dist/components/LpCommandPalette.vue.js +2 -2
- package/dist/components/LpConfirmDialog.vue.js +1 -1
- package/dist/components/LpConfirmHost.vue.js +1 -1
- package/dist/components/LpCopyButton.vue.js +1 -1
- package/dist/components/LpCountdown.vue.js +1 -1
- package/dist/components/LpDataList.vue.js +1 -1
- package/dist/components/LpDropzone.vue.js +1 -1
- package/dist/components/LpEditable.vue.js +1 -1
- package/dist/components/LpFileTree.vue.js +1 -1
- package/dist/components/LpFileTreeNode.vue.js +1 -1
- package/dist/components/LpFormField.vue.js +1 -1
- package/dist/components/LpHintLayer.vue.js +1 -1
- package/dist/components/LpHints.vue.js +1 -1
- package/dist/components/LpImageEditor.vue.js +1 -1
- package/dist/components/LpInfraNode.vue.js +1 -1
- package/dist/components/LpInput.vue.js +1 -1
- package/dist/components/LpLightbox.vue.js +1 -1
- package/dist/components/LpLoader.vue.js +1 -1
- package/dist/components/LpLogViewer.vue.js +1 -1
- package/dist/components/LpMapPicker.vue.js +1 -1
- package/dist/components/LpMediaGallery.vue.js +1 -1
- package/dist/components/LpModalNav.vue.js +1 -1
- package/dist/components/LpNotificationBell.vue.js +1 -1
- package/dist/components/LpPaletteTheme.vue.js +1 -1
- package/dist/components/LpPasswordInput.vue.js +1 -1
- package/dist/components/LpPie.vue.js +1 -1
- package/dist/components/LpPipeline.vue.js +1 -1
- package/dist/components/LpRepeater.vue.js +1 -1
- package/dist/components/LpScramble.vue.js +1 -1
- package/dist/components/LpSecretField.vue.js +1 -1
- package/dist/components/LpShift.vue.d.ts +4 -3
- package/dist/components/LpShift.vue.js +1 -1
- package/dist/components/LpSidebar.vue.js +1 -1
- package/dist/components/LpSidebarNav.vue.js +1 -1
- package/dist/components/LpSidebarRow.vue.d.ts +2 -0
- package/dist/components/LpSidebarRow.vue.js +1 -1
- package/dist/components/LpStat.vue.js +1 -1
- package/dist/components/LpStatus.vue.js +1 -1
- package/dist/components/LpStepMark.vue.js +1 -1
- package/dist/components/LpStepper.vue.js +1 -1
- package/dist/components/LpSwap.vue.js +1 -1
- package/dist/components/LpSwitch.vue.js +1 -1
- package/dist/components/LpTabFace.vue.js +1 -1
- package/dist/components/LpTable.vue.js +6 -6
- package/dist/components/LpTableFilter.vue.js +1 -1
- package/dist/components/LpTabs.vue.js +1 -1
- package/dist/components/LpTagsInput.vue.js +1 -1
- package/dist/components/LpTextarea.vue.js +1 -1
- package/dist/components/LpThemeStudio.vue.js +1 -1
- package/dist/components/LpThemeSwitcher.vue.js +1 -1
- package/dist/components/LpToaster.vue.js +1 -1
- package/dist/components/LpTopologyCanvas.vue.js +1 -1
- package/dist/components/LpTour.vue.js +1 -1
- package/dist/components/LpTruncate.vue.js +1 -1
- package/dist/components/LpUptimeBar.vue.js +1 -1
- package/dist/components/RevealToggle.vue.js +1 -1
- package/dist/components/TourCard.vue.js +1 -1
- package/dist/composables/useToast.d.ts +2 -0
- package/dist/composables/useToast.js +12 -2
- package/dist/index.js +55 -55
- package/package.json +1 -1
- package/src/components/LpShift.vue +43 -7
- package/src/components/LpSidebarNav.vue +1 -0
- package/src/components/LpSidebarRow.vue +18 -1
- package/src/components/LpToaster.vue +1 -1
- package/src/composables/useToast.ts +21 -1
|
@@ -57,9 +57,10 @@ const props = withDefaults(
|
|
|
57
57
|
* Fade the box's own children in and out as they come and go. Without it
|
|
58
58
|
* the box glides but a control still pops into being as the edge uncovers
|
|
59
59
|
* it, and one that leaves is gone in a frame while its space closes up.
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
60
|
+
* Anything that takes room counts, at any depth, since controls often
|
|
61
|
+
* arrive by teleport into a wrapper inside the box; an absolutely placed
|
|
62
|
+
* overlay (a tab's marker) does not, it moves nothing and animates itself.
|
|
63
|
+
* Markup put back unchanged by a re-render is not animated either.
|
|
63
64
|
*/
|
|
64
65
|
presence?: boolean
|
|
65
66
|
}>(),
|
|
@@ -105,6 +106,7 @@ interface Seen {
|
|
|
105
106
|
height: number
|
|
106
107
|
x: number
|
|
107
108
|
y: number
|
|
109
|
+
flow: boolean
|
|
108
110
|
}
|
|
109
111
|
|
|
110
112
|
const seen = new WeakMap<Element, Seen>()
|
|
@@ -129,15 +131,48 @@ function remember(box: HTMLElement) {
|
|
|
129
131
|
height: r.height,
|
|
130
132
|
x: r.left,
|
|
131
133
|
y: r.top,
|
|
134
|
+
flow: inFlow(node),
|
|
132
135
|
})
|
|
133
136
|
}
|
|
134
137
|
}
|
|
135
138
|
|
|
139
|
+
// Only what takes room in the box comes and goes visibly. An overlay inside a
|
|
140
|
+
// control (a tab's sliding marker, a badge pinned to a corner) moves nothing
|
|
141
|
+
// around it and is animated by its own component; fading it in on top would
|
|
142
|
+
// override that animation's transform, and the marker would pop instead of
|
|
143
|
+
// sliding.
|
|
144
|
+
function inFlow(node: Element): boolean {
|
|
145
|
+
const position = getComputedStyle(node).position
|
|
146
|
+
return position !== "absolute" && position !== "fixed"
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// A re-render that puts back the same markup (a page redrawing its header
|
|
150
|
+
// actions, a list re-keyed after a reload) is not a change anyone sees, so the
|
|
151
|
+
// pair is left alone rather than flashing out and in.
|
|
152
|
+
function signature(node: Node): string | undefined {
|
|
153
|
+
return node instanceof Element ? node.outerHTML : undefined
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function unchanged(records: MutationRecord[]): Set<Node> {
|
|
157
|
+
const removed = new Map<string, Node[]>()
|
|
158
|
+
for (const record of records) record.removedNodes.forEach((node) => {
|
|
159
|
+
const key = signature(node)
|
|
160
|
+
if (key) removed.set(key, [...(removed.get(key) ?? []), node])
|
|
161
|
+
})
|
|
162
|
+
const same = new Set<Node>()
|
|
163
|
+
for (const record of records) record.addedNodes.forEach((node) => {
|
|
164
|
+
const key = signature(node)
|
|
165
|
+
const twin = key ? removed.get(key)?.shift() : undefined
|
|
166
|
+
if (twin) same.add(twin).add(node)
|
|
167
|
+
})
|
|
168
|
+
return same
|
|
169
|
+
}
|
|
170
|
+
|
|
136
171
|
const offset = () => (props.anchor === "end" ? -6 : 6)
|
|
137
172
|
|
|
138
173
|
function ghost(box: HTMLElement, node: Element) {
|
|
139
174
|
const at = seen.get(node)
|
|
140
|
-
if (!at || !(node instanceof HTMLElement) || node.hasAttribute(GHOST) || at.width === 0) return
|
|
175
|
+
if (!at || !at.flow || !(node instanceof HTMLElement) || node.hasAttribute(GHOST) || at.width === 0) return
|
|
141
176
|
const copy = node.cloneNode(true) as HTMLElement
|
|
142
177
|
copy.setAttribute(GHOST, "")
|
|
143
178
|
copy.setAttribute("aria-hidden", "true")
|
|
@@ -172,7 +207,7 @@ function ghost(box: HTMLElement, node: Element) {
|
|
|
172
207
|
}
|
|
173
208
|
|
|
174
209
|
function arrive(node: Element) {
|
|
175
|
-
if (!(node instanceof HTMLElement) || node.hasAttribute(GHOST)) return
|
|
210
|
+
if (!(node instanceof HTMLElement) || node.hasAttribute(GHOST) || !inFlow(node)) return
|
|
176
211
|
node.animate(
|
|
177
212
|
[
|
|
178
213
|
{ opacity: 0, transform: `translateX(${offset()}px) scale(0.96)`, filter: "blur(2px)" },
|
|
@@ -208,11 +243,12 @@ watch(
|
|
|
208
243
|
)
|
|
209
244
|
if (real.length && !prefersReducedMotion()) {
|
|
210
245
|
const added = new Set<Node>()
|
|
246
|
+
const same = unchanged(real)
|
|
211
247
|
for (const record of real) {
|
|
212
|
-
record.removedNodes.forEach((node) => node instanceof Element && ghost(box, node))
|
|
248
|
+
record.removedNodes.forEach((node) => node instanceof Element && !same.has(node) && ghost(box, node))
|
|
213
249
|
record.addedNodes.forEach((node) => {
|
|
214
250
|
added.add(node)
|
|
215
|
-
if (node instanceof Element) arrive(node)
|
|
251
|
+
if (node instanceof Element && !same.has(node)) arrive(node)
|
|
216
252
|
})
|
|
217
253
|
}
|
|
218
254
|
// Measured in the next frame, which still comes before the paint: by
|
|
@@ -31,6 +31,8 @@ const props = withDefaults(
|
|
|
31
31
|
pill: boolean
|
|
32
32
|
pillId: string
|
|
33
33
|
compact?: boolean
|
|
34
|
+
/** A folded group standing in for its pages: a click opens its card. */
|
|
35
|
+
group?: boolean
|
|
34
36
|
/** A page under another: indented, a size smaller. */
|
|
35
37
|
nested?: boolean
|
|
36
38
|
menu?: ContextMenuItemDef[]
|
|
@@ -98,11 +100,25 @@ const initials = computed(() =>
|
|
|
98
100
|
const hidden = computed(() => (props.compact || !props.expanded) && !!props.item.children?.some(waiting))
|
|
99
101
|
const hasBadge = computed(() => props.item.badge != null || !!props.item.dot || hidden.value)
|
|
100
102
|
const card = computed(() => !props.item.disabled && (props.compact || !!props.item.preview))
|
|
103
|
+
|
|
104
|
+
// A folded group with no page of its own is reached only through its card, so
|
|
105
|
+
// a click opens the card rather than waiting for the pointer to rest: a click
|
|
106
|
+
// that does nothing on a nav icon reads as broken.
|
|
107
|
+
const cardOpen = ref(false)
|
|
108
|
+
const opensCard = computed(() => props.compact && props.group && !!props.item.children?.length)
|
|
109
|
+
function press(): void {
|
|
110
|
+
if (opensCard.value) {
|
|
111
|
+
cardOpen.value = !cardOpen.value
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
emit("activate", props.item)
|
|
115
|
+
}
|
|
101
116
|
const delay = computed(() => (props.compact && !props.item.preview ? 250 : props.previewDelay))
|
|
102
117
|
</script>
|
|
103
118
|
|
|
104
119
|
<template>
|
|
105
120
|
<LpHoverCard
|
|
121
|
+
v-model:open="cardOpen"
|
|
106
122
|
:disabled="!card"
|
|
107
123
|
side="right"
|
|
108
124
|
align="start"
|
|
@@ -136,7 +152,8 @@ const delay = computed(() => (props.compact && !props.item.preview ? 250 : props
|
|
|
136
152
|
? 'text-ink'
|
|
137
153
|
: 'text-muted hover:text-ink',
|
|
138
154
|
]"
|
|
139
|
-
|
|
155
|
+
:aria-expanded="opensCard ? cardOpen : undefined"
|
|
156
|
+
@click="press"
|
|
140
157
|
@pointerenter="emit('hover', item)"
|
|
141
158
|
>
|
|
142
159
|
<span
|
|
@@ -204,7 +204,7 @@ async function settle(t: ToastItem, run: () => void | Promise<void>) {
|
|
|
204
204
|
*/
|
|
205
205
|
const copyable = (t: ToastItem) => t.variant === "error" || t.variant === "warning"
|
|
206
206
|
// Read on click rather than bound, so a toast whose text is updated in place copies what it now says.
|
|
207
|
-
const toastText = (t: ToastItem) => () => [t.title, t.message, t.details].filter(Boolean).join("\n")
|
|
207
|
+
const toastText = (t: ToastItem) => () => [t.title, t.message, t.details, t.context].filter(Boolean).join("\n")
|
|
208
208
|
|
|
209
209
|
function selecting(): boolean {
|
|
210
210
|
return Boolean(window.getSelection()?.toString())
|
|
@@ -25,6 +25,8 @@ export interface ToastItem {
|
|
|
25
25
|
onClick?: () => void | Promise<void>
|
|
26
26
|
/** Copied with the message, not shown: what a bug report needs (request, status, ids). */
|
|
27
27
|
details?: string
|
|
28
|
+
/** Page and moment an error toast came up, copied last: "it broke" rarely says where or when. */
|
|
29
|
+
context?: string
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
export interface ToastOptions {
|
|
@@ -61,9 +63,26 @@ function detailsOf(source: unknown, depth = 0): string | undefined {
|
|
|
61
63
|
return detailsOf(cause, depth + 1)
|
|
62
64
|
}
|
|
63
65
|
|
|
66
|
+
// A code fault (TypeError and the like) has no request behind it, and its
|
|
67
|
+
// message alone ("x is undefined") says nothing about where it happened: the
|
|
68
|
+
// copy gets its type and stack instead. Firefox and Safari leave the message
|
|
69
|
+
// out of `stack`, Chromium starts with it; the head is written once either way.
|
|
70
|
+
function traceOf(source: unknown): string | undefined {
|
|
71
|
+
if (!(source instanceof Error)) return undefined
|
|
72
|
+
const head = `${source.name}: ${source.message}`
|
|
73
|
+
const frames = (source.stack ?? "").split("\n").filter((line) => line.trim() && line.trim() !== head)
|
|
74
|
+
const own = [head, ...frames].join("\n")
|
|
75
|
+
const inner = traceOf(source.cause)
|
|
76
|
+
return inner ? `${own}\nCaused by ${inner}` : own
|
|
77
|
+
}
|
|
78
|
+
|
|
64
79
|
function split(message: ToastMessage, options: ToastOptions): [string, ToastOptions] {
|
|
65
80
|
const text = typeof message === "string" ? message : message.message
|
|
66
|
-
const details =
|
|
81
|
+
const details =
|
|
82
|
+
options.details ??
|
|
83
|
+
(typeof message === "string" ? undefined : detailsOf(message)) ??
|
|
84
|
+
detailsOf(options.cause) ??
|
|
85
|
+
traceOf(typeof message === "string" ? options.cause : message)
|
|
67
86
|
return [text, { ...options, details }]
|
|
68
87
|
}
|
|
69
88
|
|
|
@@ -101,6 +120,7 @@ function push(
|
|
|
101
120
|
actions: options.actions,
|
|
102
121
|
onClick: options.onClick,
|
|
103
122
|
details: options.details,
|
|
123
|
+
context: variant === "error" ? [globalThis.location?.href, new Date().toISOString()].filter(Boolean).join(" · ") : undefined,
|
|
104
124
|
}
|
|
105
125
|
|
|
106
126
|
const same = options.key === undefined ? -1 : queue.findIndex((t) => t.key === options.key)
|