beez-ui 2.6.0 → 2.6.2
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 +15 -0
- package/README.md +1 -1
- 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 -3
- package/dist/components/themed-toaster.js +66 -50
- package/dist/components/toaster.d.ts +12 -0
- package/dist/components/toaster.js +62 -0
- 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/sonner.d.ts +6 -1
- package/dist/sonner.js +6 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@ 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.2] - 2026-10-16
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- El `Toaster` exportado por beez-ui (desde `beez-ui` y `beez-ui/sonner`) también responde al click y al teclado (Alt+T) mientras hay un `Dialog`, `AlertDialog` o `Sheet` abierto, y devuelve el foco al modal cuando se cierra el toast enfocado, sin cambiar su aspecto ni sus props.
|
|
12
|
+
|
|
13
|
+
## [2.6.1] - 2026-10-16
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- 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.
|
|
18
|
+
- Presionar Escape en un menú, select o diálogo abierto desde el `Sidebar` en mobile cierra solo esa capa y deja el sidebar abierto.
|
|
19
|
+
- 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.
|
|
20
|
+
- 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.
|
|
21
|
+
|
|
7
22
|
## [2.6.0] - 2026-10-15
|
|
8
23
|
|
|
9
24
|
### Added
|
package/README.md
CHANGED
|
@@ -187,7 +187,7 @@ Next y TanStack Router son peers opcionales aislados en sus entrypoints. El prov
|
|
|
187
187
|
|
|
188
188
|
La tabla conserva agrupación estable, columnas configurables, memoización, exclusiones y sincronización de qualifiers por identificadores. La barra conserva navegación por teclado, autocompletado y filtros de texto, rangos, fechas, presencia y carpetas. `Calendar` usa español por defecto y acepta otra locale. Los textos y configuraciones de filtros se pueden personalizar por props.
|
|
189
189
|
|
|
190
|
-
Los componentes compartidos conservan el tema de LaTribu. Se incorporaron atributos `data-variant`/`data-size` del botón, scroll para paneles largos y persistencia opcional del sidebar. `Button` sigue la API de Arc: `variant` `primary`, `secondary`, `ghost` o `danger`, `size` `sm`, `md` o `lg` y `loading`; renderiza un `<button>` nativo con `type="button"` por defecto y no admite `asChild`: un link con aspecto de botón se estiliza como link. Se mantienen los estados deshabilitados y los skeletons deterministas. `AvatarImage` delega carga y fallback a Base UI; conserva carga diferida y recuperación al cambiar `src`. El export
|
|
190
|
+
Los componentes compartidos conservan el tema de LaTribu. Se incorporaron atributos `data-variant`/`data-size` del botón, scroll para paneles largos y persistencia opcional del sidebar. `Button` sigue la API de Arc: `variant` `primary`, `secondary`, `ghost` o `danger`, `size` `sm`, `md` o `lg` y `loading`; renderiza un `<button>` nativo con `type="button"` por defecto y no admite `asChild`: un link con aspecto de botón se estiliza como link. Se mantienen los estados deshabilitados y los skeletons deterministas. `AvatarImage` delega carga y fallback a Base UI; conserva carga diferida y recuperación al cambiar `src`. El export `Toaster` conserva el aspecto y las props de Sonner, y sus toasts responden al click y al teclado (Alt+T) con un `Dialog`, `AlertDialog` o `Sheet` abierto; `ThemedToaster` se apoya en él y agrega los estilos e iconos compartidos.
|
|
191
191
|
|
|
192
192
|
## Componentes de producto reutilizables
|
|
193
193
|
|
|
@@ -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,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
/**
|
|
3
|
-
|
|
1
|
+
import type { ToasterProps } from "sonner";
|
|
2
|
+
/**
|
|
3
|
+
* Renders shared notification styling using the consumer's resolved theme, on top of beez-ui's `Toaster`, so its
|
|
4
|
+
* toasts stay usable from an open `Dialog`, `AlertDialog` or `Sheet`.
|
|
5
|
+
*/
|
|
6
|
+
declare const ThemedToaster: ({ theme, className, ...props }: ToasterProps) => import("react").JSX.Element;
|
|
4
7
|
export { ThemedToaster };
|
|
@@ -1,104 +1,120 @@
|
|
|
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 {
|
|
4
|
+
import { cn } from "../lib/utils.js";
|
|
5
|
+
import { Toaster } from "./toaster.js";
|
|
5
6
|
import { useTheme } from "next-themes";
|
|
6
7
|
import { CircleCheck, Info, TriangleAlert, OctagonAlert, Loader } from "lucide-react";
|
|
7
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Renders shared notification styling using the consumer's resolved theme, on top of beez-ui's `Toaster`, so its
|
|
11
|
+
* toasts stay usable from an open `Dialog`, `AlertDialog` or `Sheet`.
|
|
12
|
+
*/
|
|
9
13
|
const ThemedToaster = (t0) => {
|
|
10
|
-
const $ = _c(
|
|
14
|
+
const $ = _c(16);
|
|
15
|
+
let className;
|
|
11
16
|
let props;
|
|
12
17
|
let theme;
|
|
13
18
|
if ($[0] !== t0) {
|
|
14
|
-
({theme, ...props} = t0);
|
|
19
|
+
({theme, className, ...props} = t0);
|
|
15
20
|
$[0] = t0;
|
|
16
|
-
$[1] =
|
|
17
|
-
$[2] =
|
|
21
|
+
$[1] = className;
|
|
22
|
+
$[2] = props;
|
|
23
|
+
$[3] = theme;
|
|
18
24
|
} else {
|
|
19
|
-
|
|
20
|
-
|
|
25
|
+
className = $[1];
|
|
26
|
+
props = $[2];
|
|
27
|
+
theme = $[3];
|
|
21
28
|
}
|
|
22
29
|
const { resolvedTheme } = useTheme();
|
|
23
30
|
const activeTheme = theme ?? (resolvedTheme === "dark" ? "dark" : "light");
|
|
24
31
|
let t1;
|
|
25
|
-
if ($[
|
|
26
|
-
t1 =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
});
|
|
30
|
-
$[3] = t1;
|
|
32
|
+
if ($[4] !== className) {
|
|
33
|
+
t1 = cn("toaster group", className);
|
|
34
|
+
$[4] = className;
|
|
35
|
+
$[5] = t1;
|
|
31
36
|
} else {
|
|
32
|
-
t1 = $[
|
|
37
|
+
t1 = $[5];
|
|
33
38
|
}
|
|
34
39
|
let t2;
|
|
35
|
-
if ($[
|
|
40
|
+
if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
|
|
36
41
|
t2 = /* @__PURE__ */ _jsx(MotionSlot, {
|
|
37
42
|
kind: "selection",
|
|
38
|
-
children: /* @__PURE__ */ _jsx(
|
|
43
|
+
children: /* @__PURE__ */ _jsx(CircleCheck, { className: "size-4" })
|
|
39
44
|
});
|
|
40
|
-
$[
|
|
45
|
+
$[6] = t2;
|
|
41
46
|
} else {
|
|
42
|
-
t2 = $[
|
|
47
|
+
t2 = $[6];
|
|
43
48
|
}
|
|
44
49
|
let t3;
|
|
45
|
-
if ($[
|
|
50
|
+
if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
|
|
46
51
|
t3 = /* @__PURE__ */ _jsx(MotionSlot, {
|
|
47
52
|
kind: "selection",
|
|
48
|
-
children: /* @__PURE__ */ _jsx(
|
|
53
|
+
children: /* @__PURE__ */ _jsx(Info, { className: "size-4" })
|
|
49
54
|
});
|
|
50
|
-
$[
|
|
55
|
+
$[7] = t3;
|
|
51
56
|
} else {
|
|
52
|
-
t3 = $[
|
|
57
|
+
t3 = $[7];
|
|
53
58
|
}
|
|
54
59
|
let t4;
|
|
60
|
+
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
|
|
61
|
+
t4 = /* @__PURE__ */ _jsx(MotionSlot, {
|
|
62
|
+
kind: "selection",
|
|
63
|
+
children: /* @__PURE__ */ _jsx(TriangleAlert, { className: "size-4" })
|
|
64
|
+
});
|
|
65
|
+
$[8] = t4;
|
|
66
|
+
} else {
|
|
67
|
+
t4 = $[8];
|
|
68
|
+
}
|
|
55
69
|
let t5;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
let t6;
|
|
71
|
+
if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
|
|
72
|
+
t5 = {
|
|
73
|
+
success: t2,
|
|
74
|
+
info: t3,
|
|
75
|
+
warning: t4,
|
|
61
76
|
error: /* @__PURE__ */ _jsx(MotionSlot, {
|
|
62
77
|
kind: "selection",
|
|
63
78
|
children: /* @__PURE__ */ _jsx(OctagonAlert, { className: "size-4" })
|
|
64
79
|
}),
|
|
65
80
|
loading: /* @__PURE__ */ _jsx(Loader, { className: "size-4 animate-spin" })
|
|
66
81
|
};
|
|
67
|
-
|
|
82
|
+
t6 = {
|
|
68
83
|
"--normal-bg": "var(--popover)",
|
|
69
84
|
"--normal-text": "var(--popover-foreground)",
|
|
70
85
|
"--normal-border": "var(--border)",
|
|
71
86
|
"--border-radius": "var(--radius)"
|
|
72
87
|
};
|
|
73
|
-
$[
|
|
74
|
-
$[
|
|
88
|
+
$[9] = t5;
|
|
89
|
+
$[10] = t6;
|
|
75
90
|
} else {
|
|
76
|
-
|
|
77
|
-
|
|
91
|
+
t5 = $[9];
|
|
92
|
+
t6 = $[10];
|
|
78
93
|
}
|
|
79
|
-
let
|
|
80
|
-
if ($[
|
|
81
|
-
|
|
82
|
-
$[
|
|
94
|
+
let t7;
|
|
95
|
+
if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
|
|
96
|
+
t7 = { classNames: { toast: "cn-toast" } };
|
|
97
|
+
$[11] = t7;
|
|
83
98
|
} else {
|
|
84
|
-
|
|
99
|
+
t7 = $[11];
|
|
85
100
|
}
|
|
86
|
-
let
|
|
87
|
-
if ($[
|
|
88
|
-
|
|
101
|
+
let t8;
|
|
102
|
+
if ($[12] !== activeTheme || $[13] !== props || $[14] !== t1) {
|
|
103
|
+
t8 = /* @__PURE__ */ _jsx(Toaster, {
|
|
89
104
|
theme: activeTheme,
|
|
90
|
-
className:
|
|
91
|
-
icons:
|
|
92
|
-
style:
|
|
93
|
-
toastOptions:
|
|
105
|
+
className: t1,
|
|
106
|
+
icons: t5,
|
|
107
|
+
style: t6,
|
|
108
|
+
toastOptions: t7,
|
|
94
109
|
...props
|
|
95
110
|
});
|
|
96
|
-
$[
|
|
97
|
-
$[
|
|
98
|
-
$[
|
|
111
|
+
$[12] = activeTheme;
|
|
112
|
+
$[13] = props;
|
|
113
|
+
$[14] = t1;
|
|
114
|
+
$[15] = t8;
|
|
99
115
|
} else {
|
|
100
|
-
|
|
116
|
+
t8 = $[15];
|
|
101
117
|
}
|
|
102
|
-
return
|
|
118
|
+
return t8;
|
|
103
119
|
};
|
|
104
120
|
export { ThemedToaster };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ComponentProps } from "react";
|
|
2
|
+
import { Toaster as SonnerToaster } from "sonner";
|
|
3
|
+
/**
|
|
4
|
+
* Renders Sonner's toaster unchanged in look, but keeps its toasts usable while a modal `Dialog`, `AlertDialog` or
|
|
5
|
+
* `Sheet` is open: the toast layer takes pointer input even though the modal disables pointer events on the page,
|
|
6
|
+
* and Sonner's hotkey moves keyboard focus into the toasts past the modal's focus trap (focus returns to the modal
|
|
7
|
+
* when the focused toast goes away). Accepts every Sonner prop, including `ref`, and keeps the consumer's `className`.
|
|
8
|
+
* @param props - Sonner's toaster props.
|
|
9
|
+
* @returns The toast layer.
|
|
10
|
+
*/
|
|
11
|
+
declare const Toaster: ({ className, ...props }: ComponentProps<typeof SonnerToaster>) => import("react").JSX.Element;
|
|
12
|
+
export { Toaster };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { c as _c } from "react/compiler-runtime";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
import { letFocusReachToastLayer } from "../lib/toast-layer.js";
|
|
5
|
+
import { useEffect } from "react";
|
|
6
|
+
import { Toaster as SonnerToaster } from "sonner";
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
/**
|
|
9
|
+
* Renders Sonner's toaster unchanged in look, but keeps its toasts usable while a modal `Dialog`, `AlertDialog` or
|
|
10
|
+
* `Sheet` is open: the toast layer takes pointer input even though the modal disables pointer events on the page,
|
|
11
|
+
* and Sonner's hotkey moves keyboard focus into the toasts past the modal's focus trap (focus returns to the modal
|
|
12
|
+
* when the focused toast goes away). Accepts every Sonner prop, including `ref`, and keeps the consumer's `className`.
|
|
13
|
+
* @param props - Sonner's toaster props.
|
|
14
|
+
* @returns The toast layer.
|
|
15
|
+
*/
|
|
16
|
+
const Toaster = (t0) => {
|
|
17
|
+
const $ = _c(9);
|
|
18
|
+
let className;
|
|
19
|
+
let props;
|
|
20
|
+
if ($[0] !== t0) {
|
|
21
|
+
({className, ...props} = t0);
|
|
22
|
+
$[0] = t0;
|
|
23
|
+
$[1] = className;
|
|
24
|
+
$[2] = props;
|
|
25
|
+
} else {
|
|
26
|
+
className = $[1];
|
|
27
|
+
props = $[2];
|
|
28
|
+
}
|
|
29
|
+
let t1;
|
|
30
|
+
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
|
31
|
+
t1 = [];
|
|
32
|
+
$[3] = t1;
|
|
33
|
+
} else {
|
|
34
|
+
t1 = $[3];
|
|
35
|
+
}
|
|
36
|
+
useEffect(_temp, t1);
|
|
37
|
+
let t2;
|
|
38
|
+
if ($[4] !== className) {
|
|
39
|
+
t2 = cn("pointer-events-auto", className);
|
|
40
|
+
$[4] = className;
|
|
41
|
+
$[5] = t2;
|
|
42
|
+
} else {
|
|
43
|
+
t2 = $[5];
|
|
44
|
+
}
|
|
45
|
+
let t3;
|
|
46
|
+
if ($[6] !== props || $[7] !== t2) {
|
|
47
|
+
t3 = /* @__PURE__ */ _jsx(SonnerToaster, {
|
|
48
|
+
className: t2,
|
|
49
|
+
...props
|
|
50
|
+
});
|
|
51
|
+
$[6] = props;
|
|
52
|
+
$[7] = t2;
|
|
53
|
+
$[8] = t3;
|
|
54
|
+
} else {
|
|
55
|
+
t3 = $[8];
|
|
56
|
+
}
|
|
57
|
+
return t3;
|
|
58
|
+
};
|
|
59
|
+
export { Toaster };
|
|
60
|
+
function _temp() {
|
|
61
|
+
return letFocusReachToastLayer(document);
|
|
62
|
+
}
|
|
@@ -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;
|