@elogroup-sereduc/portal-aluno-tour 1.0.7 → 1.0.8

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.
@@ -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,kDA0iBX"}
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,kDAqmBX"}
@@ -17,7 +17,7 @@ export function Tour({ enabled, steps, initialStep = 0, options = {}, onExit, on
17
17
  // Calcula a posição da tooltip baseado no elemento destacado
18
18
  // Usa getBoundingClientRect() que retorna posições relativas à viewport
19
19
  // Isso mantém a tooltip sempre visível mesmo durante scroll
20
- const calculateTooltipPosition = useCallback((element, position = "bottom") => {
20
+ const calculateTooltipPosition = useCallback((element, position = "auto") => {
21
21
  const rect = element.getBoundingClientRect();
22
22
  const viewportWidth = window.innerWidth;
23
23
  const viewportHeight = window.innerHeight;
@@ -62,8 +62,63 @@ export function Tour({ enabled, steps, initialStep = 0, options = {}, onExit, on
62
62
  }
63
63
  return { top, left, position: finalPosition };
64
64
  }
65
- // Elemento está visível - calcula posição normal próxima ao elemento
66
- switch (position) {
65
+ // Calcula espaço disponível em todas as direções
66
+ const spaceAbove = rect.top;
67
+ const spaceBelow = viewportHeight - rect.bottom;
68
+ const spaceLeft = rect.left;
69
+ const spaceRight = viewportWidth - rect.right;
70
+ // Determina a melhor posição baseado no espaço disponível
71
+ let bestPosition;
72
+ // Se position for "auto" ou não especificado, calcula automaticamente a melhor posição
73
+ if (!position || position === "auto") {
74
+ // Escolhe automaticamente a direção com mais espaço disponível
75
+ const maxSpace = Math.max(spaceAbove, spaceBelow, spaceLeft, spaceRight);
76
+ if (maxSpace === spaceAbove)
77
+ bestPosition = "top";
78
+ else if (maxSpace === spaceBelow)
79
+ bestPosition = "bottom";
80
+ else if (maxSpace === spaceLeft)
81
+ bestPosition = "left";
82
+ else
83
+ bestPosition = "right";
84
+ }
85
+ else {
86
+ // Posição específica foi fornecida - tenta usar ela primeiro
87
+ // Verifica se a posição especificada tem espaço suficiente
88
+ const hasEnoughSpace = (position === "top" && spaceAbove >= tooltipHeight + spacing + 8) ||
89
+ (position === "bottom" && spaceBelow >= tooltipHeight + spacing + 8) ||
90
+ (position === "left" && spaceLeft >= tooltipWidth + spacing + 8) ||
91
+ (position === "right" && spaceRight >= tooltipWidth + spacing + 8);
92
+ if (hasEnoughSpace) {
93
+ // Tem espaço suficiente, usa a posição especificada
94
+ bestPosition = position;
95
+ }
96
+ else {
97
+ // Não tem espaço suficiente na posição especificada, escolhe a melhor alternativa
98
+ // Para posições verticais (top/bottom), compara entre elas
99
+ if (position === "top" || position === "bottom") {
100
+ bestPosition = spaceAbove > spaceBelow ? "top" : "bottom";
101
+ }
102
+ // Para posições horizontais (left/right), compara entre elas
103
+ else if (position === "left" || position === "right") {
104
+ bestPosition = spaceLeft > spaceRight ? "left" : "right";
105
+ }
106
+ // Fallback: escolhe a direção com mais espaço
107
+ else {
108
+ const maxSpace = Math.max(spaceAbove, spaceBelow, spaceLeft, spaceRight);
109
+ if (maxSpace === spaceAbove)
110
+ bestPosition = "top";
111
+ else if (maxSpace === spaceBelow)
112
+ bestPosition = "bottom";
113
+ else if (maxSpace === spaceLeft)
114
+ bestPosition = "left";
115
+ else
116
+ bestPosition = "right";
117
+ }
118
+ }
119
+ }
120
+ // Calcula posição base na melhor direção escolhida
121
+ switch (bestPosition) {
67
122
  case "top":
68
123
  top = rect.top - spacing;
69
124
  left = rect.left + rect.width / 2;
@@ -74,7 +129,9 @@ export function Tour({ enabled, steps, initialStep = 0, options = {}, onExit, on
74
129
  break;
75
130
  case "left":
76
131
  top = rect.top + rect.height / 2;
77
- left = rect.left - spacing;
132
+ // Para left, a tooltip fica à esquerda do elemento
133
+ // left é onde a tooltip termina (borda direita), então subtrai a largura
134
+ left = rect.left - tooltipWidth - spacing;
78
135
  break;
79
136
  case "right":
80
137
  top = rect.top + rect.height / 2;
@@ -83,8 +140,9 @@ export function Tour({ enabled, steps, initialStep = 0, options = {}, onExit, on
83
140
  default:
84
141
  top = rect.bottom + spacing;
85
142
  left = rect.left + rect.width / 2;
86
- finalPosition = "bottom";
143
+ bestPosition = "bottom";
87
144
  }
145
+ finalPosition = bestPosition;
88
146
  // Ajusta horizontalmente para tooltips top/bottom - mantém próximo ao elemento
89
147
  if (finalPosition === "bottom" || finalPosition === "top") {
90
148
  // Centraliza no elemento, mas ajusta apenas se necessário para não sair da tela
@@ -153,28 +211,32 @@ export function Tour({ enabled, steps, initialStep = 0, options = {}, onExit, on
153
211
  if (spaceLeft < tooltipWidth + spacing + 8) {
154
212
  const spaceRight = viewportWidth - rect.right;
155
213
  if (spaceRight > spaceLeft && spaceRight > tooltipWidth + spacing + 8) {
214
+ // Muda para direita se houver mais espaço
156
215
  left = rect.right + spacing;
157
216
  finalPosition = "right";
158
217
  }
159
218
  else {
160
- // Mantém próximo ao elemento mesmo se não couber perfeitamente
161
- left = rect.left - spacing;
219
+ // Mantém à esquerda, mas ajusta para ficar visível
220
+ left = Math.max(8, rect.left - tooltipWidth - spacing);
162
221
  }
163
222
  }
223
+ // Se tem espaço suficiente, o left já foi calculado corretamente no switch acima
164
224
  }
165
225
  else if (finalPosition === "right") {
166
226
  const spaceRight = viewportWidth - rect.right;
167
227
  if (spaceRight < tooltipWidth + spacing + 8) {
168
228
  const spaceLeft = rect.left;
169
229
  if (spaceLeft > spaceRight && spaceLeft > tooltipWidth + spacing + 8) {
170
- left = rect.left - spacing;
230
+ // Muda para esquerda se houver mais espaço
231
+ left = rect.left - tooltipWidth - spacing;
171
232
  finalPosition = "left";
172
233
  }
173
234
  else {
174
- // Mantém próximo ao elemento mesmo se não couber perfeitamente
175
- left = rect.right + spacing;
235
+ // Mantém à direita, mas ajusta para ficar visível
236
+ left = Math.min(viewportWidth - tooltipWidth - 8, rect.right + spacing);
176
237
  }
177
238
  }
239
+ // Se tem espaço suficiente, o left já foi calculado corretamente no switch acima
178
240
  }
179
241
  }
180
242
  return { top, left, position: finalPosition };
@@ -216,7 +278,8 @@ export function Tour({ enabled, steps, initialStep = 0, options = {}, onExit, on
216
278
  const updatePosition = () => {
217
279
  const updatedRect = element.getBoundingClientRect();
218
280
  if (updatedRect.width > 0 && updatedRect.height > 0) {
219
- const position = calculateTooltipPosition(element, step.position || "bottom");
281
+ // Usa "auto" como default se position não for especificado
282
+ const position = calculateTooltipPosition(element, step.position || "auto");
220
283
  setTooltipPosition(position);
221
284
  }
222
285
  };
@@ -12,9 +12,11 @@ export interface TourStep {
12
12
  intro: string;
13
13
  /**
14
14
  * Posição da tooltip em relação ao elemento
15
- * @default "bottom"
15
+ * - "auto": Calcula automaticamente a melhor posição baseada no espaço disponível
16
+ * - "top" | "bottom" | "left" | "right": Posição específica (pode ser ajustada se não houver espaço)
17
+ * @default "auto"
16
18
  */
17
- position?: "top" | "bottom" | "left" | "right";
19
+ position?: "auto" | "top" | "bottom" | "left" | "right";
18
20
  /**
19
21
  * Título do passo (opcional)
20
22
  */
@@ -1 +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"}
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;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IAExD;;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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elogroup-sereduc/portal-aluno-tour",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Componente de tour guiado customizado usando HeroUI para o Portal do Aluno",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -36,7 +36,7 @@ export function Tour({
36
36
  // Calcula a posição da tooltip baseado no elemento destacado
37
37
  // Usa getBoundingClientRect() que retorna posições relativas à viewport
38
38
  // Isso mantém a tooltip sempre visível mesmo durante scroll
39
- const calculateTooltipPosition = useCallback((element: HTMLElement, position: string = "bottom") => {
39
+ const calculateTooltipPosition = useCallback((element: HTMLElement, position: string | undefined = "auto") => {
40
40
  const rect = element.getBoundingClientRect();
41
41
  const viewportWidth = window.innerWidth;
42
42
  const viewportHeight = window.innerHeight;
@@ -84,8 +84,58 @@ export function Tour({
84
84
  return { top, left, position: finalPosition };
85
85
  }
86
86
 
87
- // Elemento está visível - calcula posição normal próxima ao elemento
88
- switch (position) {
87
+ // Calcula espaço disponível em todas as direções
88
+ const spaceAbove = rect.top;
89
+ const spaceBelow = viewportHeight - rect.bottom;
90
+ const spaceLeft = rect.left;
91
+ const spaceRight = viewportWidth - rect.right;
92
+
93
+ // Determina a melhor posição baseado no espaço disponível
94
+ let bestPosition: "top" | "bottom" | "left" | "right";
95
+
96
+ // Se position for "auto" ou não especificado, calcula automaticamente a melhor posição
97
+ if (!position || position === "auto") {
98
+ // Escolhe automaticamente a direção com mais espaço disponível
99
+ const maxSpace = Math.max(spaceAbove, spaceBelow, spaceLeft, spaceRight);
100
+ if (maxSpace === spaceAbove) bestPosition = "top";
101
+ else if (maxSpace === spaceBelow) bestPosition = "bottom";
102
+ else if (maxSpace === spaceLeft) bestPosition = "left";
103
+ else bestPosition = "right";
104
+ } else {
105
+ // Posição específica foi fornecida - tenta usar ela primeiro
106
+ // Verifica se a posição especificada tem espaço suficiente
107
+ const hasEnoughSpace =
108
+ (position === "top" && spaceAbove >= tooltipHeight + spacing + 8) ||
109
+ (position === "bottom" && spaceBelow >= tooltipHeight + spacing + 8) ||
110
+ (position === "left" && spaceLeft >= tooltipWidth + spacing + 8) ||
111
+ (position === "right" && spaceRight >= tooltipWidth + spacing + 8);
112
+
113
+ if (hasEnoughSpace) {
114
+ // Tem espaço suficiente, usa a posição especificada
115
+ bestPosition = position as "top" | "bottom" | "left" | "right";
116
+ } else {
117
+ // Não tem espaço suficiente na posição especificada, escolhe a melhor alternativa
118
+ // Para posições verticais (top/bottom), compara entre elas
119
+ if (position === "top" || position === "bottom") {
120
+ bestPosition = spaceAbove > spaceBelow ? "top" : "bottom";
121
+ }
122
+ // Para posições horizontais (left/right), compara entre elas
123
+ else if (position === "left" || position === "right") {
124
+ bestPosition = spaceLeft > spaceRight ? "left" : "right";
125
+ }
126
+ // Fallback: escolhe a direção com mais espaço
127
+ else {
128
+ const maxSpace = Math.max(spaceAbove, spaceBelow, spaceLeft, spaceRight);
129
+ if (maxSpace === spaceAbove) bestPosition = "top";
130
+ else if (maxSpace === spaceBelow) bestPosition = "bottom";
131
+ else if (maxSpace === spaceLeft) bestPosition = "left";
132
+ else bestPosition = "right";
133
+ }
134
+ }
135
+ }
136
+
137
+ // Calcula posição base na melhor direção escolhida
138
+ switch (bestPosition) {
89
139
  case "top":
90
140
  top = rect.top - spacing;
91
141
  left = rect.left + rect.width / 2;
@@ -96,7 +146,9 @@ export function Tour({
96
146
  break;
97
147
  case "left":
98
148
  top = rect.top + rect.height / 2;
99
- left = rect.left - spacing;
149
+ // Para left, a tooltip fica à esquerda do elemento
150
+ // left é onde a tooltip termina (borda direita), então subtrai a largura
151
+ left = rect.left - tooltipWidth - spacing;
100
152
  break;
101
153
  case "right":
102
154
  top = rect.top + rect.height / 2;
@@ -105,9 +157,11 @@ export function Tour({
105
157
  default:
106
158
  top = rect.bottom + spacing;
107
159
  left = rect.left + rect.width / 2;
108
- finalPosition = "bottom";
160
+ bestPosition = "bottom";
109
161
  }
110
162
 
163
+ finalPosition = bestPosition;
164
+
111
165
  // Ajusta horizontalmente para tooltips top/bottom - mantém próximo ao elemento
112
166
  if (finalPosition === "bottom" || finalPosition === "top") {
113
167
  // Centraliza no elemento, mas ajusta apenas se necessário para não sair da tela
@@ -173,25 +227,29 @@ export function Tour({
173
227
  if (spaceLeft < tooltipWidth + spacing + 8) {
174
228
  const spaceRight = viewportWidth - rect.right;
175
229
  if (spaceRight > spaceLeft && spaceRight > tooltipWidth + spacing + 8) {
230
+ // Muda para direita se houver mais espaço
176
231
  left = rect.right + spacing;
177
232
  finalPosition = "right";
178
233
  } else {
179
- // Mantém próximo ao elemento mesmo se não couber perfeitamente
180
- left = rect.left - spacing;
234
+ // Mantém à esquerda, mas ajusta para ficar visível
235
+ left = Math.max(8, rect.left - tooltipWidth - spacing);
181
236
  }
182
237
  }
238
+ // Se tem espaço suficiente, o left já foi calculado corretamente no switch acima
183
239
  } else if (finalPosition === "right") {
184
240
  const spaceRight = viewportWidth - rect.right;
185
241
  if (spaceRight < tooltipWidth + spacing + 8) {
186
242
  const spaceLeft = rect.left;
187
243
  if (spaceLeft > spaceRight && spaceLeft > tooltipWidth + spacing + 8) {
188
- left = rect.left - spacing;
244
+ // Muda para esquerda se houver mais espaço
245
+ left = rect.left - tooltipWidth - spacing;
189
246
  finalPosition = "left";
190
247
  } else {
191
- // Mantém próximo ao elemento mesmo se não couber perfeitamente
192
- left = rect.right + spacing;
248
+ // Mantém à direita, mas ajusta para ficar visível
249
+ left = Math.min(viewportWidth - tooltipWidth - 8, rect.right + spacing);
193
250
  }
194
251
  }
252
+ // Se tem espaço suficiente, o left já foi calculado corretamente no switch acima
195
253
  }
196
254
  }
197
255
 
@@ -241,7 +299,8 @@ export function Tour({
241
299
  const updatePosition = () => {
242
300
  const updatedRect = element.getBoundingClientRect();
243
301
  if (updatedRect.width > 0 && updatedRect.height > 0) {
244
- const position = calculateTooltipPosition(element, step.position || "bottom");
302
+ // Usa "auto" como default se position não for especificado
303
+ const position = calculateTooltipPosition(element, step.position || "auto");
245
304
  setTooltipPosition(position);
246
305
  }
247
306
  };
@@ -15,9 +15,11 @@ export interface TourStep {
15
15
 
16
16
  /**
17
17
  * Posição da tooltip em relação ao elemento
18
- * @default "bottom"
18
+ * - "auto": Calcula automaticamente a melhor posição baseada no espaço disponível
19
+ * - "top" | "bottom" | "left" | "right": Posição específica (pode ser ajustada se não houver espaço)
20
+ * @default "auto"
19
21
  */
20
- position?: "top" | "bottom" | "left" | "right";
22
+ position?: "auto" | "top" | "bottom" | "left" | "right";
21
23
 
22
24
  /**
23
25
  * Título do passo (opcional)