Initial commit
This commit is contained in:
681
node_modules/@radix-ui/react-toast/dist/index.js
generated
vendored
Normal file
681
node_modules/@radix-ui/react-toast/dist/index.js
generated
vendored
Normal file
@ -0,0 +1,681 @@
|
||||
"use strict";
|
||||
"use client";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// packages/react/toast/src/index.ts
|
||||
var src_exports = {};
|
||||
__export(src_exports, {
|
||||
Action: () => Action,
|
||||
Close: () => Close,
|
||||
Description: () => Description,
|
||||
Provider: () => Provider,
|
||||
Root: () => Root2,
|
||||
Title: () => Title,
|
||||
Toast: () => Toast,
|
||||
ToastAction: () => ToastAction,
|
||||
ToastClose: () => ToastClose,
|
||||
ToastDescription: () => ToastDescription,
|
||||
ToastProvider: () => ToastProvider,
|
||||
ToastTitle: () => ToastTitle,
|
||||
ToastViewport: () => ToastViewport,
|
||||
Viewport: () => Viewport,
|
||||
createToastScope: () => createToastScope
|
||||
});
|
||||
module.exports = __toCommonJS(src_exports);
|
||||
|
||||
// packages/react/toast/src/Toast.tsx
|
||||
var React = __toESM(require("react"));
|
||||
var ReactDOM = __toESM(require("react-dom"));
|
||||
var import_primitive = require("@radix-ui/primitive");
|
||||
var import_react_compose_refs = require("@radix-ui/react-compose-refs");
|
||||
var import_react_collection = require("@radix-ui/react-collection");
|
||||
var import_react_context = require("@radix-ui/react-context");
|
||||
var DismissableLayer = __toESM(require("@radix-ui/react-dismissable-layer"));
|
||||
var import_react_portal = require("@radix-ui/react-portal");
|
||||
var import_react_presence = require("@radix-ui/react-presence");
|
||||
var import_react_primitive = require("@radix-ui/react-primitive");
|
||||
var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref");
|
||||
var import_react_use_controllable_state = require("@radix-ui/react-use-controllable-state");
|
||||
var import_react_use_layout_effect = require("@radix-ui/react-use-layout-effect");
|
||||
var import_react_visually_hidden = require("@radix-ui/react-visually-hidden");
|
||||
var import_jsx_runtime = require("react/jsx-runtime");
|
||||
var PROVIDER_NAME = "ToastProvider";
|
||||
var [Collection, useCollection, createCollectionScope] = (0, import_react_collection.createCollection)("Toast");
|
||||
var [createToastContext, createToastScope] = (0, import_react_context.createContextScope)("Toast", [createCollectionScope]);
|
||||
var [ToastProviderProvider, useToastProviderContext] = createToastContext(PROVIDER_NAME);
|
||||
var ToastProvider = (props) => {
|
||||
const {
|
||||
__scopeToast,
|
||||
label = "Notification",
|
||||
duration = 5e3,
|
||||
swipeDirection = "right",
|
||||
swipeThreshold = 50,
|
||||
children
|
||||
} = props;
|
||||
const [viewport, setViewport] = React.useState(null);
|
||||
const [toastCount, setToastCount] = React.useState(0);
|
||||
const isFocusedToastEscapeKeyDownRef = React.useRef(false);
|
||||
const isClosePausedRef = React.useRef(false);
|
||||
if (!label.trim()) {
|
||||
console.error(
|
||||
`Invalid prop \`label\` supplied to \`${PROVIDER_NAME}\`. Expected non-empty \`string\`.`
|
||||
);
|
||||
}
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.Provider, { scope: __scopeToast, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
||||
ToastProviderProvider,
|
||||
{
|
||||
scope: __scopeToast,
|
||||
label,
|
||||
duration,
|
||||
swipeDirection,
|
||||
swipeThreshold,
|
||||
toastCount,
|
||||
viewport,
|
||||
onViewportChange: setViewport,
|
||||
onToastAdd: React.useCallback(() => setToastCount((prevCount) => prevCount + 1), []),
|
||||
onToastRemove: React.useCallback(() => setToastCount((prevCount) => prevCount - 1), []),
|
||||
isFocusedToastEscapeKeyDownRef,
|
||||
isClosePausedRef,
|
||||
children
|
||||
}
|
||||
) });
|
||||
};
|
||||
ToastProvider.displayName = PROVIDER_NAME;
|
||||
var VIEWPORT_NAME = "ToastViewport";
|
||||
var VIEWPORT_DEFAULT_HOTKEY = ["F8"];
|
||||
var VIEWPORT_PAUSE = "toast.viewportPause";
|
||||
var VIEWPORT_RESUME = "toast.viewportResume";
|
||||
var ToastViewport = React.forwardRef(
|
||||
(props, forwardedRef) => {
|
||||
const {
|
||||
__scopeToast,
|
||||
hotkey = VIEWPORT_DEFAULT_HOTKEY,
|
||||
label = "Notifications ({hotkey})",
|
||||
...viewportProps
|
||||
} = props;
|
||||
const context = useToastProviderContext(VIEWPORT_NAME, __scopeToast);
|
||||
const getItems = useCollection(__scopeToast);
|
||||
const wrapperRef = React.useRef(null);
|
||||
const headFocusProxyRef = React.useRef(null);
|
||||
const tailFocusProxyRef = React.useRef(null);
|
||||
const ref = React.useRef(null);
|
||||
const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, ref, context.onViewportChange);
|
||||
const hotkeyLabel = hotkey.join("+").replace(/Key/g, "").replace(/Digit/g, "");
|
||||
const hasToasts = context.toastCount > 0;
|
||||
React.useEffect(() => {
|
||||
const handleKeyDown = (event) => {
|
||||
const isHotkeyPressed = hotkey.length !== 0 && hotkey.every((key) => event[key] || event.code === key);
|
||||
if (isHotkeyPressed) ref.current?.focus();
|
||||
};
|
||||
document.addEventListener("keydown", handleKeyDown);
|
||||
return () => document.removeEventListener("keydown", handleKeyDown);
|
||||
}, [hotkey]);
|
||||
React.useEffect(() => {
|
||||
const wrapper = wrapperRef.current;
|
||||
const viewport = ref.current;
|
||||
if (hasToasts && wrapper && viewport) {
|
||||
const handlePause = () => {
|
||||
if (!context.isClosePausedRef.current) {
|
||||
const pauseEvent = new CustomEvent(VIEWPORT_PAUSE);
|
||||
viewport.dispatchEvent(pauseEvent);
|
||||
context.isClosePausedRef.current = true;
|
||||
}
|
||||
};
|
||||
const handleResume = () => {
|
||||
if (context.isClosePausedRef.current) {
|
||||
const resumeEvent = new CustomEvent(VIEWPORT_RESUME);
|
||||
viewport.dispatchEvent(resumeEvent);
|
||||
context.isClosePausedRef.current = false;
|
||||
}
|
||||
};
|
||||
const handleFocusOutResume = (event) => {
|
||||
const isFocusMovingOutside = !wrapper.contains(event.relatedTarget);
|
||||
if (isFocusMovingOutside) handleResume();
|
||||
};
|
||||
const handlePointerLeaveResume = () => {
|
||||
const isFocusInside = wrapper.contains(document.activeElement);
|
||||
if (!isFocusInside) handleResume();
|
||||
};
|
||||
wrapper.addEventListener("focusin", handlePause);
|
||||
wrapper.addEventListener("focusout", handleFocusOutResume);
|
||||
wrapper.addEventListener("pointermove", handlePause);
|
||||
wrapper.addEventListener("pointerleave", handlePointerLeaveResume);
|
||||
window.addEventListener("blur", handlePause);
|
||||
window.addEventListener("focus", handleResume);
|
||||
return () => {
|
||||
wrapper.removeEventListener("focusin", handlePause);
|
||||
wrapper.removeEventListener("focusout", handleFocusOutResume);
|
||||
wrapper.removeEventListener("pointermove", handlePause);
|
||||
wrapper.removeEventListener("pointerleave", handlePointerLeaveResume);
|
||||
window.removeEventListener("blur", handlePause);
|
||||
window.removeEventListener("focus", handleResume);
|
||||
};
|
||||
}
|
||||
}, [hasToasts, context.isClosePausedRef]);
|
||||
const getSortedTabbableCandidates = React.useCallback(
|
||||
({ tabbingDirection }) => {
|
||||
const toastItems = getItems();
|
||||
const tabbableCandidates = toastItems.map((toastItem) => {
|
||||
const toastNode = toastItem.ref.current;
|
||||
const toastTabbableCandidates = [toastNode, ...getTabbableCandidates(toastNode)];
|
||||
return tabbingDirection === "forwards" ? toastTabbableCandidates : toastTabbableCandidates.reverse();
|
||||
});
|
||||
return (tabbingDirection === "forwards" ? tabbableCandidates.reverse() : tabbableCandidates).flat();
|
||||
},
|
||||
[getItems]
|
||||
);
|
||||
React.useEffect(() => {
|
||||
const viewport = ref.current;
|
||||
if (viewport) {
|
||||
const handleKeyDown = (event) => {
|
||||
const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;
|
||||
const isTabKey = event.key === "Tab" && !isMetaKey;
|
||||
if (isTabKey) {
|
||||
const focusedElement = document.activeElement;
|
||||
const isTabbingBackwards = event.shiftKey;
|
||||
const targetIsViewport = event.target === viewport;
|
||||
if (targetIsViewport && isTabbingBackwards) {
|
||||
headFocusProxyRef.current?.focus();
|
||||
return;
|
||||
}
|
||||
const tabbingDirection = isTabbingBackwards ? "backwards" : "forwards";
|
||||
const sortedCandidates = getSortedTabbableCandidates({ tabbingDirection });
|
||||
const index = sortedCandidates.findIndex((candidate) => candidate === focusedElement);
|
||||
if (focusFirst(sortedCandidates.slice(index + 1))) {
|
||||
event.preventDefault();
|
||||
} else {
|
||||
isTabbingBackwards ? headFocusProxyRef.current?.focus() : tailFocusProxyRef.current?.focus();
|
||||
}
|
||||
}
|
||||
};
|
||||
viewport.addEventListener("keydown", handleKeyDown);
|
||||
return () => viewport.removeEventListener("keydown", handleKeyDown);
|
||||
}
|
||||
}, [getItems, getSortedTabbableCandidates]);
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
||||
DismissableLayer.Branch,
|
||||
{
|
||||
ref: wrapperRef,
|
||||
role: "region",
|
||||
"aria-label": label.replace("{hotkey}", hotkeyLabel),
|
||||
tabIndex: -1,
|
||||
style: { pointerEvents: hasToasts ? void 0 : "none" },
|
||||
children: [
|
||||
hasToasts && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
||||
FocusProxy,
|
||||
{
|
||||
ref: headFocusProxyRef,
|
||||
onFocusFromOutsideViewport: () => {
|
||||
const tabbableCandidates = getSortedTabbableCandidates({
|
||||
tabbingDirection: "forwards"
|
||||
});
|
||||
focusFirst(tabbableCandidates);
|
||||
}
|
||||
}
|
||||
),
|
||||
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.Slot, { scope: __scopeToast, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.ol, { tabIndex: -1, ...viewportProps, ref: composedRefs }) }),
|
||||
hasToasts && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
||||
FocusProxy,
|
||||
{
|
||||
ref: tailFocusProxyRef,
|
||||
onFocusFromOutsideViewport: () => {
|
||||
const tabbableCandidates = getSortedTabbableCandidates({
|
||||
tabbingDirection: "backwards"
|
||||
});
|
||||
focusFirst(tabbableCandidates);
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
ToastViewport.displayName = VIEWPORT_NAME;
|
||||
var FOCUS_PROXY_NAME = "ToastFocusProxy";
|
||||
var FocusProxy = React.forwardRef(
|
||||
(props, forwardedRef) => {
|
||||
const { __scopeToast, onFocusFromOutsideViewport, ...proxyProps } = props;
|
||||
const context = useToastProviderContext(FOCUS_PROXY_NAME, __scopeToast);
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
||||
import_react_visually_hidden.VisuallyHidden,
|
||||
{
|
||||
"aria-hidden": true,
|
||||
tabIndex: 0,
|
||||
...proxyProps,
|
||||
ref: forwardedRef,
|
||||
style: { position: "fixed" },
|
||||
onFocus: (event) => {
|
||||
const prevFocusedElement = event.relatedTarget;
|
||||
const isFocusFromOutsideViewport = !context.viewport?.contains(prevFocusedElement);
|
||||
if (isFocusFromOutsideViewport) onFocusFromOutsideViewport();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
FocusProxy.displayName = FOCUS_PROXY_NAME;
|
||||
var TOAST_NAME = "Toast";
|
||||
var TOAST_SWIPE_START = "toast.swipeStart";
|
||||
var TOAST_SWIPE_MOVE = "toast.swipeMove";
|
||||
var TOAST_SWIPE_CANCEL = "toast.swipeCancel";
|
||||
var TOAST_SWIPE_END = "toast.swipeEnd";
|
||||
var Toast = React.forwardRef(
|
||||
(props, forwardedRef) => {
|
||||
const { forceMount, open: openProp, defaultOpen, onOpenChange, ...toastProps } = props;
|
||||
const [open = true, setOpen] = (0, import_react_use_controllable_state.useControllableState)({
|
||||
prop: openProp,
|
||||
defaultProp: defaultOpen,
|
||||
onChange: onOpenChange
|
||||
});
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_presence.Presence, { present: forceMount || open, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
||||
ToastImpl,
|
||||
{
|
||||
open,
|
||||
...toastProps,
|
||||
ref: forwardedRef,
|
||||
onClose: () => setOpen(false),
|
||||
onPause: (0, import_react_use_callback_ref.useCallbackRef)(props.onPause),
|
||||
onResume: (0, import_react_use_callback_ref.useCallbackRef)(props.onResume),
|
||||
onSwipeStart: (0, import_primitive.composeEventHandlers)(props.onSwipeStart, (event) => {
|
||||
event.currentTarget.setAttribute("data-swipe", "start");
|
||||
}),
|
||||
onSwipeMove: (0, import_primitive.composeEventHandlers)(props.onSwipeMove, (event) => {
|
||||
const { x, y } = event.detail.delta;
|
||||
event.currentTarget.setAttribute("data-swipe", "move");
|
||||
event.currentTarget.style.setProperty("--radix-toast-swipe-move-x", `${x}px`);
|
||||
event.currentTarget.style.setProperty("--radix-toast-swipe-move-y", `${y}px`);
|
||||
}),
|
||||
onSwipeCancel: (0, import_primitive.composeEventHandlers)(props.onSwipeCancel, (event) => {
|
||||
event.currentTarget.setAttribute("data-swipe", "cancel");
|
||||
event.currentTarget.style.removeProperty("--radix-toast-swipe-move-x");
|
||||
event.currentTarget.style.removeProperty("--radix-toast-swipe-move-y");
|
||||
event.currentTarget.style.removeProperty("--radix-toast-swipe-end-x");
|
||||
event.currentTarget.style.removeProperty("--radix-toast-swipe-end-y");
|
||||
}),
|
||||
onSwipeEnd: (0, import_primitive.composeEventHandlers)(props.onSwipeEnd, (event) => {
|
||||
const { x, y } = event.detail.delta;
|
||||
event.currentTarget.setAttribute("data-swipe", "end");
|
||||
event.currentTarget.style.removeProperty("--radix-toast-swipe-move-x");
|
||||
event.currentTarget.style.removeProperty("--radix-toast-swipe-move-y");
|
||||
event.currentTarget.style.setProperty("--radix-toast-swipe-end-x", `${x}px`);
|
||||
event.currentTarget.style.setProperty("--radix-toast-swipe-end-y", `${y}px`);
|
||||
setOpen(false);
|
||||
})
|
||||
}
|
||||
) });
|
||||
}
|
||||
);
|
||||
Toast.displayName = TOAST_NAME;
|
||||
var [ToastInteractiveProvider, useToastInteractiveContext] = createToastContext(TOAST_NAME, {
|
||||
onClose() {
|
||||
}
|
||||
});
|
||||
var ToastImpl = React.forwardRef(
|
||||
(props, forwardedRef) => {
|
||||
const {
|
||||
__scopeToast,
|
||||
type = "foreground",
|
||||
duration: durationProp,
|
||||
open,
|
||||
onClose,
|
||||
onEscapeKeyDown,
|
||||
onPause,
|
||||
onResume,
|
||||
onSwipeStart,
|
||||
onSwipeMove,
|
||||
onSwipeCancel,
|
||||
onSwipeEnd,
|
||||
...toastProps
|
||||
} = props;
|
||||
const context = useToastProviderContext(TOAST_NAME, __scopeToast);
|
||||
const [node, setNode] = React.useState(null);
|
||||
const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, (node2) => setNode(node2));
|
||||
const pointerStartRef = React.useRef(null);
|
||||
const swipeDeltaRef = React.useRef(null);
|
||||
const duration = durationProp || context.duration;
|
||||
const closeTimerStartTimeRef = React.useRef(0);
|
||||
const closeTimerRemainingTimeRef = React.useRef(duration);
|
||||
const closeTimerRef = React.useRef(0);
|
||||
const { onToastAdd, onToastRemove } = context;
|
||||
const handleClose = (0, import_react_use_callback_ref.useCallbackRef)(() => {
|
||||
const isFocusInToast = node?.contains(document.activeElement);
|
||||
if (isFocusInToast) context.viewport?.focus();
|
||||
onClose();
|
||||
});
|
||||
const startTimer = React.useCallback(
|
||||
(duration2) => {
|
||||
if (!duration2 || duration2 === Infinity) return;
|
||||
window.clearTimeout(closeTimerRef.current);
|
||||
closeTimerStartTimeRef.current = (/* @__PURE__ */ new Date()).getTime();
|
||||
closeTimerRef.current = window.setTimeout(handleClose, duration2);
|
||||
},
|
||||
[handleClose]
|
||||
);
|
||||
React.useEffect(() => {
|
||||
const viewport = context.viewport;
|
||||
if (viewport) {
|
||||
const handleResume = () => {
|
||||
startTimer(closeTimerRemainingTimeRef.current);
|
||||
onResume?.();
|
||||
};
|
||||
const handlePause = () => {
|
||||
const elapsedTime = (/* @__PURE__ */ new Date()).getTime() - closeTimerStartTimeRef.current;
|
||||
closeTimerRemainingTimeRef.current = closeTimerRemainingTimeRef.current - elapsedTime;
|
||||
window.clearTimeout(closeTimerRef.current);
|
||||
onPause?.();
|
||||
};
|
||||
viewport.addEventListener(VIEWPORT_PAUSE, handlePause);
|
||||
viewport.addEventListener(VIEWPORT_RESUME, handleResume);
|
||||
return () => {
|
||||
viewport.removeEventListener(VIEWPORT_PAUSE, handlePause);
|
||||
viewport.removeEventListener(VIEWPORT_RESUME, handleResume);
|
||||
};
|
||||
}
|
||||
}, [context.viewport, duration, onPause, onResume, startTimer]);
|
||||
React.useEffect(() => {
|
||||
if (open && !context.isClosePausedRef.current) startTimer(duration);
|
||||
}, [open, duration, context.isClosePausedRef, startTimer]);
|
||||
React.useEffect(() => {
|
||||
onToastAdd();
|
||||
return () => onToastRemove();
|
||||
}, [onToastAdd, onToastRemove]);
|
||||
const announceTextContent = React.useMemo(() => {
|
||||
return node ? getAnnounceTextContent(node) : null;
|
||||
}, [node]);
|
||||
if (!context.viewport) return null;
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
||||
announceTextContent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
||||
ToastAnnounce,
|
||||
{
|
||||
__scopeToast,
|
||||
role: "status",
|
||||
"aria-live": type === "foreground" ? "assertive" : "polite",
|
||||
"aria-atomic": true,
|
||||
children: announceTextContent
|
||||
}
|
||||
),
|
||||
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastInteractiveProvider, { scope: __scopeToast, onClose: handleClose, children: ReactDOM.createPortal(
|
||||
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.ItemSlot, { scope: __scopeToast, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
||||
DismissableLayer.Root,
|
||||
{
|
||||
asChild: true,
|
||||
onEscapeKeyDown: (0, import_primitive.composeEventHandlers)(onEscapeKeyDown, () => {
|
||||
if (!context.isFocusedToastEscapeKeyDownRef.current) handleClose();
|
||||
context.isFocusedToastEscapeKeyDownRef.current = false;
|
||||
}),
|
||||
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
||||
import_react_primitive.Primitive.li,
|
||||
{
|
||||
role: "status",
|
||||
"aria-live": "off",
|
||||
"aria-atomic": true,
|
||||
tabIndex: 0,
|
||||
"data-state": open ? "open" : "closed",
|
||||
"data-swipe-direction": context.swipeDirection,
|
||||
...toastProps,
|
||||
ref: composedRefs,
|
||||
style: { userSelect: "none", touchAction: "none", ...props.style },
|
||||
onKeyDown: (0, import_primitive.composeEventHandlers)(props.onKeyDown, (event) => {
|
||||
if (event.key !== "Escape") return;
|
||||
onEscapeKeyDown?.(event.nativeEvent);
|
||||
if (!event.nativeEvent.defaultPrevented) {
|
||||
context.isFocusedToastEscapeKeyDownRef.current = true;
|
||||
handleClose();
|
||||
}
|
||||
}),
|
||||
onPointerDown: (0, import_primitive.composeEventHandlers)(props.onPointerDown, (event) => {
|
||||
if (event.button !== 0) return;
|
||||
pointerStartRef.current = { x: event.clientX, y: event.clientY };
|
||||
}),
|
||||
onPointerMove: (0, import_primitive.composeEventHandlers)(props.onPointerMove, (event) => {
|
||||
if (!pointerStartRef.current) return;
|
||||
const x = event.clientX - pointerStartRef.current.x;
|
||||
const y = event.clientY - pointerStartRef.current.y;
|
||||
const hasSwipeMoveStarted = Boolean(swipeDeltaRef.current);
|
||||
const isHorizontalSwipe = ["left", "right"].includes(context.swipeDirection);
|
||||
const clamp = ["left", "up"].includes(context.swipeDirection) ? Math.min : Math.max;
|
||||
const clampedX = isHorizontalSwipe ? clamp(0, x) : 0;
|
||||
const clampedY = !isHorizontalSwipe ? clamp(0, y) : 0;
|
||||
const moveStartBuffer = event.pointerType === "touch" ? 10 : 2;
|
||||
const delta = { x: clampedX, y: clampedY };
|
||||
const eventDetail = { originalEvent: event, delta };
|
||||
if (hasSwipeMoveStarted) {
|
||||
swipeDeltaRef.current = delta;
|
||||
handleAndDispatchCustomEvent(TOAST_SWIPE_MOVE, onSwipeMove, eventDetail, {
|
||||
discrete: false
|
||||
});
|
||||
} else if (isDeltaInDirection(delta, context.swipeDirection, moveStartBuffer)) {
|
||||
swipeDeltaRef.current = delta;
|
||||
handleAndDispatchCustomEvent(TOAST_SWIPE_START, onSwipeStart, eventDetail, {
|
||||
discrete: false
|
||||
});
|
||||
event.target.setPointerCapture(event.pointerId);
|
||||
} else if (Math.abs(x) > moveStartBuffer || Math.abs(y) > moveStartBuffer) {
|
||||
pointerStartRef.current = null;
|
||||
}
|
||||
}),
|
||||
onPointerUp: (0, import_primitive.composeEventHandlers)(props.onPointerUp, (event) => {
|
||||
const delta = swipeDeltaRef.current;
|
||||
const target = event.target;
|
||||
if (target.hasPointerCapture(event.pointerId)) {
|
||||
target.releasePointerCapture(event.pointerId);
|
||||
}
|
||||
swipeDeltaRef.current = null;
|
||||
pointerStartRef.current = null;
|
||||
if (delta) {
|
||||
const toast = event.currentTarget;
|
||||
const eventDetail = { originalEvent: event, delta };
|
||||
if (isDeltaInDirection(delta, context.swipeDirection, context.swipeThreshold)) {
|
||||
handleAndDispatchCustomEvent(TOAST_SWIPE_END, onSwipeEnd, eventDetail, {
|
||||
discrete: true
|
||||
});
|
||||
} else {
|
||||
handleAndDispatchCustomEvent(
|
||||
TOAST_SWIPE_CANCEL,
|
||||
onSwipeCancel,
|
||||
eventDetail,
|
||||
{
|
||||
discrete: true
|
||||
}
|
||||
);
|
||||
}
|
||||
toast.addEventListener("click", (event2) => event2.preventDefault(), {
|
||||
once: true
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
) }),
|
||||
context.viewport
|
||||
) })
|
||||
] });
|
||||
}
|
||||
);
|
||||
var ToastAnnounce = (props) => {
|
||||
const { __scopeToast, children, ...announceProps } = props;
|
||||
const context = useToastProviderContext(TOAST_NAME, __scopeToast);
|
||||
const [renderAnnounceText, setRenderAnnounceText] = React.useState(false);
|
||||
const [isAnnounced, setIsAnnounced] = React.useState(false);
|
||||
useNextFrame(() => setRenderAnnounceText(true));
|
||||
React.useEffect(() => {
|
||||
const timer = window.setTimeout(() => setIsAnnounced(true), 1e3);
|
||||
return () => window.clearTimeout(timer);
|
||||
}, []);
|
||||
return isAnnounced ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_portal.Portal, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_visually_hidden.VisuallyHidden, { ...announceProps, children: renderAnnounceText && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
||||
context.label,
|
||||
" ",
|
||||
children
|
||||
] }) }) });
|
||||
};
|
||||
var TITLE_NAME = "ToastTitle";
|
||||
var ToastTitle = React.forwardRef(
|
||||
(props, forwardedRef) => {
|
||||
const { __scopeToast, ...titleProps } = props;
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.div, { ...titleProps, ref: forwardedRef });
|
||||
}
|
||||
);
|
||||
ToastTitle.displayName = TITLE_NAME;
|
||||
var DESCRIPTION_NAME = "ToastDescription";
|
||||
var ToastDescription = React.forwardRef(
|
||||
(props, forwardedRef) => {
|
||||
const { __scopeToast, ...descriptionProps } = props;
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.div, { ...descriptionProps, ref: forwardedRef });
|
||||
}
|
||||
);
|
||||
ToastDescription.displayName = DESCRIPTION_NAME;
|
||||
var ACTION_NAME = "ToastAction";
|
||||
var ToastAction = React.forwardRef(
|
||||
(props, forwardedRef) => {
|
||||
const { altText, ...actionProps } = props;
|
||||
if (!altText.trim()) {
|
||||
console.error(
|
||||
`Invalid prop \`altText\` supplied to \`${ACTION_NAME}\`. Expected non-empty \`string\`.`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastAnnounceExclude, { altText, asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastClose, { ...actionProps, ref: forwardedRef }) });
|
||||
}
|
||||
);
|
||||
ToastAction.displayName = ACTION_NAME;
|
||||
var CLOSE_NAME = "ToastClose";
|
||||
var ToastClose = React.forwardRef(
|
||||
(props, forwardedRef) => {
|
||||
const { __scopeToast, ...closeProps } = props;
|
||||
const interactiveContext = useToastInteractiveContext(CLOSE_NAME, __scopeToast);
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastAnnounceExclude, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
||||
import_react_primitive.Primitive.button,
|
||||
{
|
||||
type: "button",
|
||||
...closeProps,
|
||||
ref: forwardedRef,
|
||||
onClick: (0, import_primitive.composeEventHandlers)(props.onClick, interactiveContext.onClose)
|
||||
}
|
||||
) });
|
||||
}
|
||||
);
|
||||
ToastClose.displayName = CLOSE_NAME;
|
||||
var ToastAnnounceExclude = React.forwardRef((props, forwardedRef) => {
|
||||
const { __scopeToast, altText, ...announceExcludeProps } = props;
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
||||
import_react_primitive.Primitive.div,
|
||||
{
|
||||
"data-radix-toast-announce-exclude": "",
|
||||
"data-radix-toast-announce-alt": altText || void 0,
|
||||
...announceExcludeProps,
|
||||
ref: forwardedRef
|
||||
}
|
||||
);
|
||||
});
|
||||
function getAnnounceTextContent(container) {
|
||||
const textContent = [];
|
||||
const childNodes = Array.from(container.childNodes);
|
||||
childNodes.forEach((node) => {
|
||||
if (node.nodeType === node.TEXT_NODE && node.textContent) textContent.push(node.textContent);
|
||||
if (isHTMLElement(node)) {
|
||||
const isHidden = node.ariaHidden || node.hidden || node.style.display === "none";
|
||||
const isExcluded = node.dataset.radixToastAnnounceExclude === "";
|
||||
if (!isHidden) {
|
||||
if (isExcluded) {
|
||||
const altText = node.dataset.radixToastAnnounceAlt;
|
||||
if (altText) textContent.push(altText);
|
||||
} else {
|
||||
textContent.push(...getAnnounceTextContent(node));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return textContent;
|
||||
}
|
||||
function handleAndDispatchCustomEvent(name, handler, detail, { discrete }) {
|
||||
const currentTarget = detail.originalEvent.currentTarget;
|
||||
const event = new CustomEvent(name, { bubbles: true, cancelable: true, detail });
|
||||
if (handler) currentTarget.addEventListener(name, handler, { once: true });
|
||||
if (discrete) {
|
||||
(0, import_react_primitive.dispatchDiscreteCustomEvent)(currentTarget, event);
|
||||
} else {
|
||||
currentTarget.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
var isDeltaInDirection = (delta, direction, threshold = 0) => {
|
||||
const deltaX = Math.abs(delta.x);
|
||||
const deltaY = Math.abs(delta.y);
|
||||
const isDeltaX = deltaX > deltaY;
|
||||
if (direction === "left" || direction === "right") {
|
||||
return isDeltaX && deltaX > threshold;
|
||||
} else {
|
||||
return !isDeltaX && deltaY > threshold;
|
||||
}
|
||||
};
|
||||
function useNextFrame(callback = () => {
|
||||
}) {
|
||||
const fn = (0, import_react_use_callback_ref.useCallbackRef)(callback);
|
||||
(0, import_react_use_layout_effect.useLayoutEffect)(() => {
|
||||
let raf1 = 0;
|
||||
let raf2 = 0;
|
||||
raf1 = window.requestAnimationFrame(() => raf2 = window.requestAnimationFrame(fn));
|
||||
return () => {
|
||||
window.cancelAnimationFrame(raf1);
|
||||
window.cancelAnimationFrame(raf2);
|
||||
};
|
||||
}, [fn]);
|
||||
}
|
||||
function isHTMLElement(node) {
|
||||
return node.nodeType === node.ELEMENT_NODE;
|
||||
}
|
||||
function getTabbableCandidates(container) {
|
||||
const nodes = [];
|
||||
const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
|
||||
acceptNode: (node) => {
|
||||
const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
|
||||
if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP;
|
||||
return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
|
||||
}
|
||||
});
|
||||
while (walker.nextNode()) nodes.push(walker.currentNode);
|
||||
return nodes;
|
||||
}
|
||||
function focusFirst(candidates) {
|
||||
const previouslyFocusedElement = document.activeElement;
|
||||
return candidates.some((candidate) => {
|
||||
if (candidate === previouslyFocusedElement) return true;
|
||||
candidate.focus();
|
||||
return document.activeElement !== previouslyFocusedElement;
|
||||
});
|
||||
}
|
||||
var Provider = ToastProvider;
|
||||
var Viewport = ToastViewport;
|
||||
var Root2 = Toast;
|
||||
var Title = ToastTitle;
|
||||
var Description = ToastDescription;
|
||||
var Action = ToastAction;
|
||||
var Close = ToastClose;
|
||||
//# sourceMappingURL=index.js.map
|
||||
Reference in New Issue
Block a user