@elogroup-sereduc/portal-aluno-tour 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Tour.d.ts +6 -0
- package/dist/components/Tour.d.ts.map +1 -0
- package/dist/components/Tour.js +178 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/types/index.d.ts +92 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/package.json +1 -1
- package/src/components/Tour.tsx +36 -9
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { TourProps } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Componente de tour guiado customizado usando HeroUI
|
|
4
|
+
*/
|
|
5
|
+
export declare function Tour({ enabled, steps, initialStep, options, onExit, onComplete, }: TourProps): import("react/jsx-runtime").JSX.Element | null;
|
|
6
|
+
//# sourceMappingURL=Tour.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tour.d.ts","sourceRoot":"","sources":["../../src/components/Tour.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAY,MAAM,UAAU,CAAC;AAG/C;;GAEG;AACH,wBAAgB,IAAI,CAAC,EACnB,OAAO,EACP,KAAK,EACL,WAAe,EACf,OAAY,EACZ,MAAM,EACN,UAAU,GACX,EAAE,SAAS,kDA4UX"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState, useCallback, useRef } from "react";
|
|
3
|
+
import { Button } from "@heroui/button";
|
|
4
|
+
import { HiXMark, HiChevronLeft, HiChevronRight } from "react-icons/hi2";
|
|
5
|
+
/**
|
|
6
|
+
* Componente de tour guiado customizado usando HeroUI
|
|
7
|
+
*/
|
|
8
|
+
export function Tour({ enabled, steps, initialStep = 0, options = {}, onExit, onComplete, }) {
|
|
9
|
+
const [currentStep, setCurrentStep] = useState(initialStep);
|
|
10
|
+
const [highlightedElement, setHighlightedElement] = useState(null);
|
|
11
|
+
const [tooltipPosition, setTooltipPosition] = useState(null);
|
|
12
|
+
const overlayRef = useRef(null);
|
|
13
|
+
const tooltipRef = useRef(null);
|
|
14
|
+
const { nextLabel = "Próximo", prevLabel = "Anterior", skipLabel = "Pular", doneLabel = "Concluir", showProgress = true, showBullets = true, exitOnOverlayClick = false, exitOnEsc = true, } = options;
|
|
15
|
+
// Calcula a posição da tooltip baseado no elemento destacado
|
|
16
|
+
const calculateTooltipPosition = useCallback((element, position = "bottom") => {
|
|
17
|
+
const rect = element.getBoundingClientRect();
|
|
18
|
+
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
19
|
+
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
|
|
20
|
+
let top = 0;
|
|
21
|
+
let left = 0;
|
|
22
|
+
switch (position) {
|
|
23
|
+
case "top":
|
|
24
|
+
top = rect.top + scrollTop - 10;
|
|
25
|
+
left = rect.left + scrollLeft + rect.width / 2;
|
|
26
|
+
break;
|
|
27
|
+
case "bottom":
|
|
28
|
+
top = rect.bottom + scrollTop + 10;
|
|
29
|
+
left = rect.left + scrollLeft + rect.width / 2;
|
|
30
|
+
break;
|
|
31
|
+
case "left":
|
|
32
|
+
top = rect.top + scrollTop + rect.height / 2;
|
|
33
|
+
left = rect.left + scrollLeft - 10;
|
|
34
|
+
break;
|
|
35
|
+
case "right":
|
|
36
|
+
top = rect.top + scrollTop + rect.height / 2;
|
|
37
|
+
left = rect.right + scrollLeft + 10;
|
|
38
|
+
break;
|
|
39
|
+
default:
|
|
40
|
+
top = rect.bottom + scrollTop + 10;
|
|
41
|
+
left = rect.left + scrollLeft + rect.width / 2;
|
|
42
|
+
}
|
|
43
|
+
return { top, left };
|
|
44
|
+
}, []);
|
|
45
|
+
// Destaca o elemento atual
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (!enabled || currentStep < 0 || currentStep >= steps.length) {
|
|
48
|
+
setHighlightedElement(null);
|
|
49
|
+
setTooltipPosition(null);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const step = steps[currentStep];
|
|
53
|
+
const element = document.querySelector(step.element);
|
|
54
|
+
if (!element) {
|
|
55
|
+
console.warn(`Elemento não encontrado: ${step.element}`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
setHighlightedElement(element);
|
|
59
|
+
// Scroll para o elemento
|
|
60
|
+
element.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
61
|
+
// Calcula posição da tooltip após um pequeno delay para garantir que o scroll terminou
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
const position = calculateTooltipPosition(element, step.position);
|
|
64
|
+
setTooltipPosition(position);
|
|
65
|
+
}, 300);
|
|
66
|
+
}, [enabled, currentStep, steps, calculateTooltipPosition]);
|
|
67
|
+
// Adiciona overlay e highlight ao elemento
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (!highlightedElement) {
|
|
70
|
+
// Remove highlights anteriores
|
|
71
|
+
document.querySelectorAll(".tour-highlight").forEach((el) => {
|
|
72
|
+
el.classList.remove("tour-highlight");
|
|
73
|
+
});
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
// Adiciona classe de highlight
|
|
77
|
+
highlightedElement.classList.add("tour-highlight");
|
|
78
|
+
return () => {
|
|
79
|
+
highlightedElement.classList.remove("tour-highlight");
|
|
80
|
+
};
|
|
81
|
+
}, [highlightedElement]);
|
|
82
|
+
// Handler de teclado (ESC)
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (!enabled || !exitOnEsc)
|
|
85
|
+
return;
|
|
86
|
+
const handleKeyDown = (e) => {
|
|
87
|
+
if (e.key === "Escape") {
|
|
88
|
+
handleExit();
|
|
89
|
+
}
|
|
90
|
+
else if (e.key === "ArrowRight") {
|
|
91
|
+
handleNext();
|
|
92
|
+
}
|
|
93
|
+
else if (e.key === "ArrowLeft") {
|
|
94
|
+
handlePrev();
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
98
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
99
|
+
}, [enabled, exitOnEsc, currentStep, steps.length]);
|
|
100
|
+
const handleNext = useCallback(() => {
|
|
101
|
+
if (currentStep < steps.length - 1) {
|
|
102
|
+
setCurrentStep(currentStep + 1);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
handleComplete();
|
|
106
|
+
}
|
|
107
|
+
}, [currentStep, steps.length]);
|
|
108
|
+
const handlePrev = useCallback(() => {
|
|
109
|
+
if (currentStep > 0) {
|
|
110
|
+
setCurrentStep(currentStep - 1);
|
|
111
|
+
}
|
|
112
|
+
}, [currentStep]);
|
|
113
|
+
const handleSkip = useCallback(() => {
|
|
114
|
+
handleExit();
|
|
115
|
+
}, []);
|
|
116
|
+
const handleComplete = useCallback(() => {
|
|
117
|
+
onComplete?.();
|
|
118
|
+
handleExit();
|
|
119
|
+
}, [onComplete]);
|
|
120
|
+
const handleExit = useCallback(() => {
|
|
121
|
+
setCurrentStep(initialStep);
|
|
122
|
+
setHighlightedElement(null);
|
|
123
|
+
setTooltipPosition(null);
|
|
124
|
+
onExit?.();
|
|
125
|
+
}, [initialStep, onExit]);
|
|
126
|
+
const handleOverlayClick = useCallback((e) => {
|
|
127
|
+
if (exitOnOverlayClick && e.target === overlayRef.current) {
|
|
128
|
+
handleExit();
|
|
129
|
+
}
|
|
130
|
+
}, [exitOnOverlayClick, handleExit]);
|
|
131
|
+
if (!enabled) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
const currentStepData = steps[currentStep];
|
|
135
|
+
const isFirstStep = currentStep === 0;
|
|
136
|
+
const isLastStep = currentStep === steps.length - 1;
|
|
137
|
+
const progress = ((currentStep + 1) / steps.length) * 100;
|
|
138
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { ref: overlayRef, className: "fixed inset-0 bg-black/60 z-[9998]", onClick: handleOverlayClick, style: { pointerEvents: exitOnOverlayClick ? "auto" : "none" } }), tooltipPosition && currentStepData && highlightedElement && (_jsxs("div", { ref: tooltipRef, className: "fixed z-[9999] max-w-sm", style: {
|
|
139
|
+
top: currentStepData.position === "bottom" ? `${tooltipPosition.top}px` : undefined,
|
|
140
|
+
bottom: currentStepData.position === "top" ? `${window.innerHeight - tooltipPosition.top}px` : undefined,
|
|
141
|
+
left: currentStepData.position === "left" || currentStepData.position === "right"
|
|
142
|
+
? `${tooltipPosition.left}px`
|
|
143
|
+
: `${tooltipPosition.left}px`,
|
|
144
|
+
transform: currentStepData.position === "left" || currentStepData.position === "right"
|
|
145
|
+
? "translate(0, -50%)"
|
|
146
|
+
: "translate(-50%, 0)",
|
|
147
|
+
}, children: [_jsxs("div", { className: "bg-white rounded-lg shadow-xl p-6 relative", children: [_jsx("button", { onClick: handleExit, className: "absolute top-2 right-2 p-1 rounded-full hover:bg-gray-100 transition-colors", "aria-label": "Fechar tour", children: _jsx(HiXMark, { className: "w-5 h-5 text-gray-500" }) }), currentStepData.title && (_jsx("h3", { className: "text-lg font-semibold text-gray-900 mb-2 pr-6", children: currentStepData.title })), _jsx("p", { className: "text-gray-700 mb-4", children: currentStepData.intro }), showProgress && (_jsxs("div", { className: "mb-4", children: [_jsx("div", { className: "w-full bg-gray-200 rounded-full h-2", children: _jsx("div", { className: "bg-brand-primary h-2 rounded-full transition-all duration-300", style: { width: `${progress}%` } }) }), _jsxs("p", { className: "text-xs text-gray-500 mt-1 text-center", children: [currentStep + 1, " de ", steps.length] })] })), showBullets && (_jsx("div", { className: "flex justify-center gap-1 mb-4", children: steps.map((_, index) => (_jsx("button", { onClick: () => setCurrentStep(index), className: `w-2 h-2 rounded-full transition-all ${index === currentStep
|
|
148
|
+
? "bg-brand-primary w-6"
|
|
149
|
+
: "bg-gray-300 hover:bg-gray-400"}`, "aria-label": `Ir para passo ${index + 1}` }, index))) })), _jsxs("div", { className: "flex justify-between items-center gap-2", children: [_jsx("div", { className: "flex gap-2", children: !isFirstStep && (_jsx(Button, { variant: "bordered", onPress: handlePrev, startContent: _jsx(HiChevronLeft, { className: "w-4 h-4" }), children: prevLabel })) }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "light", onPress: handleSkip, children: skipLabel }), _jsx(Button, { color: "primary", onPress: isLastStep ? handleComplete : handleNext, endContent: !isLastStep ? _jsx(HiChevronRight, { className: "w-4 h-4" }) : undefined, children: isLastStep ? doneLabel : nextLabel })] })] })] }), currentStepData.position === "bottom" && (_jsx("div", { className: "absolute w-0 h-0 border-8 border-transparent", style: {
|
|
150
|
+
top: "-16px",
|
|
151
|
+
left: "50%",
|
|
152
|
+
transform: "translateX(-50%)",
|
|
153
|
+
borderColor: "transparent transparent white transparent",
|
|
154
|
+
} })), currentStepData.position === "top" && (_jsx("div", { className: "absolute w-0 h-0 border-8 border-transparent", style: {
|
|
155
|
+
bottom: "-16px",
|
|
156
|
+
left: "50%",
|
|
157
|
+
transform: "translateX(-50%)",
|
|
158
|
+
borderColor: "white transparent transparent transparent",
|
|
159
|
+
} })), currentStepData.position === "right" && (_jsx("div", { className: "absolute w-0 h-0 border-8 border-transparent", style: {
|
|
160
|
+
left: "-16px",
|
|
161
|
+
top: "50%",
|
|
162
|
+
transform: "translateY(-50%)",
|
|
163
|
+
borderColor: "transparent white transparent transparent",
|
|
164
|
+
} })), currentStepData.position === "left" && (_jsx("div", { className: "absolute w-0 h-0 border-8 border-transparent", style: {
|
|
165
|
+
right: "-16px",
|
|
166
|
+
top: "50%",
|
|
167
|
+
transform: "translateY(-50%)",
|
|
168
|
+
borderColor: "transparent transparent transparent white",
|
|
169
|
+
} }))] })), _jsx("style", { children: `
|
|
170
|
+
.tour-highlight {
|
|
171
|
+
position: relative;
|
|
172
|
+
z-index: 9999 !important;
|
|
173
|
+
outline: 3px solid var(--brand-primary, #0056b0) !important;
|
|
174
|
+
outline-offset: 2px;
|
|
175
|
+
border-radius: 4px;
|
|
176
|
+
}
|
|
177
|
+
` })] }));
|
|
178
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Tour } from "./components/Tour";
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tipos para o componente de tour
|
|
3
|
+
*/
|
|
4
|
+
export interface TourStep {
|
|
5
|
+
/**
|
|
6
|
+
* Seletor CSS do elemento a ser destacado
|
|
7
|
+
*/
|
|
8
|
+
element: string;
|
|
9
|
+
/**
|
|
10
|
+
* Texto explicativo do passo
|
|
11
|
+
*/
|
|
12
|
+
intro: string;
|
|
13
|
+
/**
|
|
14
|
+
* Posição da tooltip em relação ao elemento
|
|
15
|
+
* @default "bottom"
|
|
16
|
+
*/
|
|
17
|
+
position?: "top" | "bottom" | "left" | "right";
|
|
18
|
+
/**
|
|
19
|
+
* Título do passo (opcional)
|
|
20
|
+
*/
|
|
21
|
+
title?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface TourOptions {
|
|
24
|
+
/**
|
|
25
|
+
* Label do botão "Próximo"
|
|
26
|
+
* @default "Próximo"
|
|
27
|
+
*/
|
|
28
|
+
nextLabel?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Label do botão "Anterior"
|
|
31
|
+
* @default "Anterior"
|
|
32
|
+
*/
|
|
33
|
+
prevLabel?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Label do botão "Pular"
|
|
36
|
+
* @default "Pular"
|
|
37
|
+
*/
|
|
38
|
+
skipLabel?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Label do botão "Concluir"
|
|
41
|
+
* @default "Concluir"
|
|
42
|
+
*/
|
|
43
|
+
doneLabel?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Mostrar barra de progresso
|
|
46
|
+
* @default true
|
|
47
|
+
*/
|
|
48
|
+
showProgress?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Mostrar bullets de navegação
|
|
51
|
+
* @default true
|
|
52
|
+
*/
|
|
53
|
+
showBullets?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Permitir fechar clicando no overlay
|
|
56
|
+
* @default false
|
|
57
|
+
*/
|
|
58
|
+
exitOnOverlayClick?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Permitir fechar com ESC
|
|
61
|
+
* @default true
|
|
62
|
+
*/
|
|
63
|
+
exitOnEsc?: boolean;
|
|
64
|
+
}
|
|
65
|
+
export interface TourProps {
|
|
66
|
+
/**
|
|
67
|
+
* Se o tour está habilitado/ativo
|
|
68
|
+
*/
|
|
69
|
+
enabled: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Array de passos do tour
|
|
72
|
+
*/
|
|
73
|
+
steps: TourStep[];
|
|
74
|
+
/**
|
|
75
|
+
* Passo inicial (índice)
|
|
76
|
+
* @default 0
|
|
77
|
+
*/
|
|
78
|
+
initialStep?: number;
|
|
79
|
+
/**
|
|
80
|
+
* Opções de configuração do tour
|
|
81
|
+
*/
|
|
82
|
+
options?: TourOptions;
|
|
83
|
+
/**
|
|
84
|
+
* Callback quando o tour é encerrado
|
|
85
|
+
*/
|
|
86
|
+
onExit?: () => void;
|
|
87
|
+
/**
|
|
88
|
+
* Callback quando o tour é concluído
|
|
89
|
+
*/
|
|
90
|
+
onComplete?: () => void;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IAE/C;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,QAAQ,EAAE,CAAC;IAElB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB"}
|
package/package.json
CHANGED
package/src/components/Tour.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useState, useCallback, useRef } from "react";
|
|
2
2
|
import { Button } from "@heroui/button";
|
|
3
3
|
import { TourProps, TourStep } from "../types";
|
|
4
|
-
import {
|
|
4
|
+
import { HiXMark, HiChevronLeft, HiChevronRight } from "react-icons/hi2";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Componente de tour guiado customizado usando HeroUI
|
|
@@ -31,6 +31,19 @@ export function Tour({
|
|
|
31
31
|
exitOnEsc = true,
|
|
32
32
|
} = options;
|
|
33
33
|
|
|
34
|
+
// Garante que o overlay seja renderizado quando enabled for true
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (enabled) {
|
|
37
|
+
// Força o body a não ter scroll quando o tour está ativo
|
|
38
|
+
document.body.style.overflow = "hidden";
|
|
39
|
+
} else {
|
|
40
|
+
document.body.style.overflow = "";
|
|
41
|
+
}
|
|
42
|
+
return () => {
|
|
43
|
+
document.body.style.overflow = "";
|
|
44
|
+
};
|
|
45
|
+
}, [enabled]);
|
|
46
|
+
|
|
34
47
|
// Calcula a posição da tooltip baseado no elemento destacado
|
|
35
48
|
const calculateTooltipPosition = useCallback((element: HTMLElement, position: string = "bottom") => {
|
|
36
49
|
const rect = element.getBoundingClientRect();
|
|
@@ -103,11 +116,14 @@ export function Tour({
|
|
|
103
116
|
return;
|
|
104
117
|
}
|
|
105
118
|
|
|
106
|
-
// Adiciona classe de highlight
|
|
119
|
+
// Adiciona classe de highlight e z-index alto
|
|
107
120
|
highlightedElement.classList.add("tour-highlight");
|
|
121
|
+
const originalZIndex = highlightedElement.style.zIndex;
|
|
122
|
+
highlightedElement.style.zIndex = "10000";
|
|
108
123
|
|
|
109
124
|
return () => {
|
|
110
125
|
highlightedElement.classList.remove("tour-highlight");
|
|
126
|
+
highlightedElement.style.zIndex = originalZIndex;
|
|
111
127
|
};
|
|
112
128
|
}, [highlightedElement]);
|
|
113
129
|
|
|
@@ -179,20 +195,29 @@ export function Tour({
|
|
|
179
195
|
|
|
180
196
|
return (
|
|
181
197
|
<>
|
|
182
|
-
{/* Overlay escuro */}
|
|
198
|
+
{/* Overlay escuro - sempre visível quando tour está ativo */}
|
|
183
199
|
<div
|
|
184
200
|
ref={overlayRef}
|
|
185
|
-
className="fixed inset-0 bg-black/60 z-[9998]"
|
|
186
201
|
onClick={handleOverlayClick}
|
|
187
|
-
style={{
|
|
202
|
+
style={{
|
|
203
|
+
position: "fixed",
|
|
204
|
+
top: 0,
|
|
205
|
+
left: 0,
|
|
206
|
+
right: 0,
|
|
207
|
+
bottom: 0,
|
|
208
|
+
backgroundColor: "rgba(0, 0, 0, 0.6)",
|
|
209
|
+
zIndex: 9998,
|
|
210
|
+
pointerEvents: exitOnOverlayClick ? "auto" : "none",
|
|
211
|
+
}}
|
|
188
212
|
/>
|
|
189
213
|
|
|
190
214
|
{/* Tooltip */}
|
|
191
215
|
{tooltipPosition && currentStepData && highlightedElement && (
|
|
192
216
|
<div
|
|
193
217
|
ref={tooltipRef}
|
|
194
|
-
className="
|
|
218
|
+
className="max-w-sm"
|
|
195
219
|
style={{
|
|
220
|
+
position: "fixed",
|
|
196
221
|
top: currentStepData.position === "bottom" ? `${tooltipPosition.top}px` : undefined,
|
|
197
222
|
bottom: currentStepData.position === "top" ? `${window.innerHeight - tooltipPosition.top}px` : undefined,
|
|
198
223
|
left: currentStepData.position === "left" || currentStepData.position === "right"
|
|
@@ -201,6 +226,7 @@ export function Tour({
|
|
|
201
226
|
transform: currentStepData.position === "left" || currentStepData.position === "right"
|
|
202
227
|
? "translate(0, -50%)"
|
|
203
228
|
: "translate(-50%, 0)",
|
|
229
|
+
zIndex: 10001,
|
|
204
230
|
}}
|
|
205
231
|
>
|
|
206
232
|
<div className="bg-white rounded-lg shadow-xl p-6 relative">
|
|
@@ -210,7 +236,7 @@ export function Tour({
|
|
|
210
236
|
className="absolute top-2 right-2 p-1 rounded-full hover:bg-gray-100 transition-colors"
|
|
211
237
|
aria-label="Fechar tour"
|
|
212
238
|
>
|
|
213
|
-
<
|
|
239
|
+
<HiXMark className="w-5 h-5 text-gray-500" />
|
|
214
240
|
</button>
|
|
215
241
|
|
|
216
242
|
{/* Título (se fornecido) */}
|
|
@@ -336,11 +362,12 @@ export function Tour({
|
|
|
336
362
|
{/* Estilos inline para highlight */}
|
|
337
363
|
<style>{`
|
|
338
364
|
.tour-highlight {
|
|
339
|
-
position: relative;
|
|
340
|
-
z-index:
|
|
365
|
+
position: relative !important;
|
|
366
|
+
z-index: 10000 !important;
|
|
341
367
|
outline: 3px solid var(--brand-primary, #0056b0) !important;
|
|
342
368
|
outline-offset: 2px;
|
|
343
369
|
border-radius: 4px;
|
|
370
|
+
box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.6) !important;
|
|
344
371
|
}
|
|
345
372
|
`}</style>
|
|
346
373
|
</>
|