@elogroup-sereduc/portal-aluno-tour 1.0.3 → 1.0.4

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/README.md CHANGED
@@ -8,6 +8,12 @@ Componente de tour guiado customizado usando HeroUI para o Portal do Aluno.
8
8
  npm install @elogroup-sereduc/portal-aluno-tour
9
9
  ```
10
10
 
11
+ ## Configuração do Tailwind
12
+
13
+ Este pacote usa `@elogroup-sereduc/portal-aluno-tailwind-config` com o prefixo `portal-tour:`.
14
+
15
+ Certifique-se de que o Tailwind está configurado para processar as classes deste pacote. O pacote inclui um `tailwind.config.js` que estende a configuração compartilhada.
16
+
11
17
  ## Uso
12
18
 
13
19
  ```tsx
@@ -77,4 +83,3 @@ function MyComponent() {
77
83
  - `showBullets?: boolean` - Mostrar bullets de navegação
78
84
  - `exitOnOverlayClick?: boolean` - Permitir fechar clicando no overlay
79
85
  - `exitOnEsc?: boolean` - Permitir fechar com ESC
80
-
@@ -1 +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,kDA0YX"}
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,kDAqcX"}
@@ -19,30 +19,86 @@ export function Tour({ enabled, steps, initialStep = 0, options = {}, onExit, on
19
19
  const rect = element.getBoundingClientRect();
20
20
  const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
21
21
  const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
22
+ const viewportWidth = window.innerWidth;
23
+ const viewportHeight = window.innerHeight;
24
+ // Tamanho estimado da tooltip (ajuste conforme necessário)
25
+ const tooltipWidth = 384; // max-w-sm = 384px
26
+ const tooltipHeight = 200; // altura estimada
27
+ const spacing = 16; // espaçamento entre elemento e tooltip
22
28
  let top = 0;
23
29
  let left = 0;
30
+ let finalPosition = position;
31
+ // Calcula posição base
24
32
  switch (position) {
25
33
  case "top":
26
- top = rect.top + scrollTop - 10;
34
+ top = rect.top + scrollTop - spacing;
27
35
  left = rect.left + scrollLeft + rect.width / 2;
28
36
  break;
29
37
  case "bottom":
30
- top = rect.bottom + scrollTop + 10;
38
+ top = rect.bottom + scrollTop + spacing;
31
39
  left = rect.left + scrollLeft + rect.width / 2;
32
40
  break;
33
41
  case "left":
34
42
  top = rect.top + scrollTop + rect.height / 2;
35
- left = rect.left + scrollLeft - 10;
43
+ left = rect.left + scrollLeft - spacing;
36
44
  break;
37
45
  case "right":
38
46
  top = rect.top + scrollTop + rect.height / 2;
39
- left = rect.right + scrollLeft + 10;
47
+ left = rect.right + scrollLeft + spacing;
40
48
  break;
41
49
  default:
42
- top = rect.bottom + scrollTop + 10;
50
+ top = rect.bottom + scrollTop + spacing;
43
51
  left = rect.left + scrollLeft + rect.width / 2;
52
+ finalPosition = "bottom";
44
53
  }
45
- return { top, left };
54
+ // Ajusta posição se a tooltip sair da viewport
55
+ if (finalPosition === "bottom" || finalPosition === "top") {
56
+ // Ajusta horizontalmente
57
+ if (left - tooltipWidth / 2 < scrollLeft) {
58
+ left = scrollLeft + tooltipWidth / 2 + 16;
59
+ }
60
+ else if (left + tooltipWidth / 2 > scrollLeft + viewportWidth) {
61
+ left = scrollLeft + viewportWidth - tooltipWidth / 2 - 16;
62
+ }
63
+ // Se não couber embaixo, tenta em cima
64
+ if (finalPosition === "bottom" && top + tooltipHeight > scrollTop + viewportHeight) {
65
+ if (rect.top - tooltipHeight > scrollTop) {
66
+ top = rect.top + scrollTop - tooltipHeight - spacing;
67
+ finalPosition = "top";
68
+ }
69
+ }
70
+ // Se não couber em cima, tenta embaixo
71
+ else if (finalPosition === "top" && top - tooltipHeight < scrollTop) {
72
+ if (rect.bottom + tooltipHeight < scrollTop + viewportHeight) {
73
+ top = rect.bottom + scrollTop + spacing;
74
+ finalPosition = "bottom";
75
+ }
76
+ }
77
+ }
78
+ else if (finalPosition === "left" || finalPosition === "right") {
79
+ // Ajusta verticalmente
80
+ if (top - tooltipHeight / 2 < scrollTop) {
81
+ top = scrollTop + tooltipHeight / 2 + 16;
82
+ }
83
+ else if (top + tooltipHeight / 2 > scrollTop + viewportHeight) {
84
+ top = scrollTop + viewportHeight - tooltipHeight / 2 - 16;
85
+ }
86
+ // Se não couber à esquerda, tenta à direita
87
+ if (finalPosition === "left" && left - tooltipWidth < scrollLeft) {
88
+ if (rect.right + tooltipWidth < scrollLeft + viewportWidth) {
89
+ left = rect.right + scrollLeft + spacing;
90
+ finalPosition = "right";
91
+ }
92
+ }
93
+ // Se não couber à direita, tenta à esquerda
94
+ else if (finalPosition === "right" && left + tooltipWidth > scrollLeft + viewportWidth) {
95
+ if (rect.left - tooltipWidth > scrollLeft) {
96
+ left = rect.left + scrollLeft - spacing;
97
+ finalPosition = "left";
98
+ }
99
+ }
100
+ }
101
+ return { top, left, position: finalPosition };
46
102
  }, []);
47
103
  // Configura o tour quando steps ou options mudam
48
104
  const configureTour = useCallback(() => {
@@ -79,7 +135,7 @@ export function Tour({ enabled, steps, initialStep = 0, options = {}, onExit, on
79
135
  element.scrollIntoView({ behavior: "smooth", block: "center" });
80
136
  // Calcula posição da tooltip após um pequeno delay para garantir que o scroll terminou
81
137
  setTimeout(() => {
82
- const position = calculateTooltipPosition(element, step.position);
138
+ const position = calculateTooltipPosition(element, step.position || "bottom");
83
139
  setTooltipPosition(position);
84
140
  }, 300);
85
141
  }, [isVisible, currentStep, steps, calculateTooltipPosition]);
@@ -191,35 +247,37 @@ export function Tour({ enabled, steps, initialStep = 0, options = {}, onExit, on
191
247
  backgroundColor: "rgba(0, 0, 0, 0.6)",
192
248
  zIndex: 9998,
193
249
  pointerEvents: exitOnOverlayClick ? "auto" : "none",
194
- } }), tooltipPosition && currentStepData && highlightedElement && (_jsxs("div", { ref: tooltipRef, className: "max-w-sm", style: {
250
+ } }), tooltipPosition && currentStepData && highlightedElement && (_jsxs("div", { ref: tooltipRef, className: "portal-tour:max-w-sm", style: {
195
251
  position: "fixed",
196
- top: currentStepData.position === "bottom" ? `${tooltipPosition.top}px` : undefined,
197
- bottom: currentStepData.position === "top" ? `${window.innerHeight - tooltipPosition.top}px` : undefined,
198
- left: currentStepData.position === "left" || currentStepData.position === "right"
252
+ top: tooltipPosition.position === "bottom" || tooltipPosition.position === "left" || tooltipPosition.position === "right"
253
+ ? `${tooltipPosition.top}px`
254
+ : undefined,
255
+ bottom: tooltipPosition.position === "top" ? `${window.innerHeight - tooltipPosition.top}px` : undefined,
256
+ left: tooltipPosition.position === "left" || tooltipPosition.position === "right"
199
257
  ? `${tooltipPosition.left}px`
200
258
  : `${tooltipPosition.left}px`,
201
- transform: currentStepData.position === "left" || currentStepData.position === "right"
259
+ transform: tooltipPosition.position === "left" || tooltipPosition.position === "right"
202
260
  ? "translate(0, -50%)"
203
261
  : "translate(-50%, 0)",
204
262
  zIndex: 10001,
205
- }, 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 z-10", "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
206
- ? "bg-brand-primary w-6"
207
- : "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: {
263
+ }, children: [_jsxs("div", { className: "portal-tour:bg-white portal-tour:rounded-lg portal-tour:shadow-xl portal-tour:p-6 portal-tour:relative", children: [_jsx("button", { onClick: handleExit, className: "portal-tour:absolute portal-tour:top-2 portal-tour:right-2 portal-tour:p-1 portal-tour:rounded-full portal-tour:hover:bg-gray-100 portal-tour:transition-colors portal-tour:z-10", "aria-label": "Fechar tour", children: _jsx(HiXMark, { className: "portal-tour:w-5 portal-tour:h-5 portal-tour:text-gray-500" }) }), currentStepData.title && (_jsx("h3", { className: "portal-tour:text-lg portal-tour:font-semibold portal-tour:text-gray-900 portal-tour:mb-2 portal-tour:pr-6", children: currentStepData.title })), _jsx("p", { className: "portal-tour:text-gray-700 portal-tour:mb-4", children: currentStepData.intro }), showProgress && (_jsxs("div", { className: "portal-tour:mb-4", children: [_jsx("div", { className: "portal-tour:w-full portal-tour:bg-gray-200 portal-tour:rounded-full portal-tour:h-2", children: _jsx("div", { className: "portal-tour:bg-brand-primary portal-tour:h-2 portal-tour:rounded-full portal-tour:transition-all portal-tour:duration-300", style: { width: `${progress}%` } }) }), _jsxs("p", { className: "portal-tour:text-xs portal-tour:text-gray-500 portal-tour:mt-1 portal-tour:text-center", children: [currentStep + 1, " de ", steps.length] })] })), showBullets && (_jsx("div", { className: "portal-tour:flex portal-tour:justify-center portal-tour:gap-1 portal-tour:mb-4", children: steps.map((_, index) => (_jsx("button", { onClick: () => setCurrentStep(index), className: `portal-tour:w-2 portal-tour:h-2 portal-tour:rounded-full portal-tour:transition-all ${index === currentStep
264
+ ? "portal-tour:bg-brand-primary portal-tour:w-6"
265
+ : "portal-tour:bg-gray-300 portal-tour:hover:bg-gray-400"}`, "aria-label": `Ir para passo ${index + 1}` }, index))) })), _jsxs("div", { className: "portal-tour:flex portal-tour:justify-between portal-tour:items-center portal-tour:gap-2", children: [_jsx("div", { className: "portal-tour:flex portal-tour:gap-2", children: !isFirstStep && (_jsx(Button, { variant: "bordered", onPress: handlePrev, startContent: _jsx(HiChevronLeft, { className: "portal-tour:w-4 portal-tour:h-4" }), children: prevLabel })) }), _jsxs("div", { className: "portal-tour:flex portal-tour:gap-2", children: [_jsx(Button, { variant: "light", onPress: handleSkip, children: skipLabel }), _jsx(Button, { color: "primary", onPress: isLastStep ? handleComplete : handleNext, endContent: !isLastStep ? _jsx(HiChevronRight, { className: "portal-tour:w-4 portal-tour:h-4" }) : undefined, children: isLastStep ? doneLabel : nextLabel })] })] })] }), tooltipPosition.position === "bottom" && (_jsx("div", { className: "portal-tour:absolute portal-tour:w-0 portal-tour:h-0 portal-tour:border-8 portal-tour:border-transparent", style: {
208
266
  top: "-16px",
209
267
  left: "50%",
210
268
  transform: "translateX(-50%)",
211
269
  borderColor: "transparent transparent white transparent",
212
- } })), currentStepData.position === "top" && (_jsx("div", { className: "absolute w-0 h-0 border-8 border-transparent", style: {
270
+ } })), tooltipPosition.position === "top" && (_jsx("div", { className: "portal-tour:absolute portal-tour:w-0 portal-tour:h-0 portal-tour:border-8 portal-tour:border-transparent", style: {
213
271
  bottom: "-16px",
214
272
  left: "50%",
215
273
  transform: "translateX(-50%)",
216
274
  borderColor: "white transparent transparent transparent",
217
- } })), currentStepData.position === "right" && (_jsx("div", { className: "absolute w-0 h-0 border-8 border-transparent", style: {
275
+ } })), tooltipPosition.position === "right" && (_jsx("div", { className: "portal-tour:absolute portal-tour:w-0 portal-tour:h-0 portal-tour:border-8 portal-tour:border-transparent", style: {
218
276
  left: "-16px",
219
277
  top: "50%",
220
278
  transform: "translateY(-50%)",
221
279
  borderColor: "transparent white transparent transparent",
222
- } })), currentStepData.position === "left" && (_jsx("div", { className: "absolute w-0 h-0 border-8 border-transparent", style: {
280
+ } })), tooltipPosition.position === "left" && (_jsx("div", { className: "portal-tour:absolute portal-tour:w-0 portal-tour:h-0 portal-tour:border-8 portal-tour:border-transparent", style: {
223
281
  right: "-16px",
224
282
  top: "50%",
225
283
  transform: "translateY(-50%)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elogroup-sereduc/portal-aluno-tour",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Componente de tour guiado customizado usando HeroUI para o Portal do Aluno",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -13,7 +13,8 @@
13
13
  "react-dom": "^18.0.0",
14
14
  "@heroui/button": "^2.0.0",
15
15
  "@heroui/system": "^2.0.0",
16
- "react-icons": "^5.0.0"
16
+ "react-icons": "^5.0.0",
17
+ "@elogroup-sereduc/portal-aluno-tailwind-config": "^1.0.0"
17
18
  },
18
19
  "devDependencies": {
19
20
  "@types/react": "^18.0.0",
@@ -17,7 +17,7 @@ export function Tour({
17
17
  const [currentStep, setCurrentStep] = useState(initialStep);
18
18
  const [isVisible, setIsVisible] = useState(false);
19
19
  const [highlightedElement, setHighlightedElement] = useState<HTMLElement | null>(null);
20
- const [tooltipPosition, setTooltipPosition] = useState<{ top: number; left: number } | null>(null);
20
+ const [tooltipPosition, setTooltipPosition] = useState<{ top: number; left: number; position: string } | null>(null);
21
21
  const overlayRef = useRef<HTMLDivElement>(null);
22
22
  const tooltipRef = useRef<HTMLDivElement>(null);
23
23
  const isConfiguredRef = useRef(false);
@@ -38,33 +38,90 @@ export function Tour({
38
38
  const rect = element.getBoundingClientRect();
39
39
  const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
40
40
  const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
41
+ const viewportWidth = window.innerWidth;
42
+ const viewportHeight = window.innerHeight;
43
+
44
+ // Tamanho estimado da tooltip (ajuste conforme necessário)
45
+ const tooltipWidth = 384; // max-w-sm = 384px
46
+ const tooltipHeight = 200; // altura estimada
47
+ const spacing = 16; // espaçamento entre elemento e tooltip
41
48
 
42
49
  let top = 0;
43
50
  let left = 0;
51
+ let finalPosition = position;
44
52
 
53
+ // Calcula posição base
45
54
  switch (position) {
46
55
  case "top":
47
- top = rect.top + scrollTop - 10;
56
+ top = rect.top + scrollTop - spacing;
48
57
  left = rect.left + scrollLeft + rect.width / 2;
49
58
  break;
50
59
  case "bottom":
51
- top = rect.bottom + scrollTop + 10;
60
+ top = rect.bottom + scrollTop + spacing;
52
61
  left = rect.left + scrollLeft + rect.width / 2;
53
62
  break;
54
63
  case "left":
55
64
  top = rect.top + scrollTop + rect.height / 2;
56
- left = rect.left + scrollLeft - 10;
65
+ left = rect.left + scrollLeft - spacing;
57
66
  break;
58
67
  case "right":
59
68
  top = rect.top + scrollTop + rect.height / 2;
60
- left = rect.right + scrollLeft + 10;
69
+ left = rect.right + scrollLeft + spacing;
61
70
  break;
62
71
  default:
63
- top = rect.bottom + scrollTop + 10;
72
+ top = rect.bottom + scrollTop + spacing;
64
73
  left = rect.left + scrollLeft + rect.width / 2;
74
+ finalPosition = "bottom";
65
75
  }
66
76
 
67
- return { top, left };
77
+ // Ajusta posição se a tooltip sair da viewport
78
+ if (finalPosition === "bottom" || finalPosition === "top") {
79
+ // Ajusta horizontalmente
80
+ if (left - tooltipWidth / 2 < scrollLeft) {
81
+ left = scrollLeft + tooltipWidth / 2 + 16;
82
+ } else if (left + tooltipWidth / 2 > scrollLeft + viewportWidth) {
83
+ left = scrollLeft + viewportWidth - tooltipWidth / 2 - 16;
84
+ }
85
+
86
+ // Se não couber embaixo, tenta em cima
87
+ if (finalPosition === "bottom" && top + tooltipHeight > scrollTop + viewportHeight) {
88
+ if (rect.top - tooltipHeight > scrollTop) {
89
+ top = rect.top + scrollTop - tooltipHeight - spacing;
90
+ finalPosition = "top";
91
+ }
92
+ }
93
+ // Se não couber em cima, tenta embaixo
94
+ else if (finalPosition === "top" && top - tooltipHeight < scrollTop) {
95
+ if (rect.bottom + tooltipHeight < scrollTop + viewportHeight) {
96
+ top = rect.bottom + scrollTop + spacing;
97
+ finalPosition = "bottom";
98
+ }
99
+ }
100
+ } else if (finalPosition === "left" || finalPosition === "right") {
101
+ // Ajusta verticalmente
102
+ if (top - tooltipHeight / 2 < scrollTop) {
103
+ top = scrollTop + tooltipHeight / 2 + 16;
104
+ } else if (top + tooltipHeight / 2 > scrollTop + viewportHeight) {
105
+ top = scrollTop + viewportHeight - tooltipHeight / 2 - 16;
106
+ }
107
+
108
+ // Se não couber à esquerda, tenta à direita
109
+ if (finalPosition === "left" && left - tooltipWidth < scrollLeft) {
110
+ if (rect.right + tooltipWidth < scrollLeft + viewportWidth) {
111
+ left = rect.right + scrollLeft + spacing;
112
+ finalPosition = "right";
113
+ }
114
+ }
115
+ // Se não couber à direita, tenta à esquerda
116
+ else if (finalPosition === "right" && left + tooltipWidth > scrollLeft + viewportWidth) {
117
+ if (rect.left - tooltipWidth > scrollLeft) {
118
+ left = rect.left + scrollLeft - spacing;
119
+ finalPosition = "left";
120
+ }
121
+ }
122
+ }
123
+
124
+ return { top, left, position: finalPosition };
68
125
  }, []);
69
126
 
70
127
  // Configura o tour quando steps ou options mudam
@@ -108,7 +165,7 @@ export function Tour({
108
165
 
109
166
  // Calcula posição da tooltip após um pequeno delay para garantir que o scroll terminou
110
167
  setTimeout(() => {
111
- const position = calculateTooltipPosition(element, step.position);
168
+ const position = calculateTooltipPosition(element, step.position || "bottom");
112
169
  setTooltipPosition(position);
113
170
  }, 300);
114
171
  }, [isVisible, currentStep, steps, calculateTooltipPosition]);
@@ -249,51 +306,53 @@ export function Tour({
249
306
  {tooltipPosition && currentStepData && highlightedElement && (
250
307
  <div
251
308
  ref={tooltipRef}
252
- className="max-w-sm"
309
+ className="portal-tour:max-w-sm"
253
310
  style={{
254
311
  position: "fixed",
255
- top: currentStepData.position === "bottom" ? `${tooltipPosition.top}px` : undefined,
256
- bottom: currentStepData.position === "top" ? `${window.innerHeight - tooltipPosition.top}px` : undefined,
257
- left: currentStepData.position === "left" || currentStepData.position === "right"
312
+ top: tooltipPosition.position === "bottom" || tooltipPosition.position === "left" || tooltipPosition.position === "right"
313
+ ? `${tooltipPosition.top}px`
314
+ : undefined,
315
+ bottom: tooltipPosition.position === "top" ? `${window.innerHeight - tooltipPosition.top}px` : undefined,
316
+ left: tooltipPosition.position === "left" || tooltipPosition.position === "right"
258
317
  ? `${tooltipPosition.left}px`
259
318
  : `${tooltipPosition.left}px`,
260
319
  transform:
261
- currentStepData.position === "left" || currentStepData.position === "right"
320
+ tooltipPosition.position === "left" || tooltipPosition.position === "right"
262
321
  ? "translate(0, -50%)"
263
322
  : "translate(-50%, 0)",
264
323
  zIndex: 10001,
265
324
  }}
266
325
  >
267
- <div className="bg-white rounded-lg shadow-xl p-6 relative">
326
+ <div className="portal-tour:bg-white portal-tour:rounded-lg portal-tour:shadow-xl portal-tour:p-6 portal-tour:relative">
268
327
  {/* Botão fechar */}
269
328
  <button
270
329
  onClick={handleExit}
271
- className="absolute top-2 right-2 p-1 rounded-full hover:bg-gray-100 transition-colors z-10"
330
+ className="portal-tour:absolute portal-tour:top-2 portal-tour:right-2 portal-tour:p-1 portal-tour:rounded-full portal-tour:hover:bg-gray-100 portal-tour:transition-colors portal-tour:z-10"
272
331
  aria-label="Fechar tour"
273
332
  >
274
- <HiXMark className="w-5 h-5 text-gray-500" />
333
+ <HiXMark className="portal-tour:w-5 portal-tour:h-5 portal-tour:text-gray-500" />
275
334
  </button>
276
335
 
277
336
  {/* Título (se fornecido) */}
278
337
  {currentStepData.title && (
279
- <h3 className="text-lg font-semibold text-gray-900 mb-2 pr-6">
338
+ <h3 className="portal-tour:text-lg portal-tour:font-semibold portal-tour:text-gray-900 portal-tour:mb-2 portal-tour:pr-6">
280
339
  {currentStepData.title}
281
340
  </h3>
282
341
  )}
283
342
 
284
343
  {/* Conteúdo */}
285
- <p className="text-gray-700 mb-4">{currentStepData.intro}</p>
344
+ <p className="portal-tour:text-gray-700 portal-tour:mb-4">{currentStepData.intro}</p>
286
345
 
287
346
  {/* Progresso */}
288
347
  {showProgress && (
289
- <div className="mb-4">
290
- <div className="w-full bg-gray-200 rounded-full h-2">
348
+ <div className="portal-tour:mb-4">
349
+ <div className="portal-tour:w-full portal-tour:bg-gray-200 portal-tour:rounded-full portal-tour:h-2">
291
350
  <div
292
- className="bg-brand-primary h-2 rounded-full transition-all duration-300"
351
+ className="portal-tour:bg-brand-primary portal-tour:h-2 portal-tour:rounded-full portal-tour:transition-all portal-tour:duration-300"
293
352
  style={{ width: `${progress}%` }}
294
353
  />
295
354
  </div>
296
- <p className="text-xs text-gray-500 mt-1 text-center">
355
+ <p className="portal-tour:text-xs portal-tour:text-gray-500 portal-tour:mt-1 portal-tour:text-center">
297
356
  {currentStep + 1} de {steps.length}
298
357
  </p>
299
358
  </div>
@@ -301,15 +360,15 @@ export function Tour({
301
360
 
302
361
  {/* Bullets */}
303
362
  {showBullets && (
304
- <div className="flex justify-center gap-1 mb-4">
363
+ <div className="portal-tour:flex portal-tour:justify-center portal-tour:gap-1 portal-tour:mb-4">
305
364
  {steps.map((_, index) => (
306
365
  <button
307
366
  key={index}
308
367
  onClick={() => setCurrentStep(index)}
309
- className={`w-2 h-2 rounded-full transition-all ${
368
+ className={`portal-tour:w-2 portal-tour:h-2 portal-tour:rounded-full portal-tour:transition-all ${
310
369
  index === currentStep
311
- ? "bg-brand-primary w-6"
312
- : "bg-gray-300 hover:bg-gray-400"
370
+ ? "portal-tour:bg-brand-primary portal-tour:w-6"
371
+ : "portal-tour:bg-gray-300 portal-tour:hover:bg-gray-400"
313
372
  }`}
314
373
  aria-label={`Ir para passo ${index + 1}`}
315
374
  />
@@ -318,27 +377,27 @@ export function Tour({
318
377
  )}
319
378
 
320
379
  {/* Botões de navegação */}
321
- <div className="flex justify-between items-center gap-2">
322
- <div className="flex gap-2">
380
+ <div className="portal-tour:flex portal-tour:justify-between portal-tour:items-center portal-tour:gap-2">
381
+ <div className="portal-tour:flex portal-tour:gap-2">
323
382
  {!isFirstStep && (
324
383
  <Button
325
384
  variant="bordered"
326
385
  onPress={handlePrev}
327
- startContent={<HiChevronLeft className="w-4 h-4" />}
386
+ startContent={<HiChevronLeft className="portal-tour:w-4 portal-tour:h-4" />}
328
387
  >
329
388
  {prevLabel}
330
389
  </Button>
331
390
  )}
332
391
  </div>
333
392
 
334
- <div className="flex gap-2">
393
+ <div className="portal-tour:flex portal-tour:gap-2">
335
394
  <Button variant="light" onPress={handleSkip}>
336
395
  {skipLabel}
337
396
  </Button>
338
397
  <Button
339
398
  color="primary"
340
399
  onPress={isLastStep ? handleComplete : handleNext}
341
- endContent={!isLastStep ? <HiChevronRight className="w-4 h-4" /> : undefined}
400
+ endContent={!isLastStep ? <HiChevronRight className="portal-tour:w-4 portal-tour:h-4" /> : undefined}
342
401
  >
343
402
  {isLastStep ? doneLabel : nextLabel}
344
403
  </Button>
@@ -347,9 +406,9 @@ export function Tour({
347
406
  </div>
348
407
 
349
408
  {/* Seta indicadora */}
350
- {currentStepData.position === "bottom" && (
409
+ {tooltipPosition.position === "bottom" && (
351
410
  <div
352
- className="absolute w-0 h-0 border-8 border-transparent"
411
+ className="portal-tour:absolute portal-tour:w-0 portal-tour:h-0 portal-tour:border-8 portal-tour:border-transparent"
353
412
  style={{
354
413
  top: "-16px",
355
414
  left: "50%",
@@ -358,9 +417,9 @@ export function Tour({
358
417
  }}
359
418
  />
360
419
  )}
361
- {currentStepData.position === "top" && (
420
+ {tooltipPosition.position === "top" && (
362
421
  <div
363
- className="absolute w-0 h-0 border-8 border-transparent"
422
+ className="portal-tour:absolute portal-tour:w-0 portal-tour:h-0 portal-tour:border-8 portal-tour:border-transparent"
364
423
  style={{
365
424
  bottom: "-16px",
366
425
  left: "50%",
@@ -369,9 +428,9 @@ export function Tour({
369
428
  }}
370
429
  />
371
430
  )}
372
- {currentStepData.position === "right" && (
431
+ {tooltipPosition.position === "right" && (
373
432
  <div
374
- className="absolute w-0 h-0 border-8 border-transparent"
433
+ className="portal-tour:absolute portal-tour:w-0 portal-tour:h-0 portal-tour:border-8 portal-tour:border-transparent"
375
434
  style={{
376
435
  left: "-16px",
377
436
  top: "50%",
@@ -380,9 +439,9 @@ export function Tour({
380
439
  }}
381
440
  />
382
441
  )}
383
- {currentStepData.position === "left" && (
442
+ {tooltipPosition.position === "left" && (
384
443
  <div
385
- className="absolute w-0 h-0 border-8 border-transparent"
444
+ className="portal-tour:absolute portal-tour:w-0 portal-tour:h-0 portal-tour:border-8 portal-tour:border-transparent"
386
445
  style={{
387
446
  right: "-16px",
388
447
  top: "50%",
@@ -0,0 +1,8 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ const shared = require("@elogroup-sereduc/portal-aluno-tailwind-config");
3
+
4
+ module.exports = {
5
+ ...shared,
6
+ prefix: "portal-tour",
7
+ };
8
+