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
225 lines (224 loc) • 10.5 kB
JavaScript
import { jsxs as x, jsx as d, Fragment as R } from "react/jsx-runtime";
import { useRef as H, useMemo as I, useEffect as v, useState as L, createContext as $, useContext as z } from "react";
import { mockDomRect as O } from "./shared/mock-data/index.js";
import A from "./shared/ui/spinner/index.js";
import { getRectById as k } from "./shared/utils/getRectById.js";
import { createPortal as D } from "react-dom";
import './assets/useTips.css';const V = "_wrapper_2z7aw_3", Z = "_dark_2z7aw_17", F = "_relative_2z7aw_22", K = "_block_2z7aw_28", P = {
wrapper: V,
dark: Z,
relative: F,
block: K
}, U = "_wrapper_1hvjj_1", Y = "_header_1hvjj_17", q = "_leftHeader_1hvjj_22", G = "_count_1hvjj_27", J = "_close_1hvjj_34", Q = "_textWrapper_1hvjj_50", X = "_footer_1hvjj_62", m = {
wrapper: U,
header: Y,
leftHeader: q,
count: G,
close: J,
textWrapper: Q,
footer: X
}, tt = (o) => {
var T;
const { item: n, prevItem: i, nextItem: r, itemRect: s, countItems: t, itemIdx: p, isLoading: c, onPrev: w, onNext: a, onClose: f } = o, { isHiddenClose: h, highlightPadding: C } = y(), u = 10, g = {}, b = `${p + 1} / ${t}`, _ = H(null), j = I(() => h ? t - 1 === p : !0, [p, t, h]), e = ((T = _ == null ? void 0 : _.current) == null ? void 0 : T.getBoundingClientRect()) || O, l = (e == null ? void 0 : e.width) || 0, E = C ?? 0, S = window.innerWidth - s.right, W = s.left + s.width / 2 > window.innerWidth / 2 ? "right" : "left", B = W === "left" ? s.left : S, N = l + B > window.innerWidth ? B * -1 + 8 : 0;
return g.maxWidth = (n == null ? void 0 : n.maxWidth) || s.right, s.height > window.innerHeight - ((e == null ? void 0 : e.height) || 200) ? (g.top = u, g[W] = N || u) : (s.top + s.height / 2 > window.innerHeight / 2 ? g.bottom = s.height + u + E : g.top = s.height + u + E, g[W] = N), /* @__PURE__ */ x("div", { ref: _, style: g, className: m.wrapper, children: [
/* @__PURE__ */ x("header", { className: m.header, children: [
/* @__PURE__ */ x("div", { className: m.leftHeader, children: [
/* @__PURE__ */ d("span", { className: m.count, "data-testid": "tooltip-count", title: `Номер подсказки - (${b})`, children: b }),
c && /* @__PURE__ */ d(A, {})
] }),
j && /* @__PURE__ */ d(
"button",
{
className: m.close,
onClick: f,
type: "button",
"data-testid": "tooltip-close",
title: "Закрыть подсказки",
children: /* @__PURE__ */ d("svg", { width: "8", height: "8", viewBox: "0 0 8 8", children: /* @__PURE__ */ d("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__ */ x("div", { className: m.textWrapper, children: [
(n == null ? void 0 : n.title) && /* @__PURE__ */ d("h4", { "data-testid": "tooltip-title", title: n.title, children: n.title }),
/* @__PURE__ */ d("p", { "data-testid": "tooltip-text", title: n.text, children: n.text })
] }),
/* @__PURE__ */ x("footer", { className: m.footer, children: [
i && /* @__PURE__ */ d(
"button",
{
disabled: !i || c,
onClick: w,
type: "button",
"data-testid": "tooltip-prev",
title: "Предыдущая подсказка",
children: "Назад"
}
),
/* @__PURE__ */ x(
"button",
{
disabled: c,
title: r ? "Следующая подсказка" : "Закрыть",
onClick: r ? a : f,
type: "button",
"data-testid": "tooltip-next",
children: [
r ? "Далее" : "Все понятно",
r && /* @__PURE__ */ d("svg", { width: "10", height: "8", viewBox: "0 0 10 8", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ d(
"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"
}
) })
]
}
)
] })
] });
}, et = (o) => {
const { setIsShow: n } = y();
v(() => {
if (!o) return;
const i = (r) => {
r.code === "Escape" && n(!1);
};
return window.addEventListener("keydown", i), () => window.removeEventListener("keydown", i);
}, [o]);
};
function ot(o) {
return "--rct-" + o.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
}
const nt = (o) => {
const { customColors: n, theme: i } = y();
v(() => {
n && Object.entries(n[i || "light"]).forEach(([r, s]) => {
var t;
(t = o == null ? void 0 : o.current) == null || t.style.setProperty(ot(r), s);
});
}, [n, o, i]);
}, st = ({ data: o }) => {
var j;
const { setIsShow: n, theme: i, escapeToClose: r, highlightPadding: s } = y(), [t, p] = L(o[0]), [c, w] = L(k(t.nodeId)), a = H(null), [f, h] = L(!1), C = o[o.indexOf(t) + 1], u = o[o.indexOf(t) - 1], g = async () => {
var e, l;
(e = t == null ? void 0 : t.onClick) != null && e.nextButton && (h(!0), await ((l = t == null ? void 0 : t.onClick) == null ? void 0 : l.nextButton()), h(!1)), p(C), w(k(C.nodeId));
}, b = async () => {
var e, l;
(e = t == null ? void 0 : t.onClick) != null && e.prevButton && (h(!0), await ((l = t == null ? void 0 : t.onClick) == null ? void 0 : l.prevButton()), h(!1)), p(u), w(k(u.nodeId));
}, _ = async () => {
var e, l;
(e = t == null ? void 0 : t.onClick) != null && e.closeButton && (h(!0), await ((l = t == null ? void 0 : t.onClick) == null ? void 0 : l.closeButton()), h(!1)), n(!1);
};
return et(!!r), nt(a), v(() => {
const e = () => {
w(k(t.nodeId));
};
return window.addEventListener("resize", e), window.addEventListener("scroll", e), () => {
window.removeEventListener("resize", e), window.removeEventListener("scroll", e);
};
}, [t]), v(() => {
var e;
(e = t == null ? void 0 : t.node) == null || e.scrollIntoView({
behavior: "smooth",
block: c.height > window.innerHeight - 200 ? "start" : "center",
inline: "nearest"
});
}, [t]), v(() => {
var e;
p(o[0]), w(k((e = o[0]) == null ? void 0 : e.nodeId));
}, [o]), v(() => {
const e = a == null ? void 0 : a.current;
if (!e) return;
const l = (E) => {
E.stopPropagation();
};
return e.addEventListener("mousedown", l), () => {
e.removeEventListener("mousedown", l);
};
}, [a == null ? void 0 : a.current]), D(
/* @__PURE__ */ d(
"div",
{
className: `${P.wrapper} ${i === "dark" ? P.dark : ""}`,
ref: a,
"data-testid": "tips-active-layout",
children: /* @__PURE__ */ d("div", { className: P.relative, children: /* @__PURE__ */ d(
"div",
{
className: P.block,
style: {
width: c.width + (s || 0),
height: c.height + (s || 0),
left: c.left - (s ? s / 2 : 0),
top: c.top - (s ? s / 2 : 0),
borderRadius: (j = t == null ? void 0 : t.node) == null ? void 0 : j.style.borderRadius
},
children: /* @__PURE__ */ d(
tt,
{
isLoading: f,
countItems: o.length,
itemIdx: o.indexOf(t),
item: t,
itemRect: c,
nextItem: C,
prevItem: u,
onNext: g,
onPrev: b,
onClose: _
}
)
}
) })
}
),
document.body
);
}, rt = "You are trying to show a tour, but the DOM nodes for this tour are not found in the DOM Tree, please check it!", it = ({ children: o }) => {
const { data: n, isShow: i } = y();
return /* @__PURE__ */ x(R, { children: [
/* @__PURE__ */ d(dt, { data: n, isShow: i }),
o
] });
}, dt = ({ isShow: o, data: n }) => {
if (!o || !n) return null;
const i = n.filter((r) => r == null ? void 0 : r.node).sort((r, s) => r.idx - s.idx);
return i.length === 0 ? (console.warn(rt), null) : /* @__PURE__ */ d(st, { data: i });
}, M = $({}), wt = (o) => {
const { children: n, tips: i, theme: r, customColors: s, escapeToClose: t, isHiddenClose: p, highlightPadding: c } = o, [w, a] = L(null), [f, h] = L(!1);
v(() => {
f && a(
i.map((u) => ({
...u,
node: document.getElementById(u.nodeId)
}))
);
}, [i, f]);
const C = I(
() => ({
data: w,
isShow: f,
theme: r,
escapeToClose: t,
customColors: s,
isHiddenClose: p,
highlightPadding: c,
setIsShow: h
}),
[w, f, r, t, h, s, p, c]
);
return /* @__PURE__ */ d(M.Provider, { value: C, children: /* @__PURE__ */ d(it, { children: n }) });
}, y = () => z(M);
export {
wt as T,
tt as a,
et as b,
nt as c,
st as d,
it as e,
M as f,
y as u
};