UNPKG

@gfazioli/mantine-onboarding-tour

Version:

A Mantine 9 onboarding tour component with focus-reveal overlays, cutout highlights, step-by-step popover navigation, and compound components for guided user experiences.

73 lines (69 loc) 2.22 kB
'use client'; 'use strict'; var React = require('react'); function buildCutoutPath(vw, vh, rect, padding, radius) { const x = rect.x - padding; const y = rect.y - padding; const w = rect.width + padding * 2; const h = rect.height + padding * 2; const r = Math.min(radius, w / 2, h / 2); return [ `M0,0 H${vw} V${vh} H0 Z`, `M${x + r},${y}`, `H${x + w - r}`, `Q${x + w},${y} ${x + w},${y + r}`, `V${y + h - r}`, `Q${x + w},${y + h} ${x + w - r},${y + h}`, `H${x + r}`, `Q${x},${y + h} ${x},${y + h - r}`, `V${y + r}`, `Q${x},${y} ${x + r},${y}`, `Z` ].join(" "); } function useCutoutRect(active, stepId) { const [state, setState] = React.useState(null); const measure = React.useCallback(() => { const el = document.querySelector("[data-onboarding-tour-focus-reveal-focused]"); if (el) { const r = el.getBoundingClientRect(); const vw = window.innerWidth; const vh = window.innerHeight; setState((prev) => { if (prev && prev.rect.x === r.x && prev.rect.y === r.y && prev.rect.width === r.width && prev.rect.height === r.height && prev.vw === vw && prev.vh === vh) { return prev; } return { rect: { x: r.x, y: r.y, width: r.width, height: r.height }, vw, vh }; }); } else { setState(null); } }, []); React.useEffect(() => { if (!active) { setState(null); return void 0; } let rafId = 0; const onUpdate = () => { cancelAnimationFrame(rafId); rafId = requestAnimationFrame(measure); }; const poll = setInterval(onUpdate, 50); const stopPoll = setTimeout(() => clearInterval(poll), 1500); window.addEventListener("scroll", onUpdate, true); window.addEventListener("resize", onUpdate); onUpdate(); return () => { cancelAnimationFrame(rafId); clearInterval(poll); clearTimeout(stopPoll); window.removeEventListener("scroll", onUpdate, true); window.removeEventListener("resize", onUpdate); }; }, [active, stepId, measure]); return state; } exports.buildCutoutPath = buildCutoutPath; exports.useCutoutRect = useCutoutRect; //# sourceMappingURL=use-cutout-rect.cjs.map