UNPKG

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

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