@ada-cx/lovelace 1.3.0 → 1.5.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.
Files changed (61) hide show
  1. package/dist/components/Banner/Banner.css.d.ts +1 -0
  2. package/dist/components/Banner/Banner.css.js +7 -0
  3. package/dist/components/Banner/Banner.css.js.map +1 -0
  4. package/dist/components/Banner/Banner.d.ts +51 -0
  5. package/dist/components/Banner/Banner.js +25 -0
  6. package/dist/components/Banner/Banner.js.map +1 -0
  7. package/dist/components/Banner/BannerSurface.d.ts +17 -0
  8. package/dist/components/Banner/BannerSurface.js +65 -0
  9. package/dist/components/Banner/BannerSurface.js.map +1 -0
  10. package/dist/components/Banner/index.d.ts +1 -0
  11. package/dist/components/BubbleOverlay/BubbleOverlay.js +21 -20
  12. package/dist/components/BubbleOverlay/BubbleOverlay.js.map +1 -1
  13. package/dist/components/Dialog/DialogIcon.js +5 -5
  14. package/dist/components/DialogOverlay/DialogOverlay.js +23 -22
  15. package/dist/components/DialogOverlay/DialogOverlay.js.map +1 -1
  16. package/dist/components/FullscreenOverlay/FullscreenOverlay.js +21 -20
  17. package/dist/components/FullscreenOverlay/FullscreenOverlay.js.map +1 -1
  18. package/dist/components/Input/InputRoot.js +4 -4
  19. package/dist/components/Input/InputTextArea.js +7 -7
  20. package/dist/components/MenuItem/MenuItemRoot.js +9 -9
  21. package/dist/components/Sheet/SheetBody.d.ts +3 -1
  22. package/dist/components/Sheet/SheetBody.js +5 -4
  23. package/dist/components/Sheet/SheetBody.js.map +1 -1
  24. package/dist/components/SheetOverlay/SheetOverlay.d.ts +3 -1
  25. package/dist/components/SheetOverlay/SheetOverlay.js +22 -20
  26. package/dist/components/SheetOverlay/SheetOverlay.js.map +1 -1
  27. package/dist/components/ToastNotification/ToastNotification.css.d.ts +1 -14
  28. package/dist/components/ToastNotification/ToastNotification.css.js +1 -9
  29. package/dist/components/ToastNotification/ToastNotification.css.js.map +1 -1
  30. package/dist/components/ToastNotification/ToastNotification.d.ts +30 -11
  31. package/dist/components/ToastNotification/ToastNotification.js +29 -18
  32. package/dist/components/ToastNotification/ToastNotification.js.map +1 -1
  33. package/dist/components/ToastNotification/index.d.ts +1 -1
  34. package/dist/components/ToastRegion/ToastContent.d.ts +9 -0
  35. package/dist/components/ToastRegion/ToastRegion.css.d.ts +2 -0
  36. package/dist/components/ToastRegion/ToastRegion.css.js +7 -0
  37. package/dist/components/ToastRegion/ToastRegion.css.js.map +1 -0
  38. package/dist/components/ToastRegion/ToastRegion.d.ts +45 -0
  39. package/dist/components/ToastRegion/ToastRegion.js +38 -0
  40. package/dist/components/ToastRegion/ToastRegion.js.map +1 -0
  41. package/dist/components/ToastRegion/ToastRegionItem.d.ts +13 -0
  42. package/dist/components/ToastRegion/ToastRegionItem.js +49 -0
  43. package/dist/components/ToastRegion/ToastRegionItem.js.map +1 -0
  44. package/dist/components/ToastRegion/ToastRegionLandmark.d.ts +15 -0
  45. package/dist/components/ToastRegion/ToastRegionLandmark.js +62 -0
  46. package/dist/components/ToastRegion/ToastRegionLandmark.js.map +1 -0
  47. package/dist/components/ToastRegion/index.d.ts +4 -0
  48. package/dist/components/ToastRegion/index.js +3 -0
  49. package/dist/components/Tooltip/Tooltip.js +8 -8
  50. package/dist/hooks/index.d.ts +1 -0
  51. package/dist/hooks/overlayRegistry.d.ts +22 -0
  52. package/dist/hooks/overlayRegistry.js +32 -0
  53. package/dist/hooks/overlayRegistry.js.map +1 -0
  54. package/dist/index.d.ts +2 -0
  55. package/dist/index.js +76 -72
  56. package/dist/runtime/LovelaceProvider.js +12 -12
  57. package/dist/style.css +1 -1
  58. package/dist/utils/animation.d.ts +28 -0
  59. package/dist/utils/animation.js +68 -0
  60. package/dist/utils/animation.js.map +1 -0
  61. package/package.json +3 -2
@@ -1,28 +1,30 @@
1
1
  import { cx as e } from "../../utils/cx.js";
2
- import { sheetDialog as t, sheetModal as n, sheetScrim as r } from "./SheetOverlay.css.js";
3
- import { jsx as i } from "react/jsx-runtime";
4
- import { useLocale as a } from "react-aria";
5
- import { Dialog as o, Modal as s, ModalOverlay as c } from "react-aria-components";
2
+ import { OverlayRegistration as t } from "../../hooks/overlayRegistry.js";
3
+ import { sheetDialog as n, sheetModal as r, sheetScrim as i } from "./SheetOverlay.css.js";
4
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
5
+ import { Dialog as s, Modal as c, ModalOverlay as l } from "react-aria-components";
6
+ import { useLocale as u } from "react-aria";
6
7
  //#region src/components/SheetOverlay/SheetOverlay.tsx
7
- function l({ isOpen: l, onOpenChange: u, isDismissable: d = !0, "aria-label": f, className: p, children: m }) {
8
- let { direction: h } = a();
9
- return /* @__PURE__ */ i(c, {
10
- isOpen: l,
11
- onOpenChange: u,
12
- isDismissable: d,
13
- className: r,
14
- dir: h,
15
- children: /* @__PURE__ */ i(s, {
16
- className: n,
17
- children: /* @__PURE__ */ i(o, {
18
- "aria-label": f,
19
- className: e(t, p),
20
- children: m
8
+ function d({ isOpen: d, onOpenChange: f, isDismissable: p = !0, "aria-label": m, "aria-describedby": h, className: g, children: _ }) {
9
+ let { direction: v } = u();
10
+ return /* @__PURE__ */ o(l, {
11
+ isOpen: d,
12
+ onOpenChange: f,
13
+ isDismissable: p,
14
+ className: i,
15
+ dir: v,
16
+ children: [/* @__PURE__ */ a(t, {}), /* @__PURE__ */ a(c, {
17
+ className: r,
18
+ children: /* @__PURE__ */ a(s, {
19
+ "aria-label": m,
20
+ "aria-describedby": h,
21
+ className: e(n, g),
22
+ children: _
21
23
  })
22
- })
24
+ })]
23
25
  });
24
26
  }
25
27
  //#endregion
26
- export { l as SheetOverlay };
28
+ export { d as SheetOverlay };
27
29
 
28
30
  //# sourceMappingURL=SheetOverlay.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SheetOverlay.js","names":[],"sources":["../../../src/components/SheetOverlay/SheetOverlay.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { useLocale } from \"react-aria\";\nimport {\n\tDialog as AriaDialog,\n\tModal,\n\tModalOverlay,\n} from \"react-aria-components\";\nimport { cx } from \"../../utils/cx.js\";\nimport { sheetDialog, sheetModal, sheetScrim } from \"./SheetOverlay.css.js\";\n\nexport interface SheetOverlayProps {\n\t/** Whether the sheet is open. */\n\tisOpen: boolean;\n\t/** Called with the next open state on dismiss (scrim tap, Escape) or programmatic close. */\n\tonOpenChange: (isOpen: boolean) => void;\n\t/** Dismiss on scrim tap. Escape always cancels (RAC default). Defaults to `true`. */\n\tisDismissable?: boolean;\n\t/** Accessible name fallback when the child has no `Sheet.Header` title. */\n\t\"aria-label\"?: string;\n\tclassName?: string;\n\tchildren: ReactNode;\n}\n\n/**\n * Modal bottom-sheet presentation: dark scrim, focus-trap, dismiss-on-tap/Escape,\n * bottom-anchored, rounded-top corners, slide-up. Wraps arbitrary children\n * (typically a `Sheet`). For a full-window surface use `FullscreenOverlay`; for a\n * centered dialog `Dialog`; for a non-dimming bottom bubble `BubbleOverlay`.\n *\n * Give the dialog an accessible name via either a `Sheet.Header` title or the\n * `aria-label` prop — with neither (e.g. an actions-only Confirm sheet) RAC\n * emits a missing-name warning.\n */\nexport function SheetOverlay({\n\tisOpen,\n\tonOpenChange,\n\tisDismissable = true,\n\t\"aria-label\": ariaLabel,\n\tclassName,\n\tchildren,\n}: SheetOverlayProps) {\n\t// Stated, not inherited: this renders through a portal, so its direction must\n\t// not depend on where the portal lands. See the portalled-surface scenario\n\t// under the RTL requirement in openspec/specs/accessibility/spec.md.\n\tconst { direction } = useLocale();\n\n\treturn (\n\t\t<ModalOverlay\n\t\t\tisOpen={isOpen}\n\t\t\tonOpenChange={onOpenChange}\n\t\t\tisDismissable={isDismissable}\n\t\t\tclassName={sheetScrim}\n\t\t\tdir={direction}\n\t\t>\n\t\t\t<Modal className={sheetModal}>\n\t\t\t\t<AriaDialog\n\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\tclassName={cx(sheetDialog, className)}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</AriaDialog>\n\t\t\t</Modal>\n\t\t</ModalOverlay>\n\t);\n}\n"],"mappings":";;;;;;AAiCA,SAAgB,EAAa,EAC5B,WACA,iBACA,mBAAgB,IAChB,cAAc,GACd,cACA,eACqB;CAIrB,IAAM,EAAE,iBAAc,GAAW;AAEjC,QACC,kBAAC,GAAD;EACS;EACM;EACC;EACf,WAAW;EACX,KAAK;YAEL,kBAAC,GAAD;GAAO,WAAW;aACjB,kBAAC,GAAD;IACC,cAAY;IACZ,WAAW,EAAG,GAAa,EAAU;IAEpC;IACW,CAAA;GACN,CAAA;EACM,CAAA"}
1
+ {"version":3,"file":"SheetOverlay.js","names":[],"sources":["../../../src/components/SheetOverlay/SheetOverlay.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { useLocale } from \"react-aria\";\nimport {\n\tDialog as AriaDialog,\n\tModal,\n\tModalOverlay,\n} from \"react-aria-components\";\nimport { OverlayRegistration } from \"../../hooks/overlayRegistry.js\";\nimport { cx } from \"../../utils/cx.js\";\nimport { sheetDialog, sheetModal, sheetScrim } from \"./SheetOverlay.css.js\";\n\nexport interface SheetOverlayProps {\n\t/** Whether the sheet is open. */\n\tisOpen: boolean;\n\t/** Called with the next open state on dismiss (scrim tap, Escape) or programmatic close. */\n\tonOpenChange: (isOpen: boolean) => void;\n\t/** Dismiss on scrim tap. Escape always cancels (RAC default). Defaults to `true`. */\n\tisDismissable?: boolean;\n\t/** Accessible name fallback when the child has no `Sheet.Header` title. */\n\t\"aria-label\"?: string;\n\t/** Id of the element describing the sheet, typically a `Sheet.Body`. */\n\t\"aria-describedby\"?: string;\n\tclassName?: string;\n\tchildren: ReactNode;\n}\n\n/**\n * Modal bottom-sheet presentation: dark scrim, focus-trap, dismiss-on-tap/Escape,\n * bottom-anchored, rounded-top corners, slide-up. Wraps arbitrary children\n * (typically a `Sheet`). For a full-window surface use `FullscreenOverlay`; for a\n * centered dialog `Dialog`; for a non-dimming bottom bubble `BubbleOverlay`.\n *\n * Give the dialog an accessible name via either a `Sheet.Header` title or the\n * `aria-label` prop — with neither (e.g. an actions-only Confirm sheet) RAC\n * emits a missing-name warning.\n */\nexport function SheetOverlay({\n\tisOpen,\n\tonOpenChange,\n\tisDismissable = true,\n\t\"aria-label\": ariaLabel,\n\t\"aria-describedby\": ariaDescribedBy,\n\tclassName,\n\tchildren,\n}: SheetOverlayProps) {\n\t// Stated, not inherited: this renders through a portal, so its direction must\n\t// not depend on where the portal lands. See the portalled-surface scenario\n\t// under the RTL requirement in openspec/specs/accessibility/spec.md.\n\tconst { direction } = useLocale();\n\n\treturn (\n\t\t<ModalOverlay\n\t\t\tisOpen={isOpen}\n\t\t\tonOpenChange={onOpenChange}\n\t\t\tisDismissable={isDismissable}\n\t\t\tclassName={sheetScrim}\n\t\t\tdir={direction}\n\t\t>\n\t\t\t<OverlayRegistration />\n\t\t\t<Modal className={sheetModal}>\n\t\t\t\t<AriaDialog\n\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\taria-describedby={ariaDescribedBy}\n\t\t\t\t\tclassName={cx(sheetDialog, className)}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</AriaDialog>\n\t\t\t</Modal>\n\t\t</ModalOverlay>\n\t);\n}\n"],"mappings":";;;;;;;AAoCA,SAAgB,EAAa,EAC5B,WACA,iBACA,mBAAgB,IAChB,cAAc,GACd,oBAAoB,GACpB,cACA,eACqB;CAIrB,IAAM,EAAE,iBAAc,GAAW;AAEjC,QACC,kBAAC,GAAD;EACS;EACM;EACC;EACf,WAAW;EACX,KAAK;YALN,CAOC,kBAAC,GAAD,EAAuB,CAAA,EACvB,kBAAC,GAAD;GAAO,WAAW;aACjB,kBAAC,GAAD;IACC,cAAY;IACZ,oBAAkB;IAClB,WAAW,EAAG,GAAa,EAAU;IAEpC;IACW,CAAA;GACN,CAAA,CACM"}
@@ -14,17 +14,4 @@ export declare const toastRoot: import("@vanilla-extract/recipes").RuntimeFn<{
14
14
  };
15
15
  };
16
16
  }>;
17
- export declare const toastMessage: import("@vanilla-extract/recipes").RuntimeFn<{
18
- variant: {
19
- "single-line": {
20
- flexShrink: number;
21
- whiteSpace: "nowrap";
22
- textAlign: "center";
23
- };
24
- "multi-line": {
25
- flex: "1 0 0";
26
- minWidth: number;
27
- textAlign: "left";
28
- };
29
- };
30
- }>;
17
+ export declare const toastMessage: string;
@@ -10,15 +10,7 @@ var t = e({
10
10
  } },
11
11
  defaultVariants: { status: "success" },
12
12
  compoundVariants: []
13
- }), n = e({
14
- defaultClassName: "k6tn095",
15
- variantClassNames: { variant: {
16
- "single-line": "k6tn096",
17
- "multi-line": "k6tn097"
18
- } },
19
- defaultVariants: { variant: "single-line" },
20
- compoundVariants: []
21
- });
13
+ }), n = "k6tn095";
22
14
  //#endregion
23
15
  export { n as toastMessage, t as toastRoot };
24
16
 
@@ -1 +1 @@
1
- {"version":3,"file":"ToastNotification.css.js","names":[],"sources":["../../../src/components/ToastNotification/ToastNotification.css.ts"],"sourcesContent":["import { globalStyle, style } from \"@vanilla-extract/css\";\nimport { recipe } from \"@vanilla-extract/recipes\";\nimport { t } from \"../../tokens/index.js\";\n\nconst toastBase = style({\n\tdisplay: \"flex\",\n\talignItems: \"center\",\n\tjustifyContent: \"center\",\n\tboxSizing: \"border-box\",\n\twidth: \"100%\",\n\tgap: t(\"gap-8\"),\n\tpaddingInline: t(\"padding-12\"),\n\tpaddingBlock: t(\"padding-8\"),\n});\n\nexport const toastRoot = recipe({\n\tbase: toastBase,\n\t// Each status pairs a light background with its matching content color; the\n\t// message inherits `color` from the root so it never has to restate it.\n\tvariants: {\n\t\tstatus: {\n\t\t\tsuccess: {\n\t\t\t\tbackgroundColor: t(\"color-background-success-light\"),\n\t\t\t\tcolor: t(\"color-content-success\"),\n\t\t\t},\n\t\t\twarning: {\n\t\t\t\tbackgroundColor: t(\"color-background-warning-light\"),\n\t\t\t\tcolor: t(\"color-content-warning\"),\n\t\t\t},\n\t\t\terror: {\n\t\t\t\tbackgroundColor: t(\"color-background-destructive-light\"),\n\t\t\t\tcolor: t(\"color-content-destructive\"),\n\t\t\t},\n\t\t},\n\t},\n\tdefaultVariants: {\n\t\tstatus: \"success\",\n\t},\n});\n\nexport const toastMessage = recipe({\n\tbase: {\n\t\tmargin: 0,\n\t\tcolor: \"inherit\",\n\t\tfontFamily: t(\"font-family-body\"),\n\t\tfontWeight: t(\"font-weight-medium\"),\n\t\tfontSize: t(\"font-size-body\"),\n\t\tlineHeight: t(\"line-height-body\"),\n\t\toverflowWrap: \"break-word\",\n\t},\n\tvariants: {\n\t\t// single-line: icon + centered label sit as a cluster (justify-center on\n\t\t// the root does the centering); the label never wraps.\n\t\t// multi-line: the label fills the row and wraps left-aligned, with the\n\t\t// icon centered against the block.\n\t\tvariant: {\n\t\t\t\"single-line\": {\n\t\t\t\tflexShrink: 0,\n\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\ttextAlign: \"center\",\n\t\t\t},\n\t\t\t\"multi-line\": {\n\t\t\t\tflex: \"1 0 0\",\n\t\t\t\tminWidth: 0,\n\t\t\t\ttextAlign: \"left\",\n\t\t\t},\n\t\t},\n\t},\n\tdefaultVariants: {\n\t\tvariant: \"single-line\",\n\t},\n});\n\nglobalStyle(`${toastBase} [data-slot='icon']`, {\n\tfontSize: t(\"icon-size-control\"),\n});\n"],"mappings":""}
1
+ {"version":3,"file":"ToastNotification.css.js","names":[],"sources":["../../../src/components/ToastNotification/ToastNotification.css.ts"],"sourcesContent":["import { globalStyle, style } from \"@vanilla-extract/css\";\nimport { recipe } from \"@vanilla-extract/recipes\";\nimport { t } from \"../../tokens/index.js\";\n\nconst toastBase = style({\n\tdisplay: \"flex\",\n\tgap: t(\"gap-8\"),\n\talignItems: \"flex-start\",\n\tboxSizing: \"border-box\",\n\twidth: \"100%\",\n\tpaddingInline: t(\"padding-12\"),\n\tpaddingBlock: t(\"padding-8\"),\n\tfontFamily: t(\"font-family-body\"),\n\tfontWeight: t(\"font-weight-medium\"),\n\tfontSize: t(\"font-size-body\"),\n\tlineHeight: t(\"line-height-body\"),\n\ttextAlign: \"center\",\n\toverflowWrap: \"break-word\",\n});\n\nexport const toastRoot = recipe({\n\tbase: toastBase,\n\tvariants: {\n\t\tstatus: {\n\t\t\tsuccess: {\n\t\t\t\tbackgroundColor: t(\"color-background-success-light\"),\n\t\t\t\tcolor: t(\"color-content-success\"),\n\t\t\t},\n\t\t\twarning: {\n\t\t\t\tbackgroundColor: t(\"color-background-warning-light\"),\n\t\t\t\tcolor: t(\"color-content-warning\"),\n\t\t\t},\n\t\t\terror: {\n\t\t\t\tbackgroundColor: t(\"color-background-destructive-light\"),\n\t\t\t\tcolor: t(\"color-content-destructive\"),\n\t\t\t},\n\t\t},\n\t},\n\tdefaultVariants: {\n\t\tstatus: \"success\",\n\t},\n});\n\nexport const toastMessage = style({\n\tmarginInlineEnd: \"auto\",\n\tminWidth: 0,\n});\n\nglobalStyle(`${toastBase} > [data-slot='icon']`, {\n\tfontSize: t(\"icon-size-control\"),\n\tflexShrink: 0,\n\tmarginInlineStart: \"auto\",\n});\n\nglobalStyle(`${toastBase} > [data-slot='button']`, {\n\tcolor: \"inherit\",\n});\n\nglobalStyle(`${toastBase} > [data-slot='button'] [data-slot='icon']`, {\n\tfontSize: t(\"icon-size-sm\"),\n});\n\n// The card disables its dismiss button only while the surface is leaving, which\n// is not a control the reader should read as unavailable it is the same\n// control, on its way out. Keeping its own look means taking the press away\n// costs nothing on screen.\nglobalStyle(`${toastBase} > [data-slot='button'][data-disabled]`, {\n\tcolor: \"inherit\",\n\tcursor: \"inherit\",\n});\n"],"mappings":""}
@@ -1,6 +1,5 @@
1
- import type { CSSProperties, ReactNode, Ref } from "react";
1
+ import type { CSSProperties, HTMLAttributes, ReactNode, Ref } from "react";
2
2
  export type ToastStatus = "success" | "warning" | "error";
3
- export type ToastVariant = "single-line" | "multi-line";
4
3
  export interface ToastNotificationProps {
5
4
  /**
6
5
  * The outcome being reported — selects the background/content color pair.
@@ -8,15 +7,35 @@ export interface ToastNotificationProps {
8
7
  */
9
8
  status?: ToastStatus;
10
9
  /**
11
- * `single-line` keeps the icon + label as a centered, non-wrapping cluster;
12
- * `multi-line` lets the label fill the row and wrap left-aligned.
10
+ * Renders a trailing dismiss button and runs this when the user presses it.
11
+ * Omit it when the consumer takes the toast down on its own.
13
12
  */
14
- variant?: ToastVariant;
13
+ onDismiss?: () => void;
14
+ /**
15
+ * Accessible name for the dismiss button. Override it when "Dismiss
16
+ * notification" would be ambiguous, or to localize it.
17
+ */
18
+ dismissLabel?: string;
19
+ /**
20
+ * Takes the press away while the card is on screen only to finish leaving.
21
+ * The container it sits in is `inert` by then, but `inert` lands in Safari
22
+ * 15.5 and the supported baseline is iOS 15, where the attribute does nothing
23
+ * — so the button would stay tabbable and offer a press that no longer acts
24
+ * on anything. Disabling keeps the card's layout still through the travel,
25
+ * which removing the button would not.
26
+ */
27
+ dismissDisabled?: boolean;
28
+ /**
29
+ * Attributes for the message element. A container that owns announcement
30
+ * passes its live-region props through here, so the dismiss button stays
31
+ * outside what gets announced.
32
+ */
33
+ messageProps?: HTMLAttributes<HTMLElement>;
15
34
  className?: string;
16
35
  style?: CSSProperties;
17
36
  ref?: Ref<HTMLDivElement>;
18
37
  /**
19
- * The message to announce. A status icon is rendered automatically, so the
38
+ * The message to display. A status icon is rendered automatically, so the
20
39
  * status is conveyed without color perception; for screen-reader users the
21
40
  * icon is decorative, so include the status in the copy when the message
22
41
  * alone wouldn't make the outcome clear.
@@ -28,9 +47,9 @@ export interface ToastNotificationProps {
28
47
  * auto-dismissing feedback after an action — not for blocking errors or anything
29
48
  * needing a decision (use a dialog).
30
49
  *
31
- * Rendered in a live region so assistive tech announces it: Success and Warning
32
- * as a polite `status`, Error as an assertive `alert`. The consumer owns
33
- * dismissal timingkeep it on screen long enough to read or pair it with a
34
- * manual dismiss.
50
+ * Purely presentational: it carries no live region of its own, so it can sit
51
+ * inside a container that owns the announcement. Rendering it standalone
52
+ * announces nothingreach for `ToastRegion` (queued, transient) or
53
+ * `Banner` (persistent, tied to a condition) instead.
35
54
  */
36
- export declare function ToastNotification({ status, variant, className, children, ...rest }: ToastNotificationProps): import("react/jsx-runtime").JSX.Element;
55
+ export declare function ToastNotification({ status, onDismiss, dismissLabel, dismissDisabled, messageProps, className, children, ...rest }: ToastNotificationProps): import("react/jsx-runtime").JSX.Element;
@@ -1,31 +1,42 @@
1
1
  import { cx as e } from "../../utils/cx.js";
2
2
  import { Checkmark as t } from "../Icon/icons/Checkmark.js";
3
3
  import { ExclamationTriangle as n } from "../Icon/icons/ExclamationTriangle.js";
4
- import { XmarkCircle as r } from "../Icon/icons/XmarkCircle.js";
5
- import { toastMessage as i, toastRoot as a } from "./ToastNotification.css.js";
6
- import { jsx as o, jsxs as s } from "react/jsx-runtime";
4
+ import { Xmark as r } from "../Icon/icons/Xmark.js";
5
+ import { XmarkCircle as i } from "../Icon/icons/XmarkCircle.js";
6
+ import { IconButton as a } from "../IconButton/IconButton.js";
7
+ import { toastMessage as o, toastRoot as s } from "./ToastNotification.css.js";
8
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
9
  //#region src/components/ToastNotification/ToastNotification.tsx
8
- var c = {
10
+ var u = {
9
11
  success: t,
10
12
  warning: n,
11
- error: r
13
+ error: i
12
14
  };
13
- function l({ status: t = "success", variant: n = "single-line", className: r, children: l, ...u }) {
14
- let d = t === "error", f = c[t];
15
- return /* @__PURE__ */ s("div", {
16
- ...u,
17
- role: d ? "alert" : "status",
18
- "aria-live": d ? "assertive" : "polite",
15
+ function d({ status: t = "success", onDismiss: n, dismissLabel: i = "Dismiss notification", dismissDisabled: d = !1, messageProps: f, className: p, children: m, ...h }) {
16
+ let g = u[t];
17
+ return /* @__PURE__ */ l("div", {
18
+ ...h,
19
19
  "data-status": t,
20
- "data-variant": n,
21
- className: e(a({ status: t }), r),
22
- children: [/* @__PURE__ */ o(f, {}), /* @__PURE__ */ o("p", {
23
- className: i({ variant: n }),
24
- children: l
25
- })]
20
+ className: e(s({ status: t }), p),
21
+ children: [
22
+ /* @__PURE__ */ c(g, {}),
23
+ /* @__PURE__ */ c("span", {
24
+ ...f,
25
+ className: e(f?.className, o),
26
+ children: m
27
+ }),
28
+ !!n && /* @__PURE__ */ c(a, {
29
+ label: i,
30
+ variant: "tertiary",
31
+ size: "xs",
32
+ isDisabled: d,
33
+ onPress: n,
34
+ children: /* @__PURE__ */ c(r, {})
35
+ })
36
+ ]
26
37
  });
27
38
  }
28
39
  //#endregion
29
- export { l as ToastNotification };
40
+ export { d as ToastNotification };
30
41
 
31
42
  //# sourceMappingURL=ToastNotification.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToastNotification.js","names":[],"sources":["../../../src/components/ToastNotification/ToastNotification.tsx"],"sourcesContent":["import type { CSSProperties, ReactNode, Ref } from \"react\";\nimport { cx } from \"../../utils/cx.js\";\nimport {\n\tCheckmark,\n\tExclamationTriangle,\n\tXmarkCircle,\n} from \"../Icon/icons/index.js\";\nimport { toastMessage, toastRoot } from \"./ToastNotification.css.js\";\n\nexport type ToastStatus = \"success\" | \"warning\" | \"error\";\nexport type ToastVariant = \"single-line\" | \"multi-line\";\n\nconst STATUS_ICON = {\n\tsuccess: Checkmark,\n\twarning: ExclamationTriangle,\n\terror: XmarkCircle,\n} as const;\n\nexport interface ToastNotificationProps {\n\t/**\n\t * The outcome being reported — selects the background/content color pair.\n\t * Bind it to the result of the action, not the UI.\n\t */\n\tstatus?: ToastStatus;\n\t/**\n\t * `single-line` keeps the icon + label as a centered, non-wrapping cluster;\n\t * `multi-line` lets the label fill the row and wrap left-aligned.\n\t */\n\tvariant?: ToastVariant;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n\tref?: Ref<HTMLDivElement>;\n\t/**\n\t * The message to announce. A status icon is rendered automatically, so the\n\t * status is conveyed without color perception; for screen-reader users the\n\t * icon is decorative, so include the status in the copy when the message\n\t * alone wouldn't make the outcome clear.\n\t */\n\tchildren?: ReactNode;\n}\n\n/**\n * Transient inline status message on a status-colored background. Use for brief,\n * auto-dismissing feedback after an action — not for blocking errors or anything\n * needing a decision (use a dialog).\n *\n * Rendered in a live region so assistive tech announces it: Success and Warning\n * as a polite `status`, Error as an assertive `alert`. The consumer owns\n * dismissal timingkeep it on screen long enough to read or pair it with a\n * manual dismiss.\n */\nexport function ToastNotification({\n\tstatus = \"success\",\n\tvariant = \"single-line\",\n\tclassName,\n\tchildren,\n\t...rest\n}: ToastNotificationProps) {\n\tconst isError = status === \"error\";\n\tconst StatusIcon = STATUS_ICON[status];\n\treturn (\n\t\t<div\n\t\t\t{...rest}\n\t\t\trole={isError ? \"alert\" : \"status\"}\n\t\t\taria-live={isError ? \"assertive\" : \"polite\"}\n\t\t\tdata-status={status}\n\t\t\tdata-variant={variant}\n\t\t\tclassName={cx(toastRoot({ status }), className)}\n\t\t>\n\t\t\t<StatusIcon />\n\t\t\t<p className={toastMessage({ variant })}>{children}</p>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;;AAYA,IAAM,IAAc;CACnB,SAAS;CACT,SAAS;CACT,OAAO;CACP;AAmCD,SAAgB,EAAkB,EACjC,YAAS,WACT,aAAU,eACV,cACA,aACA,GAAG,KACuB;CAC1B,IAAM,IAAU,MAAW,SACrB,IAAa,EAAY;AAC/B,QACC,kBAAC,OAAD;EACC,GAAI;EACJ,MAAM,IAAU,UAAU;EAC1B,aAAW,IAAU,cAAc;EACnC,eAAa;EACb,gBAAc;EACd,WAAW,EAAG,EAAU,EAAE,WAAQ,CAAC,EAAE,EAAU;YANhD,CAQC,kBAAC,GAAD,EAAc,CAAA,EACd,kBAAC,KAAD;GAAG,WAAW,EAAa,EAAE,YAAS,CAAC;GAAG;GAAa,CAAA,CAClD"}
1
+ {"version":3,"file":"ToastNotification.js","names":[],"sources":["../../../src/components/ToastNotification/ToastNotification.tsx"],"sourcesContent":["import type { CSSProperties, HTMLAttributes, ReactNode, Ref } from \"react\";\nimport { cx } from \"../../utils/cx.js\";\nimport {\n\tCheckmark,\n\tExclamationTriangle,\n\tXmark,\n\tXmarkCircle,\n} from \"../Icon/icons/index.js\";\nimport { IconButton } from \"../IconButton/IconButton.js\";\nimport { toastMessage, toastRoot } from \"./ToastNotification.css.js\";\n\nexport type ToastStatus = \"success\" | \"warning\" | \"error\";\n\nconst STATUS_ICON = {\n\tsuccess: Checkmark,\n\twarning: ExclamationTriangle,\n\terror: XmarkCircle,\n} as const;\n\nexport interface ToastNotificationProps {\n\t/**\n\t * The outcome being reported — selects the background/content color pair.\n\t * Bind it to the result of the action, not the UI.\n\t */\n\tstatus?: ToastStatus;\n\t/**\n\t * Renders a trailing dismiss button and runs this when the user presses it.\n\t * Omit it when the consumer takes the toast down on its own.\n\t */\n\tonDismiss?: () => void;\n\t/**\n\t * Accessible name for the dismiss button. Override it when \"Dismiss\n\t * notification\" would be ambiguous, or to localize it.\n\t */\n\tdismissLabel?: string;\n\t/**\n\t * Takes the press away while the card is on screen only to finish leaving.\n\t * The container it sits in is `inert` by then, but `inert` lands in Safari\n\t * 15.5 and the supported baseline is iOS 15, where the attribute does nothing\n\t * — so the button would stay tabbable and offer a press that no longer acts\n\t * on anything. Disabling keeps the card's layout still through the travel,\n\t * which removing the button would not.\n\t */\n\tdismissDisabled?: boolean;\n\t/**\n\t * Attributes for the message element. A container that owns announcement\n\t * passes its live-region props through here, so the dismiss button stays\n\t * outside what gets announced.\n\t */\n\tmessageProps?: HTMLAttributes<HTMLElement>;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n\tref?: Ref<HTMLDivElement>;\n\t/**\n\t * The message to display. A status icon is rendered automatically, so the\n\t * status is conveyed without color perception; for screen-reader users the\n\t * icon is decorative, so include the status in the copy when the message\n\t * alone wouldn't make the outcome clear.\n\t */\n\tchildren?: ReactNode;\n}\n\n/**\n * Transient inline status message on a status-colored background. Use for brief,\n * auto-dismissing feedback after an action — not for blocking errors or anything\n * needing a decision (use a dialog).\n *\n * Purely presentational: it carries no live region of its own, so it can sit\n * inside a container that owns the announcement. Rendering it standalone\n * announces nothingreach for `ToastRegion` (queued, transient) or\n * `Banner` (persistent, tied to a condition) instead.\n */\nexport function ToastNotification({\n\tstatus = \"success\",\n\tonDismiss,\n\tdismissLabel = \"Dismiss notification\",\n\tdismissDisabled = false,\n\tmessageProps,\n\tclassName,\n\tchildren,\n\t...rest\n}: ToastNotificationProps) {\n\tconst StatusIcon = STATUS_ICON[status];\n\treturn (\n\t\t<div\n\t\t\t{...rest}\n\t\t\tdata-status={status}\n\t\t\tclassName={cx(toastRoot({ status }), className)}\n\t\t>\n\t\t\t<StatusIcon />\n\t\t\t<span\n\t\t\t\t{...messageProps}\n\t\t\t\tclassName={cx(messageProps?.className, toastMessage)}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</span>\n\t\t\t{!!onDismiss && (\n\t\t\t\t<IconButton\n\t\t\t\t\tlabel={dismissLabel}\n\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\tisDisabled={dismissDisabled}\n\t\t\t\t\tonPress={onDismiss}\n\t\t\t\t>\n\t\t\t\t\t<Xmark />\n\t\t\t\t</IconButton>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;;;;AAaA,IAAM,IAAc;CACnB,SAAS;CACT,SAAS;CACT,OAAO;CACP;AAuDD,SAAgB,EAAkB,EACjC,YAAS,WACT,cACA,kBAAe,wBACf,qBAAkB,IAClB,iBACA,cACA,aACA,GAAG,KACuB;CAC1B,IAAM,IAAa,EAAY;AAC/B,QACC,kBAAC,OAAD;EACC,GAAI;EACJ,eAAa;EACb,WAAW,EAAG,EAAU,EAAE,WAAQ,CAAC,EAAE,EAAU;YAHhD;GAKC,kBAAC,GAAD,EAAc,CAAA;GACd,kBAAC,QAAD;IACC,GAAI;IACJ,WAAW,EAAG,GAAc,WAAW,EAAa;IAEnD;IACK,CAAA;GACN,CAAC,CAAC,KACF,kBAAC,GAAD;IACC,OAAO;IACP,SAAQ;IACR,MAAK;IACL,YAAY;IACZ,SAAS;cAET,kBAAC,GAAD,EAAS,CAAA;IACG,CAAA;GAET"}
@@ -1,2 +1,2 @@
1
- export type { ToastNotificationProps, ToastStatus, ToastVariant, } from "./ToastNotification.js";
1
+ export type { ToastNotificationProps, ToastStatus, } from "./ToastNotification.js";
2
2
  export { ToastNotification } from "./ToastNotification.js";
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ToastStatus } from "../ToastNotification/ToastNotification.js";
3
+ /** What a caller puts on the queue via `queue.add(content, options)`. */
4
+ export interface ToastContent {
5
+ /** The message to announce and display. */
6
+ message: ReactNode;
7
+ /** The outcome being reported. Defaults to `success`. */
8
+ status?: ToastStatus;
9
+ }
@@ -0,0 +1,2 @@
1
+ export declare const toastRegion: string;
2
+ export declare const toastRegionItem: string;
@@ -0,0 +1,7 @@
1
+ /* empty css */
2
+ //#region src/components/ToastRegion/ToastRegion.css.ts
3
+ var e = "kycjg90", t = "kycjg91";
4
+ //#endregion
5
+ export { e as toastRegion, t as toastRegionItem };
6
+
7
+ //# sourceMappingURL=ToastRegion.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToastRegion.css.js","names":[],"sources":["../../../src/components/ToastRegion/ToastRegion.css.ts"],"sourcesContent":["import { style } from \"@vanilla-extract/css\";\nimport { t } from \"../../tokens/index.js\";\n\nexport const toastRegion = style({\n\tdisplay: \"flex\",\n\tflexDirection: \"column\",\n\toutline: \"none\",\n\t// The outgoing toast is taken out of flow on a replacement, so it anchors here.\n\tposition: \"relative\",\n});\n\n// Slides down from the leading edge of whatever the consumer anchors the region\n// to. The travel is the item's own height, so the consumer only has to clip at\n// that edge — no magic offset that has to track the chrome above it.\nexport const toastRegionItem = style({\n\tposition: \"relative\",\n\toutline: \"none\",\n\tzIndex: 1,\n\tselectors: {\n\t\t\"&[data-entering]\": { transform: \"translateY(-100%)\" },\n\t\t\"&[data-exiting]\": { transform: \"translateY(-100%)\" },\n\t\t// A toast replacing another keeps the same motion: the leaving toast slides\n\t\t// up while the arriving one slides down in front of it. The leaving toast has\n\t\t// to come out of flow for that — sliding both in flow stacked them for the\n\t\t// length of the travel, doubling the region's height and shoving the content\n\t\t// below it down and back.\n\t\t//\n\t\t// Keyed on the queue having dropped the toast rather than on `data-exiting`, which drops\n\t\t// the moment the travel ends while the toast is still mounted: the region\n\t\t// then reflowed to two toasts' height for the one frame before the parent\n\t\t// dropped it, exactly as the arriving toast settled.\n\t\t\"&[data-replacing][data-dropped]\": {\n\t\t\tposition: \"absolute\",\n\t\t\ttop: 0,\n\t\t\tleft: 0,\n\t\t\tright: 0,\n\t\t\tzIndex: 0,\n\t\t},\n\t\t\"&[data-focus-visible]\": {\n\t\t\tboxShadow: `inset 0 0 0 ${t(\"border-width-focus\")} ${t(\"color-border-focus\")}`,\n\t\t},\n\t},\n\t\"@media\": {\n\t\t\"(prefers-reduced-motion: no-preference)\": {\n\t\t\ttransition: `transform ${t(\"duration-medium\")} ${t(\"easing-standard\")}`,\n\t\t},\n\t\t\"(forced-colors: active)\": {\n\t\t\tselectors: {\n\t\t\t\t\"&[data-focus-visible]\": {\n\t\t\t\t\toutline: \"2px solid Highlight\",\n\t\t\t\t\toutlineOffset: \"-2px\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n});\n"],"mappings":""}
@@ -0,0 +1,45 @@
1
+ import type { CSSProperties, Ref } from "react";
2
+ import type { ToastQueue } from "react-stately";
3
+ import type { ToastContent } from "./ToastContent.js";
4
+ export interface ToastRegionProps {
5
+ /** The queue to display. Create one per surface with `new ToastQueue()`. */
6
+ queue: ToastQueue<ToastContent>;
7
+ /**
8
+ * Overrides the landmark's accessible name. Leave it unset: the default is
9
+ * already localized and counts the toasts on show ("2 notifications."), which
10
+ * is what a screen-reader user hears on navigating here with F6.
11
+ */
12
+ "aria-label"?: string;
13
+ className?: string;
14
+ style?: CSSProperties;
15
+ /** Attaches to the always-mounted anchor, not the landmark. */
16
+ ref?: Ref<HTMLDivElement>;
17
+ }
18
+ /**
19
+ * Displays the toasts on a queue as a labelled landmark region.
20
+ *
21
+ * The region owns announcement, dismissal timing and focus: the dismiss button
22
+ * is named in the reader's own language, timers pause while
23
+ * the user hovers or focuses it, focus moves to a sibling toast when a focused
24
+ * one closes and returns to where it came from once the last one goes, and the
25
+ * region is reachable with F6. Anchor and clip it from the consumer side — a
26
+ * toast slides in from the region's leading edge, so give the region's container
27
+ * `overflow: hidden` to hide the travel.
28
+ *
29
+ * No landmark renders while the queue is empty, so it does not sit in the
30
+ * accessibility tree between notifications. The anchor it renders into stays
31
+ * mounted regardless: `ariaHideOutside` decides what an open modal hides at the
32
+ * moment it opens, and it spares a subtree only if a top-layer node is already
33
+ * inside it. An anchor that came and went with the toasts would leave the
34
+ * consumer's chrome hidden, and a toast raised afterwards would mount inside
35
+ * that hidden subtree and never be announced.
36
+ *
37
+ * That exemption is why no landmark renders while a modal overlay is open. The
38
+ * region is anchored in the consumer's chrome, which the overlay paints over and
39
+ * seals off from the pointer, so a toast there would be announced and F6-reachable
40
+ * with a dismiss control nobody could click. Unmounting the landmark is what makes
41
+ * the accessibility tree agree with the screen, and it defers rather than discards:
42
+ * the queue keeps the entry, react-aria pauses its countdown as the item unmounts,
43
+ * and the toast arrives whole once the overlay goes.
44
+ */
45
+ export declare function ToastRegion({ queue, ref, ...props }: ToastRegionProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,38 @@
1
+ import { useHasOpenOverlay as e } from "../../hooks/overlayRegistry.js";
2
+ import { ToastRegionLandmark as t } from "./ToastRegionLandmark.js";
3
+ import { jsx as n } from "react/jsx-runtime";
4
+ import { useCallback as r, useState as i } from "react";
5
+ import { useToastQueue as a } from "react-stately";
6
+ //#region src/components/ToastRegion/ToastRegion.tsx
7
+ function o({ queue: o, ref: s, ...c }) {
8
+ let l = a(o), u = e(), [d, f] = i([]), [p, m] = i(l.visibleToasts);
9
+ if (p !== l.visibleToasts) {
10
+ m(l.visibleToasts);
11
+ let e = (e) => l.visibleToasts.some((t) => t.key === e.key), t = p.map((e, t) => ({
12
+ toast: e,
13
+ index: t
14
+ })).filter(({ toast: t }) => !e(t));
15
+ f((n) => [...n.filter(({ toast: t }) => !e(t)), ...t]);
16
+ }
17
+ u && d.length > 0 && f([]);
18
+ let h = r((e) => {
19
+ f((t) => t.filter(({ toast: t }) => t.key !== e));
20
+ }, []), g = d.filter(({ toast: e }) => !l.visibleToasts.some((t) => t.key === e.key)), _ = [...l.visibleToasts];
21
+ for (let { toast: e, index: t } of g) _.splice(Math.min(t, _.length), 0, e);
22
+ let v = new Set(g.filter(({ index: e }) => e === 0).map(({ toast: e }) => e.key));
23
+ return /* @__PURE__ */ n("div", {
24
+ "data-react-aria-top-layer": "true",
25
+ ref: s,
26
+ children: !u && _.length > 0 && /* @__PURE__ */ n(t, {
27
+ ...c,
28
+ state: l,
29
+ toasts: _,
30
+ leavingFromTop: v,
31
+ onExited: h
32
+ })
33
+ });
34
+ }
35
+ //#endregion
36
+ export { o as ToastRegion };
37
+
38
+ //# sourceMappingURL=ToastRegion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToastRegion.js","names":[],"sources":["../../../src/components/ToastRegion/ToastRegion.tsx"],"sourcesContent":["import type { CSSProperties, Ref } from \"react\";\nimport { useCallback, useState } from \"react\";\nimport type { QueuedToast, ToastQueue } from \"react-stately\";\nimport { useToastQueue } from \"react-stately\";\nimport { useHasOpenOverlay } from \"../../hooks/overlayRegistry.js\";\nimport type { ToastContent } from \"./ToastContent.js\";\nimport { ToastRegionLandmark } from \"./ToastRegionLandmark.js\";\n\nexport interface ToastRegionProps {\n\t/** The queue to display. Create one per surface with `new ToastQueue()`. */\n\tqueue: ToastQueue<ToastContent>;\n\t/**\n\t * Overrides the landmark's accessible name. Leave it unset: the default is\n\t * already localized and counts the toasts on show (\"2 notifications.\"), which\n\t * is what a screen-reader user hears on navigating here with F6.\n\t */\n\t\"aria-label\"?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n\t/** Attaches to the always-mounted anchor, not the landmark. */\n\tref?: Ref<HTMLDivElement>;\n}\n\ninterface ExitingToast {\n\ttoast: QueuedToast<ToastContent>;\n\t/** Where it sat in the region, which is where it has to leave from. */\n\tindex: number;\n}\n\n/**\n * Displays the toasts on a queue as a labelled landmark region.\n *\n * The region owns announcement, dismissal timing and focus: the dismiss button\n * is named in the reader's own language, timers pause while\n * the user hovers or focuses it, focus moves to a sibling toast when a focused\n * one closes and returns to where it came from once the last one goes, and the\n * region is reachable with F6. Anchor and clip it from the consumer side — a\n * toast slides in from the region's leading edge, so give the region's container\n * `overflow: hidden` to hide the travel.\n *\n * No landmark renders while the queue is empty, so it does not sit in the\n * accessibility tree between notifications. The anchor it renders into stays\n * mounted regardless: `ariaHideOutside` decides what an open modal hides at the\n * moment it opens, and it spares a subtree only if a top-layer node is already\n * inside it. An anchor that came and went with the toasts would leave the\n * consumer's chrome hidden, and a toast raised afterwards would mount inside\n * that hidden subtree and never be announced.\n *\n * That exemption is why no landmark renders while a modal overlay is open. The\n * region is anchored in the consumer's chrome, which the overlay paints over and\n * seals off from the pointer, so a toast there would be announced and F6-reachable\n * with a dismiss control nobody could click. Unmounting the landmark is what makes\n * the accessibility tree agree with the screen, and it defers rather than discards:\n * the queue keeps the entry, react-aria pauses its countdown as the item unmounts,\n * and the toast arrives whole once the overlay goes.\n */\nexport function ToastRegion({ queue, ref, ...props }: ToastRegionProps) {\n\tconst state = useToastQueue(queue);\n\tconst hasOpenOverlay = useHasOpenOverlay();\n\tconst [exiting, setExiting] = useState<ExitingToast[]>([]);\n\tconst [previous, setPrevious] = useState(state.visibleToasts);\n\n\t// The queue drops a toast the moment it closes, so hold onto what it removed\n\t// until the exit animation finishes — otherwise React unmounts mid-slide.\n\t// Derive during render rather than in a layout effect: an effect runs after\n\t// the commit that already unmounted the item, so it would come back with its\n\t// exit animation missed. The previous list is state rather than a ref because\n\t// React can discard a render, which would keep a ref write but drop the\n\t// update beside it.\n\tif (previous !== state.visibleToasts) {\n\t\tsetPrevious(state.visibleToasts);\n\t\tconst isVisible = (toast: QueuedToast<ToastContent>) =>\n\t\t\tstate.visibleToasts.some((visible) => visible.key === toast.key);\n\t\tconst removed = previous\n\t\t\t.map((toast, index) => ({ toast, index }))\n\t\t\t.filter(({ toast }) => !isVisible(toast));\n\t\t// A toast the queue handed the slot back to is on screen again, so drop the\n\t\t// copy held for its exit — leaving it would queue the key a second time\n\t\t// when it closes for good, and React cannot render one key twice.\n\t\tsetExiting((current) => [\n\t\t\t...current.filter(({ toast }) => !isVisible(toast)),\n\t\t\t...removed,\n\t\t]);\n\t}\n\n\t// A suppressed region takes its toasts off screen at once, so nothing is left\n\t// to animate out. An exit held here would have no `onExited` to end it and\n\t// would replay when the overlay goes, putting a toast back that already left.\n\tif (hasOpenOverlay && exiting.length > 0) {\n\t\tsetExiting([]);\n\t}\n\n\tconst handleExited = useCallback((key: string) => {\n\t\tsetExiting((current) => current.filter(({ toast }) => toast.key !== key));\n\t}, []);\n\n\t// A toast that returns to the queue before its exit animation finishes is\n\t// visible again, so drop the stale copy rather than render the key twice.\n\tconst leaving = exiting.filter(\n\t\t({ toast }) =>\n\t\t\t!state.visibleToasts.some((visible) => visible.key === toast.key),\n\t);\n\t// Each leaver goes back where it sat rather than after the visible ones: a toast\n\t// removed from the middle of a stack would otherwise jump to the bottom of the\n\t// region and travel back up across its neighbour.\n\tconst toasts = [...state.visibleToasts];\n\tfor (const { toast, index } of leaving) {\n\t\ttoasts.splice(Math.min(index, toasts.length), 0, toast);\n\t}\n\t// Only a toast that held the top can leave from there, which is the one place\n\t// the region can take it out of flow without moving it first.\n\tconst leavingFromTop = new Set(\n\t\tleaving.filter(({ index }) => index === 0).map(({ toast }) => toast.key),\n\t);\n\treturn (\n\t\t<div data-react-aria-top-layer=\"true\" ref={ref}>\n\t\t\t{!hasOpenOverlay && toasts.length > 0 && (\n\t\t\t\t<ToastRegionLandmark\n\t\t\t\t\t{...props}\n\t\t\t\t\tstate={state}\n\t\t\t\t\ttoasts={toasts}\n\t\t\t\t\tleavingFromTop={leavingFromTop}\n\t\t\t\t\tonExited={handleExited}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;AAwDA,SAAgB,EAAY,EAAE,UAAO,QAAK,GAAG,KAA2B;CACvE,IAAM,IAAQ,EAAc,EAAM,EAC5B,IAAiB,GAAmB,EACpC,CAAC,GAAS,KAAc,EAAyB,EAAE,CAAC,EACpD,CAAC,GAAU,KAAe,EAAS,EAAM,cAAc;AAS7D,KAAI,MAAa,EAAM,eAAe;AACrC,IAAY,EAAM,cAAc;EAChC,IAAM,KAAa,MAClB,EAAM,cAAc,MAAM,MAAY,EAAQ,QAAQ,EAAM,IAAI,EAC3D,IAAU,EACd,KAAK,GAAO,OAAW;GAAE;GAAO;GAAO,EAAE,CACzC,QAAQ,EAAE,eAAY,CAAC,EAAU,EAAM,CAAC;AAI1C,KAAY,MAAY,CACvB,GAAG,EAAQ,QAAQ,EAAE,eAAY,CAAC,EAAU,EAAM,CAAC,EACnD,GAAG,EACH,CAAC;;AAMH,CAAI,KAAkB,EAAQ,SAAS,KACtC,EAAW,EAAE,CAAC;CAGf,IAAM,IAAe,GAAa,MAAgB;AACjD,KAAY,MAAY,EAAQ,QAAQ,EAAE,eAAY,EAAM,QAAQ,EAAI,CAAC;IACvE,EAAE,CAAC,EAIA,IAAU,EAAQ,QACtB,EAAE,eACF,CAAC,EAAM,cAAc,MAAM,MAAY,EAAQ,QAAQ,EAAM,IAAI,CAClE,EAIK,IAAS,CAAC,GAAG,EAAM,cAAc;AACvC,MAAK,IAAM,EAAE,UAAO,cAAW,EAC9B,GAAO,OAAO,KAAK,IAAI,GAAO,EAAO,OAAO,EAAE,GAAG,EAAM;CAIxD,IAAM,IAAiB,IAAI,IAC1B,EAAQ,QAAQ,EAAE,eAAY,MAAU,EAAE,CAAC,KAAK,EAAE,eAAY,EAAM,IAAI,CACxE;AACD,QACC,kBAAC,OAAD;EAAK,6BAA0B;EAAY;YACzC,CAAC,KAAkB,EAAO,SAAS,KACnC,kBAAC,GAAD;GACC,GAAI;GACG;GACC;GACQ;GAChB,UAAU;GACT,CAAA;EAEE,CAAA"}
@@ -0,0 +1,13 @@
1
+ import type { QueuedToast, ToastState } from "react-stately";
2
+ import type { ToastContent } from "./ToastContent.js";
3
+ export interface ToastRegionItemProps {
4
+ toast: QueuedToast<ToastContent>;
5
+ state: ToastState<ToastContent>;
6
+ /** False once the queue drops the toast, which starts its exit animation. */
7
+ isPresent: boolean;
8
+ /** Whether this toast shares the slot with one being replaced. */
9
+ isReplacing?: boolean;
10
+ /** Runs when the exit animation finishes and the toast can be unmounted. */
11
+ onExited: (key: string) => void;
12
+ }
13
+ export declare function ToastRegionItem({ toast, state, isPresent, isReplacing, onExited, }: ToastRegionItemProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,49 @@
1
+ import { useEnterAnimation as e, useExitAnimation as t } from "../../utils/animation.js";
2
+ import { ToastNotification as n } from "../ToastNotification/ToastNotification.js";
3
+ import { toastRegionItem as r } from "./ToastRegion.css.js";
4
+ import { jsx as i } from "react/jsx-runtime";
5
+ import { useEffect as a, useRef as o } from "react";
6
+ import { mergeProps as s, useFocusRing as c, useToast as l } from "react-aria";
7
+ //#region src/components/ToastRegion/ToastRegionItem.tsx
8
+ function u({ toast: u, state: d, isPresent: f, isReplacing: p, onExited: m }) {
9
+ let h = o(null), { toastProps: g, contentProps: _, titleProps: v, closeButtonProps: y } = l({ toast: u }, d, h), { isFocusVisible: b, focusProps: x } = c(), S = e(h), C = t(h, f);
10
+ a(() => {
11
+ !f && !C && m(u.key);
12
+ }, [
13
+ f,
14
+ C,
15
+ m,
16
+ u.key
17
+ ]);
18
+ let { status: w = "success", message: T } = u.content;
19
+ return /* @__PURE__ */ i("div", {
20
+ ...s(g, x),
21
+ ref: h,
22
+ tabIndex: f ? g.tabIndex : -1,
23
+ role: f ? g.role : void 0,
24
+ inert: !f,
25
+ className: r,
26
+ "data-replacing": p || void 0,
27
+ "data-dropped": !f || void 0,
28
+ "data-entering": S || void 0,
29
+ "data-exiting": C || void 0,
30
+ "data-focus-visible": b || void 0,
31
+ children: /* @__PURE__ */ i(n, {
32
+ status: w,
33
+ onDismiss: () => d.close(u.key),
34
+ dismissDisabled: !f,
35
+ dismissLabel: y["aria-label"],
36
+ messageProps: {
37
+ ..._,
38
+ ...v,
39
+ role: w === "error" ? "alert" : "status",
40
+ "aria-live": w === "error" ? "assertive" : "polite"
41
+ },
42
+ children: T
43
+ })
44
+ });
45
+ }
46
+ //#endregion
47
+ export { u as ToastRegionItem };
48
+
49
+ //# sourceMappingURL=ToastRegionItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToastRegionItem.js","names":[],"sources":["../../../src/components/ToastRegion/ToastRegionItem.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { mergeProps, useFocusRing, useToast } from \"react-aria\";\nimport type { QueuedToast, ToastState } from \"react-stately\";\nimport { useEnterAnimation, useExitAnimation } from \"../../utils/animation.js\";\nimport { ToastNotification } from \"../ToastNotification/ToastNotification.js\";\nimport type { ToastContent } from \"./ToastContent.js\";\nimport { toastRegionItem } from \"./ToastRegion.css.js\";\n\nexport interface ToastRegionItemProps {\n\ttoast: QueuedToast<ToastContent>;\n\tstate: ToastState<ToastContent>;\n\t/** False once the queue drops the toast, which starts its exit animation. */\n\tisPresent: boolean;\n\t/** Whether this toast shares the slot with one being replaced. */\n\tisReplacing?: boolean;\n\t/** Runs when the exit animation finishes and the toast can be unmounted. */\n\tonExited: (key: string) => void;\n}\n\nexport function ToastRegionItem({\n\ttoast,\n\tstate,\n\tisPresent,\n\tisReplacing,\n\tonExited,\n}: ToastRegionItemProps) {\n\tconst ref = useRef<HTMLDivElement>(null);\n\tconst { toastProps, contentProps, titleProps, closeButtonProps } = useToast(\n\t\t{ toast },\n\t\tstate,\n\t\tref,\n\t);\n\tconst { isFocusVisible, focusProps } = useFocusRing();\n\tconst isEntering = useEnterAnimation(ref);\n\tconst isExiting = useExitAnimation(ref, isPresent);\n\n\tuseEffect(() => {\n\t\tif (!isPresent && !isExiting) {\n\t\t\tonExited(toast.key);\n\t\t}\n\t}, [isPresent, isExiting, onExited, toast.key]);\n\n\tconst { status = \"success\", message } = toast.content;\n\n\treturn (\n\t\t<div\n\t\t\t{...mergeProps(toastProps, focusProps)}\n\t\t\tref={ref}\n\t\t\t// The queue has already dropped it, so it is on screen only to finish\n\t\t\t// its travel. Taking only the container out of the tab order left a\n\t\t\t// reachable control whose key the queue no longer holds, so the dismiss\n\t\t\t// button is disabled alongside this.\n\t\t\ttabIndex={isPresent ? toastProps.tabIndex : -1}\n\t\t\t// `useToastRegion` moves focus off a closing toast by taking the first\n\t\t\t// `[role=\"alertdialog\"]` it finds in the region. A dropped toast is still\n\t\t\t// in the DOM for its travel and still sits first, so it would take the\n\t\t\t// focus meant for the arriving one — and being inert, drop it entirely.\n\t\t\trole={isPresent ? toastProps.role : undefined}\n\t\t\tinert={!isPresent}\n\t\t\tclassName={toastRegionItem}\n\t\t\tdata-replacing={isReplacing || undefined}\n\t\t\tdata-dropped={!isPresent || undefined}\n\t\t\tdata-entering={isEntering || undefined}\n\t\t\tdata-exiting={isExiting || undefined}\n\t\t\tdata-focus-visible={isFocusVisible || undefined}\n\t\t>\n\t\t\t<ToastNotification\n\t\t\t\tstatus={status}\n\t\t\t\tonDismiss={() => state.close(toast.key)}\n\t\t\t\tdismissDisabled={!isPresent}\n\t\t\t\tdismissLabel={closeButtonProps[\"aria-label\"]}\n\t\t\t\tmessageProps={{\n\t\t\t\t\t...contentProps,\n\t\t\t\t\t...titleProps,\n\t\t\t\t\t// The queue is one shared surface, so urgency has to be chosen per\n\t\t\t\t\t// toast: a failure interrupts, anything else waits its turn.\n\t\t\t\t\trole: status === \"error\" ? \"alert\" : \"status\",\n\t\t\t\t\t\"aria-live\": status === \"error\" ? \"assertive\" : \"polite\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{message}\n\t\t\t</ToastNotification>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;;AAmBA,SAAgB,EAAgB,EAC/B,UACA,UACA,cACA,gBACA,eACwB;CACxB,IAAM,IAAM,EAAuB,KAAK,EAClC,EAAE,eAAY,iBAAc,eAAY,wBAAqB,EAClE,EAAE,UAAO,EACT,GACA,EACA,EACK,EAAE,mBAAgB,kBAAe,GAAc,EAC/C,IAAa,EAAkB,EAAI,EACnC,IAAY,EAAiB,GAAK,EAAU;AAElD,SAAgB;AACf,EAAI,CAAC,KAAa,CAAC,KAClB,EAAS,EAAM,IAAI;IAElB;EAAC;EAAW;EAAW;EAAU,EAAM;EAAI,CAAC;CAE/C,IAAM,EAAE,YAAS,WAAW,eAAY,EAAM;AAE9C,QACC,kBAAC,OAAD;EACC,GAAI,EAAW,GAAY,EAAW;EACjC;EAKL,UAAU,IAAY,EAAW,WAAW;EAK5C,MAAM,IAAY,EAAW,OAAO,KAAA;EACpC,OAAO,CAAC;EACR,WAAW;EACX,kBAAgB,KAAe,KAAA;EAC/B,gBAAc,CAAC,KAAa,KAAA;EAC5B,iBAAe,KAAc,KAAA;EAC7B,gBAAc,KAAa,KAAA;EAC3B,sBAAoB,KAAkB,KAAA;YAEtC,kBAAC,GAAD;GACS;GACR,iBAAiB,EAAM,MAAM,EAAM,IAAI;GACvC,iBAAiB,CAAC;GAClB,cAAc,EAAiB;GAC/B,cAAc;IACb,GAAG;IACH,GAAG;IAGH,MAAM,MAAW,UAAU,UAAU;IACrC,aAAa,MAAW,UAAU,cAAc;IAChD;aAEA;GACkB,CAAA;EACf,CAAA"}
@@ -0,0 +1,15 @@
1
+ import type { CSSProperties } from "react";
2
+ import type { QueuedToast, ToastState } from "react-stately";
3
+ import type { ToastContent } from "./ToastContent.js";
4
+ export interface ToastRegionLandmarkProps {
5
+ "aria-label"?: string;
6
+ state: ToastState<ToastContent>;
7
+ /** Visible toasts followed by any still playing their exit animation. */
8
+ toasts: QueuedToast<ToastContent>[];
9
+ /** Keys of the leaving toasts that held the top of the region. */
10
+ leavingFromTop: Set<string>;
11
+ onExited: (key: string) => void;
12
+ className?: string;
13
+ style?: CSSProperties;
14
+ }
15
+ export declare function ToastRegionLandmark({ state, toasts, leavingFromTop, onExited, className, style, ...props }: ToastRegionLandmarkProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,62 @@
1
+ import { cx as e } from "../../utils/cx.js";
2
+ import { toastRegion as t } from "./ToastRegion.css.js";
3
+ import { ToastRegionItem as n } from "./ToastRegionItem.js";
4
+ import { jsx as r } from "react/jsx-runtime";
5
+ import { useEffect as i, useRef as a } from "react";
6
+ import { mergeProps as o, useFocusWithin as s, useHover as c, useToastRegion as l } from "react-aria";
7
+ //#region src/components/ToastRegion/ToastRegionLandmark.tsx
8
+ function u({ state: u, toasts: d, leavingFromTop: f, onExited: p, className: m, style: h, ...g }) {
9
+ let _ = a(null), { regionProps: v } = l(g, u, _), y = a(!1), b = a(!1), { hoverProps: x } = c({
10
+ onHoverStart: () => {
11
+ y.current = !0;
12
+ },
13
+ onHoverEnd: () => {
14
+ y.current = !1;
15
+ }
16
+ }), { focusWithinProps: S } = s({
17
+ onFocusWithin: () => {
18
+ b.current = !0;
19
+ },
20
+ onBlurWithin: () => {
21
+ b.current = !1;
22
+ }
23
+ }), C = a(u);
24
+ C.current = u;
25
+ let { visibleToasts: w } = u;
26
+ return i(() => {
27
+ if (w.length === 0) return;
28
+ let e = _.current, t = e?.matches(":hover") ?? !1;
29
+ if (!(y.current || b.current || t)) return;
30
+ C.current.pauseAll();
31
+ let n = () => {
32
+ document.removeEventListener("pointerover", i, !0), document.removeEventListener("pointerout", a, !0), window.removeEventListener("blur", o);
33
+ }, r = () => {
34
+ b.current || (C.current.resumeAll(), n());
35
+ }, i = (t) => {
36
+ let n = t.target;
37
+ e && n instanceof Node && e.contains(n) || r();
38
+ }, a = (e) => {
39
+ e.relatedTarget === null && r();
40
+ }, o = () => r();
41
+ return document.addEventListener("pointerover", i, !0), document.addEventListener("pointerout", a, !0), window.addEventListener("blur", o), n;
42
+ }, [w]), /* @__PURE__ */ r("div", {
43
+ ...o(v, x, S),
44
+ ref: _,
45
+ className: e(t, m),
46
+ style: h,
47
+ children: d.map((e) => {
48
+ let t = u.visibleToasts.some((t) => t.key === e.key);
49
+ return /* @__PURE__ */ r(n, {
50
+ toast: e,
51
+ state: u,
52
+ isPresent: t,
53
+ isReplacing: !t && f.has(e.key) && u.visibleToasts.length > 0,
54
+ onExited: p
55
+ }, e.key);
56
+ })
57
+ });
58
+ }
59
+ //#endregion
60
+ export { u as ToastRegionLandmark };
61
+
62
+ //# sourceMappingURL=ToastRegionLandmark.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToastRegionLandmark.js","names":[],"sources":["../../../src/components/ToastRegion/ToastRegionLandmark.tsx"],"sourcesContent":["import type { CSSProperties } from \"react\";\nimport { useEffect, useRef } from \"react\";\nimport {\n\tmergeProps,\n\tuseFocusWithin,\n\tuseHover,\n\tuseToastRegion,\n} from \"react-aria\";\nimport type { QueuedToast, ToastState } from \"react-stately\";\nimport { cx } from \"../../utils/cx.js\";\nimport type { ToastContent } from \"./ToastContent.js\";\nimport { toastRegion } from \"./ToastRegion.css.js\";\nimport { ToastRegionItem } from \"./ToastRegionItem.js\";\n\nexport interface ToastRegionLandmarkProps {\n\t\"aria-label\"?: string;\n\tstate: ToastState<ToastContent>;\n\t/** Visible toasts followed by any still playing their exit animation. */\n\ttoasts: QueuedToast<ToastContent>[];\n\t/** Keys of the leaving toasts that held the top of the region. */\n\tleavingFromTop: Set<string>;\n\tonExited: (key: string) => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function ToastRegionLandmark({\n\tstate,\n\ttoasts,\n\tleavingFromTop,\n\tonExited,\n\tclassName,\n\tstyle,\n\t...props\n}: ToastRegionLandmarkProps) {\n\tconst ref = useRef<HTMLDivElement>(null);\n\tconst { regionProps } = useToastRegion(props, state, ref);\n\n\t// `useToastRegion` only pauses on a hover or focus change, while a toast starts\n\t// its own countdown as it mounts. A toast that takes the slot while the reader\n\t// is already on the region would therefore run down under them, since nothing\n\t// enters or leaves to trigger that pause — and on a one-slot surface that is\n\t// the ordinary path, not an edge case.\n\t//\n\t// Hover and focus are tracked apart: leaving one while the other still holds\n\t// is not the reader letting go.\n\tconst isHovered = useRef(false);\n\tconst isFocused = useRef(false);\n\tconst { hoverProps } = useHover({\n\t\tonHoverStart: () => {\n\t\t\tisHovered.current = true;\n\t\t},\n\t\tonHoverEnd: () => {\n\t\t\tisHovered.current = false;\n\t\t},\n\t});\n\tconst { focusWithinProps } = useFocusWithin({\n\t\tonFocusWithin: () => {\n\t\t\tisFocused.current = true;\n\t\t},\n\t\tonBlurWithin: () => {\n\t\t\tisFocused.current = false;\n\t\t},\n\t});\n\tconst stateRef = useRef(state);\n\tstateRef.current = state;\n\tconst { visibleToasts } = state;\n\tuseEffect(() => {\n\t\tif (visibleToasts.length === 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst element = ref.current;\n\t\t// The landmark unmounts whenever the slot empties, so a pointer resting\n\t\t// where the next toast lands has no enter event left to report itself with.\n\t\t// The browser keeps `:hover` current across that, so ask the element.\n\t\tconst isUnderPointer = element?.matches(\":hover\") ?? false;\n\t\tif (!(isHovered.current || isFocused.current || isUnderPointer)) {\n\t\t\treturn;\n\t\t}\n\t\tstateRef.current.pauseAll();\n\n\t\t// The pause has to release itself. `useToastRegion` resumes only from its own\n\t\t// hover and focus callbacks, and `useHover` reports no hover end for a pointer\n\t\t// it never saw arrive — or for a touch pointer, which it ignores in both\n\t\t// directions. Without this the countdown never restarts, so the toast holds\n\t\t// the slot for good and the consumer never hears it close.\n\t\tconst stop = () => {\n\t\t\tdocument.removeEventListener(\"pointerover\", onPointerOver, true);\n\t\t\tdocument.removeEventListener(\"pointerout\", onPointerOut, true);\n\t\t\twindow.removeEventListener(\"blur\", onWindowBlur);\n\t\t};\n\t\tconst release = () => {\n\t\t\tif (isFocused.current) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstateRef.current.resumeAll();\n\t\t\tstop();\n\t\t};\n\t\tconst onPointerOver = (event: PointerEvent) => {\n\t\t\tconst target = event.target;\n\t\t\tif (element && target instanceof Node && element.contains(target)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\trelease();\n\t\t};\n\t\t// A pointer that leaves the document reports no further `pointerover`, so\n\t\t// watching that alone leaves the countdown paused for good. Leaving the\n\t\t// document is a null `relatedTarget`; leaving the frame entirely is the blur.\n\t\tconst onPointerOut = (event: PointerEvent) => {\n\t\t\tif (event.relatedTarget === null) {\n\t\t\t\trelease();\n\t\t\t}\n\t\t};\n\t\tconst onWindowBlur = () => release();\n\t\tdocument.addEventListener(\"pointerover\", onPointerOver, true);\n\t\tdocument.addEventListener(\"pointerout\", onPointerOut, true);\n\t\twindow.addEventListener(\"blur\", onWindowBlur);\n\t\treturn stop;\n\t}, [visibleToasts]);\n\n\treturn (\n\t\t<div\n\t\t\t{...mergeProps(regionProps, hoverProps, focusWithinProps)}\n\t\t\tref={ref}\n\t\t\tclassName={cx(toastRegion, className)}\n\t\t\tstyle={style}\n\t\t>\n\t\t\t{toasts.map((toast) => {\n\t\t\t\tconst isPresent = state.visibleToasts.some(\n\t\t\t\t\t(visible) => visible.key === toast.key,\n\t\t\t\t);\n\t\t\t\treturn (\n\t\t\t\t\t<ToastRegionItem\n\t\t\t\t\t\tkey={toast.key}\n\t\t\t\t\t\ttoast={toast}\n\t\t\t\t\t\tstate={state}\n\t\t\t\t\t\tisPresent={isPresent}\n\t\t\t\t\t\t// A toast leaving the top while another is on screen is the slot\n\t\t\t\t\t\t// changing message, so the two slide past each other rather than\n\t\t\t\t\t\t// each animating alone. The motion takes the leaving one out of\n\t\t\t\t\t\t// flow at the region's top, so it is only right for a toast that\n\t\t\t\t\t\t// sat there — one leaving from deeper in a stack stays in flow and\n\t\t\t\t\t\t// lets the stack close over it.\n\t\t\t\t\t\tisReplacing={\n\t\t\t\t\t\t\t!isPresent &&\n\t\t\t\t\t\t\tleavingFromTop.has(toast.key) &&\n\t\t\t\t\t\t\tstate.visibleToasts.length > 0\n\t\t\t\t\t\t}\n\t\t\t\t\t\tonExited={onExited}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;;AA0BA,SAAgB,EAAoB,EACnC,UACA,WACA,mBACA,aACA,cACA,UACA,GAAG,KACyB;CAC5B,IAAM,IAAM,EAAuB,KAAK,EAClC,EAAE,mBAAgB,EAAe,GAAO,GAAO,EAAI,EAUnD,IAAY,EAAO,GAAM,EACzB,IAAY,EAAO,GAAM,EACzB,EAAE,kBAAe,EAAS;EAC/B,oBAAoB;AACnB,KAAU,UAAU;;EAErB,kBAAkB;AACjB,KAAU,UAAU;;EAErB,CAAC,EACI,EAAE,wBAAqB,EAAe;EAC3C,qBAAqB;AACpB,KAAU,UAAU;;EAErB,oBAAoB;AACnB,KAAU,UAAU;;EAErB,CAAC,EACI,IAAW,EAAO,EAAM;AAC9B,GAAS,UAAU;CACnB,IAAM,EAAE,qBAAkB;AAsD1B,QArDA,QAAgB;AACf,MAAI,EAAc,WAAW,EAC5B;EAED,IAAM,IAAU,EAAI,SAId,IAAiB,GAAS,QAAQ,SAAS,IAAI;AACrD,MAAI,EAAE,EAAU,WAAW,EAAU,WAAW,GAC/C;AAED,IAAS,QAAQ,UAAU;EAO3B,IAAM,UAAa;AAGlB,GAFA,SAAS,oBAAoB,eAAe,GAAe,GAAK,EAChE,SAAS,oBAAoB,cAAc,GAAc,GAAK,EAC9D,OAAO,oBAAoB,QAAQ,EAAa;KAE3C,UAAgB;AACjB,KAAU,YAGd,EAAS,QAAQ,WAAW,EAC5B,GAAM;KAED,KAAiB,MAAwB;GAC9C,IAAM,IAAS,EAAM;AACjB,QAAW,aAAkB,QAAQ,EAAQ,SAAS,EAAO,IAGjE,GAAS;KAKJ,KAAgB,MAAwB;AAC7C,GAAI,EAAM,kBAAkB,QAC3B,GAAS;KAGL,UAAqB,GAAS;AAIpC,SAHA,SAAS,iBAAiB,eAAe,GAAe,GAAK,EAC7D,SAAS,iBAAiB,cAAc,GAAc,GAAK,EAC3D,OAAO,iBAAiB,QAAQ,EAAa,EACtC;IACL,CAAC,EAAc,CAAC,EAGlB,kBAAC,OAAD;EACC,GAAI,EAAW,GAAa,GAAY,EAAiB;EACpD;EACL,WAAW,EAAG,GAAa,EAAU;EAC9B;YAEN,EAAO,KAAK,MAAU;GACtB,IAAM,IAAY,EAAM,cAAc,MACpC,MAAY,EAAQ,QAAQ,EAAM,IACnC;AACD,UACC,kBAAC,GAAD;IAEQ;IACA;IACI;IAOX,aACC,CAAC,KACD,EAAe,IAAI,EAAM,IAAI,IAC7B,EAAM,cAAc,SAAS;IAEpB;IACT,EAhBI,EAAM,IAgBV;IAEF;EACG,CAAA"}
@@ -0,0 +1,4 @@
1
+ export type { ToastOptions } from "react-stately";
2
+ export { ToastQueue } from "react-stately";
3
+ export type { ToastContent } from "./ToastContent.js";
4
+ export { ToastRegion, type ToastRegionProps } from "./ToastRegion.js";
@@ -0,0 +1,3 @@
1
+ import "./ToastRegion.js";
2
+ import { ToastQueue as e } from "react-stately";
3
+ export { e as ToastQueue };