@mortenbrudvik/waveui 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +357 -72
- package/dist/components/button/Toolbar.cjs +1 -1
- package/dist/components/button/Toolbar.cjs.map +1 -1
- package/dist/components/button/Toolbar.mjs +25 -30
- package/dist/components/button/Toolbar.mjs.map +1 -1
- package/dist/components/button/Toolbar.navigation.cjs +2 -0
- package/dist/components/button/Toolbar.navigation.cjs.map +1 -0
- package/dist/components/button/Toolbar.navigation.mjs +17 -0
- package/dist/components/button/Toolbar.navigation.mjs.map +1 -0
- package/dist/components/data-display/Avatar.cjs +1 -1
- package/dist/components/data-display/Avatar.cjs.map +1 -1
- package/dist/components/data-display/Avatar.context.cjs +2 -0
- package/dist/components/data-display/Avatar.context.cjs.map +1 -0
- package/dist/components/data-display/Avatar.context.mjs +9 -0
- package/dist/components/data-display/Avatar.context.mjs.map +1 -0
- package/dist/components/data-display/Avatar.mjs +66 -61
- package/dist/components/data-display/Avatar.mjs.map +1 -1
- package/dist/components/data-display/InteractionTag.cjs +2 -0
- package/dist/components/data-display/InteractionTag.cjs.map +1 -0
- package/dist/components/data-display/InteractionTag.mjs +234 -0
- package/dist/components/data-display/InteractionTag.mjs.map +1 -0
- package/dist/components/data-display/Tag.cjs +1 -1
- package/dist/components/data-display/Tag.cjs.map +1 -1
- package/dist/components/data-display/Tag.mjs +222 -90
- package/dist/components/data-display/Tag.mjs.map +1 -1
- package/dist/components/data-display/TagGroup.cjs +2 -0
- package/dist/components/data-display/TagGroup.cjs.map +1 -0
- package/dist/components/data-display/TagGroup.context.cjs +2 -0
- package/dist/components/data-display/TagGroup.context.cjs.map +1 -0
- package/dist/components/data-display/TagGroup.context.mjs +113 -0
- package/dist/components/data-display/TagGroup.context.mjs.map +1 -0
- package/dist/components/data-display/TagGroup.mjs +149 -0
- package/dist/components/data-display/TagGroup.mjs.map +1 -0
- package/dist/components/data-display/tagStyles.cjs +2 -0
- package/dist/components/data-display/tagStyles.cjs.map +1 -0
- package/dist/components/data-display/tagStyles.mjs +108 -0
- package/dist/components/data-display/tagStyles.mjs.map +1 -0
- package/dist/components/feedback/Toaster.cjs +1 -1
- package/dist/components/feedback/Toaster.cjs.map +1 -1
- package/dist/components/feedback/Toaster.mjs +213 -181
- package/dist/components/feedback/Toaster.mjs.map +1 -1
- package/dist/components/input/Combobox.expand.cjs +1 -1
- package/dist/components/input/Combobox.expand.cjs.map +1 -1
- package/dist/components/input/Combobox.expand.mjs +7 -7
- package/dist/components/input/Combobox.expand.mjs.map +1 -1
- package/dist/components/input/Option.cjs +1 -1
- package/dist/components/input/Option.cjs.map +1 -1
- package/dist/components/input/Option.mjs +16 -11
- package/dist/components/input/Option.mjs.map +1 -1
- package/dist/components/input/SwatchPicker.cjs.map +1 -1
- package/dist/components/input/SwatchPicker.context.cjs.map +1 -1
- package/dist/components/input/SwatchPicker.context.mjs.map +1 -1
- package/dist/components/input/SwatchPicker.mjs.map +1 -1
- package/dist/components/input/TagPicker.cjs +1 -1
- package/dist/components/input/TagPicker.cjs.map +1 -1
- package/dist/components/input/TagPicker.context.cjs +2 -0
- package/dist/components/input/TagPicker.context.cjs.map +1 -0
- package/dist/components/input/TagPicker.context.mjs +20 -0
- package/dist/components/input/TagPicker.context.mjs.map +1 -0
- package/dist/components/input/TagPicker.create.cjs +2 -0
- package/dist/components/input/TagPicker.create.cjs.map +1 -0
- package/dist/components/input/TagPicker.create.mjs +24 -0
- package/dist/components/input/TagPicker.create.mjs.map +1 -0
- package/dist/components/input/TagPicker.mjs +13 -279
- package/dist/components/input/TagPicker.mjs.map +1 -1
- package/dist/components/input/TagPicker.option.cjs +2 -0
- package/dist/components/input/TagPicker.option.cjs.map +1 -0
- package/dist/components/input/TagPicker.option.mjs +45 -0
- package/dist/components/input/TagPicker.option.mjs.map +1 -0
- package/dist/components/input/TagPicker.overflow.cjs +2 -0
- package/dist/components/input/TagPicker.overflow.cjs.map +1 -0
- package/dist/components/input/TagPicker.overflow.mjs +153 -0
- package/dist/components/input/TagPicker.overflow.mjs.map +1 -0
- package/dist/components/input/TagPicker.parts.cjs +2 -0
- package/dist/components/input/TagPicker.parts.cjs.map +1 -0
- package/dist/components/input/TagPicker.parts.mjs +425 -0
- package/dist/components/input/TagPicker.parts.mjs.map +1 -0
- package/dist/components/input/TagPicker.root.cjs +2 -0
- package/dist/components/input/TagPicker.root.cjs.map +1 -0
- package/dist/components/input/TagPicker.root.mjs +416 -0
- package/dist/components/input/TagPicker.root.mjs.map +1 -0
- package/dist/components/layout/Accordion.cjs.map +1 -1
- package/dist/components/layout/Accordion.mjs.map +1 -1
- package/dist/components/navigation/Hamburger.cjs +2 -0
- package/dist/components/navigation/Hamburger.cjs.map +1 -0
- package/dist/components/navigation/Hamburger.mjs +54 -0
- package/dist/components/navigation/Hamburger.mjs.map +1 -0
- package/dist/components/navigation/Nav.cjs +1 -1
- package/dist/components/navigation/Nav.cjs.map +1 -1
- package/dist/components/navigation/Nav.context.cjs +2 -0
- package/dist/components/navigation/Nav.context.cjs.map +1 -0
- package/dist/components/navigation/Nav.context.mjs +137 -0
- package/dist/components/navigation/Nav.context.mjs.map +1 -0
- package/dist/components/navigation/Nav.mjs +151 -258
- package/dist/components/navigation/Nav.mjs.map +1 -1
- package/dist/components/navigation/Nav.parts.cjs +2 -0
- package/dist/components/navigation/Nav.parts.cjs.map +1 -0
- package/dist/components/navigation/Nav.parts.mjs +77 -0
- package/dist/components/navigation/Nav.parts.mjs.map +1 -0
- package/dist/components/navigation/Nav.root.cjs +2 -0
- package/dist/components/navigation/Nav.root.cjs.map +1 -0
- package/dist/components/navigation/Nav.root.mjs +78 -0
- package/dist/components/navigation/Nav.root.mjs.map +1 -0
- package/dist/components/navigation/NavDrawer.cjs +2 -0
- package/dist/components/navigation/NavDrawer.cjs.map +1 -0
- package/dist/components/navigation/NavDrawer.context.cjs +2 -0
- package/dist/components/navigation/NavDrawer.context.cjs.map +1 -0
- package/dist/components/navigation/NavDrawer.context.mjs +11 -0
- package/dist/components/navigation/NavDrawer.context.mjs.map +1 -0
- package/dist/components/navigation/NavDrawer.mjs +179 -0
- package/dist/components/navigation/NavDrawer.mjs.map +1 -0
- package/dist/components/overlays/Dialog.cjs +1 -1
- package/dist/components/overlays/Dialog.cjs.map +1 -1
- package/dist/components/overlays/Dialog.mjs +190 -125
- package/dist/components/overlays/Dialog.mjs.map +1 -1
- package/dist/components/overlays/Dialog.shared.cjs +1 -1
- package/dist/components/overlays/Dialog.shared.cjs.map +1 -1
- package/dist/components/overlays/Dialog.shared.mjs +157 -81
- package/dist/components/overlays/Dialog.shared.mjs.map +1 -1
- package/dist/components/overlays/Dialog.slots.cjs +2 -0
- package/dist/components/overlays/Dialog.slots.cjs.map +1 -0
- package/dist/components/overlays/Dialog.slots.mjs +129 -0
- package/dist/components/overlays/Dialog.slots.mjs.map +1 -0
- package/dist/components/overlays/Drawer.cjs +1 -1
- package/dist/components/overlays/Drawer.cjs.map +1 -1
- package/dist/components/overlays/Drawer.context.cjs +2 -0
- package/dist/components/overlays/Drawer.context.cjs.map +1 -0
- package/dist/components/overlays/Drawer.context.mjs +29 -0
- package/dist/components/overlays/Drawer.context.mjs.map +1 -0
- package/dist/components/overlays/Drawer.mjs +12 -187
- package/dist/components/overlays/Drawer.mjs.map +1 -1
- package/dist/components/overlays/Drawer.panel.cjs +2 -0
- package/dist/components/overlays/Drawer.panel.cjs.map +1 -0
- package/dist/components/overlays/Drawer.panel.mjs +159 -0
- package/dist/components/overlays/Drawer.panel.mjs.map +1 -0
- package/dist/components/overlays/Drawer.parts.cjs +2 -0
- package/dist/components/overlays/Drawer.parts.cjs.map +1 -0
- package/dist/components/overlays/Drawer.parts.mjs +152 -0
- package/dist/components/overlays/Drawer.parts.mjs.map +1 -0
- package/dist/components/overlays/Drawer.root.cjs +2 -0
- package/dist/components/overlays/Drawer.root.cjs.map +1 -0
- package/dist/components/overlays/Drawer.root.mjs +207 -0
- package/dist/components/overlays/Drawer.root.mjs.map +1 -0
- package/dist/components/overlays/Drawer.scroll.cjs +2 -0
- package/dist/components/overlays/Drawer.scroll.cjs.map +1 -0
- package/dist/components/overlays/Drawer.scroll.mjs +42 -0
- package/dist/components/overlays/Drawer.scroll.mjs.map +1 -0
- package/dist/hooks/useDismiss.cjs.map +1 -1
- package/dist/hooks/useDismiss.mjs.map +1 -1
- package/dist/hooks/useFocusTrap.cjs +1 -1
- package/dist/hooks/useFocusTrap.cjs.map +1 -1
- package/dist/hooks/useFocusTrap.mjs +115 -98
- package/dist/hooks/useFocusTrap.mjs.map +1 -1
- package/dist/hooks/useModalLayer.cjs +1 -1
- package/dist/hooks/useModalLayer.cjs.map +1 -1
- package/dist/hooks/useModalLayer.mjs +35 -22
- package/dist/hooks/useModalLayer.mjs.map +1 -1
- package/dist/hooks/useRestoreFocus.cjs +1 -1
- package/dist/hooks/useRestoreFocus.cjs.map +1 -1
- package/dist/hooks/useRestoreFocus.mjs +91 -78
- package/dist/hooks/useRestoreFocus.mjs.map +1 -1
- package/dist/hooks/useRovingTabIndex.cjs +1 -1
- package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
- package/dist/hooks/useRovingTabIndex.mjs +102 -78
- package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2226 -221
- package/dist/index.d.ts +2226 -221
- package/dist/index.mjs +115 -107
- package/dist/lib/classNames.cjs +1 -1
- package/dist/lib/classNames.cjs.map +1 -1
- package/dist/lib/classNames.mjs +137 -77
- package/dist/lib/classNames.mjs.map +1 -1
- package/dist/lib/icons.cjs +1 -1
- package/dist/lib/icons.cjs.map +1 -1
- package/dist/lib/icons.mjs +13 -6
- package/dist/lib/icons.mjs.map +1 -1
- package/dist/lib/layers.cjs +1 -1
- package/dist/lib/layers.cjs.map +1 -1
- package/dist/lib/layers.mjs +53 -47
- package/dist/lib/layers.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/styles/tokens.css +25 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toaster.cjs","names":["getOpenLayers","isInsideLayerTree","getTabbableElements","isToastOptions","React","ToasterContext","getDirection","usePresence","useMergedRefs","useId","useEventCallback","getStatusLabel","isOwnEvent","isEditableTarget","joinIds","cn","toasterClassNames","focusRing","StatusText","ToastContext","ToastRoot","useDirection","subscribeLayers","bindToasterHandle","getFirstTabbable","isConnectedAndFocusable","Portal","composeEventHandlers","require_runtime","require_cn","require_dev","require_composeEventHandlers","require_classNames","require_toaster","require_useEventCallback","require_useId","require_direction","require_focus","require_useMergedRefs","require_aria","require_usePresence","require_layers","require_useDirection","require_Portal","require_styles","require_events","require_usePreserveFocus","require_MessageBar_status","require_Toast_context","require_Toast_root","react","react_jsx_runtime","promoteQueued","active","waiting","toast","toasts","limit","markDismissed","index","id","next","markAllDismissed","findNewestToast","newest","isInToastRegion","viewport","node","anchor","layer","hasAction","dismissButton","container","el","resolveLimit","INERT_CONTROLLER","first","second","MISSING_TOASTER_MESSAGE","useToastController","DEFAULT_TIMEOUT","createToastTimers","timers","pauses","started","inBackground","suspended","sync","timer","canRun","onExpire","syncAll","stop","seq","timeout","reason","paused","value","positionClasses","EDGE_GAP","isOnRightSide","inline","position","rtl","getSidePanelOffset","modals","doc","view","width","height","right","top","offset","box","onSide","onEdge","ANNOUNCEMENT_DURATION","LiveMessage","present","setPresent","handle","text","isTitlePart","part","isBodyPart","isFooterPart","INLINE_ELEMENTS","NOT_TEXT_ELEMENTS","NATIVE_NAMED_BY_LABEL","ROLES_NAMED_BY_LABEL","isNamedByLabel","role","isNotRendered","getAccessibleText","root","parts","visit","isRoot","skip","label","separate","child","getChildTexts","composeToastText","title","body","ownStatusTextId","row","titleActions","slot","footer","ToastContainer","entry","presenceRef","dismissed","onExited","containerRef","lastElementRef","attach","registerContainer","mergedRef","getFocusFallback","titleId","setParts","partsRef","registerPart","item","setToast","toastRef","registerToast","registration","dismiss","onDismiss","context","titlePart","bodyPart","ownSeverityLabel","severityId","registered","status","announce","optionStatus","toastStatus","handleKeyDown","event","isMounted","presenceProps","Toaster","limitProp","rest","setToasts","announcements","setAnnouncements","current","prev","announcement","settled","shownToasts","prefix","counterRef","viewportRef","viewportRefs","ref","previousFocusRef","dir","sideOffset","setSideOffset","update","unsubscribe","blurred","handleBlur","handleFocus","dispatchToast","dispatched","t","shown","dismissToast","dismissAllToasts","removeExited","controller","handleOwner","binding","containers","onContainer","from","isLive","previous","candidate","target","previousFocus","reconcileFocus","held","origin","regionPointerOverRef","handlePointerOver","fromRegion","toastsRef","containersRef","hasFocusShortcut","shortcuts","handleShortcut","listener","rememberFocusOrigin","forgetFocusOrigin","to","handleEscape","polite","assertive","message","viewportStyle","style","children","onFocus","onBlur","onPointerEnter","onPointerLeave","onPointerOver","onKeyDown","className"],"sources":["../../../src/components/feedback/Toaster.tsx"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { toasterClassNames } from '../../lib/classNames';\nimport { reportMissingContext, warnOnce } from '../../lib/dev';\nimport { getDirection } from '../../lib/direction';\nimport { isEditableTarget, isOwnEvent } from '../../lib/events';\nimport { getFirstTabbable, getTabbableElements, isConnectedAndFocusable } from '../../lib/focus';\nimport { getOpenLayers, isInsideLayerTree, subscribeLayers } from '../../lib/layers';\nimport { focusRing } from '../../lib/styles';\nimport { bindToasterHandle, isToastOptions } from '../../lib/toaster';\nimport type { ToasterHandle } from '../../lib/toaster';\nimport type { Status } from '../../lib/types';\nimport { useDirection } from '../../hooks/useDirection';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { usePresence } from '../../hooks/usePresence';\nimport { usePreserveFocus } from '../../hooks/usePreserveFocus';\nimport { Portal } from '../portal/Portal';\nimport { StatusText, getStatusLabel } from './MessageBar.status';\nimport { ToastContext, ToasterContext } from './Toast.context';\nimport type { ToastContextValue, ToastPartRegistration, ToastRegistration } from './Toast.context';\nimport { ToastRoot } from './Toast.root';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/** Options for dispatching a toast notification. */\nexport interface ToastOptions {\n /** Status level controlling the toast color, icon, status text and announcement politeness\n * (`error` is announced assertively, every other status politely).\n * @default 'info'\n */\n status?: Status;\n /** Title text of the toast. */\n title: string;\n /** Optional body text displayed below the title. */\n body?: string;\n /**\n * Auto-dismiss timeout in milliseconds. The countdown starts when the toast is shown (a toast\n * waiting beyond the Toaster's `limit` does not count down) and pauses while the pointer or\n * focus is anywhere in the toast region (a menu or popover opened from a toast included) and\n * while the browser window is in the background (it has lost focus, or the page is not shown, as\n * in a background tab, also when the Toaster mounts there). `0` (or any value that is not a\n * positive finite number) keeps the toast until it is dismissed.\n * @default 5000\n */\n timeout?: number;\n /**\n * Identifier of the toast. `dispatchToast` returns it (a generated one when omitted). Dispatching\n * again with the id of a toast that is shown, or still exiting after its dismissal, replaces or\n * revives that toast (content and timer); with the id of a toast that waits beyond the Toaster's\n * `limit`, it replaces its options and the toast keeps its place in the queue.\n */\n toastId?: string;\n /**\n * Visually hidden status text read before the toast (`'Info:'`, `'Success:'`, `'Warning:'`,\n * `'Error:'` by default). Pass a translation for other languages, or `''` to omit it.\n */\n statusLabel?: string;\n /**\n * Accessible name of the toast's dismiss button. Pass a translation for other languages.\n * @default 'Dismiss'\n */\n dismissLabel?: string;\n}\n\n/** Options of `dispatchToast(content, options)`, the form that shows your own React content. */\nexport interface ToastDispatchOptions {\n /** As `ToastOptions.toastId`: dispatching again with the id of a shown or exiting toast replaces it. */\n toastId?: string;\n /**\n * Auto-dismiss timeout in milliseconds, as `ToastOptions.timeout`. A toast that holds an action\n * (an interactive element besides its Dismiss button) stays until it is dismissed unless you\n * pass one: people using a screen reader, a switch or voice control need time to reach it.\n * @default 5000, or no timeout for a toast with an action\n */\n timeout?: number;\n /**\n * Severity of content that renders no `Toast`: the announcement's politeness (`error` is\n * assertive), its spoken prefix and the container's name. A rendered `Toast` uses its own\n * `status`; a different value passed here warns in development.\n * @default 'info'\n */\n status?: Status;\n /** Visually hidden severity text for content that renders no `Toast` (as `Toast.statusLabel`). */\n statusLabel?: string;\n /**\n * Text announced instead of the toast's title, body and action labels (the severity text still\n * comes first), for a toast whose visible text is no good announcement, such as a progress toast.\n */\n announcement?: string;\n}\n\n/** The toast API returned by {@link useToastController}. */\nexport interface ToastController {\n /**\n * Shows a toast and returns its id. `dispatchToast(content, options?)` shows your content,\n * usually a `<Toast>` with parts; `dispatchToast(options)` builds a toast from text (0.5). A\n * plain object is read as options; anything else (an element, a portal, a string) is content. A\n * toast with the same id is replaced (revived while it exits); beyond the Toaster's `limit` the\n * toast waits in a queue. Fluent's `dispatchToast(content, options)` returns nothing.\n */\n dispatchToast: {\n (content: React.ReactNode, options?: ToastDispatchOptions): string;\n (options: ToastOptions): string;\n };\n /**\n * Dismisses the toast with this id and cancels its timer: a shown toast exits (it stays, inert,\n * until an exit motion of yours ends), a waiting one is removed. Unknown ids are ignored.\n */\n dismissToast: (id: string) => void;\n /**\n * Dismisses every toast and cancels their timers: shown toasts exit (as `dismissToast`), queued\n * ones are removed.\n */\n dismissAllToasts: () => void;\n}\n\n/** What a dispatch stores: the options form, or your content with its options. */\ntype DispatchedToast =\n | { form: 'options'; options: ToastOptions }\n | { form: 'content'; content: React.ReactNode; options: ToastDispatchOptions };\n\ntype ToastEntry = DispatchedToast & {\n id: string;\n /** Increases with every dispatch, so a replaced toast is announced again. */\n seq: number;\n /**\n * Whether the toast is shown (rendered, announced, its timer running) or still waits beyond the\n * Toaster's `limit`. Only {@link promoteQueued} sets it; it never goes back to `false`.\n */\n shown: boolean;\n /**\n * Dismissed: its container exits (not announced, no timer, not counted toward `limit`) and the\n * entry is removed when the exit ends; a dispatch with its id revives it (D29).\n */\n dismissed: boolean;\n};\n\n/**\n * Flags the oldest waiting toasts as shown while fewer than `limit` toasts are shown and not\n * dismissed. Returns `toasts` itself when nothing changes, so the Toaster's render-time update\n * settles.\n */\nfunction promoteQueued(toasts: ToastEntry[], limit: number): ToastEntry[] {\n let active = 0;\n let waiting = false;\n for (const toast of toasts) {\n if (!toast.shown) waiting = true;\n else if (!toast.dismissed) active += 1;\n }\n if (!waiting || active >= limit) return toasts;\n return toasts.map((toast) => {\n if (toast.shown || active >= limit) return toast;\n active += 1;\n return { ...toast, shown: true };\n });\n}\n\n/** Dismisses a shown toast (it exits) and drops a waiting one; `toasts` itself when nothing changes. */\nfunction markDismissed(toasts: ToastEntry[], id: string): ToastEntry[] {\n const index = toasts.findIndex((toast) => toast.id === id);\n if (index === -1) return toasts;\n const toast = toasts[index];\n if (!toast.shown) return [...toasts.slice(0, index), ...toasts.slice(index + 1)];\n if (toast.dismissed) return toasts;\n const next = toasts.slice();\n next[index] = { ...toast, dismissed: true };\n return next;\n}\n\n/** Dismisses every shown toast and drops the waiting ones; `toasts` itself when nothing changes. */\nfunction markAllDismissed(toasts: ToastEntry[]): ToastEntry[] {\n if (toasts.every((toast) => toast.shown && toast.dismissed)) return toasts;\n return toasts\n .filter((toast) => toast.shown)\n .map((toast) => (toast.dismissed ? toast : { ...toast, dismissed: true }));\n}\n\n/** The shown, not dismissed toast dispatched last (the highest `seq`), or `undefined`. */\nfunction findNewestToast(toasts: readonly ToastEntry[]): ToastEntry | undefined {\n let newest: ToastEntry | undefined;\n for (const toast of toasts) {\n if (toast.shown && !toast.dismissed && (!newest || toast.seq > newest.seq)) newest = toast;\n }\n return newest;\n}\n\n/**\n * Whether `node` is in the toast region: inside the viewport, or inside an open dismiss layer\n * anchored inside it (a Menu, Popover or Tooltip opened from a toast, whose portal lives elsewhere\n * in the document).\n */\nfunction isInToastRegion(viewport: HTMLElement, node: Node): boolean {\n if (viewport.contains(node)) return true;\n return getOpenLayers().some((layer) => {\n const anchor = layer.getAnchor();\n return anchor !== null && viewport.contains(anchor) && isInsideLayerTree(layer.id, node);\n });\n}\n\n/** Whether a toast holds an action: an element in its Tab order other than its Dismiss button. */\nfunction hasAction(container: HTMLElement, toast: ToastRegistration | null): boolean {\n const dismissButton = toast?.getDismissButton() ?? null;\n return getTabbableElements(container).some((el) => el !== dismissButton);\n}\n\n/** `limit` as the Toaster applies it: whole toasts, at least 1; `undefined` means no limit. */\nfunction resolveLimit(limit: number | undefined): number {\n if (limit === undefined) return Infinity;\n return limit >= 1 ? Math.floor(limit) : 1;\n}\n\n/* ------------------------------------------------------------------ */\n/* Context */\n/* ------------------------------------------------------------------ */\n\nconst INERT_CONTROLLER: ToastController = {\n dispatchToast: (first: React.ReactNode | ToastOptions, second?: ToastDispatchOptions) =>\n (isToastOptions(first) ? first.toastId : second?.toastId) ?? '',\n dismissToast: () => {},\n dismissAllToasts: () => {},\n};\n\n/** The C-CONTEXT message without the `[WaveUI] ` prefix, which `reportMissingContext` adds. */\nconst MISSING_TOASTER_MESSAGE =\n 'useToastController must be used within <Toaster>. Wrap your app (or the part of it that shows toasts) in <Toaster>: it provides the controller to its children.';\n\n/**\n * Returns the {@link ToastController} of the enclosing `<Toaster>`: `dispatchToast(content,\n * options?)` shows your content (usually a `<Toast>` with parts) and `dispatchToast(options)` a\n * toast built from text; both return the toast's id. `dismissToast(id)` dismisses one toast,\n * `dismissAllToasts()` every toast.\n *\n * Must be called inside `<Toaster>`, which provides the controller to its children — wrap the app\n * (or the part of it that shows toasts) in `<Toaster>`; a sibling `<Toaster />` does not work.\n * Outside a Toaster it throws in development; in production it logs an error (once) and returns a\n * controller that does nothing.\n *\n * @example\n * function SaveButton() {\n * const { dispatchToast } = useToastController();\n * return (\n * <Button\n * onClick={() =>\n * dispatchToast(\n * <Toast status=\"success\">\n * <Toast.Title>Saved</Toast.Title>\n * </Toast>,\n * )\n * }\n * >\n * Save\n * </Button>\n * );\n * }\n * // <Toaster><App /></Toaster>\n */\nexport function useToastController(): ToastController {\n const controller = React.useContext(ToasterContext);\n if (controller) return controller;\n reportMissingContext('useToastController', '<Toaster>', MISSING_TOASTER_MESSAGE);\n return INERT_CONTROLLER;\n}\n\n/* ------------------------------------------------------------------ */\n/* Timers */\n/* ------------------------------------------------------------------ */\n\nconst DEFAULT_TIMEOUT = 5000;\n\ntype PauseReason = 'hover' | 'focus';\n\ninterface RunningTimer {\n handle: ReturnType<typeof setTimeout> | null;\n remaining: number;\n startedAt: number;\n}\n\n/**\n * Auto-dismiss timers of one Toaster. A timer runs only while neither the pointer nor focus is in\n * the toast region (D14), the window is in the foreground and the Toaster is mounted; otherwise it\n * is suspended and keeps its remaining time. Every method is called from event handlers or\n * effects, never during render.\n */\ninterface ToastTimers {\n /**\n * Starts the timer of the shown toast `id` for its dispatch `seq`, once: a call with the `seq`\n * already started does nothing, a new `seq` (the toast was replaced) restarts it. A timeout that\n * is not a positive finite number means none. A toast replaced while the region is paused stays\n * paused.\n */\n start(id: string, seq: number, timeout: number): void;\n /** Cancels the timer of `id`. */\n remove(id: string): void;\n /** Cancels every timer; the region's pause is kept. */\n clear(): void;\n /** `true` while the pointer (`'hover'`) or focus (`'focus'`) is in the toast region. */\n setPaused(reason: PauseReason, paused: boolean): void;\n /** Whether the region is paused for `reason`. */\n isPaused(reason: PauseReason): boolean;\n /** `true` while the window has lost focus or the page is not shown (a background tab). */\n setInBackground(inBackground: boolean): void;\n /** `true` while the Toaster is unmounted (including StrictMode's simulated unmount). */\n setSuspended(suspended: boolean): void;\n}\n\nfunction createToastTimers(onExpire: (id: string) => void): ToastTimers {\n const timers = new Map<string, RunningTimer>();\n /** Why the region pauses every timer. */\n const pauses = new Set<PauseReason>();\n /** The dispatch (`seq`) whose timer was started last, per toast. */\n const started = new Map<string, number>();\n let inBackground = false;\n let suspended = false;\n\n const sync = (id: string) => {\n const timer = timers.get(id);\n if (!timer) return;\n const canRun = !suspended && !inBackground && pauses.size === 0;\n if (canRun && timer.handle === null) {\n timer.startedAt = Date.now();\n timer.handle = setTimeout(() => {\n timers.delete(id);\n started.delete(id);\n onExpire(id);\n }, timer.remaining);\n } else if (!canRun && timer.handle !== null) {\n clearTimeout(timer.handle);\n timer.handle = null;\n timer.remaining = Math.max(0, timer.remaining - (Date.now() - timer.startedAt));\n }\n };\n const syncAll = () => {\n for (const id of Array.from(timers.keys())) sync(id);\n };\n const stop = (id: string) => {\n const timer = timers.get(id);\n if (timer?.handle != null) clearTimeout(timer.handle);\n timers.delete(id);\n };\n\n return {\n start(id, seq, timeout) {\n if (started.get(id) === seq) return;\n started.set(id, seq);\n stop(id);\n if (!(timeout > 0) || !Number.isFinite(timeout)) return;\n timers.set(id, { handle: null, remaining: timeout, startedAt: 0 });\n sync(id);\n },\n remove(id) {\n stop(id);\n started.delete(id);\n },\n clear() {\n for (const id of Array.from(timers.keys())) stop(id);\n started.clear();\n },\n isPaused(reason) {\n return pauses.has(reason);\n },\n setPaused(reason, paused) {\n if (paused) pauses.add(reason);\n else pauses.delete(reason);\n syncAll();\n },\n setInBackground(value) {\n inBackground = value;\n syncAll();\n },\n setSuspended(value) {\n suspended = value;\n syncAll();\n },\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Toaster (container) */\n/* ------------------------------------------------------------------ */\n\n/**\n * Corner of the viewport a {@link Toaster} shows its toasts in (`ToasterProps.position`).\n * `start`/`end` follow the writing direction; `left`/`right` are physical.\n */\nexport type ToastPosition =\n | 'top-start'\n | 'top-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'top-right'\n | 'top-left'\n | 'bottom-right'\n | 'bottom-left';\n\n/** Keyboard shortcuts of a Toaster (Fluent's shape). */\nexport interface ToasterShortcuts {\n /**\n * Returns `true` for the key press that moves focus to the most recently dispatched toast, for\n * example `(event) => event.altKey && event.shiftKey && event.code === 'KeyN'`. Use a modifier\n * (or let people change or turn off the shortcut): a single-character shortcut fails WCAG 2.1.4.\n */\n focus?: (event: KeyboardEvent) => boolean;\n}\n\n/** Properties for the Toaster container component. */\nexport interface ToasterProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Corner of the viewport the toasts appear in. `start`/`end` follow the writing direction (the\n * `end` side is the right in LTR and the left in RTL); `left`/`right` are physical.\n * @default 'bottom-end'\n */\n position?: ToastPosition;\n /**\n * Most toasts shown at once. Further toasts wait in a queue (in dispatch order) and appear when\n * a shown toast goes; a queued toast is not announced and its timer does not run until then.\n * Lowering it never hides a toast that is already shown, and a toast dispatched again with its id\n * while it exits comes back at once, even when `limit` toasts are already shown. A value below 1\n * counts as 1 (development warning); `Infinity` means no limit.\n * @default Infinity\n */\n limit?: number;\n /** Keyboard shortcuts; Escape, Delete and Backspace need none (see the component docs). */\n shortcuts?: ToasterShortcuts;\n /**\n * Binds this Toaster to a handle from `createToaster()`: toasts dispatched through the handle\n * render here. A handle binds one Toaster: a second Toaster given a bound handle does not bind\n * (development warning), and does not take the handle over when the first unmounts; the handle\n * queues again until a Toaster binds it.\n */\n toaster?: ToasterHandle;\n /** Ref to the toast region (the portaled `<div role=\"region\">`). */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Corner placement. The margin on the toasts' side is `--wave-toaster-offset`, which the Toaster\n * sets while a modal panel covers that side (see {@link getSidePanelOffset}); unset, it is `0`.\n */\nconst positionClasses: Record<ToastPosition, string> = {\n 'top-start': 'top-4 start-4 ms-(--wave-toaster-offset)',\n 'top-end': 'top-4 end-4 me-(--wave-toaster-offset)',\n 'bottom-start': 'bottom-4 start-4 ms-(--wave-toaster-offset)',\n 'bottom-end': 'bottom-4 end-4 me-(--wave-toaster-offset)',\n 'top-right': 'top-4 right-4 mr-(--wave-toaster-offset)', // wave-allow-physical: explicit physical position value\n 'top-left': 'top-4 left-4 ml-(--wave-toaster-offset)', // wave-allow-physical: explicit physical position value\n 'bottom-right': 'bottom-4 right-4 mr-(--wave-toaster-offset)', // wave-allow-physical: explicit physical position value\n 'bottom-left': 'bottom-4 left-4 ml-(--wave-toaster-offset)', // wave-allow-physical: explicit physical position value\n};\n\n/** The toasts' distance from the window edges (`*-4`), also the tolerance for \"at the edge\". */\nconst EDGE_GAP = 16;\n\n/** Whether the toasts sit at the right edge of the window (`end` is the right in LTR). */\nfunction isOnRightSide(position: ToastPosition, viewport: HTMLElement): boolean {\n const inline = position.slice(position.indexOf('-') + 1);\n if (inline === 'right' || inline === 'left') return inline === 'right';\n const rtl = getDirection(viewport) === 'rtl';\n return inline === 'end' ? !rtl : rtl;\n}\n\n/**\n * How far the toasts move away from their side while an open modal surface (a Drawer panel) covers\n * their corner, so they never hide the panel's controls (WCAG 2.4.11 Focus Not Obscured): the\n * surface's width from that side of the window, which leaves the usual gap between toasts and\n * panel. A surface counts when it reaches the toasts' side and their top or bottom edge (a centered\n * Dialog does not). `0` when no such surface is open, or when the toasts would not fit beside it\n * (a full-width panel on a phone): then they keep their corner.\n */\nfunction getSidePanelOffset(viewport: HTMLElement, position: ToastPosition): number {\n const modals = getOpenLayers().filter((layer) => layer.kind === 'modal');\n if (modals.length === 0) return 0;\n const doc = viewport.ownerDocument;\n const view = doc.defaultView;\n if (!view) return 0;\n // The box fixed elements are placed in: the window without its scrollbars.\n const width = doc.documentElement.clientWidth || view.innerWidth;\n const height = doc.documentElement.clientHeight || view.innerHeight;\n const right = isOnRightSide(position, viewport);\n const top = position.startsWith('top');\n\n let offset = 0;\n for (const layer of modals) {\n for (const el of layer.getElements()) {\n if (!el?.isConnected) continue;\n const box = el.getBoundingClientRect();\n if (box.width <= 0 || box.height <= 0) continue;\n const onSide = right ? box.right >= width - EDGE_GAP : box.left <= EDGE_GAP;\n const onEdge = top ? box.top <= EDGE_GAP : box.bottom >= height - EDGE_GAP;\n if (onSide && onEdge) offset = Math.max(offset, right ? width - box.left : box.right);\n }\n }\n if (offset <= 0 || width - offset < viewport.offsetWidth + 2 * EDGE_GAP) return 0;\n return Math.ceil(offset);\n}\n\n/**\n * How long a toast's text stays in the live region: long enough for screen readers to pick it up\n * (also a polite message queued behind other speech), short enough that someone browsing the\n * Notifications region later meets the text once, in the toast, not a second time in the region.\n */\nconst ANNOUNCEMENT_DURATION = 2000;\n\n/** A toast's message for the live regions, composed by its container after it mounts (D13). */\ninterface Announcement {\n /** The dispatch it belongs to: a replacement (a new `seq`) is announced again. */\n seq: number;\n text: string;\n /** `error` toasts are announced assertively, every other status politely. */\n assertive: boolean;\n}\n\n/**\n * One toast's message in a live region. It is added when the toast is shown (at dispatch, or when\n * a waiting toast appears; a replacement remounts it, so it is read again) and removed after\n * {@link ANNOUNCEMENT_DURATION} or with the toast. Removal is not announced (`aria-relevant` stays\n * at its default, additions and text).\n */\nfunction LiveMessage({ text }: { text: string }) {\n const [present, setPresent] = React.useState(true);\n React.useEffect(() => {\n const handle = setTimeout(() => setPresent(false), ANNOUNCEMENT_DURATION);\n return () => clearTimeout(handle);\n }, []);\n return present ? <div>{text}</div> : null;\n}\nLiveMessage.displayName = 'LiveMessage';\n\ninterface ToastContainerProps {\n entry: ToastEntry;\n timers: ToastTimers;\n onDismiss: (id: string) => void;\n onExited: (id: string) => void;\n getFocusFallback: (from: HTMLElement | null) => HTMLElement | null;\n announce: (id: string, announcement: Announcement) => void;\n registerContainer: (id: string, node: HTMLElement | null) => void;\n}\n\nfunction isTitlePart(\n part: ToastPartRegistration,\n): part is Extract<ToastPartRegistration, { kind: 'title' }> {\n return part.kind === 'title';\n}\n\nfunction isBodyPart(\n part: ToastPartRegistration,\n): part is Extract<ToastPartRegistration, { kind: 'body' }> {\n return part.kind === 'body';\n}\n\nfunction isFooterPart(\n part: ToastPartRegistration,\n): part is Extract<ToastPartRegistration, { kind: 'footer' }> {\n return part.kind === 'footer';\n}\n\n/** Elements whose text runs on without a break; every other element separates its text. */\nconst INLINE_ELEMENTS = new Set([\n 'a',\n 'abbr',\n 'b',\n 'bdi',\n 'bdo',\n 'cite',\n 'code',\n 'data',\n 'dfn',\n 'em',\n 'i',\n 'kbd',\n 'label',\n 'mark',\n 'q',\n 's',\n 'samp',\n 'small',\n 'span',\n 'strong',\n 'sub',\n 'sup',\n 'time',\n 'u',\n 'var',\n 'wbr',\n]);\n\n/** Elements browsers never render as text. */\nconst NOT_TEXT_ELEMENTS = new Set(['noscript', 'script', 'style', 'template']);\n\n/** Native elements a screen reader names by their `aria-label` rather than by their content. */\nconst NATIVE_NAMED_BY_LABEL = new Set(['button', 'img', 'input', 'select', 'textarea']);\n\n/** Roles of controls and images, which are named by their `aria-label` rather than by content. */\nconst ROLES_NAMED_BY_LABEL = new Set([\n 'button',\n 'checkbox',\n 'combobox',\n 'img',\n 'link',\n 'option',\n 'radio',\n 'slider',\n 'spinbutton',\n 'switch',\n 'tab',\n 'textbox',\n]);\n\n/**\n * Whether `aria-label` replaces the content of `el` (a control, a link or an image); any other\n * element, such as a labelled toolbar or group, is read through its content.\n */\nfunction isNamedByLabel(el: Element): boolean {\n const role = el.getAttribute('role')?.trim().split(/\\s+/)[0];\n if (role) return ROLES_NAMED_BY_LABEL.has(role) || role.startsWith('menuitem');\n if (el.localName === 'a') return el.hasAttribute('href');\n return NATIVE_NAMED_BY_LABEL.has(el.localName);\n}\n\n/**\n * Whether `el` is left out of the accessible text: the `hidden` attribute, `aria-hidden=\"true\"` and\n * elements that are no text. Text hidden by a style sheet is still read: the spec defines hidden as\n * the attribute and `aria-hidden`, and reading computed styles would make the text depend on CSS.\n */\nfunction isNotRendered(el: Element): boolean {\n return (\n el.getAttribute('aria-hidden') === 'true' ||\n el.hasAttribute('hidden') ||\n NOT_TEXT_ELEMENTS.has(el.localName)\n );\n}\n\n/**\n * The text a screen reader reads for `root`'s content (D13): text nodes, an image's `alt` and the\n * `aria-label` of a control; `aria-hidden=\"true\"` and `hidden` subtrees, elements that are no text\n * and elements `skip` accepts are left out; whitespace is collapsed. Fluent reads the raw text\n * content instead, which includes hidden text and misses `alt` text.\n */\nfunction getAccessibleText(root: Element | null, skip?: (el: Element) => boolean): string {\n if (!root) return '';\n const parts: string[] = [];\n const visit = (node: Node, isRoot: boolean): void => {\n if (node.nodeType === Node.TEXT_NODE) {\n parts.push(node.textContent ?? '');\n return;\n }\n if (node.nodeType !== Node.ELEMENT_NODE) return;\n const el = node as Element;\n if (!isRoot && skip?.(el)) return;\n if (isNotRendered(el)) return;\n const label = el.getAttribute('aria-label');\n if (label && isNamedByLabel(el)) {\n parts.push(` ${label} `);\n return;\n }\n if (el.localName === 'img') {\n parts.push(` ${el.getAttribute('alt') ?? ''} `);\n return;\n }\n const separate = !INLINE_ELEMENTS.has(el.localName);\n if (separate) parts.push(' ');\n for (const child of Array.from(el.childNodes)) visit(child, false);\n if (separate) parts.push(' ');\n };\n visit(root, true);\n return parts.join('').replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * The accessible text of each child of `root` on its own, so adjacent actions that a flex row lays\n * out side by side (two links, two span-rooted buttons) are not read as one word.\n */\nfunction getChildTexts(root: Element | null): string[] {\n if (!root || isNotRendered(root)) return [];\n return Array.from(root.childNodes, (node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n return (node.textContent ?? '').replace(/\\s+/g, ' ').trim();\n }\n return node.nodeType === Node.ELEMENT_NODE ? getAccessibleText(node as Element) : '';\n }).filter(Boolean);\n}\n\n/**\n * A toast's announced text after its severity (D13): the title, the body (its subtitle included),\n * then the labels of its actions (the title's `action` and the footer, never the Dismiss button),\n * each action on its own. Content without a title or body part is read whole, without the severity\n * texts.\n */\nfunction composeToastText(\n container: HTMLElement,\n parts: readonly ToastPartRegistration[],\n toast: ToastRegistration | null,\n ownStatusTextId: string,\n): string {\n const title = parts.find(isTitlePart);\n const body = parts.find(isBodyPart);\n if (!title && !body) {\n const dismissButton = toast?.getDismissButton() ?? null;\n return getAccessibleText(\n container,\n (el) =>\n el === dismissButton ||\n (el.id !== '' && (el.id === ownStatusTextId || el.id === toast?.statusTextId)),\n );\n }\n const label = title?.getLabel() ?? null;\n // The title row without its text: the `action` slot, whose children are the actions.\n const row = title?.getRow() ?? null;\n const titleActions = row\n ? Array.from(row.children)\n .filter((child) => child !== label)\n .flatMap((slot) => getChildTexts(slot))\n : [];\n return [\n getAccessibleText(label),\n getAccessibleText(body?.getElement() ?? null),\n ...titleActions,\n ...parts.filter(isFooterPart).flatMap((footer) => getChildTexts(footer.getElement())),\n ]\n .filter(Boolean)\n .join(' ');\n}\n\n/**\n * One toast of the Toaster (D10): a `role=\"group\"` container, focusable by script (no Tab stop),\n * named by the toast's severity text and title and described by its body while a Toast inside\n * has registered them (so no id reference dangles). It provides the per-toast context, pauses the\n * timers and keeps focus when the toast goes.\n */\nfunction ToastContainer({\n entry,\n timers,\n onDismiss,\n onExited,\n getFocusFallback,\n announce,\n registerContainer,\n}: ToastContainerProps) {\n const { id, dismissed } = entry;\n // Mounted through the presence core (D29): a dismissed toast exits, `inert`, and is removed when\n // its exit ends (at once without motion); dispatching its id again revives it.\n const {\n isMounted,\n ref: presenceRef,\n presenceProps,\n } = usePresence(!dismissed, {\n appear: true,\n onExited: () => onExited(id),\n });\n const containerRef = React.useRef<HTMLDivElement | null>(null);\n // The last element, for the focus fallback, which may run after the container has unmounted.\n const lastElementRef = React.useRef<HTMLDivElement | null>(null);\n const attach = React.useCallback(\n (node: HTMLDivElement | null) => {\n containerRef.current = node;\n if (node) lastElementRef.current = node;\n registerContainer(id, node);\n },\n [id, registerContainer],\n );\n const mergedRef = useMergedRefs<HTMLDivElement>(attach, presenceRef);\n // Focus leaves a dismissed toast in its dismissing commit: `enabled` flipping to `false` moves it\n // in the layout phase, while the inert node is still there; a toast removed with the Toaster\n // moves it after the unmount.\n usePreserveFocus(containerRef, () => getFocusFallback(lastElementRef.current), {\n enabled: !dismissed,\n });\n const titleId = useId('wave-toast-title');\n const ownStatusTextId = useId('wave-toast-status');\n\n // The registrations of the parts and of the Toast inside, whose layout effects run before this\n // component's: in state for the name and description, in refs for reads after mount.\n const [parts, setParts] = React.useState<readonly ToastPartRegistration[]>([]);\n const partsRef = React.useRef<readonly ToastPartRegistration[]>([]);\n const registerPart = React.useCallback((part: ToastPartRegistration) => {\n partsRef.current = [...partsRef.current, part];\n setParts(partsRef.current);\n return () => {\n partsRef.current = partsRef.current.filter((item) => item !== part);\n setParts(partsRef.current);\n };\n }, []);\n const [toast, setToast] = React.useState<ToastRegistration | null>(null);\n const toastRef = React.useRef<ToastRegistration | null>(null);\n const registerToast = React.useCallback((registration: ToastRegistration) => {\n toastRef.current = registration;\n setToast(registration);\n return () => {\n if (toastRef.current !== registration) return;\n toastRef.current = null;\n setToast(null);\n };\n }, []);\n\n // `Toast.Close` and the Dismiss button: the Toast's `onDismiss`, then the dismissal (D9, D11).\n const dismiss = useEventCallback(() => {\n toastRef.current?.onDismiss?.();\n onDismiss(id);\n });\n const context = React.useMemo<ToastContextValue>(\n () => ({ titleId, dismiss, registerPart, registerToast }),\n [titleId, dismiss, registerPart, registerToast],\n );\n\n const titlePart = parts.find(isTitlePart);\n const bodyPart = parts.find(isBodyPart);\n // Content without a Toast (D10): a visually hidden severity text from the dispatch options,\n // first in the container, while no Toast has registered its own.\n const ownSeverityLabel =\n entry.form === 'content' && toast === null\n ? getStatusLabel(entry.options.status ?? 'info', entry.options.statusLabel)\n : '';\n const severityId = toast ? toast.statusTextId : ownSeverityLabel ? ownStatusTextId : undefined;\n // The timer of each dispatch (D12), started once the content has mounted (its registrations ran\n // first): the dispatch's `timeout`, else none for a toast with an action — people using a screen\n // reader, a switch or voice control need time to reach it — else 5000 ms.\n React.useLayoutEffect(() => {\n const node = containerRef.current;\n if (entry.dismissed || !node) return;\n const timeout =\n entry.options.timeout ?? (hasAction(node, toastRef.current) ? 0 : DEFAULT_TIMEOUT);\n timers.start(entry.id, entry.seq, timeout);\n }, [entry, timers]);\n\n // What screen readers hear (D13), once per dispatch after the content has mounted: the severity\n // text of the rendered Toast (else the dispatch options'), then `announcement` or the text the\n // toast renders; `error` is assertive. `toast` re-runs it for a Toast that registers after this\n // commit (content that renders it later); `announce` drops a repeat of the same message.\n React.useLayoutEffect(() => {\n const node = containerRef.current;\n if (entry.dismissed || !node) return;\n const registered = toastRef.current;\n const status = registered?.status ?? entry.options.status ?? 'info';\n const label = registered\n ? registered.statusLabel\n : getStatusLabel(status, entry.options.statusLabel);\n const text =\n entry.form === 'content' && entry.options.announcement !== undefined\n ? entry.options.announcement\n : composeToastText(node, partsRef.current, registered, ownStatusTextId);\n announce(entry.id, {\n seq: entry.seq,\n text: [label, text].filter(Boolean).join(' '),\n assertive: status === 'error',\n });\n }, [entry, announce, ownStatusTextId, toast]);\n\n // A rendered Toast's severity wins over the dispatch options' (D12); an explicit, different\n // `status` in the options warns once. Read from the ref, not the `toast` state, inside the\n // effect: replacing a registered Toast with content that renders none (a replacement by\n // `toastId`) unregisters it by clearing the ref synchronously, while `setToast(null)` only lands\n // on a later render — depending on the state would fire this effect once against the\n // just-unregistered Toast's stale status. `toast` still triggers the effect (without being read\n // directly), so it also re-runs when a Toast registers after this commit (content that renders\n // its Toast later, inside the consumer's own `<Suspense>`) or changes its own `status` without a\n // new dispatch; `entry` alone would never trigger a re-check for either.\n const optionStatus = entry.form === 'content' ? entry.options.status : undefined;\n React.useEffect(() => {\n const toastStatus = toastRef.current?.status;\n if (optionStatus === undefined || toastStatus === undefined || optionStatus === toastStatus) {\n return;\n }\n warnOnce(\n 'Toaster:status-conflict',\n `Toaster: the dispatched Toast has status \"${toastStatus}\" but the dispatch options pass \"${optionStatus}\"; the Toast's status is used. Remove \\`status\\` from the options.`,\n );\n }, [entry, optionStatus, toast]);\n // Delete or Backspace on the container or inside it dismisses the toast (D14; Backspace is the\n // delete key of Mac keyboards), except in an editable field and for a key pressed in a portal\n // opened from the toast (its target is outside the container).\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Delete' && event.key !== 'Backspace') return;\n if (event.defaultPrevented || !isOwnEvent(event) || isEditableTarget(event.target)) return;\n event.preventDefault();\n onDismiss(id);\n };\n\n if (!isMounted) return null;\n return (\n <div\n ref={mergedRef}\n role=\"group\"\n tabIndex={-1}\n data-wave-toast=\"\"\n aria-labelledby={joinIds(severityId, titlePart?.id)}\n aria-describedby={bodyPart?.id}\n className={cn(toasterClassNames.toast, 'rounded', focusRing)}\n {...presenceProps}\n onKeyDown={handleKeyDown}\n >\n {ownSeverityLabel ? <StatusText label={ownSeverityLabel} id={ownStatusTextId} /> : null}\n <ToastContext.Provider value={context}>\n {entry.form === 'options' ? (\n <ToastRoot\n status={entry.options.status}\n statusLabel={entry.options.statusLabel}\n title={entry.options.title}\n dismissLabel={entry.options.dismissLabel}\n >\n {entry.options.body}\n </ToastRoot>\n ) : (\n entry.content\n )}\n </ToastContext.Provider>\n </div>\n );\n}\nToastContainer.displayName = 'ToastContainer';\n\n/**\n * Provides {@link useToastController} to its children and shows the dispatched toasts.\n *\n * - **Wrap the app** in `<Toaster>`; components below it call `useToastController()`, and code\n * outside components (a query-cache callback, a server-event handler) dispatches through a\n * handle from `createToaster()` bound with `toaster`, which also runs several Toasters side by\n * side (one handle each).\n * - **Two ways to dispatch:** `dispatchToast(<Toast>…</Toast>)` shows your content, usually a\n * `Toast` with `Toast.Title`, `Toast.Body` and `Toast.Footer`; `dispatchToast({ title, body })`\n * builds a toast from text. Both return the toast's id. Content without a `Toast` takes its\n * severity from the options (`status`, `statusLabel`) and shows no Dismiss button (add a\n * `Toast.Close`).\n * - The toasts render in a portal (the `toast` layer, above dialogs) inside a region labelled\n * \"Notifications\" (override with `aria-label`). The region is allow-listed for modals\n * (`data-wave-focus-trap-allow`): it stays reachable by Tab and exposed to assistive technology\n * while a Dialog or Drawer is open, and clicking a toast never dismisses the overlay below.\n * - Two permanent, visually hidden live regions (polite, and assertive for `error`) announce every\n * toast once per dispatch, read from what it renders after it mounts: the severity text, then\n * the title, the body and the labels of its actions (never the Dismiss button) or, instead of\n * those, the dispatch's `announcement`.\n * The toasts themselves are not live regions. Each message stays in its live region for 2\n * seconds (or until its toast goes), so browsing the region later meets the text only once.\n * - While an open modal panel covers the toasts' corner (a Drawer on the same side), the toasts\n * move beside it, so they never hide its focused controls (WCAG 2.4.11). Without room beside it\n * (a full-width panel on a narrow screen) they keep their corner.\n * - Timers pause while the pointer or focus is anywhere in the toast region, a menu or popover\n * opened from a toast included (someone reading or operating one toast is reading the stack),\n * and while the window is in the background (it has lost focus, or the page is not shown, as in\n * a background tab). When a toast that contains focus goes away, focus moves to the next toast\n * (or the previous one), or back to the element that was focused before focus entered the\n * toasts once no toast is left.\n * - **Keyboard:** `shortcuts.focus` names a key press that moves focus to the newest toast (use a\n * modifier, WCAG 2.1.4); Escape in the toast region dismisses every toast and returns focus to\n * where it was before focus entered the toasts (a tooltip or menu of a toast closes first, and a\n * Dialog below stays open); Delete or Backspace dismisses the focused toast.\n * - Each toast's dismiss button is named \"Dismiss\"; pass `dismissLabel` to `dispatchToast` for\n * other languages.\n * - `limit` caps how many toasts show at once: the others wait in a queue, in dispatch order,\n * unannounced and without a running timer, and appear as shown toasts go.\n * `dismissAllToasts()` removes every toast, shown and queued.\n *\n * @example\n * <Toaster position=\"bottom-end\" limit={3}>\n * <App />\n * </Toaster>\n */\nexport const Toaster = ({\n position = 'bottom-end',\n limit: limitProp,\n shortcuts,\n toaster: handle,\n className,\n style,\n children,\n onFocus,\n onBlur,\n onKeyDown,\n onPointerEnter,\n onPointerLeave,\n onPointerOver,\n ref,\n ...rest\n}: ToasterProps) => {\n const [toasts, setToasts] = React.useState<ToastEntry[]>([]);\n // Each toast's message, written by its container after the toast mounts (a layout effect), so\n // the severity is the rendered Toast's and the text what the toast renders.\n const [announcements, setAnnouncements] = React.useState<ReadonlyMap<string, Announcement>>(\n () => new Map(),\n );\n const announce = React.useCallback((id: string, announcement: Announcement) => {\n setAnnouncements((prev) => {\n const current = prev.get(id);\n if (\n current &&\n current.seq === announcement.seq &&\n current.text === announcement.text &&\n current.assertive === announcement.assertive\n ) {\n return prev;\n }\n const next = new Map(prev);\n next.set(id, announcement);\n return next;\n });\n }, []);\n const limit = resolveLimit(limitProp);\n // Waiting toasts are shown here, during render, with the current limit (adjust state while\n // rendering, C-HOOKS): every path that frees a place or raises the limit promotes them, and a\n // lowered limit never hides a shown toast. `promoteQueued` returns the same array once settled.\n const settled = promoteQueued(toasts, limit);\n if (settled !== toasts) setToasts(settled);\n const shownToasts = settled.filter((toast) => toast.shown);\n\n // Development diagnostics (C-DEV): emitted from an effect, once per page.\n React.useEffect(() => {\n if (limitProp !== undefined && !(limitProp >= 1)) {\n warnOnce(\n 'Toaster:limit',\n `Toaster: \\`limit\\` must be 1 or more (got ${String(limitProp)}); it counts as 1.`,\n );\n }\n }, [limitProp]);\n const prefix = useId('toast');\n const counterRef = React.useRef(0);\n const viewportRef = React.useRef<HTMLDivElement | null>(null);\n const viewportRefs = useMergedRefs(ref, viewportRef);\n const previousFocusRef = React.useRef<HTMLElement | null>(null);\n const dir = useDirection();\n\n // Beside an open modal panel on the toasts' side (a Drawer), not over its controls. Measured when\n // a layer opens or closes (synchronously in its layout effect, before paint), on resize, and\n // after a transition or animation (a panel that slides in reaches its place only then).\n const [sideOffset, setSideOffset] = React.useState(0);\n React.useLayoutEffect(() => {\n const update = () => {\n const viewport = viewportRef.current;\n setSideOffset(viewport ? getSidePanelOffset(viewport, position) : 0);\n };\n update();\n const unsubscribe = subscribeLayers(update);\n window.addEventListener('resize', update);\n document.addEventListener('transitionend', update, true);\n document.addEventListener('animationend', update, true);\n return () => {\n unsubscribe();\n window.removeEventListener('resize', update);\n document.removeEventListener('transitionend', update, true);\n document.removeEventListener('animationend', update, true);\n };\n }, [position, dir]);\n\n const [timers] = React.useState(() =>\n createToastTimers((id) => setToasts((prev) => markDismissed(prev, id))),\n );\n\n // Timers run only while mounted (StrictMode's simulated unmount suspends and resumes them) and\n // pause while the window is in the background: after the window loses focus, and while the page\n // is not shown. The page visibility is read at mount too, so a Toaster that mounts in a\n // background tab waits until the tab is shown. (Focus is not read at mount: `hasFocus()` is also\n // false in an embedded frame nobody clicked yet and in test DOMs.)\n React.useEffect(() => {\n const doc = document;\n let blurred = false;\n const update = () => timers.setInBackground(blurred || doc.visibilityState === 'hidden');\n // Only the window's own blur/focus (element focus events do not bubble to a bubble-phase\n // window listener; anything targeted at a node is ignored).\n const handleBlur = (event: FocusEvent) => {\n if (event.target instanceof Node) return;\n blurred = true;\n update();\n };\n const handleFocus = (event: FocusEvent) => {\n if (event.target instanceof Node) return;\n blurred = false;\n update();\n };\n update();\n timers.setSuspended(false);\n window.addEventListener('blur', handleBlur);\n window.addEventListener('focus', handleFocus);\n doc.addEventListener('visibilitychange', update);\n return () => {\n window.removeEventListener('blur', handleBlur);\n window.removeEventListener('focus', handleFocus);\n doc.removeEventListener('visibilitychange', update);\n timers.setSuspended(true);\n };\n }, [timers]);\n\n // A new toast waits until the render promotes it; a replaced one keeps its place and whether it\n // is shown (a waiting toast keeps waiting with the new content), and an exiting one is revived.\n const dispatchToast = React.useCallback<ToastController['dispatchToast']>(\n (first: React.ReactNode | ToastOptions, second?: ToastDispatchOptions): string => {\n counterRef.current += 1;\n const seq = counterRef.current;\n const dispatched: DispatchedToast = isToastOptions(first)\n ? { form: 'options', options: first }\n : { form: 'content', content: first, options: second ?? {} };\n const id = dispatched.options.toastId ?? `${prefix}-${seq}`;\n setToasts((prev) => {\n const index = prev.findIndex((t) => t.id === id);\n const shown = index === -1 ? false : prev[index].shown;\n const entry: ToastEntry = { ...dispatched, id, seq, shown, dismissed: false };\n if (index === -1) return [...prev, entry];\n const next = prev.slice();\n next[index] = entry;\n return next;\n });\n return id;\n },\n [prefix],\n );\n\n const dismissToast = React.useCallback(\n (id: string) => {\n timers.remove(id);\n setToasts((prev) => markDismissed(prev, id));\n },\n [timers],\n );\n\n const dismissAllToasts = React.useCallback(() => {\n timers.clear();\n setToasts((prev) => markAllDismissed(prev));\n }, [timers]);\n\n // The exit of a dismissed toast ended: remove it and its message (one revived meanwhile stays).\n const removeExited = React.useCallback((id: string) => {\n setToasts((prev) =>\n prev.some((t) => t.id === id && t.dismissed)\n ? prev.filter((t) => !(t.id === id && t.dismissed))\n : prev,\n );\n setAnnouncements((prev) => {\n if (!prev.has(id)) return prev;\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n }, []);\n\n const controller = React.useMemo<ToastController>(\n () => ({ dispatchToast, dismissToast, dismissAllToasts }),\n [dispatchToast, dismissToast, dismissAllToasts],\n );\n\n // A handle from createToaster() (P3-08, D33): bound in a layout effect, so dispatches that waited\n // in its queue show before the first paint, and unbound on unmount (StrictMode binds again and\n // finds the queue taken). A handle bound to another Toaster stays there.\n const [handleOwner] = React.useState(() => ({}));\n React.useLayoutEffect(() => {\n if (!handle) return undefined;\n const binding = bindToasterHandle(handle, handleOwner, controller);\n if (binding.status === 'bound') return binding.unbind;\n if (binding.status === 'taken') {\n warnOnce(\n 'Toaster:handle-bound',\n 'Toaster: this handle is already bound to another Toaster; a handle binds one Toaster. Create one handle per Toaster.',\n );\n } else {\n warnOnce(\n 'Toaster:handle-unknown',\n 'Toaster: `toaster` is not a handle from createToaster(), so nothing is bound. Pass the value createToaster() returns.',\n );\n }\n return undefined;\n }, [handle, handleOwner, controller]);\n\n // Where focus goes when the focused toast is dismissed (in its dismissing commit) or removed with\n // the Toaster: the next toast that is not exiting, else the previous one — that container itself\n // when focus was on the dismissed container (after Delete or the shortcut), else its first\n // tabbable element — else the element focused before focus entered the toasts. Runs possibly\n // after the whole Toaster is gone: never throws.\n const getFocusFallback = React.useCallback((from: HTMLElement | null): HTMLElement | null => {\n const viewport = viewportRef.current;\n const containers = viewport\n ? Array.from(viewport.children).filter(\n (el): el is HTMLElement =>\n el instanceof HTMLElement && el.hasAttribute('data-wave-toast'),\n )\n : [];\n const onContainer = !!from && from.ownerDocument.activeElement === from;\n const index = from ? containers.indexOf(from) : -1;\n const isLive = (el: HTMLElement) =>\n el !== from && el.isConnected && el.getAttribute('data-presence') !== 'exiting';\n const next = containers.slice(index + 1).find(isLive);\n const previous = index > 0 ? containers.slice(0, index).reverse().find(isLive) : undefined;\n for (const candidate of [next, previous]) {\n if (!candidate) continue;\n const target = onContainer ? candidate : getFirstTabbable(candidate);\n if (target) return target;\n }\n // Focus leaves the toasts here without a blur of the viewport (the focused node is inert or\n // gone), so the element is forgotten as it is used: a toast focused later from nowhere does not\n // send focus back to it.\n const previousFocus = previousFocusRef.current;\n previousFocusRef.current = null;\n return previousFocus?.isConnected ? previousFocus : null;\n }, []);\n\n // Focus can fall to the page body without a blur reaching the viewport: the node that had it\n // (a layer opened from a toast, a button replaced by text) is gone. A move to a real element\n // always sends blur and focus through React, so only a fall to the body is reconciled, whenever\n // the toasts or the layers change: the 'focus' pause ends, and while the region still held it,\n // focus returns to the remembered origin, as it does when a focused toast goes. The origin is\n // forgotten either way.\n const reconcileFocus = useEventCallback(() => {\n const viewport = viewportRef.current;\n if (!viewport) return;\n const doc = viewport.ownerDocument;\n if (doc.activeElement && doc.activeElement !== doc.body) return;\n const held = timers.isPaused('focus');\n timers.setPaused('focus', false);\n const origin = previousFocusRef.current;\n previousFocusRef.current = null;\n if (held && origin && isConnectedAndFocusable(origin)) origin.focus({ preventScroll: true });\n });\n React.useLayoutEffect(() => {\n reconcileFocus();\n }, [settled, reconcileFocus]);\n // A layer's cleanup can notify while its focused node is still connected: look a tick later.\n React.useLayoutEffect(\n () => subscribeLayers(() => queueMicrotask(reconcileFocus)),\n [reconcileFocus],\n );\n\n // The pointer can leave the region without a leave reaching it: when the node under the pointer\n // is removed (a hovered toast dismissed, timed out or pushed out by the limit, a menu item that\n // closed its menu), the browser's next boundary event is a `pointerover` on the element now under\n // the pointer with no related target, from which React synthesises no leave. So the 'hover' pause\n // also ends on any `pointerover` that did not pass through the region in React's tree, which\n // takes in a portal opened from a toast (D14, as the enter and leave handlers do). The DOM and\n // layer check after it (`isInToastRegion`) is defensive: it keeps the pause for a layer anchored\n // in a toast but rendered outside the Toaster's tree. A document listener in the bubble phase, so\n // React's own listeners (on the root and portal containers, below the document) have marked the\n // event first.\n const regionPointerOverRef = React.useRef<Event | null>(null);\n React.useEffect(() => {\n const handlePointerOver = (event: Event) => {\n const fromRegion = regionPointerOverRef.current === event;\n regionPointerOverRef.current = null;\n if (fromRegion || !timers.isPaused('hover')) return;\n const viewport = viewportRef.current;\n if (viewport && event.target instanceof Node && isInToastRegion(viewport, event.target)) {\n return;\n }\n timers.setPaused('hover', false);\n };\n document.addEventListener('pointerover', handlePointerOver);\n return () => document.removeEventListener('pointerover', handlePointerOver);\n }, [timers]);\n\n // The latest entries and every container element, for the shortcut's document listener.\n const toastsRef = React.useRef<ToastEntry[]>(settled);\n React.useLayoutEffect(() => {\n toastsRef.current = settled;\n });\n const containersRef = React.useRef(new Map<string, HTMLElement>());\n const registerContainer = React.useCallback((id: string, node: HTMLElement | null) => {\n if (node) containersRef.current.set(id, node);\n else containersRef.current.delete(id);\n }, []);\n\n // The focus shortcut (D14): a document listener, so the key works wherever focus is. It focuses\n // the container of the newest toast that is shown and not dismissed and remembers where focus\n // was (unless it is already in the toasts).\n const hasFocusShortcut = typeof shortcuts?.focus === 'function';\n const handleShortcut = useEventCallback((event: KeyboardEvent) => {\n if (event.defaultPrevented || event.isComposing || !shortcuts?.focus?.(event)) return;\n const newest = findNewestToast(toastsRef.current);\n const target = newest ? containersRef.current.get(newest.id) : undefined;\n if (!target?.isConnected) return;\n event.preventDefault();\n const viewport = viewportRef.current;\n const active = target.ownerDocument.activeElement;\n if (\n active instanceof HTMLElement &&\n active !== target.ownerDocument.body &&\n !(viewport && isInToastRegion(viewport, active))\n ) {\n previousFocusRef.current = active;\n }\n target.focus({ preventScroll: false });\n });\n React.useEffect(() => {\n if (!hasFocusShortcut) return undefined;\n const listener = (event: KeyboardEvent) => handleShortcut(event);\n document.addEventListener('keydown', listener);\n return () => document.removeEventListener('keydown', listener);\n }, [hasFocusShortcut, handleShortcut]);\n\n // Focus entering the toast region from an element outside it: return there when the focused\n // toast goes and after Escape. Focus arriving with no related target keeps what is remembered\n // (the Toaster's own move to the next toast, the window regaining focus). Moves inside the region\n // — a layer opened from a toast included — change nothing, and an element that cannot take focus\n // (inside a closing, inert surface) is never remembered.\n const rememberFocusOrigin = (event: React.FocusEvent<HTMLDivElement>) => {\n const from = event.relatedTarget;\n if (!(from instanceof HTMLElement) || !isConnectedAndFocusable(from)) return;\n if (isInToastRegion(event.currentTarget, from)) return;\n previousFocusRef.current = from;\n };\n\n // Focus leaving the region for another element or for `<body>` forgets the element, so a toast\n // focused again later from nowhere never sends focus back to something focused long before.\n // Kept: moves inside the region (a layer opened from a toast included), a removed or dismissed\n // toast (its node is gone or inert; the Toaster moves focus itself) and the window losing focus\n // (the element keeps document focus while another window is active).\n const forgetFocusOrigin = (event: React.FocusEvent<HTMLDivElement>) => {\n const viewport = event.currentTarget;\n const to = event.relatedTarget;\n if (to instanceof Node && isInToastRegion(viewport, to)) return;\n // A blur from inside a dismissed (exiting, inert) toast: the Toaster has moved focus itself,\n // or a browser's focus fix-up blurs the inert subtree later.\n if (event.target.closest('[data-wave-toast][data-presence=\"exiting\"]')) return;\n if (to === null) {\n const from = event.target;\n if (!from.isConnected) return;\n const active = from.ownerDocument.activeElement;\n if (active && isInToastRegion(viewport, active)) return;\n }\n previousFocusRef.current = null;\n };\n\n // Escape in the toast region (D14) dismisses every toast and returns focus to where it was\n // before focus entered the toasts. Left alone: a key pressed in a portal opened from a toast\n // (its target is outside the viewport; the portal's own widget handles it) and one that an open\n // Escape-enabled layer anchored in the viewport takes first (a Tooltip on a toast's button, a\n // Menu opened from a toast). Prevented, so the dismiss-layer stack does not route it to a Dialog\n // or Drawer below (the region counts as inside every layer).\n const handleEscape = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Escape' && event.key !== 'Esc') return;\n if (event.defaultPrevented || event.nativeEvent.isComposing || !isOwnEvent(event)) return;\n const viewport = event.currentTarget;\n if (getOpenLayers().some((layer) => layer.escape && viewport.contains(layer.getAnchor()))) {\n return;\n }\n event.preventDefault();\n const origin = previousFocusRef.current;\n previousFocusRef.current = null;\n if (origin?.isConnected) origin.focus({ preventScroll: true });\n dismissAllToasts();\n };\n\n // Each shown toast's message for its first 2 s, while it is not dismissed (a waiting toast is\n // announced when it appears); a replacement is a new dispatch, so it is read again.\n const polite: React.ReactNode[] = [];\n const assertive: React.ReactNode[] = [];\n for (const toast of shownToasts) {\n if (toast.dismissed) continue;\n const announcement = announcements.get(toast.id);\n if (!announcement || announcement.seq !== toast.seq || !announcement.text) continue;\n const message = <LiveMessage key={announcement.seq} text={announcement.text} />;\n (announcement.assertive ? assertive : polite).push(message);\n }\n\n const viewportStyle =\n sideOffset > 0\n ? ({ ...style, '--wave-toaster-offset': `${sideOffset}px` } as React.CSSProperties)\n : style;\n\n return (\n <ToasterContext.Provider value={controller}>\n {children}\n <Portal layer=\"toast\">\n <div\n ref={viewportRefs}\n role=\"region\"\n aria-label=\"Notifications\"\n data-wave-focus-trap-allow=\"\"\n data-position={position}\n {...rest}\n style={viewportStyle}\n onFocus={(event) => {\n // Bookkeeping always runs (a consumer's preventDefault() cannot cancel a focus change).\n // Focus in a portal opened from a toast arrives here too (React bubbles focus events\n // through portals) and counts as focus in the region (D14).\n onFocus?.(event);\n rememberFocusOrigin(event);\n timers.setPaused('focus', true);\n }}\n onBlur={(event) => {\n onBlur?.(event);\n forgetFocusOrigin(event);\n const next = event.relatedTarget;\n if (next instanceof Node && isInToastRegion(event.currentTarget, next)) return;\n timers.setPaused('focus', false);\n }}\n onPointerEnter={(event) => {\n onPointerEnter?.(event);\n timers.setPaused('hover', true);\n }}\n onPointerLeave={(event) => {\n onPointerLeave?.(event);\n timers.setPaused('hover', false);\n }}\n onPointerOver={(event) => {\n // Bookkeeping always runs. A portal opened from a toast counts as the region (D14):\n // React bubbles its pointer events here too.\n onPointerOver?.(event);\n regionPointerOverRef.current = event.nativeEvent;\n }}\n onKeyDown={(event) => composeEventHandlers(onKeyDown, handleEscape)(event)}\n className={cn(\n toasterClassNames.root,\n 'fixed flex w-80 max-w-[calc(100vw-2rem)] flex-col gap-2',\n positionClasses[position],\n className,\n )}\n >\n {/* One message per toast for its first 2 s; not atomic, so only the added one is read. */}\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"false\" className=\"sr-only\">\n {polite}\n </div>\n <div aria-live=\"assertive\" aria-atomic=\"false\" className=\"sr-only\">\n {assertive}\n </div>\n {/* Shown toasts, exiting ones included: getFocusFallback walks the containers in this order. */}\n {shownToasts.map((toast) => (\n <ToastContainer\n key={toast.id}\n entry={toast}\n timers={timers}\n onDismiss={dismissToast}\n onExited={removeExited}\n getFocusFallback={getFocusFallback}\n announce={announce}\n registerContainer={registerContainer}\n />\n ))}\n </div>\n </Portal>\n </ToasterContext.Provider>\n );\n};\nToaster.displayName = 'Toaster';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Toaster.cjs","names":["getOpenLayers","isInsideLayerTree","getTabbableElements","isToastOptions","React","ToasterContext","getDirection","usePresence","useMergedRefs","useId","useEventCallback","getStatusLabel","isOwnEvent","isEditableTarget","joinIds","cn","toasterClassNames","focusRing","StatusText","ToastContext","ToastRoot","useDirection","subscribeLayers","bindToasterHandle","getFirstTabbable","isConnectedAndFocusable","Portal","composeEventHandlers","require_runtime","require_cn","require_dev","require_composeEventHandlers","require_classNames","require_toaster","require_useEventCallback","require_useId","require_direction","require_focus","require_useMergedRefs","require_aria","require_usePresence","require_layers","require_useDirection","require_Portal","require_styles","require_events","require_usePreserveFocus","require_MessageBar_status","require_Toast_context","require_Toast_root","react","react_jsx_runtime","promoteQueued","active","waiting","toast","toasts","limit","markDismissed","index","id","next","markAllDismissed","findNewestToast","newest","isInToastRegion","viewport","node","anchor","layer","hasAction","dismissButton","container","el","resolveLimit","INERT_CONTROLLER","first","second","MISSING_TOASTER_MESSAGE","useToastController","DEFAULT_TIMEOUT","createToastTimers","timers","pauses","started","inBackground","suspended","sync","timer","canRun","onExpire","syncAll","stop","seq","timeout","reason","paused","value","positionClasses","EDGE_GAP","isOnRightSide","inline","position","rtl","NO_PANEL_OFFSETS","getPanelLayers","getPanelElements","elements","getPanelOffsets","panels","doc","view","width","height","right","top","fitsInline","offset","fitsBlock","block","box","onSide","onEdge","inlineOffset","blockOffset","ANNOUNCEMENT_DURATION","LiveMessage","present","setPresent","handle","text","isTitlePart","part","isBodyPart","isFooterPart","INLINE_ELEMENTS","NOT_TEXT_ELEMENTS","NATIVE_NAMED_BY_LABEL","ROLES_NAMED_BY_LABEL","isNamedByLabel","role","isNotRendered","getAccessibleText","root","parts","visit","isRoot","skip","label","separate","child","getChildTexts","composeToastText","title","body","ownStatusTextId","row","titleActions","slot","footer","ToastContainer","entry","presenceRef","dismissed","onExited","containerRef","lastElementRef","attach","registerContainer","mergedRef","getFocusFallback","titleId","setParts","partsRef","registerPart","item","setToast","toastRef","registerToast","registration","dismiss","onDismiss","context","titlePart","bodyPart","ownSeverityLabel","severityId","registered","status","announce","optionStatus","toastStatus","handleKeyDown","event","isMounted","presenceProps","Toaster","limitProp","rest","setToasts","announcements","setAnnouncements","current","prev","announcement","settled","shownToasts","prefix","counterRef","viewportRef","viewportRefs","ref","previousFocusRef","dir","panelOffsets","setPanelOffsets","observer","mutationObserver","observed","observedPanels","observePanels","changed","update","unsubscribe","blurred","handleBlur","handleFocus","dispatchToast","dispatched","t","shown","dismissToast","dismissAllToasts","removeExited","controller","handleOwner","binding","containers","onContainer","from","isLive","previous","candidate","target","previousFocus","reconcileFocus","held","origin","regionPointerOverRef","handlePointerOver","fromRegion","toastsRef","containersRef","hasFocusShortcut","shortcuts","handleShortcut","listener","rememberFocusOrigin","forgetFocusOrigin","to","handleEscape","polite","assertive","message","viewportStyle","style","children","onFocus","onBlur","onPointerEnter","onPointerLeave","onPointerOver","onKeyDown","className"],"sources":["../../../src/components/feedback/Toaster.tsx"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { toasterClassNames } from '../../lib/classNames';\nimport { reportMissingContext, warnOnce } from '../../lib/dev';\nimport { getDirection } from '../../lib/direction';\nimport { isEditableTarget, isOwnEvent } from '../../lib/events';\nimport { getFirstTabbable, getTabbableElements, isConnectedAndFocusable } from '../../lib/focus';\nimport {\n getOpenLayers,\n isInsideLayerTree,\n subscribeLayers,\n type LayerRecord,\n} from '../../lib/layers';\nimport { focusRing } from '../../lib/styles';\nimport { bindToasterHandle, isToastOptions } from '../../lib/toaster';\nimport type { ToasterHandle } from '../../lib/toaster';\nimport type { Status } from '../../lib/types';\nimport { useDirection } from '../../hooks/useDirection';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { usePresence } from '../../hooks/usePresence';\nimport { usePreserveFocus } from '../../hooks/usePreserveFocus';\nimport { Portal } from '../portal/Portal';\nimport { StatusText, getStatusLabel } from './MessageBar.status';\nimport { ToastContext, ToasterContext } from './Toast.context';\nimport type { ToastContextValue, ToastPartRegistration, ToastRegistration } from './Toast.context';\nimport { ToastRoot } from './Toast.root';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/** Options for dispatching a toast notification. */\nexport interface ToastOptions {\n /** Status level controlling the toast color, icon, status text and announcement politeness\n * (`error` is announced assertively, every other status politely).\n * @default 'info'\n */\n status?: Status;\n /** Title text of the toast. */\n title: string;\n /** Optional body text displayed below the title. */\n body?: string;\n /**\n * Auto-dismiss timeout in milliseconds. The countdown starts when the toast is shown (a toast\n * waiting beyond the Toaster's `limit` does not count down) and pauses while the pointer or\n * focus is anywhere in the toast region (a menu or popover opened from a toast included) and\n * while the browser window is in the background (it has lost focus, or the page is not shown, as\n * in a background tab, also when the Toaster mounts there). `0` (or any value that is not a\n * positive finite number) keeps the toast until it is dismissed.\n * @default 5000\n */\n timeout?: number;\n /**\n * Identifier of the toast. `dispatchToast` returns it (a generated one when omitted). Dispatching\n * again with the id of a toast that is shown, or still exiting after its dismissal, replaces or\n * revives that toast (content and timer); with the id of a toast that waits beyond the Toaster's\n * `limit`, it replaces its options and the toast keeps its place in the queue.\n */\n toastId?: string;\n /**\n * Visually hidden status text read before the toast (`'Info:'`, `'Success:'`, `'Warning:'`,\n * `'Error:'` by default). Pass a translation for other languages, or `''` to omit it.\n */\n statusLabel?: string;\n /**\n * Accessible name of the toast's dismiss button. Pass a translation for other languages.\n * @default 'Dismiss'\n */\n dismissLabel?: string;\n}\n\n/** Options of `dispatchToast(content, options)`, the form that shows your own React content. */\nexport interface ToastDispatchOptions {\n /** As `ToastOptions.toastId`: dispatching again with the id of a shown or exiting toast replaces it. */\n toastId?: string;\n /**\n * Auto-dismiss timeout in milliseconds, as `ToastOptions.timeout`. A toast that holds an action\n * (an interactive element besides its Dismiss button) stays until it is dismissed unless you\n * pass one: people using a screen reader, a switch or voice control need time to reach it.\n * @default 5000, or no timeout for a toast with an action\n */\n timeout?: number;\n /**\n * Severity of content that renders no `Toast`: the announcement's politeness (`error` is\n * assertive), its spoken prefix and the container's name. A rendered `Toast` uses its own\n * `status`; a different value passed here warns in development.\n * @default 'info'\n */\n status?: Status;\n /** Visually hidden severity text for content that renders no `Toast` (as `Toast.statusLabel`). */\n statusLabel?: string;\n /**\n * Text announced instead of the toast's title, body and action labels (the severity text still\n * comes first), for a toast whose visible text is no good announcement, such as a progress toast.\n */\n announcement?: string;\n}\n\n/** The toast API returned by {@link useToastController}. */\nexport interface ToastController {\n /**\n * Shows a toast and returns its id. `dispatchToast(content, options?)` shows your content,\n * usually a `<Toast>` with parts; `dispatchToast(options)` builds a toast from text (0.5). A\n * plain object is read as options; anything else (an element, a portal, a string) is content. A\n * toast with the same id is replaced (revived while it exits); beyond the Toaster's `limit` the\n * toast waits in a queue. Fluent's `dispatchToast(content, options)` returns nothing.\n */\n dispatchToast: {\n (content: React.ReactNode, options?: ToastDispatchOptions): string;\n (options: ToastOptions): string;\n };\n /**\n * Dismisses the toast with this id and cancels its timer: a shown toast exits (it stays, inert,\n * until an exit motion of yours ends), a waiting one is removed. Unknown ids are ignored.\n */\n dismissToast: (id: string) => void;\n /**\n * Dismisses every toast and cancels their timers: shown toasts exit (as `dismissToast`), queued\n * ones are removed.\n */\n dismissAllToasts: () => void;\n}\n\n/** What a dispatch stores: the options form, or your content with its options. */\ntype DispatchedToast =\n | { form: 'options'; options: ToastOptions }\n | { form: 'content'; content: React.ReactNode; options: ToastDispatchOptions };\n\ntype ToastEntry = DispatchedToast & {\n id: string;\n /** Increases with every dispatch, so a replaced toast is announced again. */\n seq: number;\n /**\n * Whether the toast is shown (rendered, announced, its timer running) or still waits beyond the\n * Toaster's `limit`. Only {@link promoteQueued} sets it; it never goes back to `false`.\n */\n shown: boolean;\n /**\n * Dismissed: its container exits (not announced, no timer, not counted toward `limit`) and the\n * entry is removed when the exit ends; a dispatch with its id revives it (D29).\n */\n dismissed: boolean;\n};\n\n/**\n * Flags the oldest waiting toasts as shown while fewer than `limit` toasts are shown and not\n * dismissed. Returns `toasts` itself when nothing changes, so the Toaster's render-time update\n * settles.\n */\nfunction promoteQueued(toasts: ToastEntry[], limit: number): ToastEntry[] {\n let active = 0;\n let waiting = false;\n for (const toast of toasts) {\n if (!toast.shown) waiting = true;\n else if (!toast.dismissed) active += 1;\n }\n if (!waiting || active >= limit) return toasts;\n return toasts.map((toast) => {\n if (toast.shown || active >= limit) return toast;\n active += 1;\n return { ...toast, shown: true };\n });\n}\n\n/** Dismisses a shown toast (it exits) and drops a waiting one; `toasts` itself when nothing changes. */\nfunction markDismissed(toasts: ToastEntry[], id: string): ToastEntry[] {\n const index = toasts.findIndex((toast) => toast.id === id);\n if (index === -1) return toasts;\n const toast = toasts[index];\n if (!toast.shown) return [...toasts.slice(0, index), ...toasts.slice(index + 1)];\n if (toast.dismissed) return toasts;\n const next = toasts.slice();\n next[index] = { ...toast, dismissed: true };\n return next;\n}\n\n/** Dismisses every shown toast and drops the waiting ones; `toasts` itself when nothing changes. */\nfunction markAllDismissed(toasts: ToastEntry[]): ToastEntry[] {\n if (toasts.every((toast) => toast.shown && toast.dismissed)) return toasts;\n return toasts\n .filter((toast) => toast.shown)\n .map((toast) => (toast.dismissed ? toast : { ...toast, dismissed: true }));\n}\n\n/** The shown, not dismissed toast dispatched last (the highest `seq`), or `undefined`. */\nfunction findNewestToast(toasts: readonly ToastEntry[]): ToastEntry | undefined {\n let newest: ToastEntry | undefined;\n for (const toast of toasts) {\n if (toast.shown && !toast.dismissed && (!newest || toast.seq > newest.seq)) newest = toast;\n }\n return newest;\n}\n\n/**\n * Whether `node` is in the toast region: inside the viewport, or inside an open dismiss layer\n * anchored inside it (a Menu, Popover or Tooltip opened from a toast, whose portal lives elsewhere\n * in the document).\n */\nfunction isInToastRegion(viewport: HTMLElement, node: Node): boolean {\n if (viewport.contains(node)) return true;\n return getOpenLayers().some((layer) => {\n const anchor = layer.getAnchor();\n return anchor !== null && viewport.contains(anchor) && isInsideLayerTree(layer.id, node);\n });\n}\n\n/** Whether a toast holds an action: an element in its Tab order other than its Dismiss button. */\nfunction hasAction(container: HTMLElement, toast: ToastRegistration | null): boolean {\n const dismissButton = toast?.getDismissButton() ?? null;\n return getTabbableElements(container).some((el) => el !== dismissButton);\n}\n\n/** `limit` as the Toaster applies it: whole toasts, at least 1; `undefined` means no limit. */\nfunction resolveLimit(limit: number | undefined): number {\n if (limit === undefined) return Infinity;\n return limit >= 1 ? Math.floor(limit) : 1;\n}\n\n/* ------------------------------------------------------------------ */\n/* Context */\n/* ------------------------------------------------------------------ */\n\nconst INERT_CONTROLLER: ToastController = {\n dispatchToast: (first: React.ReactNode | ToastOptions, second?: ToastDispatchOptions) =>\n (isToastOptions(first) ? first.toastId : second?.toastId) ?? '',\n dismissToast: () => {},\n dismissAllToasts: () => {},\n};\n\n/** The C-CONTEXT message without the `[WaveUI] ` prefix, which `reportMissingContext` adds. */\nconst MISSING_TOASTER_MESSAGE =\n 'useToastController must be used within <Toaster>. Wrap your app (or the part of it that shows toasts) in <Toaster>: it provides the controller to its children.';\n\n/**\n * Returns the {@link ToastController} of the enclosing `<Toaster>`: `dispatchToast(content,\n * options?)` shows your content (usually a `<Toast>` with parts) and `dispatchToast(options)` a\n * toast built from text; both return the toast's id. `dismissToast(id)` dismisses one toast,\n * `dismissAllToasts()` every toast.\n *\n * Must be called inside `<Toaster>`, which provides the controller to its children — wrap the app\n * (or the part of it that shows toasts) in `<Toaster>`; a sibling `<Toaster />` does not work.\n * Outside a Toaster it throws in development; in production it logs an error (once) and returns a\n * controller that does nothing.\n *\n * @example\n * function SaveButton() {\n * const { dispatchToast } = useToastController();\n * return (\n * <Button\n * onClick={() =>\n * dispatchToast(\n * <Toast status=\"success\">\n * <Toast.Title>Saved</Toast.Title>\n * </Toast>,\n * )\n * }\n * >\n * Save\n * </Button>\n * );\n * }\n * // <Toaster><App /></Toaster>\n */\nexport function useToastController(): ToastController {\n const controller = React.useContext(ToasterContext);\n if (controller) return controller;\n reportMissingContext('useToastController', '<Toaster>', MISSING_TOASTER_MESSAGE);\n return INERT_CONTROLLER;\n}\n\n/* ------------------------------------------------------------------ */\n/* Timers */\n/* ------------------------------------------------------------------ */\n\nconst DEFAULT_TIMEOUT = 5000;\n\ntype PauseReason = 'hover' | 'focus';\n\ninterface RunningTimer {\n handle: ReturnType<typeof setTimeout> | null;\n remaining: number;\n startedAt: number;\n}\n\n/**\n * Auto-dismiss timers of one Toaster. A timer runs only while neither the pointer nor focus is in\n * the toast region (D14), the window is in the foreground and the Toaster is mounted; otherwise it\n * is suspended and keeps its remaining time. Every method is called from event handlers or\n * effects, never during render.\n */\ninterface ToastTimers {\n /**\n * Starts the timer of the shown toast `id` for its dispatch `seq`, once: a call with the `seq`\n * already started does nothing, a new `seq` (the toast was replaced) restarts it. A timeout that\n * is not a positive finite number means none. A toast replaced while the region is paused stays\n * paused.\n */\n start(id: string, seq: number, timeout: number): void;\n /** Cancels the timer of `id`. */\n remove(id: string): void;\n /** Cancels every timer; the region's pause is kept. */\n clear(): void;\n /** `true` while the pointer (`'hover'`) or focus (`'focus'`) is in the toast region. */\n setPaused(reason: PauseReason, paused: boolean): void;\n /** Whether the region is paused for `reason`. */\n isPaused(reason: PauseReason): boolean;\n /** `true` while the window has lost focus or the page is not shown (a background tab). */\n setInBackground(inBackground: boolean): void;\n /** `true` while the Toaster is unmounted (including StrictMode's simulated unmount). */\n setSuspended(suspended: boolean): void;\n}\n\nfunction createToastTimers(onExpire: (id: string) => void): ToastTimers {\n const timers = new Map<string, RunningTimer>();\n /** Why the region pauses every timer. */\n const pauses = new Set<PauseReason>();\n /** The dispatch (`seq`) whose timer was started last, per toast. */\n const started = new Map<string, number>();\n let inBackground = false;\n let suspended = false;\n\n const sync = (id: string) => {\n const timer = timers.get(id);\n if (!timer) return;\n const canRun = !suspended && !inBackground && pauses.size === 0;\n if (canRun && timer.handle === null) {\n timer.startedAt = Date.now();\n timer.handle = setTimeout(() => {\n timers.delete(id);\n started.delete(id);\n onExpire(id);\n }, timer.remaining);\n } else if (!canRun && timer.handle !== null) {\n clearTimeout(timer.handle);\n timer.handle = null;\n timer.remaining = Math.max(0, timer.remaining - (Date.now() - timer.startedAt));\n }\n };\n const syncAll = () => {\n for (const id of Array.from(timers.keys())) sync(id);\n };\n const stop = (id: string) => {\n const timer = timers.get(id);\n if (timer?.handle != null) clearTimeout(timer.handle);\n timers.delete(id);\n };\n\n return {\n start(id, seq, timeout) {\n if (started.get(id) === seq) return;\n started.set(id, seq);\n stop(id);\n if (!(timeout > 0) || !Number.isFinite(timeout)) return;\n timers.set(id, { handle: null, remaining: timeout, startedAt: 0 });\n sync(id);\n },\n remove(id) {\n stop(id);\n started.delete(id);\n },\n clear() {\n for (const id of Array.from(timers.keys())) stop(id);\n started.clear();\n },\n isPaused(reason) {\n return pauses.has(reason);\n },\n setPaused(reason, paused) {\n if (paused) pauses.add(reason);\n else pauses.delete(reason);\n syncAll();\n },\n setInBackground(value) {\n inBackground = value;\n syncAll();\n },\n setSuspended(value) {\n suspended = value;\n syncAll();\n },\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Toaster (container) */\n/* ------------------------------------------------------------------ */\n\n/**\n * Corner of the viewport a {@link Toaster} shows its toasts in (`ToasterProps.position`).\n * `start`/`end` follow the writing direction; `left`/`right` are physical.\n */\nexport type ToastPosition =\n | 'top-start'\n | 'top-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'top-right'\n | 'top-left'\n | 'bottom-right'\n | 'bottom-left';\n\n/** Keyboard shortcuts of a Toaster (Fluent's shape). */\nexport interface ToasterShortcuts {\n /**\n * Returns `true` for the key press that moves focus to the most recently dispatched toast, for\n * example `(event) => event.altKey && event.shiftKey && event.code === 'KeyN'`. Use a modifier\n * (or let people change or turn off the shortcut): a single-character shortcut fails WCAG 2.1.4.\n */\n focus?: (event: KeyboardEvent) => boolean;\n}\n\n/** Properties for the Toaster container component. */\nexport interface ToasterProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Corner of the viewport the toasts appear in. `start`/`end` follow the writing direction (the\n * `end` side is the right in LTR and the left in RTL); `left`/`right` are physical.\n * @default 'bottom-end'\n */\n position?: ToastPosition;\n /**\n * Most toasts shown at once. Further toasts wait in a queue (in dispatch order) and appear when\n * a shown toast goes; a queued toast is not announced and its timer does not run until then.\n * Lowering it never hides a toast that is already shown, and a toast dispatched again with its id\n * while it exits comes back at once, even when `limit` toasts are already shown. A value below 1\n * counts as 1 (development warning); `Infinity` means no limit.\n * @default Infinity\n */\n limit?: number;\n /** Keyboard shortcuts; Escape, Delete and Backspace need none (see the component docs). */\n shortcuts?: ToasterShortcuts;\n /**\n * Binds this Toaster to a handle from `createToaster()`: toasts dispatched through the handle\n * render here. A handle binds one Toaster: a second Toaster given a bound handle does not bind\n * (development warning), and does not take the handle over when the first unmounts; the handle\n * queues again until a Toaster binds it.\n */\n toaster?: ToasterHandle;\n /** Ref to the toast region (the portaled `<div role=\"region\">`). */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Corner placement. The margin on the toasts' side is `--wave-toaster-offset`, and the margin on\n * their top or bottom edge `--wave-toaster-offset-block`, which the Toaster sets while a modal or\n * non-modal panel covers that side or that edge (see {@link getPanelOffsets}); unset, each is `0`.\n */\nconst positionClasses: Record<ToastPosition, string> = {\n 'top-start': 'top-4 start-4 ms-(--wave-toaster-offset) mt-(--wave-toaster-offset-block)',\n 'top-end': 'top-4 end-4 me-(--wave-toaster-offset) mt-(--wave-toaster-offset-block)',\n 'bottom-start': 'bottom-4 start-4 ms-(--wave-toaster-offset) mb-(--wave-toaster-offset-block)',\n 'bottom-end': 'bottom-4 end-4 me-(--wave-toaster-offset) mb-(--wave-toaster-offset-block)',\n 'top-right': 'top-4 right-4 mr-(--wave-toaster-offset) mt-(--wave-toaster-offset-block)', // wave-allow-physical: explicit physical position value\n 'top-left': 'top-4 left-4 ml-(--wave-toaster-offset) mt-(--wave-toaster-offset-block)', // wave-allow-physical: explicit physical position value\n 'bottom-right': 'bottom-4 right-4 mr-(--wave-toaster-offset) mb-(--wave-toaster-offset-block)', // wave-allow-physical: explicit physical position value\n 'bottom-left': 'bottom-4 left-4 ml-(--wave-toaster-offset) mb-(--wave-toaster-offset-block)', // wave-allow-physical: explicit physical position value\n};\n\n/** The toasts' distance from the window edges (`*-4`), also the tolerance for \"at the edge\". */\nconst EDGE_GAP = 16;\n\n/** Whether the toasts sit at the right edge of the window (`end` is the right in LTR). */\nfunction isOnRightSide(position: ToastPosition, viewport: HTMLElement): boolean {\n const inline = position.slice(position.indexOf('-') + 1);\n if (inline === 'right' || inline === 'left') return inline === 'right';\n const rtl = getDirection(viewport) === 'rtl';\n return inline === 'end' ? !rtl : rtl;\n}\n\n/** How far the toasts move away from their corner, per axis, in px (`0`: they stay). */\ninterface PanelOffsets {\n /** Away from the toasts' side (`--wave-toaster-offset`). */\n inline: number;\n /** Away from their top or bottom edge (`--wave-toaster-offset-block`). */\n block: number;\n}\n\n/** No panel at the toasts' corner: they keep it. */\nconst NO_PANEL_OFFSETS: PanelOffsets = { inline: 0, block: 0 };\n\n/** The open layers the toasts keep clear of: kind `'modal'` or `'dialog'` (a Dialog or Drawer). */\nfunction getPanelLayers(): LayerRecord[] {\n return getOpenLayers().filter((layer) => layer.kind === 'modal' || layer.kind === 'dialog');\n}\n\n/** The connected elements of the open panel layers ({@link getPanelLayers}). */\nfunction getPanelElements(): Set<HTMLElement> {\n const elements = new Set<HTMLElement>();\n for (const layer of getPanelLayers()) {\n for (const el of layer.getElements()) if (el?.isConnected) elements.add(el);\n }\n return elements;\n}\n\n/**\n * How far the toasts move away from their corner while an open panel covers it, so they never\n * hide the panel's controls (WCAG 2.4.11 Focus Not Obscured). It reads every open layer of kind\n * `'modal'` or `'dialog'` (a modal or non-modal Dialog or Drawer). An element of such a layer\n * counts when it reaches the toasts' side and their top or bottom edge (a centered Dialog does\n * not). The toasts move beside it when they fit there (a side panel: the offset is its width from\n * that side of the window, which leaves the usual gap between toasts and panel); otherwise above\n * it for bottom toasts, below it for top toasts, when they fit there (a bottom panel: its height);\n * otherwise it is ignored (a full-width side panel or a full-height bottom panel on a phone), and\n * they keep their corner. Each axis takes the largest offset of its panels, so a side panel and a\n * bottom panel open together move the toasts on both axes; an axis without room keeps `0`.\n */\nfunction getPanelOffsets(viewport: HTMLElement, position: ToastPosition): PanelOffsets {\n const panels = getPanelLayers();\n if (panels.length === 0) return NO_PANEL_OFFSETS;\n const doc = viewport.ownerDocument;\n const view = doc.defaultView;\n if (!view) return NO_PANEL_OFFSETS;\n // The box fixed elements are placed in: the window without its scrollbars.\n const width = doc.documentElement.clientWidth || view.innerWidth;\n const height = doc.documentElement.clientHeight || view.innerHeight;\n const right = isOnRightSide(position, viewport);\n const top = position.startsWith('top');\n // Whether the toasts fit in what an offset leaves of the window's width or height.\n const fitsInline = (offset: number) => width - offset >= viewport.offsetWidth + 2 * EDGE_GAP;\n const fitsBlock = (offset: number) => height - offset >= viewport.offsetHeight + 2 * EDGE_GAP;\n\n let inline = 0;\n let block = 0;\n for (const layer of panels) {\n for (const el of layer.getElements()) {\n if (!el?.isConnected) continue;\n const box = el.getBoundingClientRect();\n if (box.width <= 0 || box.height <= 0) continue;\n const onSide = right ? box.right >= width - EDGE_GAP : box.left <= EDGE_GAP;\n const onEdge = top ? box.top <= EDGE_GAP : box.bottom >= height - EDGE_GAP;\n if (!onSide || !onEdge) continue;\n const inlineOffset = right ? width - box.left : box.right;\n const blockOffset = top ? box.bottom : height - box.top;\n if (fitsInline(inlineOffset)) inline = Math.max(inline, inlineOffset);\n else if (fitsBlock(blockOffset)) block = Math.max(block, blockOffset);\n }\n }\n return {\n inline: inline > 0 && fitsInline(inline) ? Math.ceil(inline) : 0,\n block: block > 0 && fitsBlock(block) ? Math.ceil(block) : 0,\n };\n}\n\n/**\n * How long a toast's text stays in the live region: long enough for screen readers to pick it up\n * (also a polite message queued behind other speech), short enough that someone browsing the\n * Notifications region later meets the text once, in the toast, not a second time in the region.\n */\nconst ANNOUNCEMENT_DURATION = 2000;\n\n/** A toast's message for the live regions, composed by its container after it mounts (D13). */\ninterface Announcement {\n /** The dispatch it belongs to: a replacement (a new `seq`) is announced again. */\n seq: number;\n text: string;\n /** `error` toasts are announced assertively, every other status politely. */\n assertive: boolean;\n}\n\n/**\n * One toast's message in a live region. It is added when the toast is shown (at dispatch, or when\n * a waiting toast appears; a replacement remounts it, so it is read again) and removed after\n * {@link ANNOUNCEMENT_DURATION} or with the toast. Removal is not announced (`aria-relevant` stays\n * at its default, additions and text).\n */\nfunction LiveMessage({ text }: { text: string }) {\n const [present, setPresent] = React.useState(true);\n React.useEffect(() => {\n const handle = setTimeout(() => setPresent(false), ANNOUNCEMENT_DURATION);\n return () => clearTimeout(handle);\n }, []);\n return present ? <div>{text}</div> : null;\n}\nLiveMessage.displayName = 'LiveMessage';\n\ninterface ToastContainerProps {\n entry: ToastEntry;\n timers: ToastTimers;\n onDismiss: (id: string) => void;\n onExited: (id: string) => void;\n getFocusFallback: (from: HTMLElement | null) => HTMLElement | null;\n announce: (id: string, announcement: Announcement) => void;\n registerContainer: (id: string, node: HTMLElement | null) => void;\n}\n\nfunction isTitlePart(\n part: ToastPartRegistration,\n): part is Extract<ToastPartRegistration, { kind: 'title' }> {\n return part.kind === 'title';\n}\n\nfunction isBodyPart(\n part: ToastPartRegistration,\n): part is Extract<ToastPartRegistration, { kind: 'body' }> {\n return part.kind === 'body';\n}\n\nfunction isFooterPart(\n part: ToastPartRegistration,\n): part is Extract<ToastPartRegistration, { kind: 'footer' }> {\n return part.kind === 'footer';\n}\n\n/** Elements whose text runs on without a break; every other element separates its text. */\nconst INLINE_ELEMENTS = new Set([\n 'a',\n 'abbr',\n 'b',\n 'bdi',\n 'bdo',\n 'cite',\n 'code',\n 'data',\n 'dfn',\n 'em',\n 'i',\n 'kbd',\n 'label',\n 'mark',\n 'q',\n 's',\n 'samp',\n 'small',\n 'span',\n 'strong',\n 'sub',\n 'sup',\n 'time',\n 'u',\n 'var',\n 'wbr',\n]);\n\n/** Elements browsers never render as text. */\nconst NOT_TEXT_ELEMENTS = new Set(['noscript', 'script', 'style', 'template']);\n\n/** Native elements a screen reader names by their `aria-label` rather than by their content. */\nconst NATIVE_NAMED_BY_LABEL = new Set(['button', 'img', 'input', 'select', 'textarea']);\n\n/** Roles of controls and images, which are named by their `aria-label` rather than by content. */\nconst ROLES_NAMED_BY_LABEL = new Set([\n 'button',\n 'checkbox',\n 'combobox',\n 'img',\n 'link',\n 'option',\n 'radio',\n 'slider',\n 'spinbutton',\n 'switch',\n 'tab',\n 'textbox',\n]);\n\n/**\n * Whether `aria-label` replaces the content of `el` (a control, a link or an image); any other\n * element, such as a labelled toolbar or group, is read through its content.\n */\nfunction isNamedByLabel(el: Element): boolean {\n const role = el.getAttribute('role')?.trim().split(/\\s+/)[0];\n if (role) return ROLES_NAMED_BY_LABEL.has(role) || role.startsWith('menuitem');\n if (el.localName === 'a') return el.hasAttribute('href');\n return NATIVE_NAMED_BY_LABEL.has(el.localName);\n}\n\n/**\n * Whether `el` is left out of the accessible text: the `hidden` attribute, `aria-hidden=\"true\"` and\n * elements that are no text. Text hidden by a style sheet is still read: the spec defines hidden as\n * the attribute and `aria-hidden`, and reading computed styles would make the text depend on CSS.\n */\nfunction isNotRendered(el: Element): boolean {\n return (\n el.getAttribute('aria-hidden') === 'true' ||\n el.hasAttribute('hidden') ||\n NOT_TEXT_ELEMENTS.has(el.localName)\n );\n}\n\n/**\n * The text a screen reader reads for `root`'s content (D13): text nodes, an image's `alt` and the\n * `aria-label` of a control; `aria-hidden=\"true\"` and `hidden` subtrees, elements that are no text\n * and elements `skip` accepts are left out; whitespace is collapsed. Fluent reads the raw text\n * content instead, which includes hidden text and misses `alt` text.\n */\nfunction getAccessibleText(root: Element | null, skip?: (el: Element) => boolean): string {\n if (!root) return '';\n const parts: string[] = [];\n const visit = (node: Node, isRoot: boolean): void => {\n if (node.nodeType === Node.TEXT_NODE) {\n parts.push(node.textContent ?? '');\n return;\n }\n if (node.nodeType !== Node.ELEMENT_NODE) return;\n const el = node as Element;\n if (!isRoot && skip?.(el)) return;\n if (isNotRendered(el)) return;\n const label = el.getAttribute('aria-label');\n if (label && isNamedByLabel(el)) {\n parts.push(` ${label} `);\n return;\n }\n if (el.localName === 'img') {\n parts.push(` ${el.getAttribute('alt') ?? ''} `);\n return;\n }\n const separate = !INLINE_ELEMENTS.has(el.localName);\n if (separate) parts.push(' ');\n for (const child of Array.from(el.childNodes)) visit(child, false);\n if (separate) parts.push(' ');\n };\n visit(root, true);\n return parts.join('').replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * The accessible text of each child of `root` on its own, so adjacent actions that a flex row lays\n * out side by side (two links, two span-rooted buttons) are not read as one word.\n */\nfunction getChildTexts(root: Element | null): string[] {\n if (!root || isNotRendered(root)) return [];\n return Array.from(root.childNodes, (node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n return (node.textContent ?? '').replace(/\\s+/g, ' ').trim();\n }\n return node.nodeType === Node.ELEMENT_NODE ? getAccessibleText(node as Element) : '';\n }).filter(Boolean);\n}\n\n/**\n * A toast's announced text after its severity (D13): the title, the body (its subtitle included),\n * then the labels of its actions (the title's `action` and the footer, never the Dismiss button),\n * each action on its own. Content without a title or body part is read whole, without the severity\n * texts.\n */\nfunction composeToastText(\n container: HTMLElement,\n parts: readonly ToastPartRegistration[],\n toast: ToastRegistration | null,\n ownStatusTextId: string,\n): string {\n const title = parts.find(isTitlePart);\n const body = parts.find(isBodyPart);\n if (!title && !body) {\n const dismissButton = toast?.getDismissButton() ?? null;\n return getAccessibleText(\n container,\n (el) =>\n el === dismissButton ||\n (el.id !== '' && (el.id === ownStatusTextId || el.id === toast?.statusTextId)),\n );\n }\n const label = title?.getLabel() ?? null;\n // The title row without its text: the `action` slot, whose children are the actions.\n const row = title?.getRow() ?? null;\n const titleActions = row\n ? Array.from(row.children)\n .filter((child) => child !== label)\n .flatMap((slot) => getChildTexts(slot))\n : [];\n return [\n getAccessibleText(label),\n getAccessibleText(body?.getElement() ?? null),\n ...titleActions,\n ...parts.filter(isFooterPart).flatMap((footer) => getChildTexts(footer.getElement())),\n ]\n .filter(Boolean)\n .join(' ');\n}\n\n/**\n * One toast of the Toaster (D10): a `role=\"group\"` container, focusable by script (no Tab stop),\n * named by the toast's severity text and title and described by its body while a Toast inside\n * has registered them (so no id reference dangles). It provides the per-toast context, pauses the\n * timers and keeps focus when the toast goes.\n */\nfunction ToastContainer({\n entry,\n timers,\n onDismiss,\n onExited,\n getFocusFallback,\n announce,\n registerContainer,\n}: ToastContainerProps) {\n const { id, dismissed } = entry;\n // Mounted through the presence core (D29): a dismissed toast exits, `inert`, and is removed when\n // its exit ends (at once without motion); dispatching its id again revives it.\n const {\n isMounted,\n ref: presenceRef,\n presenceProps,\n } = usePresence(!dismissed, {\n appear: true,\n onExited: () => onExited(id),\n });\n const containerRef = React.useRef<HTMLDivElement | null>(null);\n // The last element, for the focus fallback, which may run after the container has unmounted.\n const lastElementRef = React.useRef<HTMLDivElement | null>(null);\n const attach = React.useCallback(\n (node: HTMLDivElement | null) => {\n containerRef.current = node;\n if (node) lastElementRef.current = node;\n registerContainer(id, node);\n },\n [id, registerContainer],\n );\n const mergedRef = useMergedRefs<HTMLDivElement>(attach, presenceRef);\n // Focus leaves a dismissed toast in its dismissing commit: `enabled` flipping to `false` moves it\n // in the layout phase, while the inert node is still there; a toast removed with the Toaster\n // moves it after the unmount.\n usePreserveFocus(containerRef, () => getFocusFallback(lastElementRef.current), {\n enabled: !dismissed,\n });\n const titleId = useId('wave-toast-title');\n const ownStatusTextId = useId('wave-toast-status');\n\n // The registrations of the parts and of the Toast inside, whose layout effects run before this\n // component's: in state for the name and description, in refs for reads after mount.\n const [parts, setParts] = React.useState<readonly ToastPartRegistration[]>([]);\n const partsRef = React.useRef<readonly ToastPartRegistration[]>([]);\n const registerPart = React.useCallback((part: ToastPartRegistration) => {\n partsRef.current = [...partsRef.current, part];\n setParts(partsRef.current);\n return () => {\n partsRef.current = partsRef.current.filter((item) => item !== part);\n setParts(partsRef.current);\n };\n }, []);\n const [toast, setToast] = React.useState<ToastRegistration | null>(null);\n const toastRef = React.useRef<ToastRegistration | null>(null);\n const registerToast = React.useCallback((registration: ToastRegistration) => {\n toastRef.current = registration;\n setToast(registration);\n return () => {\n if (toastRef.current !== registration) return;\n toastRef.current = null;\n setToast(null);\n };\n }, []);\n\n // `Toast.Close` and the Dismiss button: the Toast's `onDismiss`, then the dismissal (D9, D11).\n const dismiss = useEventCallback(() => {\n toastRef.current?.onDismiss?.();\n onDismiss(id);\n });\n const context = React.useMemo<ToastContextValue>(\n () => ({ titleId, dismiss, registerPart, registerToast }),\n [titleId, dismiss, registerPart, registerToast],\n );\n\n const titlePart = parts.find(isTitlePart);\n const bodyPart = parts.find(isBodyPart);\n // Content without a Toast (D10): a visually hidden severity text from the dispatch options,\n // first in the container, while no Toast has registered its own.\n const ownSeverityLabel =\n entry.form === 'content' && toast === null\n ? getStatusLabel(entry.options.status ?? 'info', entry.options.statusLabel)\n : '';\n const severityId = toast ? toast.statusTextId : ownSeverityLabel ? ownStatusTextId : undefined;\n // The timer of each dispatch (D12), started once the content has mounted (its registrations ran\n // first): the dispatch's `timeout`, else none for a toast with an action — people using a screen\n // reader, a switch or voice control need time to reach it — else 5000 ms.\n React.useLayoutEffect(() => {\n const node = containerRef.current;\n if (entry.dismissed || !node) return;\n const timeout =\n entry.options.timeout ?? (hasAction(node, toastRef.current) ? 0 : DEFAULT_TIMEOUT);\n timers.start(entry.id, entry.seq, timeout);\n }, [entry, timers]);\n\n // What screen readers hear (D13), once per dispatch after the content has mounted: the severity\n // text of the rendered Toast (else the dispatch options'), then `announcement` or the text the\n // toast renders; `error` is assertive. `toast` re-runs it for a Toast that registers after this\n // commit (content that renders it later); `announce` drops a repeat of the same message.\n React.useLayoutEffect(() => {\n const node = containerRef.current;\n if (entry.dismissed || !node) return;\n const registered = toastRef.current;\n const status = registered?.status ?? entry.options.status ?? 'info';\n const label = registered\n ? registered.statusLabel\n : getStatusLabel(status, entry.options.statusLabel);\n const text =\n entry.form === 'content' && entry.options.announcement !== undefined\n ? entry.options.announcement\n : composeToastText(node, partsRef.current, registered, ownStatusTextId);\n announce(entry.id, {\n seq: entry.seq,\n text: [label, text].filter(Boolean).join(' '),\n assertive: status === 'error',\n });\n }, [entry, announce, ownStatusTextId, toast]);\n\n // A rendered Toast's severity wins over the dispatch options' (D12); an explicit, different\n // `status` in the options warns once. Read from the ref, not the `toast` state, inside the\n // effect: replacing a registered Toast with content that renders none (a replacement by\n // `toastId`) unregisters it by clearing the ref synchronously, while `setToast(null)` only lands\n // on a later render — depending on the state would fire this effect once against the\n // just-unregistered Toast's stale status. `toast` still triggers the effect (without being read\n // directly), so it also re-runs when a Toast registers after this commit (content that renders\n // its Toast later, inside the consumer's own `<Suspense>`) or changes its own `status` without a\n // new dispatch; `entry` alone would never trigger a re-check for either.\n const optionStatus = entry.form === 'content' ? entry.options.status : undefined;\n React.useEffect(() => {\n const toastStatus = toastRef.current?.status;\n if (optionStatus === undefined || toastStatus === undefined || optionStatus === toastStatus) {\n return;\n }\n warnOnce(\n 'Toaster:status-conflict',\n `Toaster: the dispatched Toast has status \"${toastStatus}\" but the dispatch options pass \"${optionStatus}\"; the Toast's status is used. Remove \\`status\\` from the options.`,\n );\n }, [entry, optionStatus, toast]);\n // Delete or Backspace on the container or inside it dismisses the toast (D14; Backspace is the\n // delete key of Mac keyboards), except in an editable field and for a key pressed in a portal\n // opened from the toast (its target is outside the container).\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Delete' && event.key !== 'Backspace') return;\n if (event.defaultPrevented || !isOwnEvent(event) || isEditableTarget(event.target)) return;\n event.preventDefault();\n onDismiss(id);\n };\n\n if (!isMounted) return null;\n return (\n <div\n ref={mergedRef}\n role=\"group\"\n tabIndex={-1}\n data-wave-toast=\"\"\n aria-labelledby={joinIds(severityId, titlePart?.id)}\n aria-describedby={bodyPart?.id}\n className={cn(toasterClassNames.toast, 'rounded', focusRing)}\n {...presenceProps}\n onKeyDown={handleKeyDown}\n >\n {ownSeverityLabel ? <StatusText label={ownSeverityLabel} id={ownStatusTextId} /> : null}\n <ToastContext.Provider value={context}>\n {entry.form === 'options' ? (\n <ToastRoot\n status={entry.options.status}\n statusLabel={entry.options.statusLabel}\n title={entry.options.title}\n dismissLabel={entry.options.dismissLabel}\n >\n {entry.options.body}\n </ToastRoot>\n ) : (\n entry.content\n )}\n </ToastContext.Provider>\n </div>\n );\n}\nToastContainer.displayName = 'ToastContainer';\n\n/**\n * Provides {@link useToastController} to its children and shows the dispatched toasts.\n *\n * - **Wrap the app** in `<Toaster>`; components below it call `useToastController()`, and code\n * outside components (a query-cache callback, a server-event handler) dispatches through a\n * handle from `createToaster()` bound with `toaster`, which also runs several Toasters side by\n * side (one handle each).\n * - **Two ways to dispatch:** `dispatchToast(<Toast>…</Toast>)` shows your content, usually a\n * `Toast` with `Toast.Title`, `Toast.Body` and `Toast.Footer`; `dispatchToast({ title, body })`\n * builds a toast from text. Both return the toast's id. Content without a `Toast` takes its\n * severity from the options (`status`, `statusLabel`) and shows no Dismiss button (add a\n * `Toast.Close`).\n * - The toasts render in a portal (the `toast` layer, above dialogs) inside a region labelled\n * \"Notifications\" (override with `aria-label`). The region is allow-listed for modals\n * (`data-wave-focus-trap-allow`): it stays reachable by Tab and exposed to assistive technology\n * while a Dialog or Drawer is open, and clicking a toast never dismisses the overlay below.\n * - Two permanent, visually hidden live regions (polite, and assertive for `error`) announce every\n * toast once per dispatch, read from what it renders after it mounts: the severity text, then\n * the title, the body and the labels of its actions (never the Dismiss button) or, instead of\n * those, the dispatch's `announcement`.\n * The toasts themselves are not live regions. Each message stays in its live region for 2\n * seconds (or until its toast goes), so browsing the region later meets the text only once.\n * - While an open panel covers the toasts' corner (a modal or non-modal Drawer on the same side,\n * or at the bottom), the toasts move beside it, or above a bottom one (below it for top toasts),\n * so they never hide its focused controls (WCAG 2.4.11). Without room there (a full-width panel\n * on a narrow screen) they keep their corner.\n * - Timers pause while the pointer or focus is anywhere in the toast region, a menu or popover\n * opened from a toast included (someone reading or operating one toast is reading the stack),\n * and while the window is in the background (it has lost focus, or the page is not shown, as in\n * a background tab). When a toast that contains focus goes away, focus moves to the next toast\n * (or the previous one), or back to the element that was focused before focus entered the\n * toasts once no toast is left.\n * - **Keyboard:** `shortcuts.focus` names a key press that moves focus to the newest toast (use a\n * modifier, WCAG 2.1.4); Escape in the toast region dismisses every toast and returns focus to\n * where it was before focus entered the toasts (a tooltip or menu of a toast closes first, and a\n * Dialog below stays open); Delete or Backspace dismisses the focused toast.\n * - Each toast's dismiss button is named \"Dismiss\"; pass `dismissLabel` to `dispatchToast` for\n * other languages.\n * - `limit` caps how many toasts show at once: the others wait in a queue, in dispatch order,\n * unannounced and without a running timer, and appear as shown toasts go.\n * `dismissAllToasts()` removes every toast, shown and queued.\n *\n * @example\n * <Toaster position=\"bottom-end\" limit={3}>\n * <App />\n * </Toaster>\n */\nexport const Toaster = ({\n position = 'bottom-end',\n limit: limitProp,\n shortcuts,\n toaster: handle,\n className,\n style,\n children,\n onFocus,\n onBlur,\n onKeyDown,\n onPointerEnter,\n onPointerLeave,\n onPointerOver,\n ref,\n ...rest\n}: ToasterProps) => {\n const [toasts, setToasts] = React.useState<ToastEntry[]>([]);\n // Each toast's message, written by its container after the toast mounts (a layout effect), so\n // the severity is the rendered Toast's and the text what the toast renders.\n const [announcements, setAnnouncements] = React.useState<ReadonlyMap<string, Announcement>>(\n () => new Map(),\n );\n const announce = React.useCallback((id: string, announcement: Announcement) => {\n setAnnouncements((prev) => {\n const current = prev.get(id);\n if (\n current &&\n current.seq === announcement.seq &&\n current.text === announcement.text &&\n current.assertive === announcement.assertive\n ) {\n return prev;\n }\n const next = new Map(prev);\n next.set(id, announcement);\n return next;\n });\n }, []);\n const limit = resolveLimit(limitProp);\n // Waiting toasts are shown here, during render, with the current limit (adjust state while\n // rendering, C-HOOKS): every path that frees a place or raises the limit promotes them, and a\n // lowered limit never hides a shown toast. `promoteQueued` returns the same array once settled.\n const settled = promoteQueued(toasts, limit);\n if (settled !== toasts) setToasts(settled);\n const shownToasts = settled.filter((toast) => toast.shown);\n\n // Development diagnostics (C-DEV): emitted from an effect, once per page.\n React.useEffect(() => {\n if (limitProp !== undefined && !(limitProp >= 1)) {\n warnOnce(\n 'Toaster:limit',\n `Toaster: \\`limit\\` must be 1 or more (got ${String(limitProp)}); it counts as 1.`,\n );\n }\n }, [limitProp]);\n const prefix = useId('toast');\n const counterRef = React.useRef(0);\n const viewportRef = React.useRef<HTMLDivElement | null>(null);\n const viewportRefs = useMergedRefs(ref, viewportRef);\n const previousFocusRef = React.useRef<HTMLElement | null>(null);\n const dir = useDirection();\n\n // Beside or above an open panel at the toasts' corner (a Drawer), not over its controls. Measured\n // when a layer opens or closes (synchronously in its layout effect, before paint), on resize,\n // after a transition or animation (a panel that slides in reaches its place only then), when the\n // region's own size changes (the stack's height decides whether it fits above a panel), and when\n // an open panel changes its size, or its classes or style (an open Drawer whose `size` or\n // `position` changes: a move without a resize is no ResizeObserver entry).\n const [panelOffsets, setPanelOffsets] = React.useState<PanelOffsets>(NO_PANEL_OFFSETS);\n React.useLayoutEffect(() => {\n // The region and the panels are observed from `update`, so a region that renders after this\n // effect (its portal waits for hydration) is observed from the next measure: a layer opening\n // runs one. Only elements not observed yet are added (observing one again would report it).\n let observer: ResizeObserver | null = null;\n let mutationObserver: MutationObserver | null = null;\n let observed: HTMLElement | null = null;\n let observedPanels = new Set<HTMLElement>();\n const observePanels = () => {\n const panels = getPanelElements();\n for (const el of observedPanels) if (!panels.has(el)) observer?.unobserve(el);\n for (const el of panels) if (!observedPanels.has(el)) observer?.observe(el);\n const changed =\n panels.size !== observedPanels.size || [...panels].some((el) => !observedPanels.has(el));\n observedPanels = panels;\n if (!changed || !mutationObserver) return;\n mutationObserver.disconnect();\n for (const el of panels) {\n mutationObserver.observe(el, { attributes: true, attributeFilter: ['class', 'style'] });\n }\n };\n const update = () => {\n const viewport = viewportRef.current;\n if (observer && viewport !== observed) {\n if (observed) observer.unobserve(observed);\n if (viewport) observer.observe(viewport);\n observed = viewport;\n }\n observePanels();\n const next = viewport ? getPanelOffsets(viewport, position) : NO_PANEL_OFFSETS;\n setPanelOffsets((current) =>\n current.inline === next.inline && current.block === next.block ? current : next,\n );\n };\n if (typeof ResizeObserver !== 'undefined') observer = new ResizeObserver(() => update());\n if (typeof MutationObserver !== 'undefined') mutationObserver = new MutationObserver(update);\n update();\n const unsubscribe = subscribeLayers(update);\n window.addEventListener('resize', update);\n document.addEventListener('transitionend', update, true);\n document.addEventListener('animationend', update, true);\n return () => {\n unsubscribe();\n observer?.disconnect();\n mutationObserver?.disconnect();\n window.removeEventListener('resize', update);\n document.removeEventListener('transitionend', update, true);\n document.removeEventListener('animationend', update, true);\n };\n }, [position, dir]);\n\n const [timers] = React.useState(() =>\n createToastTimers((id) => setToasts((prev) => markDismissed(prev, id))),\n );\n\n // Timers run only while mounted (StrictMode's simulated unmount suspends and resumes them) and\n // pause while the window is in the background: after the window loses focus, and while the page\n // is not shown. The page visibility is read at mount too, so a Toaster that mounts in a\n // background tab waits until the tab is shown. (Focus is not read at mount: `hasFocus()` is also\n // false in an embedded frame nobody clicked yet and in test DOMs.)\n React.useEffect(() => {\n const doc = document;\n let blurred = false;\n const update = () => timers.setInBackground(blurred || doc.visibilityState === 'hidden');\n // Only the window's own blur/focus (element focus events do not bubble to a bubble-phase\n // window listener; anything targeted at a node is ignored).\n const handleBlur = (event: FocusEvent) => {\n if (event.target instanceof Node) return;\n blurred = true;\n update();\n };\n const handleFocus = (event: FocusEvent) => {\n if (event.target instanceof Node) return;\n blurred = false;\n update();\n };\n update();\n timers.setSuspended(false);\n window.addEventListener('blur', handleBlur);\n window.addEventListener('focus', handleFocus);\n doc.addEventListener('visibilitychange', update);\n return () => {\n window.removeEventListener('blur', handleBlur);\n window.removeEventListener('focus', handleFocus);\n doc.removeEventListener('visibilitychange', update);\n timers.setSuspended(true);\n };\n }, [timers]);\n\n // A new toast waits until the render promotes it; a replaced one keeps its place and whether it\n // is shown (a waiting toast keeps waiting with the new content), and an exiting one is revived.\n const dispatchToast = React.useCallback<ToastController['dispatchToast']>(\n (first: React.ReactNode | ToastOptions, second?: ToastDispatchOptions): string => {\n counterRef.current += 1;\n const seq = counterRef.current;\n const dispatched: DispatchedToast = isToastOptions(first)\n ? { form: 'options', options: first }\n : { form: 'content', content: first, options: second ?? {} };\n const id = dispatched.options.toastId ?? `${prefix}-${seq}`;\n setToasts((prev) => {\n const index = prev.findIndex((t) => t.id === id);\n const shown = index === -1 ? false : prev[index].shown;\n const entry: ToastEntry = { ...dispatched, id, seq, shown, dismissed: false };\n if (index === -1) return [...prev, entry];\n const next = prev.slice();\n next[index] = entry;\n return next;\n });\n return id;\n },\n [prefix],\n );\n\n const dismissToast = React.useCallback(\n (id: string) => {\n timers.remove(id);\n setToasts((prev) => markDismissed(prev, id));\n },\n [timers],\n );\n\n const dismissAllToasts = React.useCallback(() => {\n timers.clear();\n setToasts((prev) => markAllDismissed(prev));\n }, [timers]);\n\n // The exit of a dismissed toast ended: remove it and its message (one revived meanwhile stays).\n const removeExited = React.useCallback((id: string) => {\n setToasts((prev) =>\n prev.some((t) => t.id === id && t.dismissed)\n ? prev.filter((t) => !(t.id === id && t.dismissed))\n : prev,\n );\n setAnnouncements((prev) => {\n if (!prev.has(id)) return prev;\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n }, []);\n\n const controller = React.useMemo<ToastController>(\n () => ({ dispatchToast, dismissToast, dismissAllToasts }),\n [dispatchToast, dismissToast, dismissAllToasts],\n );\n\n // A handle from createToaster() (P3-08, D33): bound in a layout effect, so dispatches that waited\n // in its queue show before the first paint, and unbound on unmount (StrictMode binds again and\n // finds the queue taken). A handle bound to another Toaster stays there.\n const [handleOwner] = React.useState(() => ({}));\n React.useLayoutEffect(() => {\n if (!handle) return undefined;\n const binding = bindToasterHandle(handle, handleOwner, controller);\n if (binding.status === 'bound') return binding.unbind;\n if (binding.status === 'taken') {\n warnOnce(\n 'Toaster:handle-bound',\n 'Toaster: this handle is already bound to another Toaster; a handle binds one Toaster. Create one handle per Toaster.',\n );\n } else {\n warnOnce(\n 'Toaster:handle-unknown',\n 'Toaster: `toaster` is not a handle from createToaster(), so nothing is bound. Pass the value createToaster() returns.',\n );\n }\n return undefined;\n }, [handle, handleOwner, controller]);\n\n // Where focus goes when the focused toast is dismissed (in its dismissing commit) or removed with\n // the Toaster: the next toast that is not exiting, else the previous one — that container itself\n // when focus was on the dismissed container (after Delete or the shortcut), else its first\n // tabbable element — else the element focused before focus entered the toasts. Runs possibly\n // after the whole Toaster is gone: never throws.\n const getFocusFallback = React.useCallback((from: HTMLElement | null): HTMLElement | null => {\n const viewport = viewportRef.current;\n const containers = viewport\n ? Array.from(viewport.children).filter(\n (el): el is HTMLElement =>\n el instanceof HTMLElement && el.hasAttribute('data-wave-toast'),\n )\n : [];\n const onContainer = !!from && from.ownerDocument.activeElement === from;\n const index = from ? containers.indexOf(from) : -1;\n const isLive = (el: HTMLElement) =>\n el !== from && el.isConnected && el.getAttribute('data-presence') !== 'exiting';\n const next = containers.slice(index + 1).find(isLive);\n const previous = index > 0 ? containers.slice(0, index).reverse().find(isLive) : undefined;\n for (const candidate of [next, previous]) {\n if (!candidate) continue;\n const target = onContainer ? candidate : getFirstTabbable(candidate);\n if (target) return target;\n }\n // Focus leaves the toasts here without a blur of the viewport (the focused node is inert or\n // gone), so the element is forgotten as it is used: a toast focused later from nowhere does not\n // send focus back to it.\n const previousFocus = previousFocusRef.current;\n previousFocusRef.current = null;\n return previousFocus?.isConnected ? previousFocus : null;\n }, []);\n\n // Focus can fall to the page body without a blur reaching the viewport: the node that had it\n // (a layer opened from a toast, a button replaced by text) is gone. A move to a real element\n // always sends blur and focus through React, so only a fall to the body is reconciled, whenever\n // the toasts or the layers change: the 'focus' pause ends, and while the region still held it,\n // focus returns to the remembered origin, as it does when a focused toast goes. The origin is\n // forgotten either way.\n const reconcileFocus = useEventCallback(() => {\n const viewport = viewportRef.current;\n if (!viewport) return;\n const doc = viewport.ownerDocument;\n if (doc.activeElement && doc.activeElement !== doc.body) return;\n const held = timers.isPaused('focus');\n timers.setPaused('focus', false);\n const origin = previousFocusRef.current;\n previousFocusRef.current = null;\n if (held && origin && isConnectedAndFocusable(origin)) origin.focus({ preventScroll: true });\n });\n React.useLayoutEffect(() => {\n reconcileFocus();\n }, [settled, reconcileFocus]);\n // A layer's cleanup can notify while its focused node is still connected: look a tick later.\n React.useLayoutEffect(\n () => subscribeLayers(() => queueMicrotask(reconcileFocus)),\n [reconcileFocus],\n );\n\n // The pointer can leave the region without a leave reaching it: when the node under the pointer\n // is removed (a hovered toast dismissed, timed out or pushed out by the limit, a menu item that\n // closed its menu), the browser's next boundary event is a `pointerover` on the element now under\n // the pointer with no related target, from which React synthesises no leave. So the 'hover' pause\n // also ends on any `pointerover` that did not pass through the region in React's tree, which\n // takes in a portal opened from a toast (D14, as the enter and leave handlers do). The DOM and\n // layer check after it (`isInToastRegion`) is defensive: it keeps the pause for a layer anchored\n // in a toast but rendered outside the Toaster's tree. A document listener in the bubble phase, so\n // React's own listeners (on the root and portal containers, below the document) have marked the\n // event first.\n const regionPointerOverRef = React.useRef<Event | null>(null);\n React.useEffect(() => {\n const handlePointerOver = (event: Event) => {\n const fromRegion = regionPointerOverRef.current === event;\n regionPointerOverRef.current = null;\n if (fromRegion || !timers.isPaused('hover')) return;\n const viewport = viewportRef.current;\n if (viewport && event.target instanceof Node && isInToastRegion(viewport, event.target)) {\n return;\n }\n timers.setPaused('hover', false);\n };\n document.addEventListener('pointerover', handlePointerOver);\n return () => document.removeEventListener('pointerover', handlePointerOver);\n }, [timers]);\n\n // The latest entries and every container element, for the shortcut's document listener.\n const toastsRef = React.useRef<ToastEntry[]>(settled);\n React.useLayoutEffect(() => {\n toastsRef.current = settled;\n });\n const containersRef = React.useRef(new Map<string, HTMLElement>());\n const registerContainer = React.useCallback((id: string, node: HTMLElement | null) => {\n if (node) containersRef.current.set(id, node);\n else containersRef.current.delete(id);\n }, []);\n\n // The focus shortcut (D14): a document listener, so the key works wherever focus is. It focuses\n // the container of the newest toast that is shown and not dismissed and remembers where focus\n // was (unless it is already in the toasts).\n const hasFocusShortcut = typeof shortcuts?.focus === 'function';\n const handleShortcut = useEventCallback((event: KeyboardEvent) => {\n if (event.defaultPrevented || event.isComposing || !shortcuts?.focus?.(event)) return;\n const newest = findNewestToast(toastsRef.current);\n const target = newest ? containersRef.current.get(newest.id) : undefined;\n if (!target?.isConnected) return;\n event.preventDefault();\n const viewport = viewportRef.current;\n const active = target.ownerDocument.activeElement;\n if (\n active instanceof HTMLElement &&\n active !== target.ownerDocument.body &&\n !(viewport && isInToastRegion(viewport, active))\n ) {\n previousFocusRef.current = active;\n }\n target.focus({ preventScroll: false });\n });\n React.useEffect(() => {\n if (!hasFocusShortcut) return undefined;\n const listener = (event: KeyboardEvent) => handleShortcut(event);\n document.addEventListener('keydown', listener);\n return () => document.removeEventListener('keydown', listener);\n }, [hasFocusShortcut, handleShortcut]);\n\n // Focus entering the toast region from an element outside it: return there when the focused\n // toast goes and after Escape. Focus arriving with no related target keeps what is remembered\n // (the Toaster's own move to the next toast, the window regaining focus). Moves inside the region\n // — a layer opened from a toast included — change nothing, and an element that cannot take focus\n // (inside a closing, inert surface) is never remembered.\n const rememberFocusOrigin = (event: React.FocusEvent<HTMLDivElement>) => {\n const from = event.relatedTarget;\n if (!(from instanceof HTMLElement) || !isConnectedAndFocusable(from)) return;\n if (isInToastRegion(event.currentTarget, from)) return;\n previousFocusRef.current = from;\n };\n\n // Focus leaving the region for another element or for `<body>` forgets the element, so a toast\n // focused again later from nowhere never sends focus back to something focused long before.\n // Kept: moves inside the region (a layer opened from a toast included), a removed or dismissed\n // toast (its node is gone or inert; the Toaster moves focus itself) and the window losing focus\n // (the element keeps document focus while another window is active).\n const forgetFocusOrigin = (event: React.FocusEvent<HTMLDivElement>) => {\n const viewport = event.currentTarget;\n const to = event.relatedTarget;\n if (to instanceof Node && isInToastRegion(viewport, to)) return;\n // A blur from inside a dismissed (exiting, inert) toast: the Toaster has moved focus itself,\n // or a browser's focus fix-up blurs the inert subtree later.\n if (event.target.closest('[data-wave-toast][data-presence=\"exiting\"]')) return;\n if (to === null) {\n const from = event.target;\n if (!from.isConnected) return;\n const active = from.ownerDocument.activeElement;\n if (active && isInToastRegion(viewport, active)) return;\n }\n previousFocusRef.current = null;\n };\n\n // Escape in the toast region (D14) dismisses every toast and returns focus to where it was\n // before focus entered the toasts. Left alone: a key pressed in a portal opened from a toast\n // (its target is outside the viewport; the portal's own widget handles it) and one that an open\n // Escape-enabled layer anchored in the viewport takes first (a Tooltip on a toast's button, a\n // Menu opened from a toast). Prevented, so the dismiss-layer stack does not route it to a Dialog\n // or Drawer below (the region counts as inside every layer).\n const handleEscape = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Escape' && event.key !== 'Esc') return;\n if (event.defaultPrevented || event.nativeEvent.isComposing || !isOwnEvent(event)) return;\n const viewport = event.currentTarget;\n if (getOpenLayers().some((layer) => layer.escape && viewport.contains(layer.getAnchor()))) {\n return;\n }\n event.preventDefault();\n const origin = previousFocusRef.current;\n previousFocusRef.current = null;\n if (origin?.isConnected) origin.focus({ preventScroll: true });\n dismissAllToasts();\n };\n\n // Each shown toast's message for its first 2 s, while it is not dismissed (a waiting toast is\n // announced when it appears); a replacement is a new dispatch, so it is read again.\n const polite: React.ReactNode[] = [];\n const assertive: React.ReactNode[] = [];\n for (const toast of shownToasts) {\n if (toast.dismissed) continue;\n const announcement = announcements.get(toast.id);\n if (!announcement || announcement.seq !== toast.seq || !announcement.text) continue;\n const message = <LiveMessage key={announcement.seq} text={announcement.text} />;\n (announcement.assertive ? assertive : polite).push(message);\n }\n\n const viewportStyle =\n panelOffsets.inline > 0 || panelOffsets.block > 0\n ? ({\n ...style,\n ...(panelOffsets.inline > 0 && { '--wave-toaster-offset': `${panelOffsets.inline}px` }),\n ...(panelOffsets.block > 0 && {\n '--wave-toaster-offset-block': `${panelOffsets.block}px`,\n }),\n } as React.CSSProperties)\n : style;\n\n return (\n <ToasterContext.Provider value={controller}>\n {children}\n <Portal layer=\"toast\">\n <div\n ref={viewportRefs}\n role=\"region\"\n aria-label=\"Notifications\"\n data-wave-focus-trap-allow=\"\"\n data-position={position}\n {...rest}\n style={viewportStyle}\n onFocus={(event) => {\n // Bookkeeping always runs (a consumer's preventDefault() cannot cancel a focus change).\n // Focus in a portal opened from a toast arrives here too (React bubbles focus events\n // through portals) and counts as focus in the region (D14).\n onFocus?.(event);\n rememberFocusOrigin(event);\n timers.setPaused('focus', true);\n }}\n onBlur={(event) => {\n onBlur?.(event);\n forgetFocusOrigin(event);\n const next = event.relatedTarget;\n if (next instanceof Node && isInToastRegion(event.currentTarget, next)) return;\n timers.setPaused('focus', false);\n }}\n onPointerEnter={(event) => {\n onPointerEnter?.(event);\n timers.setPaused('hover', true);\n }}\n onPointerLeave={(event) => {\n onPointerLeave?.(event);\n timers.setPaused('hover', false);\n }}\n onPointerOver={(event) => {\n // Bookkeeping always runs. A portal opened from a toast counts as the region (D14):\n // React bubbles its pointer events here too.\n onPointerOver?.(event);\n regionPointerOverRef.current = event.nativeEvent;\n }}\n onKeyDown={(event) => composeEventHandlers(onKeyDown, handleEscape)(event)}\n className={cn(\n toasterClassNames.root,\n 'fixed flex w-80 max-w-[calc(100vw-2rem)] flex-col gap-2',\n positionClasses[position],\n className,\n )}\n >\n {/* One message per toast for its first 2 s; not atomic, so only the added one is read. */}\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"false\" className=\"sr-only\">\n {polite}\n </div>\n <div aria-live=\"assertive\" aria-atomic=\"false\" className=\"sr-only\">\n {assertive}\n </div>\n {/* Shown toasts, exiting ones included: getFocusFallback walks the containers in this order. */}\n {shownToasts.map((toast) => (\n <ToastContainer\n key={toast.id}\n entry={toast}\n timers={timers}\n onDismiss={dismissToast}\n onExited={removeExited}\n getFocusFallback={getFocusFallback}\n announce={announce}\n registerContainer={registerContainer}\n />\n ))}\n </div>\n </Portal>\n </ToasterContext.Provider>\n );\n};\nToaster.displayName = 'Toaster';\n"],"mappings":"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"}
|