;\n};\n\ntype ScopedProps = P & { __scopeToast?: Scope };\nconst [createToastContext, createToastScope] = createContextScope('Toast', [createCollectionScope]);\nconst [ToastProviderProvider, useToastProviderContext] =\n createToastContext(PROVIDER_NAME);\n\ninterface ToastProviderProps {\n children?: React.ReactNode;\n /**\n * An author-localized label for each toast. Used to help screen reader users\n * associate the interruption with a toast.\n * @defaultValue 'Notification'\n */\n label?: string;\n /**\n * Time in milliseconds that each toast should remain visible for.\n * @defaultValue 5000\n */\n duration?: number;\n /**\n * Direction of pointer swipe that should close the toast.\n * @defaultValue 'right'\n */\n swipeDirection?: SwipeDirection;\n /**\n * Distance in pixels that the swipe must pass before a close is triggered.\n * @defaultValue 50\n */\n swipeThreshold?: number;\n}\n\nconst ToastProvider: React.FC = (props: ScopedProps) => {\n const {\n __scopeToast,\n label = 'Notification',\n duration = 5000,\n swipeDirection = 'right',\n swipeThreshold = 50,\n children,\n } = props;\n const [viewport, setViewport] = React.useState(null);\n const [toastCount, setToastCount] = React.useState(0);\n const isFocusedToastEscapeKeyDownRef = React.useRef(false);\n const isClosePausedRef = React.useRef(false);\n\n if (!label.trim()) {\n console.error(\n `Invalid prop \\`label\\` supplied to \\`${PROVIDER_NAME}\\`. Expected non-empty \\`string\\`.`\n );\n }\n\n return (\n \n setToastCount((prevCount) => prevCount + 1), [])}\n onToastRemove={React.useCallback(() => setToastCount((prevCount) => prevCount - 1), [])}\n isFocusedToastEscapeKeyDownRef={isFocusedToastEscapeKeyDownRef}\n isClosePausedRef={isClosePausedRef}\n >\n {children}\n \n \n );\n};\n\nToastProvider.displayName = PROVIDER_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * ToastViewport\n * -----------------------------------------------------------------------------------------------*/\n\nconst VIEWPORT_NAME = 'ToastViewport';\nconst VIEWPORT_DEFAULT_HOTKEY = ['F8'];\nconst VIEWPORT_PAUSE = 'toast.viewportPause';\nconst VIEWPORT_RESUME = 'toast.viewportResume';\n\ntype ToastViewportElement = React.ElementRef;\ntype PrimitiveOrderedListProps = React.ComponentPropsWithoutRef;\ninterface ToastViewportProps extends PrimitiveOrderedListProps {\n /**\n * The keys to use as the keyboard shortcut that will move focus to the toast viewport.\n * @defaultValue ['F8']\n */\n hotkey?: string[];\n /**\n * An author-localized label for the toast viewport to provide context for screen reader users\n * when navigating page landmarks. The available `{hotkey}` placeholder will be replaced for you.\n * @defaultValue 'Notifications ({hotkey})'\n */\n label?: string;\n}\n\nconst ToastViewport = React.forwardRef(\n (props: ScopedProps, forwardedRef) => {\n const {\n __scopeToast,\n hotkey = VIEWPORT_DEFAULT_HOTKEY,\n label = 'Notifications ({hotkey})',\n ...viewportProps\n } = props;\n const context = useToastProviderContext(VIEWPORT_NAME, __scopeToast);\n const getItems = useCollection(__scopeToast);\n const wrapperRef = React.useRef(null);\n const headFocusProxyRef = React.useRef(null);\n const tailFocusProxyRef = React.useRef(null);\n const ref = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, ref, context.onViewportChange);\n const hotkeyLabel = hotkey.join('+').replace(/Key/g, '').replace(/Digit/g, '');\n const hasToasts = context.toastCount > 0;\n\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n // we use `event.code` as it is consistent regardless of meta keys that were pressed.\n // for example, `event.key` for `Control+Alt+t` is `†` and `t !== †`\n const isHotkeyPressed = hotkey.every((key) => (event as any)[key] || event.code === key);\n if (isHotkeyPressed) ref.current?.focus();\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [hotkey]);\n\n React.useEffect(() => {\n const wrapper = wrapperRef.current;\n const viewport = ref.current;\n if (hasToasts && wrapper && viewport) {\n const handlePause = () => {\n if (!context.isClosePausedRef.current) {\n const pauseEvent = new CustomEvent(VIEWPORT_PAUSE);\n viewport.dispatchEvent(pauseEvent);\n context.isClosePausedRef.current = true;\n }\n };\n\n const handleResume = () => {\n if (context.isClosePausedRef.current) {\n const resumeEvent = new CustomEvent(VIEWPORT_RESUME);\n viewport.dispatchEvent(resumeEvent);\n context.isClosePausedRef.current = false;\n }\n };\n\n const handleFocusOutResume = (event: FocusEvent) => {\n const isFocusMovingOutside = !wrapper.contains(event.relatedTarget as HTMLElement);\n if (isFocusMovingOutside) handleResume();\n };\n\n const handlePointerLeaveResume = () => {\n const isFocusInside = wrapper.contains(document.activeElement);\n if (!isFocusInside) handleResume();\n };\n\n // Toasts are not in the viewport React tree so we need to bind DOM events\n wrapper.addEventListener('focusin', handlePause);\n wrapper.addEventListener('focusout', handleFocusOutResume);\n wrapper.addEventListener('pointermove', handlePause);\n wrapper.addEventListener('pointerleave', handlePointerLeaveResume);\n window.addEventListener('blur', handlePause);\n window.addEventListener('focus', handleResume);\n return () => {\n wrapper.removeEventListener('focusin', handlePause);\n wrapper.removeEventListener('focusout', handleFocusOutResume);\n wrapper.removeEventListener('pointermove', handlePause);\n wrapper.removeEventListener('pointerleave', handlePointerLeaveResume);\n window.removeEventListener('blur', handlePause);\n window.removeEventListener('focus', handleResume);\n };\n }\n }, [hasToasts, context.isClosePausedRef]);\n\n const getSortedTabbableCandidates = React.useCallback(\n ({ tabbingDirection }: { tabbingDirection: 'forwards' | 'backwards' }) => {\n const toastItems = getItems();\n const tabbableCandidates = toastItems.map((toastItem) => {\n const toastNode = toastItem.ref.current!;\n const toastTabbableCandidates = [toastNode, ...getTabbableCandidates(toastNode)];\n return tabbingDirection === 'forwards'\n ? toastTabbableCandidates\n : toastTabbableCandidates.reverse();\n });\n return (\n tabbingDirection === 'forwards' ? tabbableCandidates.reverse() : tabbableCandidates\n ).flat();\n },\n [getItems]\n );\n\n React.useEffect(() => {\n const viewport = ref.current;\n // We programmatically manage tabbing as we are unable to influence\n // the source order with portals, this allows us to reverse the\n // tab order so that it runs from most recent toast to least\n if (viewport) {\n const handleKeyDown = (event: KeyboardEvent) => {\n const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;\n const isTabKey = event.key === 'Tab' && !isMetaKey;\n\n if (isTabKey) {\n const focusedElement = document.activeElement;\n const isTabbingBackwards = event.shiftKey;\n const targetIsViewport = event.target === viewport;\n\n // If we're back tabbing after jumping to the viewport then we simply\n // proxy focus out to the preceding document\n if (targetIsViewport && isTabbingBackwards) {\n headFocusProxyRef.current?.focus();\n return;\n }\n\n const tabbingDirection = isTabbingBackwards ? 'backwards' : 'forwards';\n const sortedCandidates = getSortedTabbableCandidates({ tabbingDirection });\n const index = sortedCandidates.findIndex((candidate) => candidate === focusedElement);\n if (focusFirst(sortedCandidates.slice(index + 1))) {\n event.preventDefault();\n } else {\n // If we can't focus that means we're at the edges so we\n // proxy to the corresponding exit point and let the browser handle\n // tab/shift+tab keypress and implicitly pass focus to the next valid element in the document\n isTabbingBackwards\n ? headFocusProxyRef.current?.focus()\n : tailFocusProxyRef.current?.focus();\n }\n }\n };\n\n // Toasts are not in the viewport React tree so we need to bind DOM events\n viewport.addEventListener('keydown', handleKeyDown);\n return () => viewport.removeEventListener('keydown', handleKeyDown);\n }\n }, [getItems, getSortedTabbableCandidates]);\n\n return (\n \n {hasToasts && (\n {\n const tabbableCandidates = getSortedTabbableCandidates({\n tabbingDirection: 'forwards',\n });\n focusFirst(tabbableCandidates);\n }}\n />\n )}\n {/**\n * tabindex on the the list so that it can be focused when items are removed. we focus\n * the list instead of the viewport so it announces number of items remaining.\n */}\n \n \n \n {hasToasts && (\n {\n const tabbableCandidates = getSortedTabbableCandidates({\n tabbingDirection: 'backwards',\n });\n focusFirst(tabbableCandidates);\n }}\n />\n )}\n \n );\n }\n);\n\nToastViewport.displayName = VIEWPORT_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\nconst FOCUS_PROXY_NAME = 'ToastFocusProxy';\n\ntype FocusProxyElement = React.ElementRef;\ntype VisuallyHiddenProps = React.ComponentPropsWithoutRef;\ninterface FocusProxyProps extends VisuallyHiddenProps {\n onFocusFromOutsideViewport(): void;\n}\n\nconst FocusProxy = React.forwardRef>(\n (props, forwardedRef) => {\n const { __scopeToast, onFocusFromOutsideViewport, ...proxyProps } = props;\n const context = useToastProviderContext(FOCUS_PROXY_NAME, __scopeToast);\n\n return (\n {\n const prevFocusedElement = event.relatedTarget as HTMLElement | null;\n const isFocusFromOutsideViewport = !context.viewport?.contains(prevFocusedElement);\n if (isFocusFromOutsideViewport) onFocusFromOutsideViewport();\n }}\n />\n );\n }\n);\n\nFocusProxy.displayName = FOCUS_PROXY_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * Toast\n * -----------------------------------------------------------------------------------------------*/\n\nconst TOAST_NAME = 'Toast';\nconst TOAST_SWIPE_START = 'toast.swipeStart';\nconst TOAST_SWIPE_MOVE = 'toast.swipeMove';\nconst TOAST_SWIPE_CANCEL = 'toast.swipeCancel';\nconst TOAST_SWIPE_END = 'toast.swipeEnd';\n\ntype ToastElement = ToastImplElement;\ninterface ToastProps extends Omit {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?(open: boolean): void;\n /**\n * Used to force mounting when more control is needed. Useful when\n * controlling animation with React animation libraries.\n */\n forceMount?: true;\n}\n\nconst Toast = React.forwardRef(\n (props: ScopedProps, forwardedRef) => {\n const { forceMount, open: openProp, defaultOpen, onOpenChange, ...toastProps } = props;\n const [open = true, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n });\n return (\n \n setOpen(false)}\n onPause={useCallbackRef(props.onPause)}\n onResume={useCallbackRef(props.onResume)}\n onSwipeStart={composeEventHandlers(props.onSwipeStart, (event) => {\n event.currentTarget.setAttribute('data-swipe', 'start');\n })}\n onSwipeMove={composeEventHandlers(props.onSwipeMove, (event) => {\n const { x, y } = event.detail.delta;\n event.currentTarget.setAttribute('data-swipe', 'move');\n event.currentTarget.style.setProperty('--radix-toast-swipe-move-x', `${x}px`);\n event.currentTarget.style.setProperty('--radix-toast-swipe-move-y', `${y}px`);\n })}\n onSwipeCancel={composeEventHandlers(props.onSwipeCancel, (event) => {\n event.currentTarget.setAttribute('data-swipe', 'cancel');\n event.currentTarget.style.removeProperty('--radix-toast-swipe-move-x');\n event.currentTarget.style.removeProperty('--radix-toast-swipe-move-y');\n event.currentTarget.style.removeProperty('--radix-toast-swipe-end-x');\n event.currentTarget.style.removeProperty('--radix-toast-swipe-end-y');\n })}\n onSwipeEnd={composeEventHandlers(props.onSwipeEnd, (event) => {\n const { x, y } = event.detail.delta;\n event.currentTarget.setAttribute('data-swipe', 'end');\n event.currentTarget.style.removeProperty('--radix-toast-swipe-move-x');\n event.currentTarget.style.removeProperty('--radix-toast-swipe-move-y');\n event.currentTarget.style.setProperty('--radix-toast-swipe-end-x', `${x}px`);\n event.currentTarget.style.setProperty('--radix-toast-swipe-end-y', `${y}px`);\n setOpen(false);\n })}\n />\n \n );\n }\n);\n\nToast.displayName = TOAST_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\ntype SwipeEvent = { currentTarget: EventTarget & ToastElement } & Omit<\n CustomEvent<{ originalEvent: React.PointerEvent; delta: { x: number; y: number } }>,\n 'currentTarget'\n>;\n\nconst [ToastInteractiveProvider, useToastInteractiveContext] = createToastContext(TOAST_NAME, {\n onClose() {},\n});\n\ntype ToastImplElement = React.ElementRef;\ntype DismissableLayerProps = React.ComponentPropsWithoutRef;\ntype ToastImplPrivateProps = { open: boolean; onClose(): void };\ntype PrimitiveListItemProps = React.ComponentPropsWithoutRef;\ninterface ToastImplProps extends ToastImplPrivateProps, PrimitiveListItemProps {\n type?: 'foreground' | 'background';\n /**\n * Time in milliseconds that toast should remain visible for. Overrides value\n * given to `ToastProvider`.\n */\n duration?: number;\n onEscapeKeyDown?: DismissableLayerProps['onEscapeKeyDown'];\n onPause?(): void;\n onResume?(): void;\n onSwipeStart?(event: SwipeEvent): void;\n onSwipeMove?(event: SwipeEvent): void;\n onSwipeCancel?(event: SwipeEvent): void;\n onSwipeEnd?(event: SwipeEvent): void;\n}\n\nconst ToastImpl = React.forwardRef(\n (props: ScopedProps, forwardedRef) => {\n const {\n __scopeToast,\n type = 'foreground',\n duration: durationProp,\n open,\n onClose,\n onEscapeKeyDown,\n onPause,\n onResume,\n onSwipeStart,\n onSwipeMove,\n onSwipeCancel,\n onSwipeEnd,\n ...toastProps\n } = props;\n const context = useToastProviderContext(TOAST_NAME, __scopeToast);\n const [node, setNode] = React.useState(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setNode(node));\n const pointerStartRef = React.useRef<{ x: number; y: number } | null>(null);\n const swipeDeltaRef = React.useRef<{ x: number; y: number } | null>(null);\n const duration = durationProp || context.duration;\n const closeTimerStartTimeRef = React.useRef(0);\n const closeTimerRemainingTimeRef = React.useRef(duration);\n const closeTimerRef = React.useRef(0);\n const { onToastAdd, onToastRemove } = context;\n const handleClose = useCallbackRef(() => {\n // focus viewport if focus is within toast to read the remaining toast\n // count to SR users and ensure focus isn't lost\n const isFocusInToast = node?.contains(document.activeElement);\n if (isFocusInToast) context.viewport?.focus();\n onClose();\n });\n\n const startTimer = React.useCallback(\n (duration: number) => {\n if (!duration || duration === Infinity) return;\n window.clearTimeout(closeTimerRef.current);\n closeTimerStartTimeRef.current = new Date().getTime();\n closeTimerRef.current = window.setTimeout(handleClose, duration);\n },\n [handleClose]\n );\n\n React.useEffect(() => {\n const viewport = context.viewport;\n if (viewport) {\n const handleResume = () => {\n startTimer(closeTimerRemainingTimeRef.current);\n onResume?.();\n };\n const handlePause = () => {\n const elapsedTime = new Date().getTime() - closeTimerStartTimeRef.current;\n closeTimerRemainingTimeRef.current = closeTimerRemainingTimeRef.current - elapsedTime;\n window.clearTimeout(closeTimerRef.current);\n onPause?.();\n };\n viewport.addEventListener(VIEWPORT_PAUSE, handlePause);\n viewport.addEventListener(VIEWPORT_RESUME, handleResume);\n return () => {\n viewport.removeEventListener(VIEWPORT_PAUSE, handlePause);\n viewport.removeEventListener(VIEWPORT_RESUME, handleResume);\n };\n }\n }, [context.viewport, duration, onPause, onResume, startTimer]);\n\n // start timer when toast opens or duration changes.\n // we include `open` in deps because closed !== unmounted when animating\n // so it could reopen before being completely unmounted\n React.useEffect(() => {\n if (open && !context.isClosePausedRef.current) startTimer(duration);\n }, [open, duration, context.isClosePausedRef, startTimer]);\n\n React.useEffect(() => {\n onToastAdd();\n return () => onToastRemove();\n }, [onToastAdd, onToastRemove]);\n\n const announceTextContent = React.useMemo(() => {\n return node ? getAnnounceTextContent(node) : null;\n }, [node]);\n\n if (!context.viewport) return null;\n\n return (\n <>\n {announceTextContent && (\n \n {announceTextContent}\n \n )}\n\n \n {ReactDOM.createPortal(\n \n {\n if (!context.isFocusedToastEscapeKeyDownRef.current) handleClose();\n context.isFocusedToastEscapeKeyDownRef.current = false;\n })}\n >\n {\n if (event.key !== 'Escape') return;\n onEscapeKeyDown?.(event.nativeEvent);\n if (!event.nativeEvent.defaultPrevented) {\n context.isFocusedToastEscapeKeyDownRef.current = true;\n handleClose();\n }\n })}\n onPointerDown={composeEventHandlers(props.onPointerDown, (event) => {\n if (event.button !== 0) return;\n pointerStartRef.current = { x: event.clientX, y: event.clientY };\n })}\n onPointerMove={composeEventHandlers(props.onPointerMove, (event) => {\n if (!pointerStartRef.current) return;\n const x = event.clientX - pointerStartRef.current.x;\n const y = event.clientY - pointerStartRef.current.y;\n const hasSwipeMoveStarted = Boolean(swipeDeltaRef.current);\n const isHorizontalSwipe = ['left', 'right'].includes(context.swipeDirection);\n const clamp = ['left', 'up'].includes(context.swipeDirection)\n ? Math.min\n : Math.max;\n const clampedX = isHorizontalSwipe ? clamp(0, x) : 0;\n const clampedY = !isHorizontalSwipe ? clamp(0, y) : 0;\n const moveStartBuffer = event.pointerType === 'touch' ? 10 : 2;\n const delta = { x: clampedX, y: clampedY };\n const eventDetail = { originalEvent: event, delta };\n if (hasSwipeMoveStarted) {\n swipeDeltaRef.current = delta;\n handleAndDispatchCustomEvent(TOAST_SWIPE_MOVE, onSwipeMove, eventDetail, {\n discrete: false,\n });\n } else if (isDeltaInDirection(delta, context.swipeDirection, moveStartBuffer)) {\n swipeDeltaRef.current = delta;\n handleAndDispatchCustomEvent(TOAST_SWIPE_START, onSwipeStart, eventDetail, {\n discrete: false,\n });\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n } else if (Math.abs(x) > moveStartBuffer || Math.abs(y) > moveStartBuffer) {\n // User is swiping in wrong direction so we disable swipe gesture\n // for the current pointer down interaction\n pointerStartRef.current = null;\n }\n })}\n onPointerUp={composeEventHandlers(props.onPointerUp, (event) => {\n const delta = swipeDeltaRef.current;\n const target = event.target as HTMLElement;\n if (target.hasPointerCapture(event.pointerId)) {\n target.releasePointerCapture(event.pointerId);\n }\n swipeDeltaRef.current = null;\n pointerStartRef.current = null;\n if (delta) {\n const toast = event.currentTarget;\n const eventDetail = { originalEvent: event, delta };\n if (\n isDeltaInDirection(delta, context.swipeDirection, context.swipeThreshold)\n ) {\n handleAndDispatchCustomEvent(TOAST_SWIPE_END, onSwipeEnd, eventDetail, {\n discrete: true,\n });\n } else {\n handleAndDispatchCustomEvent(\n TOAST_SWIPE_CANCEL,\n onSwipeCancel,\n eventDetail,\n {\n discrete: true,\n }\n );\n }\n // Prevent click event from triggering on items within the toast when\n // pointer up is part of a swipe gesture\n toast.addEventListener('click', (event) => event.preventDefault(), {\n once: true,\n });\n }\n })}\n />\n \n ,\n context.viewport\n )}\n \n >\n );\n }\n);\n\n/* -----------------------------------------------------------------------------------------------*/\n\ninterface ToastAnnounceProps\n extends Omit, 'children'>,\n ScopedProps<{ children: string[] }> {}\n\nconst ToastAnnounce: React.FC = (props: ScopedProps) => {\n const { __scopeToast, children, ...announceProps } = props;\n const context = useToastProviderContext(TOAST_NAME, __scopeToast);\n const [renderAnnounceText, setRenderAnnounceText] = React.useState(false);\n const [isAnnounced, setIsAnnounced] = React.useState(false);\n\n // render text content in the next frame to ensure toast is announced in NVDA\n useNextFrame(() => setRenderAnnounceText(true));\n\n // cleanup after announcing\n React.useEffect(() => {\n const timer = window.setTimeout(() => setIsAnnounced(true), 1000);\n return () => window.clearTimeout(timer);\n }, []);\n\n return isAnnounced ? null : (\n \n \n {renderAnnounceText && (\n <>\n {context.label} {children}\n >\n )}\n \n \n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ToastTitle\n * -----------------------------------------------------------------------------------------------*/\n\nconst TITLE_NAME = 'ToastTitle';\n\ntype ToastTitleElement = React.ElementRef;\ntype PrimitiveDivProps = React.ComponentPropsWithoutRef;\ninterface ToastTitleProps extends PrimitiveDivProps {}\n\nconst ToastTitle = React.forwardRef(\n (props: ScopedProps, forwardedRef) => {\n const { __scopeToast, ...titleProps } = props;\n return ;\n }\n);\n\nToastTitle.displayName = TITLE_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * ToastDescription\n * -----------------------------------------------------------------------------------------------*/\n\nconst DESCRIPTION_NAME = 'ToastDescription';\n\ntype ToastDescriptionElement = React.ElementRef;\ninterface ToastDescriptionProps extends PrimitiveDivProps {}\n\nconst ToastDescription = React.forwardRef(\n (props: ScopedProps, forwardedRef) => {\n const { __scopeToast, ...descriptionProps } = props;\n return ;\n }\n);\n\nToastDescription.displayName = DESCRIPTION_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * ToastAction\n * -----------------------------------------------------------------------------------------------*/\n\nconst ACTION_NAME = 'ToastAction';\n\ntype ToastActionElement = ToastCloseElement;\ninterface ToastActionProps extends ToastCloseProps {\n /**\n * A short description for an alternate way to carry out the action. For screen reader users\n * who will not be able to navigate to the button easily/quickly.\n * @example Upgrade\n * @example Undo\n */\n altText: string;\n}\n\nconst ToastAction = React.forwardRef(\n (props: ScopedProps, forwardedRef) => {\n const { altText, ...actionProps } = props;\n\n if (!altText.trim()) {\n console.error(\n `Invalid prop \\`altText\\` supplied to \\`${ACTION_NAME}\\`. Expected non-empty \\`string\\`.`\n );\n return null;\n }\n\n return (\n \n \n \n );\n }\n);\n\nToastAction.displayName = ACTION_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * ToastClose\n * -----------------------------------------------------------------------------------------------*/\n\nconst CLOSE_NAME = 'ToastClose';\n\ntype ToastCloseElement = React.ElementRef;\ntype PrimitiveButtonProps = React.ComponentPropsWithoutRef;\ninterface ToastCloseProps extends PrimitiveButtonProps {}\n\nconst ToastClose = React.forwardRef(\n (props: ScopedProps, forwardedRef) => {\n const { __scopeToast, ...closeProps } = props;\n const interactiveContext = useToastInteractiveContext(CLOSE_NAME, __scopeToast);\n\n return (\n \n \n \n );\n }\n);\n\nToastClose.displayName = CLOSE_NAME;\n\n/* ---------------------------------------------------------------------------------------------- */\n\ntype ToastAnnounceExcludeElement = React.ElementRef;\ninterface ToastAnnounceExcludeProps extends PrimitiveDivProps {\n altText?: string;\n}\n\nconst ToastAnnounceExclude = React.forwardRef<\n ToastAnnounceExcludeElement,\n ToastAnnounceExcludeProps\n>((props: ScopedProps, forwardedRef) => {\n const { __scopeToast, altText, ...announceExcludeProps } = props;\n\n return (\n \n );\n});\n\nfunction getAnnounceTextContent(container: HTMLElement) {\n const textContent: string[] = [];\n const childNodes = Array.from(container.childNodes);\n\n childNodes.forEach((node) => {\n if (node.nodeType === node.TEXT_NODE && node.textContent) textContent.push(node.textContent);\n if (isHTMLElement(node)) {\n const isHidden = node.ariaHidden || node.hidden || node.style.display === 'none';\n const isExcluded = node.dataset.radixToastAnnounceExclude === '';\n\n if (!isHidden) {\n if (isExcluded) {\n const altText = node.dataset.radixToastAnnounceAlt;\n if (altText) textContent.push(altText);\n } else {\n textContent.push(...getAnnounceTextContent(node));\n }\n }\n }\n });\n\n // We return a collection of text rather than a single concatenated string.\n // This allows SR VO to naturally pause break between nodes while announcing.\n return textContent;\n}\n\n/* ---------------------------------------------------------------------------------------------- */\n\nfunction handleAndDispatchCustomEvent<\n E extends CustomEvent,\n ReactEvent extends React.SyntheticEvent\n>(\n name: string,\n handler: ((event: E) => void) | undefined,\n detail: { originalEvent: ReactEvent } & (E extends CustomEvent ? D : never),\n { discrete }: { discrete: boolean }\n) {\n const currentTarget = detail.originalEvent.currentTarget as HTMLElement;\n const event = new CustomEvent(name, { bubbles: true, cancelable: true, detail });\n if (handler) currentTarget.addEventListener(name, handler as EventListener, { once: true });\n\n if (discrete) {\n dispatchDiscreteCustomEvent(currentTarget, event);\n } else {\n currentTarget.dispatchEvent(event);\n }\n}\n\nconst isDeltaInDirection = (\n delta: { x: number; y: number },\n direction: SwipeDirection,\n threshold = 0\n) => {\n const deltaX = Math.abs(delta.x);\n const deltaY = Math.abs(delta.y);\n const isDeltaX = deltaX > deltaY;\n if (direction === 'left' || direction === 'right') {\n return isDeltaX && deltaX > threshold;\n } else {\n return !isDeltaX && deltaY > threshold;\n }\n};\n\nfunction useNextFrame(callback = () => {}) {\n const fn = useCallbackRef(callback);\n useLayoutEffect(() => {\n let raf1 = 0;\n let raf2 = 0;\n raf1 = window.requestAnimationFrame(() => (raf2 = window.requestAnimationFrame(fn)));\n return () => {\n window.cancelAnimationFrame(raf1);\n window.cancelAnimationFrame(raf2);\n };\n }, [fn]);\n}\n\nfunction isHTMLElement(node: any): node is HTMLElement {\n return node.nodeType === node.ELEMENT_NODE;\n}\n\n/**\n * Returns a list of potential tabbable candidates.\n *\n * NOTE: This is only a close approximation. For example it doesn't take into account cases like when\n * elements are not visible. This cannot be worked out easily by just reading a property, but rather\n * necessitate runtime knowledge (computed styles, etc). We deal with these cases separately.\n *\n * See: https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker\n * Credit: https://github.com/discord/focus-layers/blob/master/src/util/wrapFocus.tsx#L1\n */\nfunction getTabbableCandidates(container: HTMLElement) {\n const nodes: HTMLElement[] = [];\n const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {\n acceptNode: (node: any) => {\n const isHiddenInput = node.tagName === 'INPUT' && node.type === 'hidden';\n if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP;\n // `.tabIndex` is not the same as the `tabindex` attribute. It works on the\n // runtime's understanding of tabbability, so this automatically accounts\n // for any kind of element that could be tabbed to.\n return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;\n },\n });\n while (walker.nextNode()) nodes.push(walker.currentNode as HTMLElement);\n // we do not take into account the order of nodes with positive `tabIndex` as it\n // hinders accessibility to have tab order different from visual order.\n return nodes;\n}\n\nfunction focusFirst(candidates: HTMLElement[]) {\n const previouslyFocusedElement = document.activeElement;\n return candidates.some((candidate) => {\n // if focus is already where we want to go, we don't want to keep going through the candidates\n if (candidate === previouslyFocusedElement) return true;\n candidate.focus();\n return document.activeElement !== previouslyFocusedElement;\n });\n}\n\nconst Provider = ToastProvider;\nconst Viewport = ToastViewport;\nconst Root = Toast;\nconst Title = ToastTitle;\nconst Description = ToastDescription;\nconst Action = ToastAction;\nconst Close = ToastClose;\n\nexport {\n createToastScope,\n //\n ToastProvider,\n ToastViewport,\n Toast,\n ToastTitle,\n ToastDescription,\n ToastAction,\n ToastClose,\n //\n Provider,\n Viewport,\n Root,\n Title,\n Description,\n Action,\n Close,\n};\nexport type {\n ToastProviderProps,\n ToastViewportProps,\n ToastProps,\n ToastTitleProps,\n ToastDescriptionProps,\n ToastActionProps,\n ToastCloseProps,\n};\n","// packages/react/use-callback-ref/src/useCallbackRef.tsx\nimport * as React from \"react\";\nfunction useCallbackRef(callback) {\n const callbackRef = React.useRef(callback);\n React.useEffect(() => {\n callbackRef.current = callback;\n });\n return React.useMemo(() => (...args) => callbackRef.current?.(...args), []);\n}\nexport {\n useCallbackRef\n};\n//# sourceMappingURL=index.mjs.map\n","// packages/react/use-controllable-state/src/useControllableState.tsx\nimport * as React from \"react\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nfunction useControllableState({\n prop,\n defaultProp,\n onChange = () => {\n }\n}) {\n const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({ defaultProp, onChange });\n const isControlled = prop !== void 0;\n const value = isControlled ? prop : uncontrolledProp;\n const handleChange = useCallbackRef(onChange);\n const setValue = React.useCallback(\n (nextValue) => {\n if (isControlled) {\n const setter = nextValue;\n const value2 = typeof nextValue === \"function\" ? setter(prop) : nextValue;\n if (value2 !== prop) handleChange(value2);\n } else {\n setUncontrolledProp(nextValue);\n }\n },\n [isControlled, prop, setUncontrolledProp, handleChange]\n );\n return [value, setValue];\n}\nfunction useUncontrolledState({\n defaultProp,\n onChange\n}) {\n const uncontrolledState = React.useState(defaultProp);\n const [value] = uncontrolledState;\n const prevValueRef = React.useRef(value);\n const handleChange = useCallbackRef(onChange);\n React.useEffect(() => {\n if (prevValueRef.current !== value) {\n handleChange(value);\n prevValueRef.current = value;\n }\n }, [value, prevValueRef, handleChange]);\n return uncontrolledState;\n}\nexport {\n useControllableState\n};\n//# sourceMappingURL=index.mjs.map\n","// packages/react/use-escape-keydown/src/useEscapeKeydown.tsx\nimport * as React from \"react\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nfunction useEscapeKeydown(onEscapeKeyDownProp, ownerDocument = globalThis?.document) {\n const onEscapeKeyDown = useCallbackRef(onEscapeKeyDownProp);\n React.useEffect(() => {\n const handleKeyDown = (event) => {\n if (event.key === \"Escape\") {\n onEscapeKeyDown(event);\n }\n };\n ownerDocument.addEventListener(\"keydown\", handleKeyDown, { capture: true });\n return () => ownerDocument.removeEventListener(\"keydown\", handleKeyDown, { capture: true });\n }, [onEscapeKeyDown, ownerDocument]);\n}\nexport {\n useEscapeKeydown\n};\n//# sourceMappingURL=index.mjs.map\n","// packages/react/use-layout-effect/src/useLayoutEffect.tsx\nimport * as React from \"react\";\nvar useLayoutEffect2 = Boolean(globalThis?.document) ? React.useLayoutEffect : () => {\n};\nexport {\n useLayoutEffect2 as useLayoutEffect\n};\n//# sourceMappingURL=index.mjs.map\n","function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t