react-atom-toast
Version:
Tiny & Headless toast for React
128 lines (125 loc) • 3.93 kB
JavaScript
import { __spreadProps, __spreadValues } from '../chunk-5USKE2QT.js';
import { useRef } from 'react';
import { Transition } from 'react-transition-preset';
import { useControlledState } from '../hooks/use-controlled-state.js';
import { useIsoLayoutEffect } from '../hooks/use-iso-layout-effect.js';
import { useMemoizedFn } from '../hooks/use-memoized-fn.js';
import { useUpdateIsoLayoutEffect } from '../hooks/use-update-iso-layout-effect.js';
import { secToMs, classnames } from '../utils.js';
import { jsx } from 'react/jsx-runtime';
function Toast(props) {
const {
content,
className,
style,
duration,
onOpenChange,
onClosed,
pauseOnHover,
hover,
updateFlag,
transition: _transition,
open: _open,
onEnter: _onEnter,
onUpdate: _onUpdate,
onExited: _onExited,
offsetHeight
} = props;
const didMount = useRef(false);
const transition = useMemoizedFn(() => {
if (typeof _transition === "string") {
return { transition: _transition };
}
return {
transition: _transition == null ? void 0 : _transition.name,
duration: _transition == null ? void 0 : _transition.duration,
exitDuration: _transition == null ? void 0 : _transition.exitDuration
};
});
const timer = useRef();
const ref = useRef(null);
const [open, setOpen] = useControlledState({
defaultValue: !!_open,
value: _open,
onChange: (value) => {
onOpenChange(value);
}
});
const delayClear = useMemoizedFn(() => {
if (duration) {
timer.current && clearTimeout(timer.current);
timer.current = window.setTimeout(() => {
setOpen(false);
timer.current && clearTimeout(timer.current);
}, secToMs(duration));
}
});
useUpdateIsoLayoutEffect(() => {
if (!open) return;
if (pauseOnHover) {
if (hover) {
timer.current && clearTimeout(timer.current);
delayClear();
}
}
}, [hover]);
const onEnter = useMemoizedFn(() => {
if (!ref.current) return;
const height = ref.current.clientHeight;
_onEnter(height);
});
const onUpdate = useMemoizedFn(() => {
var _a;
const height = (_a = ref.current) == null ? void 0 : _a.clientHeight;
_onUpdate(height || 0);
});
const onExited = useMemoizedFn(() => {
var _a;
const height = (_a = ref.current) == null ? void 0 : _a.clientHeight;
_onExited(height || 0);
onClosed == null ? void 0 : onClosed();
});
const resolveTransform = useMemoizedFn((transform, offsetHeight2) => {
const internalTransform = `translate(-50%, calc(-50% - ${offsetHeight2}px))`;
return [internalTransform, transform].filter(Boolean).join(" ");
});
const resolveTransformProperty = useMemoizedFn((transform) => {
return [.../* @__PURE__ */ new Set(["transform", transform])].filter(Boolean).join(", ");
});
useIsoLayoutEffect(() => {
if (!open) return;
if (!didMount.current) {
didMount.current = true;
} else {
onUpdate();
}
delayClear();
return () => {
timer.current && clearTimeout(timer.current);
};
}, [updateFlag]);
useIsoLayoutEffect(() => {
if (!content) {
onExited();
}
}, [content]);
return /* @__PURE__ */ jsx(Transition, __spreadProps(__spreadValues({ mounted: open }, transition()), { onEnter, onExited, initial: true, children: (styles) => /* @__PURE__ */ jsx(
"div",
{
style: __spreadProps(__spreadValues(__spreadValues({
position: "fixed",
zIndex: 9999,
top: "50%",
left: "50%"
}, style), styles), {
transitionProperty: resolveTransformProperty(styles.transitionProperty),
transform: resolveTransform(styles.transform, offsetHeight)
}),
ref,
className: classnames("toast__content", className),
children: content
}
) }));
}
var toast_default = Toast;
export { toast_default as default };