@konstructio/ui
Version:
A set of reusable and customizable React components built for konstruct.io
492 lines (491 loc) • 18.6 kB
JavaScript
import { jsx as c, jsxs as D, Fragment as se } from "react/jsx-runtime";
import { u as ae, S as j } from "../../index-B_6_jmOO.js";
import * as s from "react";
import { useRef as Re, useEffect as be, useMemo as oe, isValidElement as re, useCallback as ge } from "react";
import { P as L, r as Se, d as Ie } from "../../index-D7QNmo_D.js";
import { c as Ne, a as Ae, b, d as X, u as Fe } from "../../index-Cva-e5M4.js";
import { c as _e } from "../../index-BbsJ0VIJ.js";
import { B as De, R as Le, P as Me } from "../../index-D_76wh4w.js";
import { P as Oe } from "../../index-Dj1pom3_.js";
import { V as ie, R as ke } from "../../index-CbTU3cnP.js";
import { cn as q } from "../../utils/index.js";
import { closeToastVariants as Ve, toastVariants as Ke, viewportToastVariants as He } from "./Toast.variants.js";
import { X as We } from "../../x-DU-Zw-L_.js";
import { useTheme as Xe } from "../../contexts/theme.hook.js";
var Z = "ToastProvider", [ee, $e, Ue] = _e("Toast"), [ce, bt] = Ne("Toast", [Ue]), [Ye, $] = ce(Z), ue = (e) => {
const {
__scopeToast: r,
label: o = "Notification",
duration: t = 5e3,
swipeDirection: u = "right",
swipeThreshold: d = 50,
children: f
} = e, [m, v] = s.useState(null), [n, y] = s.useState(0), w = s.useRef(!1), S = s.useRef(!1);
return o.trim() || console.error(
`Invalid prop \`label\` supplied to \`${Z}\`. Expected non-empty \`string\`.`
), /* @__PURE__ */ c(ee.Provider, { scope: r, children: /* @__PURE__ */ c(
Ye,
{
scope: r,
label: o,
duration: t,
swipeDirection: u,
swipeThreshold: d,
toastCount: n,
viewport: m,
onViewportChange: v,
onToastAdd: s.useCallback(() => y((g) => g + 1), []),
onToastRemove: s.useCallback(() => y((g) => g - 1), []),
isFocusedToastEscapeKeyDownRef: w,
isClosePausedRef: S,
children: f
}
) });
};
ue.displayName = Z;
var le = "ToastViewport", Be = ["F8"], G = "toast.viewportPause", J = "toast.viewportResume", de = s.forwardRef(
(e, r) => {
const {
__scopeToast: o,
hotkey: t = Be,
label: u = "Notifications ({hotkey})",
...d
} = e, f = $(le, o), m = $e(o), v = s.useRef(null), n = s.useRef(null), y = s.useRef(null), w = s.useRef(null), S = ae(r, w, f.onViewportChange), g = t.join("+").replace(/Key/g, "").replace(/Digit/g, ""), R = f.toastCount > 0;
s.useEffect(() => {
const a = (h) => {
var T;
t.length !== 0 && t.every((E) => h[E] || h.code === E) && ((T = w.current) == null || T.focus());
};
return document.addEventListener("keydown", a), () => document.removeEventListener("keydown", a);
}, [t]), s.useEffect(() => {
const a = v.current, h = w.current;
if (R && a && h) {
const p = () => {
if (!f.isClosePausedRef.current) {
const P = new CustomEvent(G);
h.dispatchEvent(P), f.isClosePausedRef.current = !0;
}
}, T = () => {
if (f.isClosePausedRef.current) {
const P = new CustomEvent(J);
h.dispatchEvent(P), f.isClosePausedRef.current = !1;
}
}, E = (P) => {
!a.contains(P.relatedTarget) && T();
}, C = () => {
a.contains(document.activeElement) || T();
};
return a.addEventListener("focusin", p), a.addEventListener("focusout", E), a.addEventListener("pointermove", p), a.addEventListener("pointerleave", C), window.addEventListener("blur", p), window.addEventListener("focus", T), () => {
a.removeEventListener("focusin", p), a.removeEventListener("focusout", E), a.removeEventListener("pointermove", p), a.removeEventListener("pointerleave", C), window.removeEventListener("blur", p), window.removeEventListener("focus", T);
};
}
}, [R, f.isClosePausedRef]);
const l = s.useCallback(
({ tabbingDirection: a }) => {
const p = m().map((T) => {
const E = T.ref.current, C = [E, ...st(E)];
return a === "forwards" ? C : C.reverse();
});
return (a === "forwards" ? p.reverse() : p).flat();
},
[m]
);
return s.useEffect(() => {
const a = w.current;
if (a) {
const h = (p) => {
var C, P, N;
const T = p.altKey || p.ctrlKey || p.metaKey;
if (p.key === "Tab" && !T) {
const M = document.activeElement, F = p.shiftKey;
if (p.target === a && F) {
(C = n.current) == null || C.focus();
return;
}
const A = l({ tabbingDirection: F ? "backwards" : "forwards" }), V = A.findIndex((i) => i === M);
z(A.slice(V + 1)) ? p.preventDefault() : F ? (P = n.current) == null || P.focus() : (N = y.current) == null || N.focus();
}
};
return a.addEventListener("keydown", h), () => a.removeEventListener("keydown", h);
}
}, [m, l]), /* @__PURE__ */ D(
De,
{
ref: v,
role: "region",
"aria-label": u.replace("{hotkey}", g),
tabIndex: -1,
style: { pointerEvents: R ? void 0 : "none" },
children: [
R && /* @__PURE__ */ c(
Q,
{
ref: n,
onFocusFromOutsideViewport: () => {
const a = l({
tabbingDirection: "forwards"
});
z(a);
}
}
),
/* @__PURE__ */ c(ee.Slot, { scope: o, children: /* @__PURE__ */ c(L.ol, { tabIndex: -1, ...d, ref: S }) }),
R && /* @__PURE__ */ c(
Q,
{
ref: y,
onFocusFromOutsideViewport: () => {
const a = l({
tabbingDirection: "backwards"
});
z(a);
}
}
)
]
}
);
}
);
de.displayName = le;
var fe = "ToastFocusProxy", Q = s.forwardRef(
(e, r) => {
const { __scopeToast: o, onFocusFromOutsideViewport: t, ...u } = e, d = $(fe, o);
return /* @__PURE__ */ c(
ie,
{
"aria-hidden": !0,
tabIndex: 0,
...u,
ref: r,
style: { position: "fixed" },
onFocus: (f) => {
var n;
const m = f.relatedTarget;
!((n = d.viewport) != null && n.contains(m)) && t();
}
}
);
}
);
Q.displayName = fe;
var U = "Toast", je = "toast.swipeStart", qe = "toast.swipeMove", ze = "toast.swipeCancel", Ge = "toast.swipeEnd", pe = s.forwardRef(
(e, r) => {
const { forceMount: o, open: t, defaultOpen: u, onOpenChange: d, ...f } = e, [m = !0, v] = Ae({
prop: t,
defaultProp: u,
onChange: d
});
return /* @__PURE__ */ c(Oe, { present: o || m, children: /* @__PURE__ */ c(
Ze,
{
open: m,
...f,
ref: r,
onClose: () => v(!1),
onPause: X(e.onPause),
onResume: X(e.onResume),
onSwipeStart: b(e.onSwipeStart, (n) => {
n.currentTarget.setAttribute("data-swipe", "start");
}),
onSwipeMove: b(e.onSwipeMove, (n) => {
const { x: y, y: w } = n.detail.delta;
n.currentTarget.setAttribute("data-swipe", "move"), n.currentTarget.style.setProperty("--radix-toast-swipe-move-x", `${y}px`), n.currentTarget.style.setProperty("--radix-toast-swipe-move-y", `${w}px`);
}),
onSwipeCancel: b(e.onSwipeCancel, (n) => {
n.currentTarget.setAttribute("data-swipe", "cancel"), n.currentTarget.style.removeProperty("--radix-toast-swipe-move-x"), n.currentTarget.style.removeProperty("--radix-toast-swipe-move-y"), n.currentTarget.style.removeProperty("--radix-toast-swipe-end-x"), n.currentTarget.style.removeProperty("--radix-toast-swipe-end-y");
}),
onSwipeEnd: b(e.onSwipeEnd, (n) => {
const { x: y, y: w } = n.detail.delta;
n.currentTarget.setAttribute("data-swipe", "end"), n.currentTarget.style.removeProperty("--radix-toast-swipe-move-x"), n.currentTarget.style.removeProperty("--radix-toast-swipe-move-y"), n.currentTarget.style.setProperty("--radix-toast-swipe-end-x", `${y}px`), n.currentTarget.style.setProperty("--radix-toast-swipe-end-y", `${w}px`), v(!1);
})
}
) });
}
);
pe.displayName = U;
var [Je, Qe] = ce(U, {
onClose() {
}
}), Ze = s.forwardRef(
(e, r) => {
const {
__scopeToast: o,
type: t = "foreground",
duration: u,
open: d,
onClose: f,
onEscapeKeyDown: m,
onPause: v,
onResume: n,
onSwipeStart: y,
onSwipeMove: w,
onSwipeCancel: S,
onSwipeEnd: g,
...R
} = e, l = $(U, o), [a, h] = s.useState(null), p = ae(r, (i) => h(i)), T = s.useRef(null), E = s.useRef(null), C = u || l.duration, P = s.useRef(0), N = s.useRef(C), M = s.useRef(0), { onToastAdd: F, onToastRemove: Y } = l, _ = X(() => {
var x;
(a == null ? void 0 : a.contains(document.activeElement)) && ((x = l.viewport) == null || x.focus()), f();
}), A = s.useCallback(
(i) => {
!i || i === 1 / 0 || (window.clearTimeout(M.current), P.current = (/* @__PURE__ */ new Date()).getTime(), M.current = window.setTimeout(_, i));
},
[_]
);
s.useEffect(() => {
const i = l.viewport;
if (i) {
const x = () => {
A(N.current), n == null || n();
}, I = () => {
const O = (/* @__PURE__ */ new Date()).getTime() - P.current;
N.current = N.current - O, window.clearTimeout(M.current), v == null || v();
};
return i.addEventListener(G, I), i.addEventListener(J, x), () => {
i.removeEventListener(G, I), i.removeEventListener(J, x);
};
}
}, [l.viewport, C, v, n, A]), s.useEffect(() => {
d && !l.isClosePausedRef.current && A(C);
}, [d, C, l.isClosePausedRef, A]), s.useEffect(() => (F(), () => Y()), [F, Y]);
const V = s.useMemo(() => a ? Ce(a) : null, [a]);
return l.viewport ? /* @__PURE__ */ D(se, { children: [
V && /* @__PURE__ */ c(
et,
{
__scopeToast: o,
role: "status",
"aria-live": t === "foreground" ? "assertive" : "polite",
"aria-atomic": !0,
children: V
}
),
/* @__PURE__ */ c(Je, { scope: o, onClose: _, children: Se.createPortal(
/* @__PURE__ */ c(ee.ItemSlot, { scope: o, children: /* @__PURE__ */ c(
Le,
{
asChild: !0,
onEscapeKeyDown: b(m, () => {
l.isFocusedToastEscapeKeyDownRef.current || _(), l.isFocusedToastEscapeKeyDownRef.current = !1;
}),
children: /* @__PURE__ */ c(
L.li,
{
role: "status",
"aria-live": "off",
"aria-atomic": !0,
tabIndex: 0,
"data-state": d ? "open" : "closed",
"data-swipe-direction": l.swipeDirection,
...R,
ref: p,
style: { userSelect: "none", touchAction: "none", ...e.style },
onKeyDown: b(e.onKeyDown, (i) => {
i.key === "Escape" && (m == null || m(i.nativeEvent), i.nativeEvent.defaultPrevented || (l.isFocusedToastEscapeKeyDownRef.current = !0, _()));
}),
onPointerDown: b(e.onPointerDown, (i) => {
i.button === 0 && (T.current = { x: i.clientX, y: i.clientY });
}),
onPointerMove: b(e.onPointerMove, (i) => {
if (!T.current) return;
const x = i.clientX - T.current.x, I = i.clientY - T.current.y, O = !!E.current, k = ["left", "right"].includes(l.swipeDirection), K = ["left", "up"].includes(l.swipeDirection) ? Math.min : Math.max, Pe = k ? K(0, x) : 0, xe = k ? 0 : K(0, I), B = i.pointerType === "touch" ? 10 : 2, H = { x: Pe, y: xe }, te = { originalEvent: i, delta: H };
O ? (E.current = H, W(qe, w, te, {
discrete: !1
})) : ne(H, l.swipeDirection, B) ? (E.current = H, W(je, y, te, {
discrete: !1
}), i.target.setPointerCapture(i.pointerId)) : (Math.abs(x) > B || Math.abs(I) > B) && (T.current = null);
}),
onPointerUp: b(e.onPointerUp, (i) => {
const x = E.current, I = i.target;
if (I.hasPointerCapture(i.pointerId) && I.releasePointerCapture(i.pointerId), E.current = null, T.current = null, x) {
const O = i.currentTarget, k = { originalEvent: i, delta: x };
ne(x, l.swipeDirection, l.swipeThreshold) ? W(Ge, g, k, {
discrete: !0
}) : W(
ze,
S,
k,
{
discrete: !0
}
), O.addEventListener("click", (K) => K.preventDefault(), {
once: !0
});
}
})
}
)
}
) }),
l.viewport
) })
] }) : null;
}
), et = (e) => {
const { __scopeToast: r, children: o, ...t } = e, u = $(U, r), [d, f] = s.useState(!1), [m, v] = s.useState(!1);
return rt(() => f(!0)), s.useEffect(() => {
const n = window.setTimeout(() => v(!0), 1e3);
return () => window.clearTimeout(n);
}, []), m ? null : /* @__PURE__ */ c(Me, { asChild: !0, children: /* @__PURE__ */ c(ie, { ...t, children: d && /* @__PURE__ */ D(se, { children: [
u.label,
" ",
o
] }) }) });
}, tt = "ToastTitle", me = s.forwardRef(
(e, r) => {
const { __scopeToast: o, ...t } = e;
return /* @__PURE__ */ c(L.div, { ...t, ref: r });
}
);
me.displayName = tt;
var ot = "ToastDescription", Te = s.forwardRef(
(e, r) => {
const { __scopeToast: o, ...t } = e;
return /* @__PURE__ */ c(L.div, { ...t, ref: r });
}
);
Te.displayName = ot;
var ve = "ToastAction", we = s.forwardRef(
(e, r) => {
const { altText: o, ...t } = e;
return o.trim() ? /* @__PURE__ */ c(ye, { altText: o, asChild: !0, children: /* @__PURE__ */ c(he, { ...t, ref: r }) }) : (console.error(
`Invalid prop \`altText\` supplied to \`${ve}\`. Expected non-empty \`string\`.`
), null);
}
);
we.displayName = ve;
var Ee = "ToastClose", he = s.forwardRef(
(e, r) => {
const { __scopeToast: o, ...t } = e, u = Qe(Ee, o);
return /* @__PURE__ */ c(ye, { asChild: !0, children: /* @__PURE__ */ c(
L.button,
{
type: "button",
...t,
ref: r,
onClick: b(e.onClick, u.onClose)
}
) });
}
);
he.displayName = Ee;
var ye = s.forwardRef((e, r) => {
const { __scopeToast: o, altText: t, ...u } = e;
return /* @__PURE__ */ c(
L.div,
{
"data-radix-toast-announce-exclude": "",
"data-radix-toast-announce-alt": t || void 0,
...u,
ref: r
}
);
});
function Ce(e) {
const r = [];
return Array.from(e.childNodes).forEach((t) => {
if (t.nodeType === t.TEXT_NODE && t.textContent && r.push(t.textContent), nt(t)) {
const u = t.ariaHidden || t.hidden || t.style.display === "none", d = t.dataset.radixToastAnnounceExclude === "";
if (!u)
if (d) {
const f = t.dataset.radixToastAnnounceAlt;
f && r.push(f);
} else
r.push(...Ce(t));
}
}), r;
}
function W(e, r, o, { discrete: t }) {
const u = o.originalEvent.currentTarget, d = new CustomEvent(e, { bubbles: !0, cancelable: !0, detail: o });
r && u.addEventListener(e, r, { once: !0 }), t ? Ie(u, d) : u.dispatchEvent(d);
}
var ne = (e, r, o = 0) => {
const t = Math.abs(e.x), u = Math.abs(e.y), d = t > u;
return r === "left" || r === "right" ? d && t > o : !d && u > o;
};
function rt(e = () => {
}) {
const r = X(e);
Fe(() => {
let o = 0, t = 0;
return o = window.requestAnimationFrame(() => t = window.requestAnimationFrame(r)), () => {
window.cancelAnimationFrame(o), window.cancelAnimationFrame(t);
};
}, [r]);
}
function nt(e) {
return e.nodeType === e.ELEMENT_NODE;
}
function st(e) {
const r = [], o = document.createTreeWalker(e, NodeFilter.SHOW_ELEMENT, {
acceptNode: (t) => {
const u = t.tagName === "INPUT" && t.type === "hidden";
return t.disabled || t.hidden || u ? NodeFilter.FILTER_SKIP : t.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
}
});
for (; o.nextNode(); ) r.push(o.currentNode);
return r;
}
function z(e) {
const r = document.activeElement;
return e.some((o) => o === r ? !0 : (o.focus(), document.activeElement !== r));
}
var at = ue, it = de, ct = pe, ut = me, lt = Te, dt = we;
const gt = ({
title: e,
duration: r = 5e3,
titleClassName: o,
descriptionClassName: t,
description: u,
children: d,
theme: f,
showCloseButton: m = !0,
closeButtonClassName: v,
className: n,
open: y = !1,
setOpen: w
}) => {
const S = Re(0), { theme: g } = Xe(), R = f ?? g;
be(() => () => clearTimeout(S.current), []);
const l = oe(() => re(e) ? /* @__PURE__ */ c(j, { className: o, children: e }) : e, [e, o]), a = oe(() => re(u) ? /* @__PURE__ */ c(j, { className: t, children: u }) : u, [u, t]), h = ge(() => {
w(!1), S.current = window.setTimeout(() => w(!0), 100);
}, [w]);
return /* @__PURE__ */ D(at, { swipeDirection: "right", duration: r, children: [
/* @__PURE__ */ c(j, { onClick: h, children: d }),
/* @__PURE__ */ D(
ct,
{
className: q(Ke({ theme: R, className: n })),
open: y,
onOpenChange: w,
children: [
/* @__PURE__ */ c(ut, { asChild: !0, className: o, children: l }),
a && /* @__PURE__ */ c(lt, { asChild: !0, children: a }),
m && /* @__PURE__ */ c(dt, { asChild: !0, altText: "Close the toast", children: /* @__PURE__ */ D("button", { type: "button", className: "absolute right-1.5 top-1.5", children: [
/* @__PURE__ */ c(
We,
{
className: q(
Ve({
theme: R,
className: v
})
)
}
),
/* @__PURE__ */ c(ke, { children: "Close toast" })
] }) })
]
}
),
/* @__PURE__ */ c(
it,
{
className: q(He({ theme: R }))
}
)
] });
};
export {
gt as Toast
};