@farm-investimentos/front-mfe-components 15.13.1 → 15.13.3

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.1",
3
+ "version": "15.13.3",
4
4
  "author": "farm investimentos",
5
5
  "private": false,
6
6
  "main": "./dist/front-mfe-components.common.js",
@@ -136,6 +136,7 @@
136
136
  margin-top: gutter('lg');
137
137
  padding-top: gutter('sm');
138
138
  flex-wrap: wrap;
139
+ width: 100%;
139
140
  }
140
141
 
141
142
  &__legend-title {
@@ -213,6 +214,10 @@
213
214
  margin-bottom: 0;
214
215
  }
215
216
  }
217
+ .tooltip-label {
218
+ margin-right: 4px;
219
+ }
220
+
216
221
 
217
222
  .tooltip-text {
218
223
  font-weight: 500;
@@ -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
  }
@@ -223,17 +227,23 @@ export default defineComponent({
223
227
 
224
228
  const legendStyle = computed(() => {
225
229
  const timelineWidth = monthColumns.value.length * 80;
226
- const totalWidth = 120 + timelineWidth;
230
+ const totalWidth = 180 + timelineWidth;
227
231
  return {
228
- width: `${totalWidth}px`,
232
+ minWidth: `${totalWidth}px`,
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
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,
@@ -93,15 +93,15 @@ describe('GanttChart component', () => {
93
93
  {
94
94
  id: 1,
95
95
  label: 'Early Bar',
96
- start: new Date(2025, 0, 15), // Jan 15, 2025
97
- end: new Date(2025, 2, 10), // Mar 10, 2025
96
+ start: new Date(2025, 0, 15),
97
+ end: new Date(2025, 2, 10),
98
98
  color: '#7BC4F7',
99
99
  },
100
100
  {
101
101
  id: 2,
102
102
  label: 'Late Bar',
103
- start: new Date(2025, 4, 5), // May 5, 2025
104
- end: new Date(2025, 6, 20), // Jul 20, 2025
103
+ start: new Date(2025, 4, 5),
104
+ end: new Date(2025, 6, 20),
105
105
  color: '#8BB455',
106
106
  },
107
107
  ],
@@ -113,11 +113,10 @@ describe('GanttChart component', () => {
113
113
  propsData: { data: testData },
114
114
  });
115
115
 
116
- // Should calculate from January 1st to July 31st (full months)
117
116
  const monthColumns = testWrapper.vm.monthColumns;
118
- expect(monthColumns.length).toBe(7); // Jan to Jul = 7 months
117
+ expect(monthColumns.length).toBe(8);
119
118
  expect(monthColumns[0].label).toContain('Jan');
120
- expect(monthColumns[monthColumns.length - 1].label).toContain('Jul');
119
+ expect(monthColumns[monthColumns.length - 1].label).toContain('Ago');
121
120
  });
122
121
 
123
122
  it('should handle single month range', () => {
@@ -129,8 +128,8 @@ describe('GanttChart component', () => {
129
128
  {
130
129
  id: 1,
131
130
  label: 'Single Month Bar',
132
- start: new Date(2025, 3, 5), // Apr 5, 2025
133
- end: new Date(2025, 3, 25), // Apr 25, 2025
131
+ start: new Date(2025, 3, 5),
132
+ end: new Date(2025, 3, 25),
134
133
  color: '#7BC4F7',
135
134
  },
136
135
  ],
@@ -143,8 +142,9 @@ describe('GanttChart component', () => {
143
142
  });
144
143
 
145
144
  const monthColumns = testWrapper.vm.monthColumns;
146
- expect(monthColumns.length).toBe(1);
145
+ expect(monthColumns.length).toBe(2);
147
146
  expect(monthColumns[0].label).toContain('Abr');
147
+ expect(monthColumns[1].label).toContain('Mai');
148
148
  });
149
149
  });
150
150
 
@@ -171,7 +171,7 @@ describe('GanttChart component', () => {
171
171
  },
172
172
  {
173
173
  id: 3,
174
- label: 'Design', // Same label, same color - should not duplicate
174
+ label: 'Design',
175
175
  start: new Date(2025, 2, 1),
176
176
  end: new Date(2025, 3, 1),
177
177
  color: '#8E44AD',
@@ -186,7 +186,7 @@ describe('GanttChart component', () => {
186
186
  });
187
187
 
188
188
  const legend = testWrapper.vm.autoGeneratedLegend;
189
- expect(legend).toHaveLength(2); // Only unique combinations
189
+ expect(legend).toHaveLength(2);
190
190
  expect(legend.some(item => item.label === 'Design' && item.color === '#8E44AD')).toBe(true);
191
191
  expect(legend.some(item => item.label === 'Development' && item.color === '#16A085')).toBe(true);
192
192
  });
@@ -219,7 +219,6 @@ describe('GanttChart component', () => {
219
219
  ];
220
220
  const positionedBars = component.getPositionedBars(bars);
221
221
  expect(positionedBars).toHaveLength(2);
222
- // Each bar should have its own unique row position
223
222
  expect(positionedBars[0].rowPosition).toBe(0);
224
223
  expect(positionedBars[1].rowPosition).toBe(1);
225
224
  });
@@ -228,21 +227,21 @@ describe('GanttChart component', () => {
228
227
  const bars = [
229
228
  {
230
229
  id: 3,
231
- start: new Date(2025, 2, 1), // Latest date but first in array
230
+ start: new Date(2025, 2, 1),
232
231
  end: new Date(2025, 2, 15),
233
232
  label: 'Latest Bar',
234
233
  color: '#FFB84D',
235
234
  },
236
235
  {
237
236
  id: 1,
238
- start: new Date(2025, 0, 1), // Earliest date but second in array
237
+ start: new Date(2025, 0, 1),
239
238
  end: new Date(2025, 0, 15),
240
239
  label: 'Early Bar',
241
240
  color: '#7BC4F7',
242
241
  },
243
242
  {
244
243
  id: 2,
245
- start: new Date(2025, 1, 1), // Middle date but third in array
244
+ start: new Date(2025, 1, 1),
246
245
  end: new Date(2025, 1, 15),
247
246
  label: 'Middle Bar',
248
247
  color: '#8BB455',
@@ -250,10 +249,9 @@ describe('GanttChart component', () => {
250
249
  ];
251
250
  const positionedBars = component.getPositionedBars(bars);
252
251
  expect(positionedBars).toHaveLength(3);
253
- // Bars should maintain original order, not be sorted by date
254
- expect(positionedBars[0].id).toBe(3); // Latest date stays first
255
- expect(positionedBars[1].id).toBe(1); // Earliest date stays second
256
- expect(positionedBars[2].id).toBe(2); // Middle date stays third
252
+ expect(positionedBars[0].id).toBe(3);
253
+ expect(positionedBars[1].id).toBe(1);
254
+ expect(positionedBars[2].id).toBe(2);
257
255
  expect(positionedBars[0].rowPosition).toBe(0);
258
256
  expect(positionedBars[1].rowPosition).toBe(1);
259
257
  expect(positionedBars[2].rowPosition).toBe(2);
@@ -310,7 +308,6 @@ describe('GanttChart component', () => {
310
308
  label: 'Bar Without Color',
311
309
  start: new Date(2025, 0, 1),
312
310
  end: new Date(2025, 1, 1),
313
- // color não definido - deve usar fallback
314
311
  }]
315
312
  }]
316
313
  };
@@ -350,16 +347,13 @@ describe('GanttChart component', () => {
350
347
  it('should validate invalid data prop structure', () => {
351
348
  const consoleSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
352
349
 
353
- // Teste com data null
354
350
  const validator = wrapper.vm.$options.props.data.validator;
355
351
  expect(validator(null)).toBe(false);
356
352
  expect(consoleSpy).toHaveBeenCalledWith('GanttChart: prop "data" deve ser um objeto.');
357
353
 
358
- // Teste com data sem groups
359
354
  expect(validator({})).toBe(false);
360
355
  expect(consoleSpy).toHaveBeenCalledWith('GanttChart: prop "data.groups" deve ser um array.');
361
356
 
362
- // Teste com groups inválido
363
357
  expect(validator({ groups: 'invalid' })).toBe(false);
364
358
  expect(consoleSpy).toHaveBeenCalledWith('GanttChart: prop "data.groups" deve ser um array.');
365
359
 
@@ -370,7 +364,6 @@ describe('GanttChart component', () => {
370
364
  const consoleSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
371
365
  const validator = wrapper.vm.$options.props.data.validator;
372
366
 
373
- // Teste com grupo sem title
374
367
  const invalidData = {
375
368
  groups: [{
376
369
  bars: []
@@ -379,7 +372,6 @@ describe('GanttChart component', () => {
379
372
  expect(validator(invalidData)).toBe(false);
380
373
  expect(consoleSpy).toHaveBeenCalledWith('GanttChart: cada grupo deve ter título (string) e barras (array).');
381
374
 
382
- // Teste com grupo sem bars
383
375
  const invalidData2 = {
384
376
  groups: [{
385
377
  title: 'Valid Title'
@@ -408,18 +400,15 @@ describe('GanttChart component', () => {
408
400
  const bar = {
409
401
  id: 1,
410
402
  label: 'Inverted Date Bar',
411
- // Datas invertidas (end antes de start)
412
- start: new Date(2025, 3, 15), // 15 de abril
413
- end: new Date(2025, 2, 15), // 15 de março (antes do início)
403
+ start: new Date(2025, 3, 15),
404
+ end: new Date(2025, 2, 15),
414
405
  color: '#7BC4F7',
415
406
  };
416
407
 
417
- // Normalizar barra via função de posicionamento
418
408
  const dates = component.normalizeBarDates(bar);
419
409
 
420
- // Verificar se as datas foram invertidas corretamente
421
- expect(dates.startDate.getTime()).toBe(new Date(2025, 2, 15).getTime()); // Agora é 15 de março
422
- expect(dates.endDate.getTime()).toBe(new Date(2025, 3, 15).getTime()); // Agora é 15 de abril
410
+ expect(dates.startDate.getTime()).toBe(new Date(2025, 2, 15).getTime());
411
+ expect(dates.endDate.getTime()).toBe(new Date(2025, 3, 15).getTime());
423
412
  });
424
413
 
425
414
  it('should handle invalid dates', () => {
@@ -438,17 +427,14 @@ describe('GanttChart component', () => {
438
427
 
439
428
  describe('Tooltip System', () => {
440
429
  it('should show tooltip on bar mouseenter', async () => {
441
- // Encontrar uma barra
442
430
  const bar = wrapper.find('.farm-gantt-chart__bar');
443
431
 
444
432
  if (bar.exists()) {
445
- // Disparar evento mouseenter
446
433
  await bar.trigger('mouseenter', {
447
434
  clientX: 100,
448
435
  clientY: 100,
449
436
  });
450
437
 
451
- // Verificar se tooltipState foi atualizado
452
438
  expect(component.tooltipState.visible).toBe(true);
453
439
  expect(component.tooltipState.title).toBe('Test Bar');
454
440
  expect(component.tooltipState.barData).not.toBeNull();
@@ -456,24 +442,20 @@ describe('GanttChart component', () => {
456
442
  });
457
443
 
458
444
  it('should hide tooltip on bar mouseleave', async () => {
459
- // Preparar estado (mostrar tooltip)
460
445
  component.tooltipState.visible = true;
461
446
  component.tooltipState.title = 'Teste';
462
447
  component.tooltipState.barData = { label: 'Teste' };
463
448
 
464
- // Encontrar e disparar mouseleave
465
449
  const bar = wrapper.find('.farm-gantt-chart__bar');
466
450
  if (bar.exists()) {
467
451
  await bar.trigger('mouseleave');
468
452
 
469
- // Verificar se tooltipState foi atualizado
470
453
  expect(component.tooltipState.visible).toBe(false);
471
454
  expect(component.tooltipState.barData).toBeNull();
472
455
  }
473
456
  });
474
457
 
475
458
  it('should show structured tooltip when tooltipData is available', () => {
476
- // Criar wrapper com dados para tooltip
477
459
  const testData = {
478
460
  groups: [{
479
461
  title: 'Group with Tooltips',
@@ -495,7 +477,6 @@ describe('GanttChart component', () => {
495
477
  propsData: { data: testData },
496
478
  });
497
479
 
498
- // Simular mouseenter
499
480
  const barWithTooltip = tooltipWrapper.find('.farm-gantt-chart__bar');
500
481
  if (barWithTooltip.exists()) {
501
482
  barWithTooltip.trigger('mouseenter', {
@@ -503,8 +484,6 @@ describe('GanttChart component', () => {
503
484
  clientY: 100
504
485
  });
505
486
 
506
- // Verificar que tooltip com dados estruturados será exibido
507
- // quando tooltipState.barData.tooltipData existir
508
487
  expect(tooltipWrapper.vm.tooltipState.barData.tooltipData).toBeDefined();
509
488
  expect(tooltipWrapper.vm.tooltipState.barData.tooltipData.Taxa).toBe('1,75%');
510
489
  }
@@ -518,11 +497,8 @@ describe('GanttChart component', () => {
518
497
  propsData: { data: emptyData },
519
498
  });
520
499
 
521
- // Componente deve renderizar sem erros mesmo com dados vazios
522
- expect(emptyWrapper.exists()).toBe(true);
523
500
  expect(emptyWrapper.find('.farm-gantt-chart').exists()).toBe(true);
524
501
 
525
- // Não deve haver grupos renderizados
526
502
  const groups = emptyWrapper.findAll('.farm-gantt-chart__group');
527
503
  expect(groups.length).toBe(0);
528
504
  });
@@ -533,7 +509,6 @@ describe('GanttChart component', () => {
533
509
  propsData: { data: emptyData },
534
510
  });
535
511
 
536
- // Timeline headers devem estar presentes (baseado em data range padrão ou calculado)
537
512
  const header = emptyWrapper.find('.farm-gantt-chart__header');
538
513
  expect(header.exists()).toBe(true);
539
514
  });
@@ -1,8 +1,12 @@
1
1
  import { isValid } from 'date-fns';
2
- import type { GanttBar } from '../types';
2
+ import { Ref } from 'vue';
3
+ import type { GanttBar, DateRange, MonthColumn } from '../types';
3
4
  import { getColumnForDate, getDaysInMonth } from '../utils/dateUtils';
4
5
 
5
- export default function buildBarPositioning(dateRange, monthColumns) {
6
+ export default function buildBarPositioning(
7
+ dateRange: Ref<DateRange>,
8
+ monthColumns: Ref<MonthColumn[]>
9
+ ) {
6
10
  const normalizeBarDates = (bar: GanttBar) => {
7
11
  let startDate = bar.start instanceof Date ? bar.start : new Date(bar.start);
8
12
  let endDate = bar.end instanceof Date ? bar.end : new Date(bar.end);
@@ -1,5 +1,5 @@
1
1
  import { computed } from 'vue';
2
- import { isValid, endOfMonth } from 'date-fns';
2
+ import { isValid, endOfMonth, addMonths } from 'date-fns';
3
3
 
4
4
  export default function buildGanttData(props) {
5
5
  const autoCalculatedDateRange = computed(() => {
@@ -23,7 +23,7 @@ export default function buildGanttData(props) {
23
23
  const now = new Date();
24
24
  return {
25
25
  start: new Date(now.getFullYear(), 0, 1),
26
- end: new Date(now.getFullYear(), 11, 31)
26
+ end: endOfMonth(addMonths(new Date(now.getFullYear(), 11, 31), 1))
27
27
  };
28
28
  }
29
29
 
@@ -31,7 +31,7 @@ export default function buildGanttData(props) {
31
31
  const maxDate = new Date(Math.max(...allDates.map(d => d.getTime())));
32
32
 
33
33
  minDate.setDate(1);
34
- const adjustedMaxDate = endOfMonth(maxDate);
34
+ const adjustedMaxDate = endOfMonth(addMonths(maxDate, 1));
35
35
 
36
36
  return { start: minDate, end: adjustedMaxDate };
37
37
  });
@@ -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
 
@@ -44,13 +45,10 @@ export interface DateRange {
44
45
  end: Date;
45
46
  }
46
47
 
47
-
48
- // NEW: Tooltip data interface
49
48
  export interface TooltipData {
50
49
  [key: string]: string | number | null | undefined;
51
50
  }
52
51
 
53
- // NEW: Enhanced tooltip state
54
52
  export interface TooltipState {
55
53
  visible: boolean;
56
54
  x: number;
package/src/main.ts CHANGED
@@ -41,6 +41,7 @@ export {
41
41
  Collapsible,
42
42
  IdCaption,
43
43
  ResourceMetaInfo,
44
+ GanttChart,
44
45
  };
45
46
 
46
47
  export * from './components/AlertBox';