beez-ui 2.6.0 → 2.6.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/CHANGELOG.md +9 -0
- package/dist/components/dialog.js +46 -35
- package/dist/components/popover.d.ts +1 -0
- package/dist/components/popover.js +2 -1
- package/dist/components/sheet.js +37 -26
- package/dist/components/sidebar.js +11 -0
- package/dist/components/themed-toaster.d.ts +6 -2
- package/dist/components/themed-toaster.js +80 -50
- package/dist/constants/toast.d.ts +3 -0
- package/dist/constants/toast.js +3 -0
- package/dist/lib/toast-layer.d.ts +24 -0
- package/dist/lib/toast-layer.js +76 -0
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,15 @@ Todos los cambios relevantes de beez-ui se documentan en este archivo con el for
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [2.6.1] - 2026-10-16
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Los botones de un toast de `ThemedToaster` (acción, cancelar o cerrar) responden mientras hay un `Dialog`, `AlertDialog` o `Sheet` abierto, y presionarlos ya no cierra el `Dialog` o el `Sheet`. También se alcanzan con el teclado mediante el atajo de Sonner (Alt+T), que ya no queda bloqueado por la trampa de foco del modal; si el control enfocado cierra su toast, el foco vuelve al modal en lugar de perderse.
|
|
12
|
+
- Presionar Escape en un menú, select o diálogo abierto desde el `Sidebar` en mobile cierra solo esa capa y deja el sidebar abierto.
|
|
13
|
+
- Abrir el `Sidebar` en mobile en una ventana de escritorio angosta ya no desplaza la página de costado cuando desaparece la barra de scroll.
|
|
14
|
+
- El contenido de `PopoverContent` más alto que el espacio disponible en pantalla se desplaza dentro del panel en lugar de quedar cortado fuera del viewport.
|
|
15
|
+
|
|
7
16
|
## [2.6.0] - 2026-10-15
|
|
8
17
|
|
|
9
18
|
### Added
|
|
@@ -11,6 +11,7 @@ import { Dialog as DialogPrimitive } from "radix-ui";
|
|
|
11
11
|
import { MotionSlot } from "../motion/motion-slot.js";
|
|
12
12
|
import { MotionPresence, MotionOpenProvider, useMotionOpenState } from "../motion/presence.js";
|
|
13
13
|
import { cn } from "../lib/utils.js";
|
|
14
|
+
import { keepOpenOnToastInteraction } from "../lib/toast-layer.js";
|
|
14
15
|
import { Button } from "./button.js";
|
|
15
16
|
import { ControlButton } from "./control-button.js";
|
|
16
17
|
import { XIcon } from "lucide-react";
|
|
@@ -210,7 +211,7 @@ function DialogViewportCloseButton() {
|
|
|
210
211
|
* @returns The styled primitive with its original interaction contract.
|
|
211
212
|
*/
|
|
212
213
|
function DialogContent(t0) {
|
|
213
|
-
const $ = _c(
|
|
214
|
+
const $ = _c(29);
|
|
214
215
|
let children;
|
|
215
216
|
let className;
|
|
216
217
|
let props;
|
|
@@ -256,17 +257,25 @@ function DialogContent(t0) {
|
|
|
256
257
|
t7 = $[9];
|
|
257
258
|
}
|
|
258
259
|
let t8;
|
|
259
|
-
if ($[10] !==
|
|
260
|
-
t8 =
|
|
261
|
-
$[10] =
|
|
262
|
-
$[11] =
|
|
263
|
-
$[12] = t8;
|
|
260
|
+
if ($[10] !== props.onInteractOutside) {
|
|
261
|
+
t8 = keepOpenOnToastInteraction(props.onInteractOutside);
|
|
262
|
+
$[10] = props.onInteractOutside;
|
|
263
|
+
$[11] = t8;
|
|
264
264
|
} else {
|
|
265
|
-
t8 = $[
|
|
265
|
+
t8 = $[11];
|
|
266
266
|
}
|
|
267
267
|
let t9;
|
|
268
|
-
if ($[
|
|
269
|
-
t9 = showCloseButton && closeButtonPlacement === "
|
|
268
|
+
if ($[12] !== closeButtonPlacement || $[13] !== showCloseButton) {
|
|
269
|
+
t9 = showCloseButton && closeButtonPlacement === "viewport" && /* @__PURE__ */ _jsx(DialogViewportCloseButton, {});
|
|
270
|
+
$[12] = closeButtonPlacement;
|
|
271
|
+
$[13] = showCloseButton;
|
|
272
|
+
$[14] = t9;
|
|
273
|
+
} else {
|
|
274
|
+
t9 = $[14];
|
|
275
|
+
}
|
|
276
|
+
let t10;
|
|
277
|
+
if ($[15] !== closeButtonPlacement || $[16] !== showCloseButton) {
|
|
278
|
+
t10 = showCloseButton && closeButtonPlacement === "content" && /* @__PURE__ */ _jsx(DialogPrimitive.Close, {
|
|
270
279
|
"data-slot": "dialog-close",
|
|
271
280
|
asChild: true,
|
|
272
281
|
children: /* @__PURE__ */ _jsx(MotionSlot, {
|
|
@@ -282,15 +291,15 @@ function DialogContent(t0) {
|
|
|
282
291
|
})
|
|
283
292
|
})
|
|
284
293
|
});
|
|
285
|
-
$[
|
|
286
|
-
$[
|
|
287
|
-
$[
|
|
294
|
+
$[15] = closeButtonPlacement;
|
|
295
|
+
$[16] = showCloseButton;
|
|
296
|
+
$[17] = t10;
|
|
288
297
|
} else {
|
|
289
|
-
|
|
298
|
+
t10 = $[17];
|
|
290
299
|
}
|
|
291
|
-
let
|
|
292
|
-
if ($[
|
|
293
|
-
|
|
300
|
+
let t11;
|
|
301
|
+
if ($[18] !== children || $[19] !== props || $[20] !== t10 || $[21] !== t5 || $[22] !== t7 || $[23] !== t8 || $[24] !== t9) {
|
|
302
|
+
t11 = /* @__PURE__ */ _jsxs(React.Fragment, { children: [t4, /* @__PURE__ */ _jsx(MotionSlot, {
|
|
294
303
|
kind: "center-morph",
|
|
295
304
|
children: /* @__PURE__ */ _jsxs(DialogPrimitive.Content, {
|
|
296
305
|
forceMount: true,
|
|
@@ -298,40 +307,42 @@ function DialogContent(t0) {
|
|
|
298
307
|
"data-close-button-placement": t5,
|
|
299
308
|
className: t7,
|
|
300
309
|
...props,
|
|
310
|
+
onInteractOutside: t8,
|
|
301
311
|
children: [
|
|
302
312
|
children,
|
|
303
|
-
|
|
304
|
-
|
|
313
|
+
t9,
|
|
314
|
+
t10
|
|
305
315
|
]
|
|
306
316
|
})
|
|
307
317
|
})] });
|
|
308
|
-
$[
|
|
309
|
-
$[
|
|
310
|
-
$[
|
|
311
|
-
$[
|
|
312
|
-
$[
|
|
313
|
-
$[
|
|
314
|
-
$[
|
|
318
|
+
$[18] = children;
|
|
319
|
+
$[19] = props;
|
|
320
|
+
$[20] = t10;
|
|
321
|
+
$[21] = t5;
|
|
322
|
+
$[22] = t7;
|
|
323
|
+
$[23] = t8;
|
|
324
|
+
$[24] = t9;
|
|
325
|
+
$[25] = t11;
|
|
315
326
|
} else {
|
|
316
|
-
|
|
327
|
+
t11 = $[25];
|
|
317
328
|
}
|
|
318
|
-
let
|
|
319
|
-
if ($[
|
|
320
|
-
|
|
329
|
+
let t12;
|
|
330
|
+
if ($[26] !== props.forceMount || $[27] !== t11) {
|
|
331
|
+
t12 = /* @__PURE__ */ _jsx(DialogPortal, {
|
|
321
332
|
forceMount: true,
|
|
322
333
|
children: /* @__PURE__ */ _jsx(MotionPresence, {
|
|
323
334
|
scope: "dialog",
|
|
324
335
|
forceMount: t3,
|
|
325
|
-
children:
|
|
336
|
+
children: t11
|
|
326
337
|
})
|
|
327
338
|
});
|
|
328
|
-
$[
|
|
329
|
-
$[
|
|
330
|
-
$[
|
|
339
|
+
$[26] = props.forceMount;
|
|
340
|
+
$[27] = t11;
|
|
341
|
+
$[28] = t12;
|
|
331
342
|
} else {
|
|
332
|
-
|
|
343
|
+
t12 = $[28];
|
|
333
344
|
}
|
|
334
|
-
return
|
|
345
|
+
return t12;
|
|
335
346
|
}
|
|
336
347
|
/**
|
|
337
348
|
* Stacks the title and description. While the panel shows its own close button, the header keeps Arc's gap to it so
|
|
@@ -11,6 +11,7 @@ declare function PopoverTrigger({ ...props }: React.ComponentProps<typeof Popove
|
|
|
11
11
|
declare function PopoverClose({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Close>): React.JSX.Element;
|
|
12
12
|
/**
|
|
13
13
|
* Renders Arc's panel: raised surface, hairline border, panel radius and floating shadow, kept inside the viewport.
|
|
14
|
+
* Content taller than the room left on the placed side scrolls inside the panel instead of running off screen.
|
|
14
15
|
* @param props - Radix content properties. `align` defaults to `center`, `sideOffset` to 6px and `collisionPadding`
|
|
15
16
|
* to 10px.
|
|
16
17
|
* @returns The portaled panel.
|
|
@@ -106,6 +106,7 @@ function resolvePopoverMotion() {
|
|
|
106
106
|
}
|
|
107
107
|
/**
|
|
108
108
|
* Renders Arc's panel: raised surface, hairline border, panel radius and floating shadow, kept inside the viewport.
|
|
109
|
+
* Content taller than the room left on the placed side scrolls inside the panel instead of running off screen.
|
|
109
110
|
* @param props - Radix content properties. `align` defaults to `center`, `sideOffset` to 6px and `collisionPadding`
|
|
110
111
|
* to 10px.
|
|
111
112
|
* @returns The portaled panel.
|
|
@@ -138,7 +139,7 @@ function PopoverContent(t0) {
|
|
|
138
139
|
const t4 = props.forceMount;
|
|
139
140
|
let t5;
|
|
140
141
|
if ($[6] !== className) {
|
|
141
|
-
t5 = cn("z-50 flex w-72 max-w-[calc(100vw-20px)] origin-(--radix-popover-content-transform-origin) flex-col gap-2.5 rounded-(--radius-panel) border border-border bg-surface-raised p-(--space-4) text-sm leading-(--leading-body) text-foreground shadow-(--shadow-floating) outline-hidden", className);
|
|
142
|
+
t5 = cn("z-50 flex max-h-(--radix-popover-content-available-height) w-72 max-w-[calc(100vw-20px)] origin-(--radix-popover-content-transform-origin) flex-col gap-2.5 overflow-y-auto overscroll-contain *:shrink-0 rounded-(--radius-panel) border border-border bg-surface-raised p-(--space-4) text-sm leading-(--leading-body) text-foreground shadow-(--shadow-floating) outline-hidden", className);
|
|
142
143
|
$[6] = className;
|
|
143
144
|
$[7] = t5;
|
|
144
145
|
} else {
|
package/dist/components/sheet.js
CHANGED
|
@@ -5,6 +5,7 @@ import { Dialog as SheetPrimitive } from "radix-ui";
|
|
|
5
5
|
import { MotionSlot } from "../motion/motion-slot.js";
|
|
6
6
|
import { MotionPresence, MotionOpenProvider, useMotionOpenState } from "../motion/presence.js";
|
|
7
7
|
import { cn } from "../lib/utils.js";
|
|
8
|
+
import { keepOpenOnToastInteraction } from "../lib/toast-layer.js";
|
|
8
9
|
import { ControlButton } from "./control-button.js";
|
|
9
10
|
import { XIcon } from "lucide-react";
|
|
10
11
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -160,7 +161,7 @@ function SheetOverlay(t0) {
|
|
|
160
161
|
* @returns The styled primitive with its original interaction contract.
|
|
161
162
|
*/
|
|
162
163
|
function SheetContent(t0) {
|
|
163
|
-
const $ = _c(
|
|
164
|
+
const $ = _c(23);
|
|
164
165
|
let children;
|
|
165
166
|
let className;
|
|
166
167
|
let props;
|
|
@@ -203,8 +204,16 @@ function SheetContent(t0) {
|
|
|
203
204
|
t5 = $[8];
|
|
204
205
|
}
|
|
205
206
|
let t6;
|
|
206
|
-
if ($[9] !==
|
|
207
|
-
t6 =
|
|
207
|
+
if ($[9] !== props.onInteractOutside) {
|
|
208
|
+
t6 = keepOpenOnToastInteraction(props.onInteractOutside);
|
|
209
|
+
$[9] = props.onInteractOutside;
|
|
210
|
+
$[10] = t6;
|
|
211
|
+
} else {
|
|
212
|
+
t6 = $[10];
|
|
213
|
+
}
|
|
214
|
+
let t7;
|
|
215
|
+
if ($[11] !== showCloseButton) {
|
|
216
|
+
t7 = showCloseButton && /* @__PURE__ */ _jsx(SheetPrimitive.Close, {
|
|
208
217
|
"data-slot": "sheet-close",
|
|
209
218
|
asChild: true,
|
|
210
219
|
children: /* @__PURE__ */ _jsx(MotionSlot, {
|
|
@@ -220,14 +229,14 @@ function SheetContent(t0) {
|
|
|
220
229
|
})
|
|
221
230
|
})
|
|
222
231
|
});
|
|
223
|
-
$[
|
|
224
|
-
$[
|
|
232
|
+
$[11] = showCloseButton;
|
|
233
|
+
$[12] = t7;
|
|
225
234
|
} else {
|
|
226
|
-
|
|
235
|
+
t7 = $[12];
|
|
227
236
|
}
|
|
228
|
-
let
|
|
229
|
-
if ($[
|
|
230
|
-
|
|
237
|
+
let t8;
|
|
238
|
+
if ($[13] !== children || $[14] !== props || $[15] !== side || $[16] !== t5 || $[17] !== t6 || $[18] !== t7) {
|
|
239
|
+
t8 = /* @__PURE__ */ _jsxs(React.Fragment, { children: [t4, /* @__PURE__ */ _jsx(MotionSlot, {
|
|
231
240
|
kind: "sheet",
|
|
232
241
|
children: /* @__PURE__ */ _jsxs(SheetPrimitive.Content, {
|
|
233
242
|
forceMount: true,
|
|
@@ -235,35 +244,37 @@ function SheetContent(t0) {
|
|
|
235
244
|
"data-side": side,
|
|
236
245
|
className: t5,
|
|
237
246
|
...props,
|
|
238
|
-
|
|
247
|
+
onInteractOutside: t6,
|
|
248
|
+
children: [children, t7]
|
|
239
249
|
})
|
|
240
250
|
})] });
|
|
241
|
-
$[
|
|
242
|
-
$[
|
|
243
|
-
$[
|
|
244
|
-
$[
|
|
245
|
-
$[
|
|
246
|
-
$[
|
|
251
|
+
$[13] = children;
|
|
252
|
+
$[14] = props;
|
|
253
|
+
$[15] = side;
|
|
254
|
+
$[16] = t5;
|
|
255
|
+
$[17] = t6;
|
|
256
|
+
$[18] = t7;
|
|
257
|
+
$[19] = t8;
|
|
247
258
|
} else {
|
|
248
|
-
|
|
259
|
+
t8 = $[19];
|
|
249
260
|
}
|
|
250
|
-
let
|
|
251
|
-
if ($[
|
|
252
|
-
|
|
261
|
+
let t9;
|
|
262
|
+
if ($[20] !== props.forceMount || $[21] !== t8) {
|
|
263
|
+
t9 = /* @__PURE__ */ _jsx(SheetPortal, {
|
|
253
264
|
forceMount: true,
|
|
254
265
|
children: /* @__PURE__ */ _jsx(MotionPresence, {
|
|
255
266
|
scope: "sheet",
|
|
256
267
|
forceMount: t3,
|
|
257
|
-
children:
|
|
268
|
+
children: t8
|
|
258
269
|
})
|
|
259
270
|
});
|
|
260
|
-
$[
|
|
261
|
-
$[
|
|
262
|
-
$[
|
|
271
|
+
$[20] = props.forceMount;
|
|
272
|
+
$[21] = t8;
|
|
273
|
+
$[22] = t9;
|
|
263
274
|
} else {
|
|
264
|
-
|
|
275
|
+
t9 = $[22];
|
|
265
276
|
}
|
|
266
|
-
return
|
|
277
|
+
return t9;
|
|
267
278
|
}
|
|
268
279
|
function SheetHeader(t0) {
|
|
269
280
|
const $ = _c(8);
|
|
@@ -404,15 +404,22 @@ function MobileSidebar(t0) {
|
|
|
404
404
|
const previousBodyStyles = {
|
|
405
405
|
left: body.style.left,
|
|
406
406
|
overflow: body.style.overflow,
|
|
407
|
+
paddingRight: body.style.paddingRight,
|
|
407
408
|
position: body.style.position,
|
|
408
409
|
right: body.style.right,
|
|
409
410
|
top: body.style.top
|
|
410
411
|
};
|
|
412
|
+
const clientWidthBeforeLock = document.documentElement.clientWidth;
|
|
413
|
+
const bodyPaddingRight = Number.parseFloat(getComputedStyle(body).paddingRight) || 0;
|
|
411
414
|
body.style.position = "fixed";
|
|
412
415
|
body.style.top = `-${scrollY}px`;
|
|
413
416
|
body.style.left = "0";
|
|
414
417
|
body.style.right = "0";
|
|
415
418
|
body.style.overflow = "hidden";
|
|
419
|
+
const scrollbarWidth = document.documentElement.clientWidth - clientWidthBeforeLock;
|
|
420
|
+
if (scrollbarWidth > 0) {
|
|
421
|
+
body.style.paddingRight = `${bodyPaddingRight + scrollbarWidth}px`;
|
|
422
|
+
}
|
|
416
423
|
const restoreTriggerFocus = () => triggerRef.current?.focus({ preventScroll: true });
|
|
417
424
|
const focusFrame = requestAnimationFrame(() => {
|
|
418
425
|
const firstFocusable = panelRef.current?.querySelector(FOCUSABLE_SELECTOR);
|
|
@@ -425,6 +432,7 @@ function MobileSidebar(t0) {
|
|
|
425
432
|
body.style.left = previousBodyStyles.left;
|
|
426
433
|
body.style.right = previousBodyStyles.right;
|
|
427
434
|
body.style.overflow = previousBodyStyles.overflow;
|
|
435
|
+
body.style.paddingRight = previousBodyStyles.paddingRight;
|
|
428
436
|
window.scrollTo(0, scrollY);
|
|
429
437
|
restoreTriggerFocus();
|
|
430
438
|
};
|
|
@@ -447,6 +455,9 @@ function MobileSidebar(t0) {
|
|
|
447
455
|
let t5;
|
|
448
456
|
if ($[7] !== setOpenMobile) {
|
|
449
457
|
t5 = (event) => {
|
|
458
|
+
if (event.defaultPrevented || !panelRef.current?.contains(event.target)) {
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
450
461
|
if (event.key === "Escape") {
|
|
451
462
|
event.preventDefault();
|
|
452
463
|
setOpenMobile(false);
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { type ToasterProps } from "sonner";
|
|
2
|
-
/**
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Renders shared notification styling using the consumer's resolved theme. Toasts take pointer input even while a
|
|
4
|
+
* modal overlay (which disables pointer events on the page) is open, and Sonner's hotkey moves keyboard focus into
|
|
5
|
+
* them past the modal's focus trap, so their actions stay usable from a dialog.
|
|
6
|
+
*/
|
|
7
|
+
declare const ThemedToaster: ({ theme, className, ...props }: ToasterProps) => import("react").JSX.Element;
|
|
4
8
|
export { ThemedToaster };
|
|
@@ -1,104 +1,134 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { c as _c } from "react/compiler-runtime";
|
|
3
3
|
import { MotionSlot } from "../motion/motion-slot.js";
|
|
4
|
+
import { cn } from "../lib/utils.js";
|
|
5
|
+
import { letFocusReachToastLayer } from "../lib/toast-layer.js";
|
|
6
|
+
import { useEffect } from "react";
|
|
4
7
|
import { Toaster as Sonner } from "sonner";
|
|
5
8
|
import { useTheme } from "next-themes";
|
|
6
9
|
import { CircleCheck, Info, TriangleAlert, OctagonAlert, Loader } from "lucide-react";
|
|
7
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Renders shared notification styling using the consumer's resolved theme. Toasts take pointer input even while a
|
|
13
|
+
* modal overlay (which disables pointer events on the page) is open, and Sonner's hotkey moves keyboard focus into
|
|
14
|
+
* them past the modal's focus trap, so their actions stay usable from a dialog.
|
|
15
|
+
*/
|
|
9
16
|
const ThemedToaster = (t0) => {
|
|
10
|
-
const $ = _c(
|
|
17
|
+
const $ = _c(17);
|
|
18
|
+
let className;
|
|
11
19
|
let props;
|
|
12
20
|
let theme;
|
|
13
21
|
if ($[0] !== t0) {
|
|
14
|
-
({theme, ...props} = t0);
|
|
22
|
+
({theme, className, ...props} = t0);
|
|
15
23
|
$[0] = t0;
|
|
16
|
-
$[1] =
|
|
17
|
-
$[2] =
|
|
24
|
+
$[1] = className;
|
|
25
|
+
$[2] = props;
|
|
26
|
+
$[3] = theme;
|
|
18
27
|
} else {
|
|
19
|
-
|
|
20
|
-
|
|
28
|
+
className = $[1];
|
|
29
|
+
props = $[2];
|
|
30
|
+
theme = $[3];
|
|
21
31
|
}
|
|
22
32
|
const { resolvedTheme } = useTheme();
|
|
23
33
|
const activeTheme = theme ?? (resolvedTheme === "dark" ? "dark" : "light");
|
|
24
34
|
let t1;
|
|
25
|
-
if ($[
|
|
26
|
-
t1 =
|
|
35
|
+
if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
|
|
36
|
+
t1 = [];
|
|
37
|
+
$[4] = t1;
|
|
38
|
+
} else {
|
|
39
|
+
t1 = $[4];
|
|
40
|
+
}
|
|
41
|
+
useEffect(_temp, t1);
|
|
42
|
+
let t2;
|
|
43
|
+
if ($[5] !== className) {
|
|
44
|
+
t2 = cn("toaster group pointer-events-auto", className);
|
|
45
|
+
$[5] = className;
|
|
46
|
+
$[6] = t2;
|
|
47
|
+
} else {
|
|
48
|
+
t2 = $[6];
|
|
49
|
+
}
|
|
50
|
+
let t3;
|
|
51
|
+
if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
|
|
52
|
+
t3 = /* @__PURE__ */ _jsx(MotionSlot, {
|
|
27
53
|
kind: "selection",
|
|
28
54
|
children: /* @__PURE__ */ _jsx(CircleCheck, { className: "size-4" })
|
|
29
55
|
});
|
|
30
|
-
$[
|
|
56
|
+
$[7] = t3;
|
|
31
57
|
} else {
|
|
32
|
-
|
|
58
|
+
t3 = $[7];
|
|
33
59
|
}
|
|
34
|
-
let
|
|
35
|
-
if ($[
|
|
36
|
-
|
|
60
|
+
let t4;
|
|
61
|
+
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
|
|
62
|
+
t4 = /* @__PURE__ */ _jsx(MotionSlot, {
|
|
37
63
|
kind: "selection",
|
|
38
64
|
children: /* @__PURE__ */ _jsx(Info, { className: "size-4" })
|
|
39
65
|
});
|
|
40
|
-
$[
|
|
66
|
+
$[8] = t4;
|
|
41
67
|
} else {
|
|
42
|
-
|
|
68
|
+
t4 = $[8];
|
|
43
69
|
}
|
|
44
|
-
let
|
|
45
|
-
if ($[
|
|
46
|
-
|
|
70
|
+
let t5;
|
|
71
|
+
if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
|
|
72
|
+
t5 = /* @__PURE__ */ _jsx(MotionSlot, {
|
|
47
73
|
kind: "selection",
|
|
48
74
|
children: /* @__PURE__ */ _jsx(TriangleAlert, { className: "size-4" })
|
|
49
75
|
});
|
|
50
|
-
$[
|
|
76
|
+
$[9] = t5;
|
|
51
77
|
} else {
|
|
52
|
-
|
|
78
|
+
t5 = $[9];
|
|
53
79
|
}
|
|
54
|
-
let
|
|
55
|
-
let
|
|
56
|
-
if ($[
|
|
57
|
-
|
|
58
|
-
success:
|
|
59
|
-
info:
|
|
60
|
-
warning:
|
|
80
|
+
let t6;
|
|
81
|
+
let t7;
|
|
82
|
+
if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
|
|
83
|
+
t6 = {
|
|
84
|
+
success: t3,
|
|
85
|
+
info: t4,
|
|
86
|
+
warning: t5,
|
|
61
87
|
error: /* @__PURE__ */ _jsx(MotionSlot, {
|
|
62
88
|
kind: "selection",
|
|
63
89
|
children: /* @__PURE__ */ _jsx(OctagonAlert, { className: "size-4" })
|
|
64
90
|
}),
|
|
65
91
|
loading: /* @__PURE__ */ _jsx(Loader, { className: "size-4 animate-spin" })
|
|
66
92
|
};
|
|
67
|
-
|
|
93
|
+
t7 = {
|
|
68
94
|
"--normal-bg": "var(--popover)",
|
|
69
95
|
"--normal-text": "var(--popover-foreground)",
|
|
70
96
|
"--normal-border": "var(--border)",
|
|
71
97
|
"--border-radius": "var(--radius)"
|
|
72
98
|
};
|
|
73
|
-
$[
|
|
74
|
-
$[
|
|
99
|
+
$[10] = t6;
|
|
100
|
+
$[11] = t7;
|
|
75
101
|
} else {
|
|
76
|
-
|
|
77
|
-
|
|
102
|
+
t6 = $[10];
|
|
103
|
+
t7 = $[11];
|
|
78
104
|
}
|
|
79
|
-
let
|
|
80
|
-
if ($[
|
|
81
|
-
|
|
82
|
-
$[
|
|
105
|
+
let t8;
|
|
106
|
+
if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
|
|
107
|
+
t8 = { classNames: { toast: "cn-toast" } };
|
|
108
|
+
$[12] = t8;
|
|
83
109
|
} else {
|
|
84
|
-
|
|
110
|
+
t8 = $[12];
|
|
85
111
|
}
|
|
86
|
-
let
|
|
87
|
-
if ($[
|
|
88
|
-
|
|
112
|
+
let t9;
|
|
113
|
+
if ($[13] !== activeTheme || $[14] !== props || $[15] !== t2) {
|
|
114
|
+
t9 = /* @__PURE__ */ _jsx(Sonner, {
|
|
89
115
|
theme: activeTheme,
|
|
90
|
-
className:
|
|
91
|
-
icons:
|
|
92
|
-
style:
|
|
93
|
-
toastOptions:
|
|
116
|
+
className: t2,
|
|
117
|
+
icons: t6,
|
|
118
|
+
style: t7,
|
|
119
|
+
toastOptions: t8,
|
|
94
120
|
...props
|
|
95
121
|
});
|
|
96
|
-
$[
|
|
97
|
-
$[
|
|
98
|
-
$[
|
|
122
|
+
$[13] = activeTheme;
|
|
123
|
+
$[14] = props;
|
|
124
|
+
$[15] = t2;
|
|
125
|
+
$[16] = t9;
|
|
99
126
|
} else {
|
|
100
|
-
|
|
127
|
+
t9 = $[16];
|
|
101
128
|
}
|
|
102
|
-
return
|
|
129
|
+
return t9;
|
|
103
130
|
};
|
|
104
131
|
export { ThemedToaster };
|
|
132
|
+
function _temp() {
|
|
133
|
+
return letFocusReachToastLayer(document);
|
|
134
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tells whether an event target belongs to the toast layer.
|
|
3
|
+
* @param target - Target of the outside interaction.
|
|
4
|
+
* @returns `true` when the target is a toast or one of its controls.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isToastLayerTarget(target: EventTarget | null): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Lets keyboard focus enter the toast layer while a modal traps focus. Radix's focus trap listens for `focusin` and
|
|
9
|
+
* `focusout` on the document and pulls focus back into the modal whenever it lands outside, so Sonner's hotkey could
|
|
10
|
+
* never move focus to a toast's controls. Focus changes that land on a toast stop at the body, after React has run
|
|
11
|
+
* its own handlers and before the document-level trap sees them; every other focus change still reaches the trap.
|
|
12
|
+
* Because the trap never sees focus leave, it cannot pull it back either: when the focused toast control is removed
|
|
13
|
+
* (an action or close button dismisses its toast), focus returns to the element it came from instead of the body.
|
|
14
|
+
* @param ownerDocument - Document whose body hosts the app and the modal portals.
|
|
15
|
+
* @returns Removes the listeners.
|
|
16
|
+
*/
|
|
17
|
+
export declare function letFocusReachToastLayer(ownerDocument: Document): () => void;
|
|
18
|
+
/**
|
|
19
|
+
* Wraps a modal's `onInteractOutside` so presses on toasts never dismiss it. The consumer's handler still runs first
|
|
20
|
+
* and can keep preventing dismissal for its own reasons.
|
|
21
|
+
* @param handler - The consumer's `onInteractOutside`, if any.
|
|
22
|
+
* @returns The handler to give the Radix content.
|
|
23
|
+
*/
|
|
24
|
+
export declare function keepOpenOnToastInteraction<OutsideEvent extends Event>(handler?: (event: OutsideEvent) => void): (event: OutsideEvent) => void;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeps toasts usable while a modal overlay is open. Toasts sit above every overlay, but a modal `Dialog` or `Sheet`
|
|
3
|
+
* treats a press on them as a press outside and closes, so a toast's action or close button would dismiss the form
|
|
4
|
+
* that raised it instead of running.
|
|
5
|
+
*/
|
|
6
|
+
import { TOAST_LAYER_SELECTOR } from "../constants/toast.js";
|
|
7
|
+
/**
|
|
8
|
+
* Tells whether an event target belongs to the toast layer.
|
|
9
|
+
* @param target - Target of the outside interaction.
|
|
10
|
+
* @returns `true` when the target is a toast or one of its controls.
|
|
11
|
+
*/
|
|
12
|
+
export function isToastLayerTarget(target) {
|
|
13
|
+
return target instanceof Element && target.closest(TOAST_LAYER_SELECTOR) !== null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Lets keyboard focus enter the toast layer while a modal traps focus. Radix's focus trap listens for `focusin` and
|
|
17
|
+
* `focusout` on the document and pulls focus back into the modal whenever it lands outside, so Sonner's hotkey could
|
|
18
|
+
* never move focus to a toast's controls. Focus changes that land on a toast stop at the body, after React has run
|
|
19
|
+
* its own handlers and before the document-level trap sees them; every other focus change still reaches the trap.
|
|
20
|
+
* Because the trap never sees focus leave, it cannot pull it back either: when the focused toast control is removed
|
|
21
|
+
* (an action or close button dismisses its toast), focus returns to the element it came from instead of the body.
|
|
22
|
+
* @param ownerDocument - Document whose body hosts the app and the modal portals.
|
|
23
|
+
* @returns Removes the listeners.
|
|
24
|
+
*/
|
|
25
|
+
export function letFocusReachToastLayer(ownerDocument) {
|
|
26
|
+
const { body } = ownerDocument;
|
|
27
|
+
let focusOrigin = null;
|
|
28
|
+
let focusedToastElement = null;
|
|
29
|
+
const restoreFocusAfterRemoval = new MutationObserver(() => {
|
|
30
|
+
if (focusedToastElement?.isConnected !== false) return;
|
|
31
|
+
const activeElement = ownerDocument.activeElement;
|
|
32
|
+
if (activeElement === null || activeElement === body) focusOrigin?.focus({ preventScroll: true });
|
|
33
|
+
stopTrackingToastFocus();
|
|
34
|
+
});
|
|
35
|
+
const stopTrackingToastFocus = () => {
|
|
36
|
+
restoreFocusAfterRemoval.disconnect();
|
|
37
|
+
focusOrigin = null;
|
|
38
|
+
focusedToastElement = null;
|
|
39
|
+
};
|
|
40
|
+
const stopFocusIntoToast = (event) => {
|
|
41
|
+
const focusedElement = event.type === "focusin" ? event.target : event.relatedTarget;
|
|
42
|
+
if (!isToastLayerTarget(focusedElement)) {
|
|
43
|
+
if (event.type === "focusin") stopTrackingToastFocus();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
event.stopPropagation();
|
|
47
|
+
if (event.type !== "focusin") return;
|
|
48
|
+
if (focusedToastElement === null) {
|
|
49
|
+
focusOrigin = event.relatedTarget instanceof HTMLElement ? event.relatedTarget : null;
|
|
50
|
+
restoreFocusAfterRemoval.observe(body, {
|
|
51
|
+
childList: true,
|
|
52
|
+
subtree: true
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
focusedToastElement = focusedElement;
|
|
56
|
+
};
|
|
57
|
+
body.addEventListener("focusin", stopFocusIntoToast);
|
|
58
|
+
body.addEventListener("focusout", stopFocusIntoToast);
|
|
59
|
+
return () => {
|
|
60
|
+
stopTrackingToastFocus();
|
|
61
|
+
body.removeEventListener("focusin", stopFocusIntoToast);
|
|
62
|
+
body.removeEventListener("focusout", stopFocusIntoToast);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Wraps a modal's `onInteractOutside` so presses on toasts never dismiss it. The consumer's handler still runs first
|
|
67
|
+
* and can keep preventing dismissal for its own reasons.
|
|
68
|
+
* @param handler - The consumer's `onInteractOutside`, if any.
|
|
69
|
+
* @returns The handler to give the Radix content.
|
|
70
|
+
*/
|
|
71
|
+
export function keepOpenOnToastInteraction(handler) {
|
|
72
|
+
return (event) => {
|
|
73
|
+
handler?.(event);
|
|
74
|
+
if (isToastLayerTarget(event.target)) event.preventDefault();
|
|
75
|
+
};
|
|
76
|
+
}
|