@farm-investimentos/front-mfe-components 15.13.0 → 15.13.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farm-investimentos/front-mfe-components",
3
- "version": "15.13.0",
3
+ "version": "15.13.2",
4
4
  "author": "farm investimentos",
5
5
  "private": false,
6
6
  "main": "./dist/front-mfe-components.common.js",
@@ -6,16 +6,15 @@
6
6
 
7
7
  .farm-gantt-chart {
8
8
  width: 100%;
9
- height: 100%;
10
9
  min-height: 500px;
11
10
  position: relative;
12
11
  overflow-x: auto;
13
- overflow-y: auto;
12
+ overflow-y: visible;
14
13
 
15
14
  &__header {
16
15
  display: flex;
17
- width: fit-content; /* Allow header to expand with timeline */
18
- min-width: 100%; /* Ensure header is at least as wide as the container */
16
+ width: fit-content;
17
+ min-width: 100%;
19
18
  margin-bottom: gutter('sm');
20
19
  position: relative;
21
20
  z-index: 2;
@@ -37,14 +36,14 @@
37
36
  &__month-header {
38
37
  display: flex;
39
38
  align-items: center;
40
- justify-content: flex-start; /* Keep label to the start */
39
+ justify-content: flex-start;
41
40
  padding-right: 8px;
42
41
  height: fit-content;
43
42
  position: relative;
44
- min-width: 0; /* Allow month header to shrink if text is too long, relying on parent scroll */
43
+ min-width: 0;
45
44
 
46
45
  .farm-typography {
47
- white-space: nowrap; /* Prevent label text from wrapping */
46
+ white-space: nowrap;
48
47
  }
49
48
 
50
49
  &::after {
@@ -68,11 +67,10 @@
68
67
 
69
68
  &__content {
70
69
  position: relative;
71
- width: fit-content; /* Allow content to expand with timeline */
72
- min-width: 100%; /* Ensure content is at least as wide as the container */
70
+ width: fit-content;
71
+ min-width: 100%;
73
72
  display: flex;
74
73
  flex-direction: column;
75
- /* overflow: hidden; // Remove this to allow content to scroll with parent */
76
74
  }
77
75
 
78
76
  &__group {
@@ -130,22 +128,6 @@
130
128
  transform: translateY(-2px);
131
129
  }
132
130
 
133
- // Bar types using library theme colors blended with white (matching Figma approach)
134
- &--campaign {
135
- background-color: #7BC4F7; // Info blended with white (73% + 27% white) - Vigência da Campanha
136
- }
137
-
138
- &--product {
139
- background-color: #8BB455; // Primary blended with white (73% + 27% white) - Vigência do Produto Comercial
140
- }
141
-
142
- &--disbursement {
143
- background-color: #FFB84D; // Warning blended with white (73% + 27% white) - Período de Desembolso
144
- }
145
-
146
- &--maturity {
147
- background-color: #F7857F; // Error blended with white (73% + 27% white) - Intervalo Vencimento
148
- }
149
131
  }
150
132
 
151
133
  &__legend {
@@ -169,8 +151,8 @@
169
151
  margin-bottom: gutter('xs');
170
152
  position: relative;
171
153
  padding: 0 12px;
172
- flex-shrink: 0; /* Prevent items from shrinking */
173
- white-space: nowrap; /* Prevent text from wrapping */
154
+ flex-shrink: 0;
155
+ white-space: nowrap;
174
156
 
175
157
  &:not(:last-child)::after {
176
158
  content: '';
@@ -197,7 +179,6 @@
197
179
  align-items: center;
198
180
  }
199
181
 
200
- // NEW: Tooltip container styles - specific to GanttChart positioning
201
182
  &__tooltip-container {
202
183
  position: absolute;
203
184
  z-index: 999;
@@ -207,40 +188,36 @@
207
188
  }
208
189
 
209
190
  &__tooltip {
210
- // Reutiliza estilos base do farm-tooltip__popup mas com customizações específicas
211
191
  @extend .farm-tooltip__popup;
212
192
  @extend .farm-tooltip__popup--visible;
213
193
  @extend .farm-tooltip__popup--fluid;
214
-
215
- // Customizações específicas para GanttChart
194
+
216
195
  pointer-events: auto;
217
196
  position: relative;
218
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); // Shadow mais forte para destacar sobre o chart
197
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
198
+
199
+ width: auto !important;
200
+ max-width: 400px !important;
201
+
202
+ .farm-tooltip__content {
203
+ white-space: nowrap;
204
+ }
219
205
 
220
- // NEW: Structured tooltip data styling - específico para dados estruturados
221
206
  .tooltip-data-row {
222
207
  display: flex;
223
- justify-content: space-between;
208
+ justify-content: flex-start;
224
209
  align-items: center;
225
210
  margin-bottom: 4px;
226
-
211
+
227
212
  &:last-child {
228
213
  margin-bottom: 0;
229
214
  }
230
215
  }
231
-
232
- .tooltip-label {
216
+
217
+ .tooltip-text {
233
218
  font-weight: 500;
234
- margin-right: 8px;
235
- color: #f5f5f5;
236
- opacity: 0.9;
237
- }
238
-
239
- .tooltip-value {
240
- font-weight: 600;
241
219
  color: #ffffff;
242
- text-align: right;
243
- flex-shrink: 0;
220
+ white-space: nowrap;
244
221
  }
245
222
  }
246
223
  }
@@ -29,7 +29,10 @@
29
29
  class="farm-gantt-chart__group"
30
30
  >
31
31
  <div class="farm-gantt-chart__group-label">
32
- <farm-typography :weight="500">
32
+ <farm-typography v-if="group.subtitle" size="md" :weight="600" color="black" color-variation="50" class="mb-1">
33
+ {{ group.subtitle }}
34
+ </farm-typography>
35
+ <farm-typography size ="md" :weight="500" color="black" color-variation="50">
33
36
  {{ group.title }}
34
37
  </farm-typography>
35
38
  </div>
@@ -50,7 +53,7 @@
50
53
  </div>
51
54
  </div>
52
55
  </div>
53
-
56
+
54
57
  </div>
55
58
 
56
59
  <div class="farm-gantt-chart__legend" v-if="autoGeneratedLegend.length > 0" :style="legendStyle">
@@ -80,6 +83,7 @@
80
83
  v-if="tooltipState.visible"
81
84
  class="farm-gantt-chart__tooltip-container"
82
85
  :style="tooltipPositionStyle"
86
+ ref="tooltipElement"
83
87
  >
84
88
  <div v-if="$slots.tooltip" class="farm-gantt-chart__tooltip">
85
89
  <slot
@@ -88,7 +92,7 @@
88
92
  :tooltipData="tooltipState.barData && tooltipState.barData.tooltipData"
89
93
  />
90
94
  </div>
91
-
95
+
92
96
  <div
93
97
  v-else-if="tooltipState.barData && tooltipState.barData.tooltipData"
94
98
  class="farm-gantt-chart__tooltip farm-tooltip__popup farm-tooltip__popup--visible"
@@ -109,7 +113,7 @@
109
113
  </div>
110
114
  </div>
111
115
  </div>
112
-
116
+
113
117
  <div
114
118
  v-else
115
119
  class="farm-gantt-chart__tooltip farm-tooltip__popup farm-tooltip__popup--visible"
@@ -128,7 +132,7 @@
128
132
  </template>
129
133
 
130
134
  <script lang="ts">
131
- import { defineComponent, PropType, computed, reactive, ref } from 'vue';
135
+ import { defineComponent, PropType, computed, reactive, ref, onMounted, onUnmounted, nextTick } from 'vue';
132
136
  import type { GanttData, TooltipState, GanttBar } from './types';
133
137
  import { getMonthsBetween, formatMonth, isCurrentMonth, getColumnForDate, formatDateRange } from './utils/dateUtils';
134
138
  import { buildGanttData, buildBarPositioning } from './composition';
@@ -144,21 +148,21 @@ export default defineComponent({
144
148
  console.warn('GanttChart: prop "data" deve ser um objeto.');
145
149
  return false;
146
150
  }
147
-
151
+
148
152
  if (!Array.isArray(value.groups)) {
149
153
  console.warn('GanttChart: prop "data.groups" deve ser um array.');
150
154
  return false;
151
155
  }
152
-
156
+
153
157
  return value.groups.every((group: any) => {
154
158
  const hasValidTitle = typeof group.title === 'string';
155
159
  const hasValidBars = Array.isArray(group.bars);
156
-
160
+
157
161
  if (!hasValidTitle || !hasValidBars) {
158
162
  console.warn('GanttChart: cada grupo deve ter título (string) e barras (array).');
159
163
  return false;
160
164
  }
161
-
165
+
162
166
  return true;
163
167
  });
164
168
  }
@@ -229,11 +233,17 @@ export default defineComponent({
229
233
  };
230
234
  });
231
235
 
236
+ const tooltipElement = ref<HTMLElement>();
237
+ const lastMousePosition = ref<{ eventX: number; eventY: number } | null>(null);
238
+
232
239
  const onBarMouseEnter = (bar: GanttBar, event: MouseEvent) => {
233
240
  tooltipState.visible = true;
234
- tooltipState.title = bar.label;
241
+ tooltipState.title = bar.tooltipTitle || bar.label;
235
242
  tooltipState.barData = bar;
236
- updateTooltipPosition(event);
243
+
244
+ nextTick(() => {
245
+ updateTooltipPosition(event);
246
+ });
237
247
  };
238
248
 
239
249
  const onBarMouseMove = (bar: GanttBar, event: MouseEvent) => {
@@ -247,30 +257,50 @@ export default defineComponent({
247
257
  tooltipState.barData = null;
248
258
  };
249
259
 
250
- const updateTooltipPosition = (event: MouseEvent) => {
251
- if (!chartContainer.value) return;
260
+ const updateTooltipPosition = (event?: MouseEvent) => {
261
+ const container = chartContainer.value;
262
+ const tooltipEl = tooltipElement.value;
263
+ if (!container || !tooltipEl) return;
264
+
265
+ const { left, top } = container.getBoundingClientRect();
252
266
 
253
- const containerRect = chartContainer.value.getBoundingClientRect();
254
- const x = event.clientX - containerRect.left;
255
- const y = event.clientY - containerRect.top;
267
+ const scrollLeft = container.scrollLeft;
268
+ const scrollTop = container.scrollTop;
256
269
 
257
- const tooltipWidth = 300;
258
- const tooltipHeight = 100;
270
+ const tooltipWidth = tooltipEl.offsetWidth || 300;
271
+ const tooltipHeight = tooltipEl.offsetHeight || 100;
259
272
  const margin = 15;
260
273
 
261
- let tooltipX = x + margin;
262
- let tooltipY = y + margin;
274
+ let contentX: number;
275
+ let contentY: number;
276
+
277
+ if (event) {
278
+ lastMousePosition.value = { eventX: event.clientX, eventY: event.clientY };
279
+ contentX = event.clientX - left + scrollLeft;
280
+ contentY = event.clientY - top + scrollTop;
281
+ } else if (lastMousePosition.value) {
282
+ contentX = lastMousePosition.value.eventX - left + scrollLeft;
283
+ contentY = lastMousePosition.value.eventY - top + scrollTop;
284
+ } else {
285
+ return;
286
+ }
287
+
288
+ let tooltipX = contentX + margin;
289
+ let tooltipY = contentY + margin;
290
+
291
+ const maxVisibleX = scrollLeft + container.clientWidth - tooltipWidth - 10;
292
+ const maxVisibleY = scrollTop + container.clientHeight - tooltipHeight - 10;
263
293
 
264
- if (tooltipX + tooltipWidth > containerRect.width) {
265
- tooltipX = Math.max(10, containerRect.width - tooltipWidth - 10);
294
+ if (tooltipX > maxVisibleX) {
295
+ tooltipX = maxVisibleX;
266
296
  }
267
297
 
268
- if (tooltipY + tooltipHeight > containerRect.height) {
269
- tooltipY = Math.max(10, y - tooltipHeight - margin);
298
+ if (tooltipY > maxVisibleY) {
299
+ tooltipY = Math.max(scrollTop + 10, contentY - tooltipHeight - margin);
270
300
  }
271
301
 
272
- tooltipX = Math.max(10, tooltipX);
273
- tooltipY = Math.max(10, tooltipY);
302
+ tooltipX = Math.max(scrollLeft + 10, tooltipX);
303
+ tooltipY = Math.max(scrollTop + 10, tooltipY);
274
304
 
275
305
  tooltipState.x = tooltipX;
276
306
  tooltipState.y = tooltipY;
@@ -281,6 +311,20 @@ export default defineComponent({
281
311
  zIndex: 999
282
312
  }));
283
313
 
314
+ onMounted(() => {
315
+ if (!chartContainer.value) return;
316
+ const container = chartContainer.value;
317
+ const handleScroll = () => {
318
+ if (tooltipState.visible) {
319
+ updateTooltipPosition();
320
+ }
321
+ };
322
+ container.addEventListener('scroll', handleScroll);
323
+ onUnmounted(() => {
324
+ container.removeEventListener('scroll', handleScroll);
325
+ });
326
+ });
327
+
284
328
  return {
285
329
  monthColumns,
286
330
  timelineGridStyle,
@@ -294,6 +338,7 @@ export default defineComponent({
294
338
  tooltipState,
295
339
  tooltipPositionStyle,
296
340
  chartContainer,
341
+ tooltipElement,
297
342
  onBarMouseEnter,
298
343
  onBarMouseMove,
299
344
  onBarMouseLeave,
@@ -128,7 +128,6 @@ export default function buildBarPositioning(dateRange, monthColumns) {
128
128
 
129
129
  const positionedBars = JSON.parse(JSON.stringify(bars));
130
130
 
131
- // Assign each bar to its own unique row position in the original order
132
131
  positionedBars.forEach((bar: GanttBar, index: number) => {
133
132
  bar.rowPosition = index;
134
133
  });
@@ -3,19 +3,20 @@ export interface GanttData {
3
3
  }
4
4
 
5
5
  export interface GanttGroup {
6
- title: string;
6
+ title: string;
7
+ subtitle?: string;
7
8
  bars: GanttBar[];
8
9
  }
9
10
 
10
11
  export interface GanttBar {
11
12
  id: string | number;
12
- label: string;
13
- start: Date | string;
14
- end: Date | string;
15
- color: string;
13
+ label: string;
14
+ start: Date | string;
15
+ end: Date | string;
16
+ color: string;
16
17
  rowPosition?: number;
17
18
  tooltipData?: TooltipData;
18
-
19
+
19
20
  [key: string]: any;
20
21
  }
21
22