react-custom-tours
Version:
A library with tips that you can attach to blocks on your sites so that users can more easily understand how to use your site
264 lines (263 loc) • 11 kB
JavaScript
import { jsxs as v, jsx as n, Fragment as T } from "react/jsx-runtime";
import { useMemo as M, useEffect as m, useTransition as j, useState as k, useRef as E, createContext as R, useContext as W } from "react";
import H from "./shared/ui/spinner/index.js";
import { createPortal as B } from "react-dom";
import './assets/useTips.css';const S = "_wrapper_16fri_1", $ = "_dark_16fri_17", I = "_relative_16fri_26", O = "_block_16fri_32", x = {
wrapper: S,
dark: $,
relative: I,
block: O
}, A = "_wrapper_jfdv5_1", z = "_header_jfdv5_19", D = "_leftHeader_jfdv5_24", V = "_count_jfdv5_29", Z = "_loader_jfdv5_35", F = "_close_jfdv5_39", K = "_textWrapper_jfdv5_56", U = "_footer_jfdv5_69", C = {
wrapper: A,
header: z,
leftHeader: D,
count: V,
loader: Z,
close: F,
textWrapper: K,
footer: U
}, Y = (t) => {
const { item: o, prevItem: i, nextItem: r, onPrev: d, onNext: u, onClose: f, itemRect: e, countItems: p, itemIdx: l, isLoading: a } = t, { isHiddenClose: c, highlightPadding: w } = _(), h = 10, g = {}, b = M(() => c ? p - 1 === l : !0, [l, p, c]), L = w ?? 0, s = e.left + e.width / 2 > window.innerWidth / 2 ? "right" : "left";
return g.maxWidth = (o == null ? void 0 : o.maxWidth) || e.right, e.height > window.innerHeight - 200 ? (g.top = h, g[s] = h) : (e.top + e.height / 2 > window.innerHeight / 2 ? g.bottom = e.height + h + L : g.top = e.height + h + L, g[s] = 0), /* @__PURE__ */ v("div", { style: g, className: C.wrapper, children: [
/* @__PURE__ */ v("header", { className: C.header, children: [
/* @__PURE__ */ v("div", { className: C.leftHeader, children: [
/* @__PURE__ */ v(
"span",
{
className: C.count,
"data-testid": "tooltip-count",
title: `Tour step counter (${l + 1}/${p})`,
children: [
l + 1,
" / ",
p
]
}
),
/* @__PURE__ */ n("div", { className: C.loader, children: a && /* @__PURE__ */ n(H, {}) })
] }),
b && /* @__PURE__ */ n(
"button",
{
className: C.close,
onClick: f,
type: "button",
"data-testid": "tooltip-close",
title: "Close tour",
children: /* @__PURE__ */ n("svg", { width: "8", height: "8", viewBox: "0 0 8 8", children: /* @__PURE__ */ n("path", { d: "M7.8228 0.183264C7.76667 0.127012 7.69999 0.0823841 7.62658 0.0519343C7.55318 0.0214845 7.47448 0.00581086 7.39501 0.00581086C7.31554 0.00581086 7.23685 0.0214845 7.16345 0.0519343C7.09004 0.0823841 7.02336 0.127012 6.96722 0.183264L4 3.14442L1.03278 0.177196C0.976598 0.121018 0.909905 0.0764551 0.836505 0.0460517C0.763104 0.0156483 0.684434 5.91933e-10 0.604986 0C0.525539 -5.91934e-10 0.446868 0.0156483 0.373468 0.0460517C0.300068 0.0764551 0.233374 0.121018 0.177196 0.177196C0.121018 0.233374 0.0764551 0.300068 0.0460517 0.373468C0.0156483 0.446868 -5.91933e-10 0.525539 0 0.604986C5.91934e-10 0.684434 0.0156483 0.763104 0.0460517 0.836505C0.0764551 0.909905 0.121018 0.976598 0.177196 1.03278L3.14442 4L0.177196 6.96722C0.121018 7.0234 0.0764551 7.0901 0.0460517 7.1635C0.0156483 7.2369 0 7.31557 0 7.39501C0 7.47446 0.0156483 7.55313 0.0460517 7.62653C0.0764551 7.69993 0.121018 7.76663 0.177196 7.8228C0.233374 7.87898 0.300068 7.92355 0.373468 7.95395C0.446868 7.98435 0.525539 8 0.604986 8C0.684434 8 0.763104 7.98435 0.836505 7.95395C0.909905 7.92355 0.976598 7.87898 1.03278 7.8228L4 4.85558L6.96722 7.8228C7.0234 7.87898 7.0901 7.92355 7.1635 7.95395C7.2369 7.98435 7.31557 8 7.39501 8C7.47446 8 7.55313 7.98435 7.62653 7.95395C7.69993 7.92355 7.76663 7.87898 7.8228 7.8228C7.87898 7.76663 7.92355 7.69993 7.95395 7.62653C7.98435 7.55313 8 7.47446 8 7.39501C8 7.31557 7.98435 7.2369 7.95395 7.1635C7.92355 7.0901 7.87898 7.0234 7.8228 6.96722L4.85558 4L7.8228 1.03278C8.05339 0.802195 8.05339 0.413846 7.8228 0.183264Z" }) })
}
)
] }),
/* @__PURE__ */ v("div", { className: C.textWrapper, children: [
(o == null ? void 0 : o.title) && /* @__PURE__ */ n("h4", { "data-testid": "tooltip-title", title: o.title, children: o.title }),
/* @__PURE__ */ n("p", { "data-testid": "tooltip-text", title: o.text, children: o.text })
] }),
/* @__PURE__ */ v("footer", { className: C.footer, children: [
/* @__PURE__ */ n(
"button",
{
disabled: !i || a,
onClick: d,
type: "button",
"data-testid": "tooltip-prev",
title: "Prev tour step",
children: /* @__PURE__ */ n("svg", { width: "10", height: "8", viewBox: "0 0 10 8", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ n(
"path",
{
d: "M8.42358 3.63123H0.923584M0.923584 3.63123L3.92358 0.631226M0.923584 3.63123L3.92358 6.63123",
stroke: "var(--rct-dark)",
strokeWidth: "1.25",
strokeLinecap: "round",
strokeLinejoin: "round"
}
) })
}
),
/* @__PURE__ */ n(
"button",
{
title: r ? "Next tour step" : "Close tour",
disabled: a,
onClick: r ? u : f,
type: "button",
"data-testid": "tooltip-next",
children: r ? /* @__PURE__ */ n("svg", { width: "10", height: "8", viewBox: "0 0 10 8", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ n(
"path",
{
d: "M1.0271 3.63123H8.5271M8.5271 3.63123L5.5271 0.631226M8.5271 3.63123L5.5271 6.63123",
stroke: "white",
strokeWidth: "1.25",
strokeLinecap: "round",
strokeLinejoin: "round"
}
) }) : /* @__PURE__ */ n(
"svg",
{
width: "15",
height: "8",
viewBox: "0 0 15 8",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
"data-testid": "tooltip-end",
children: /* @__PURE__ */ n(
"path",
{
d: "M4.9413 3.63123L7.9413 6.63123L13.9413 0.631226M1.40576 3.63123L4.40576 6.63123M8.12328 2.93456L10.4058 0.631226",
stroke: "white",
strokeWidth: "1.25",
strokeLinecap: "round",
strokeLinejoin: "round"
}
)
}
)
}
)
] })
] });
}, q = (t) => {
const { setIsShow: o } = _();
m(() => {
if (!t) return;
const i = (r) => {
r.code === "Escape" && o(!1);
};
return window.addEventListener("keydown", i), () => window.removeEventListener("keydown", i);
}, [t]);
};
function G(t) {
return "--rct-" + t.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
}
const J = (t) => {
const { customColors: o, theme: i } = _();
m(() => {
o && Object.entries(o[i || "light"]).forEach(([r, d]) => {
var u;
(u = t == null ? void 0 : t.current) == null || u.style.setProperty(G(r), d);
});
}, [o, t, i]);
}, Q = ({ data: t }) => {
var L;
const { setIsShow: o, theme: i, escapeToClose: r, highlightPadding: d } = _(), [u, f] = j(), [e, p] = k(t[0]), [l, a] = k(e == null ? void 0 : e.node.getBoundingClientRect()), c = E(null), w = t[t.indexOf(e) + 1], h = t[t.indexOf(e) - 1], g = () => {
f(() => {
p(w), a(w == null ? void 0 : w.node.getBoundingClientRect());
});
}, b = () => {
f(() => {
p(h), a(h == null ? void 0 : h.node.getBoundingClientRect());
});
};
return m(() => {
const s = () => {
a(e == null ? void 0 : e.node.getBoundingClientRect());
};
return window.addEventListener("resize", s), window.addEventListener("scroll", s), () => {
window.removeEventListener("resize", s), window.removeEventListener("scroll", s);
};
}, [e]), m(() => {
var s;
(s = e == null ? void 0 : e.node) == null || s.scrollIntoView({
behavior: "smooth",
block: l.height > window.innerHeight - 200 ? "start" : "center",
inline: "nearest"
});
}, [e]), m(() => {
var s;
p(t[0]), a((s = t[0]) == null ? void 0 : s.node.getBoundingClientRect());
}, [t]), q(!!r), J(c), m(() => {
const s = c == null ? void 0 : c.current;
if (!s) return;
const y = (P) => {
P.stopPropagation();
};
return s.addEventListener("mousedown", y), () => {
s.removeEventListener("mousedown", y);
};
}, [c == null ? void 0 : c.current]), B(
/* @__PURE__ */ n(
"div",
{
className: `${x.wrapper} ${i === "dark" ? x.dark : ""}`,
ref: c,
"data-testid": "tips-active-layout",
children: /* @__PURE__ */ n("div", { className: x.relative, children: /* @__PURE__ */ n(
"div",
{
className: x.block,
style: {
width: l.width + (d || 0),
height: l.height + (d || 0),
left: l.left - (d ? d / 2 : 0),
top: l.top - (d ? d / 2 : 0),
borderRadius: (L = e == null ? void 0 : e.node) == null ? void 0 : L.style.borderRadius
},
children: /* @__PURE__ */ n(
Y,
{
countItems: t.length,
itemIdx: t.indexOf(e),
item: e,
itemRect: l,
nextItem: w,
prevItem: h,
onNext: g,
onPrev: b,
onClose: () => o(!1),
isLoading: u
}
)
}
) })
}
),
document.body
);
}, X = ({ children: t }) => {
const { data: o, isShow: i } = _();
return /* @__PURE__ */ v(T, { children: [
/* @__PURE__ */ n(ee, { data: o, isShow: i }),
t
] });
}, ee = ({ isShow: t, data: o }) => {
if (!t || !o) return;
const i = o.filter((r) => r == null ? void 0 : r.node);
if (i.length === 0)
throw new Error(
"You are trying to show a tour, but the DOM nodes for this tour are not found in the DOM Tree, please check it!"
);
return /* @__PURE__ */ n(Q, { data: i.sort((r, d) => r.idx - d.idx) });
}, N = R({}), ie = (t) => {
const { children: o, tips: i, theme: r, customColors: d, escapeToClose: u, isHiddenClose: f, highlightPadding: e } = t, [p, l] = k(null), [a, c] = k(!1);
m(() => {
a && l(
i.map((h) => ({
...h,
node: document.getElementById(h.nodeId)
}))
);
}, [i, a]);
const w = M(
() => ({
data: p,
isShow: a,
theme: r,
escapeToClose: u,
customColors: d,
isHiddenClose: f,
highlightPadding: e,
setIsShow: c
}),
[p, a, r, u, c, d, f, e]
);
return /* @__PURE__ */ n(N.Provider, { value: w, children: /* @__PURE__ */ n(X, { children: o }) });
}, _ = () => W(N);
export {
ie as T,
Y as a,
q as b,
J as c,
Q as d,
X as e,
N as f,
_ as u
};