@vuer-ai/vuer-uikit 0.0.84 → 0.0.86

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.
Files changed (47) hide show
  1. package/dist/{chunk-WMYO3VA4.cjs → chunk-2TVNVB3X.cjs} +2 -2
  2. package/dist/{chunk-3M2Y6VIW.mjs → chunk-3ANJMSOC.mjs} +3 -3
  3. package/dist/{chunk-SYXRPCBO.cjs → chunk-EEGQLTSQ.cjs} +42 -33
  4. package/dist/{chunk-7VYMOW2I.mjs → chunk-GEFRW3FP.mjs} +5 -3
  5. package/dist/{chunk-5MIKF753.cjs → chunk-IQS5L6B2.cjs} +5 -3
  6. package/dist/{chunk-OZPCCMGQ.mjs → chunk-M45ELKOT.mjs} +2 -2
  7. package/dist/{chunk-BWBBQCG2.mjs → chunk-PC5DHSC4.mjs} +42 -33
  8. package/dist/{chunk-2ZBQXVNV.cjs → chunk-YQIPNAUH.cjs} +6 -6
  9. package/dist/index.cjs +73 -78
  10. package/dist/index.d.cts +0 -1
  11. package/dist/index.d.ts +0 -1
  12. package/dist/index.mjs +14 -15
  13. package/dist/ui/UIKitBadge.cjs +5 -5
  14. package/dist/ui/UIKitBadge.mjs +1 -1
  15. package/dist/ui/index.cjs +73 -78
  16. package/dist/ui/index.d.cts +0 -1
  17. package/dist/ui/index.d.ts +0 -1
  18. package/dist/ui/index.mjs +14 -15
  19. package/dist/ui/inputs/index.cjs +15 -15
  20. package/dist/ui/inputs/index.mjs +3 -3
  21. package/dist/ui/inputs/number-inputs/index.cjs +10 -10
  22. package/dist/ui/inputs/number-inputs/index.mjs +2 -2
  23. package/dist/ui/sidebar.cjs +26 -26
  24. package/dist/ui/sidebar.mjs +2 -2
  25. package/dist/ui/tree-view/TreeView.cjs +3 -3
  26. package/dist/ui/tree-view/TreeView.mjs +1 -1
  27. package/dist/ui/tree-view/hooks.cjs +3 -3
  28. package/dist/ui/tree-view/hooks.mjs +1 -1
  29. package/dist/ui/tree-view/index.cjs +6 -6
  30. package/dist/ui/tree-view/index.mjs +2 -2
  31. package/dist/ui/waterfall/hooks/useTimelineState.d.cts +1 -1
  32. package/dist/ui/waterfall/hooks/useTimelineState.d.ts +1 -1
  33. package/dist/ui/waterfall/index.cjs +5 -5
  34. package/dist/ui/waterfall/index.mjs +4 -4
  35. package/dist/ui/waterfall/types.d.cts +1 -1
  36. package/dist/ui/waterfall/types.d.ts +1 -1
  37. package/package.json +1 -1
  38. package/dist/chunk-AHNVEAOM.cjs +0 -855
  39. package/dist/chunk-LBENVTO2.mjs +0 -853
  40. package/dist/ui/timeline.cjs +0 -26
  41. package/dist/ui/timeline.d.cts +0 -42
  42. package/dist/ui/timeline.d.ts +0 -42
  43. package/dist/ui/timeline.mjs +0 -17
  44. package/dist/{chunk-WHKKMUON.mjs → chunk-36OE2ZZU.mjs} +1 -1
  45. package/dist/{chunk-PQZPTBQR.cjs → chunk-6TIUKO7B.cjs} +1 -1
  46. /package/dist/{chunk-KFPS5CCR.cjs → chunk-OX2U5RAG.cjs} +0 -0
  47. /package/dist/{chunk-G3EIVAVR.mjs → chunk-XMUP5MIM.mjs} +0 -0
@@ -1,855 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkD4W2G6CY_cjs = require('./chunk-D4W2G6CY.cjs');
4
- var chunkLCCNBVKZ_cjs = require('./chunk-LCCNBVKZ.cjs');
5
- var chunkOHIB3TEN_cjs = require('./chunk-OHIB3TEN.cjs');
6
- var lucideReact = require('lucide-react');
7
- var react = require('react');
8
- var jsxRuntime = require('react/jsx-runtime');
9
-
10
- var formatDuration = (seconds) => {
11
- const sign = seconds < 0 ? "-" : "";
12
- const absSeconds = Math.abs(seconds);
13
- if (absSeconds < 1) {
14
- if (absSeconds < 5e-4) return "0s";
15
- return `${sign}${Math.round(absSeconds * 1e3)}ms`;
16
- }
17
- if (absSeconds < 60) {
18
- return `${sign}${absSeconds.toFixed(3)}s`;
19
- }
20
- const SECONDS_IN_MINUTE = 60;
21
- const SECONDS_IN_HOUR = 3600;
22
- const SECONDS_IN_DAY = 86400;
23
- const SECONDS_IN_MONTH = 2592e3;
24
- const SECONDS_IN_YEAR = 31536e3;
25
- if (absSeconds < SECONDS_IN_HOUR) {
26
- const m = Math.floor(absSeconds / SECONDS_IN_MINUTE);
27
- const s = absSeconds % SECONDS_IN_MINUTE;
28
- return `${sign}${m}m ${s.toFixed(2).padStart(5, "0")}s`;
29
- }
30
- if (absSeconds < SECONDS_IN_DAY) {
31
- const h = Math.floor(absSeconds / SECONDS_IN_HOUR);
32
- const m = Math.floor(absSeconds % SECONDS_IN_HOUR / SECONDS_IN_MINUTE);
33
- const s = Math.floor(absSeconds % SECONDS_IN_MINUTE);
34
- return `${sign}${h}h ${String(m).padStart(2, "0")}m ${String(s).padStart(2, "0")}s`;
35
- }
36
- if (absSeconds < SECONDS_IN_MONTH) {
37
- const d2 = Math.floor(absSeconds / SECONDS_IN_DAY);
38
- const h = Math.floor(absSeconds % SECONDS_IN_DAY / SECONDS_IN_HOUR);
39
- const m = Math.floor(absSeconds % SECONDS_IN_HOUR / SECONDS_IN_MINUTE);
40
- return `${sign}${d2}d ${String(h).padStart(2, "0")}h ${String(m).padStart(2, "0")}m`;
41
- }
42
- if (absSeconds < SECONDS_IN_YEAR) {
43
- const mo2 = Math.floor(absSeconds / SECONDS_IN_MONTH);
44
- const d2 = Math.floor(absSeconds % SECONDS_IN_MONTH / SECONDS_IN_DAY);
45
- const h = Math.floor(absSeconds % SECONDS_IN_DAY / SECONDS_IN_HOUR);
46
- return `${sign}${mo2}mo ${String(d2).padStart(3, "0")}d ${String(h).padStart(2, "0")}h`;
47
- }
48
- const y = Math.floor(absSeconds / SECONDS_IN_YEAR);
49
- const mo = Math.floor(absSeconds % SECONDS_IN_YEAR / SECONDS_IN_MONTH);
50
- const d = Math.floor(absSeconds % SECONDS_IN_MONTH / SECONDS_IN_DAY);
51
- return `${sign}${y}y ${String(mo).padStart(2, "0")}mo ${String(d).padStart(3, "0")}d`;
52
- };
53
- var borderColorClasses = {
54
- blue: "border-blue-500/85",
55
- green: "border-green-500/85",
56
- orange: "border-orange-500/85",
57
- purple: "border-purple-500/85",
58
- "gray-light": "border-line-primary/50",
59
- "gray-medium": "border-slate-500/85"
60
- };
61
- var colorClasses = {
62
- blue: "bg-blue-500/85",
63
- green: "bg-green-500/85",
64
- orange: "bg-orange-500/85",
65
- purple: "bg-purple-500/85",
66
- "gray-light": "bg-line-secondary/20",
67
- "gray-medium": "bg-slate-500/85"
68
- };
69
- var leftWedgeClasses = {
70
- blue: "border-l-blue-500/85",
71
- green: "border-l-green-500/85",
72
- orange: "border-l-orange-500/85",
73
- purple: "border-l-purple-500/85",
74
- "gray-light": "border-l-slate-300",
75
- "gray-medium": "border-l-slate-500/85"
76
- };
77
- var rightWedgeClasses = {
78
- blue: "border-r-blue-500/85",
79
- green: "border-r-green-500/85",
80
- orange: "border-r-orange-500/85",
81
- purple: "border-r-purple-500/85",
82
- "gray-light": "border-r-slate-300",
83
- "gray-medium": "border-r-slate-500/85"
84
- };
85
- function Timeline({
86
- data,
87
- totalDuration,
88
- getIcon,
89
- getPointEventIcon,
90
- pointEventTypeColorMap
91
- }) {
92
- const [visibleData, setVisibleData] = react.useState([]);
93
- const [hoveredId, setHoveredId] = react.useState(null);
94
- const [hoveredBarInfo, setHoveredBarInfo] = react.useState(
95
- null
96
- );
97
- const timelineContainerRef = react.useRef(null);
98
- const [timelineWidth, setTimelineWidth] = react.useState(0);
99
- const [viewStart, setViewStart] = react.useState(-totalDuration * 0.25);
100
- const [viewDuration, setViewDuration] = react.useState(totalDuration * 1.5);
101
- const timeToPercent = react.useCallback(
102
- (time) => (time - viewStart) / viewDuration * 100,
103
- [viewStart, viewDuration]
104
- );
105
- const iconVisibleEvents = react.useMemo(() => {
106
- const iconEvents = /* @__PURE__ */ new Set();
107
- if (timelineWidth === 0) return iconEvents;
108
- const ICON_SPACING_PX = 16;
109
- const minTimeGap = ICON_SPACING_PX / timelineWidth * viewDuration;
110
- const showIconsInGeneral = viewDuration / totalDuration < 2;
111
- if (!showIconsInGeneral) return iconEvents;
112
- visibleData.forEach((item) => {
113
- const { pointEvents } = item;
114
- if (!pointEvents || pointEvents.length === 0) return;
115
- const isDense = new Array(pointEvents.length).fill(false);
116
- for (let i = 0; i < pointEvents.length - 1; i++) {
117
- if (pointEvents[i + 1].time - pointEvents[i].time < minTimeGap) {
118
- isDense[i] = true;
119
- isDense[i + 1] = true;
120
- }
121
- }
122
- pointEvents.forEach((event, index) => {
123
- if (!isDense[index]) {
124
- const eventId = `${item.id}-event-${index}`;
125
- iconEvents.add(eventId);
126
- }
127
- });
128
- });
129
- return iconEvents;
130
- }, [visibleData, viewDuration, timelineWidth, totalDuration]);
131
- const baseBarLayouts = react.useMemo(() => {
132
- const layouts = {};
133
- visibleData.forEach((item) => {
134
- if (!item.bars || item.bars.length === 0) {
135
- return;
136
- }
137
- const itemLayouts = Array(item.bars.length);
138
- const indexedBars = item.bars.map((b, i) => ({
139
- ...b,
140
- originalIndex: i,
141
- endTime: b.startTime + b.duration
142
- }));
143
- const adj = Array(item.bars.length).fill(0).map(() => []);
144
- for (let i = 0; i < indexedBars.length; i++) {
145
- for (let j = i + 1; j < indexedBars.length; j++) {
146
- const bar1 = indexedBars[i];
147
- const bar2 = indexedBars[j];
148
- if (bar1.startTime < bar2.endTime && bar2.startTime < bar1.endTime) {
149
- adj[i].push(j);
150
- adj[j].push(i);
151
- }
152
- }
153
- }
154
- const visited = /* @__PURE__ */ new Set();
155
- const groups = [];
156
- for (let i = 0; i < indexedBars.length; i++) {
157
- if (!visited.has(i)) {
158
- const component = [];
159
- const queue = [i];
160
- visited.add(i);
161
- while (queue.length > 0) {
162
- const u = queue.shift();
163
- component.push(indexedBars[u]);
164
- adj[u].forEach((v) => {
165
- if (!visited.has(v)) {
166
- visited.add(v);
167
- queue.push(v);
168
- }
169
- });
170
- }
171
- groups.push(component.sort((a, b) => a.startTime - b.startTime));
172
- }
173
- }
174
- groups.forEach((group) => {
175
- const n = group.length;
176
- if (n === 1) {
177
- const bar = group[0];
178
- itemLayouts[bar.originalIndex] = {
179
- top: "50%",
180
- height: "20px",
181
- transform: "translateY(-50%)",
182
- zIndex: 10
183
- };
184
- } else {
185
- const barHeight = 20 / n;
186
- const totalHeight = barHeight * n;
187
- const startTop = (32 - totalHeight) / 2;
188
- group.forEach((bar, indexInGroup) => {
189
- itemLayouts[bar.originalIndex] = {
190
- height: `${barHeight}px`,
191
- top: `${startTop + indexInGroup * barHeight}px`,
192
- zIndex: 10
193
- };
194
- });
195
- }
196
- });
197
- layouts[item.id] = itemLayouts;
198
- });
199
- return layouts;
200
- }, [visibleData]);
201
- const hoverBarLayouts = react.useMemo(() => {
202
- if (!hoveredBarInfo) return {};
203
- const layouts = {};
204
- const hoveredItem = visibleData.find((item) => item.id === hoveredBarInfo.itemId);
205
- if (!hoveredItem || !hoveredItem.bars) return {};
206
- const itemLayouts = Array(hoveredItem.bars.length);
207
- const indexedBars = hoveredItem.bars.map((b, i) => ({
208
- ...b,
209
- originalIndex: i,
210
- endTime: b.startTime + b.duration
211
- }));
212
- const hoveredBar = indexedBars[hoveredBarInfo.barIndex];
213
- if (!hoveredBar) return {};
214
- const overlappingBars = indexedBars.filter(
215
- (bar) => bar.originalIndex !== hoveredBar.originalIndex && bar.startTime < hoveredBar.endTime && hoveredBar.startTime < bar.endTime
216
- );
217
- if (overlappingBars.length === 0) return {};
218
- const allBarsInGroup = [hoveredBar, ...overlappingBars].sort(
219
- (a, b) => a.startTime - b.startTime
220
- );
221
- const hoveredGroupIndex = allBarsInGroup.findIndex(
222
- (bar) => bar.originalIndex === hoveredBar.originalIndex
223
- );
224
- const n = allBarsInGroup.length;
225
- const hoveredBarHeight = 16;
226
- const remainingHeight = 20 - hoveredBarHeight;
227
- const otherBarHeight = remainingHeight / (n - 1);
228
- const totalHeight = hoveredBarHeight + (n - 1) * otherBarHeight;
229
- const startTop = (32 - totalHeight) / 2;
230
- allBarsInGroup.forEach((bar, indexInGroup) => {
231
- if (indexInGroup === hoveredGroupIndex) {
232
- const barsBeforeHovered = hoveredGroupIndex;
233
- const topForHovered = startTop + barsBeforeHovered * otherBarHeight;
234
- itemLayouts[bar.originalIndex] = {
235
- height: `${hoveredBarHeight}px`,
236
- top: `${topForHovered}px`,
237
- zIndex: 20
238
- };
239
- } else if (indexInGroup < hoveredGroupIndex) {
240
- itemLayouts[bar.originalIndex] = {
241
- height: `${otherBarHeight}px`,
242
- top: `${startTop + indexInGroup * otherBarHeight}px`,
243
- zIndex: 10
244
- };
245
- } else {
246
- itemLayouts[bar.originalIndex] = {
247
- height: `${otherBarHeight}px`,
248
- top: `${startTop + hoveredBarHeight + (indexInGroup - hoveredGroupIndex - 1) * otherBarHeight}px`,
249
- zIndex: 10
250
- };
251
- }
252
- });
253
- layouts[hoveredBarInfo.itemId] = itemLayouts;
254
- return layouts;
255
- }, [visibleData, hoveredBarInfo]);
256
- const barLayouts = react.useMemo(() => {
257
- const merged = { ...baseBarLayouts };
258
- Object.keys(hoverBarLayouts).forEach((itemId) => {
259
- if (merged[itemId]) {
260
- merged[itemId] = { ...merged[itemId], ...hoverBarLayouts[itemId] };
261
- }
262
- });
263
- return merged;
264
- }, [baseBarLayouts, hoverBarLayouts]);
265
- const timeStyles = react.useMemo(() => {
266
- const styles = {};
267
- visibleData.forEach((item) => {
268
- if (!item.bars) return;
269
- const itemStyles = {};
270
- item.bars.forEach((bar, index) => {
271
- itemStyles[index] = {
272
- left: `${timeToPercent(bar.startTime)}%`,
273
- width: `${bar.duration / viewDuration * 100}%`
274
- };
275
- });
276
- styles[item.id] = itemStyles;
277
- });
278
- return styles;
279
- }, [visibleData, timeToPercent, viewDuration]);
280
- const pointEventPositions = react.useMemo(() => {
281
- const positions = {};
282
- visibleData.forEach((item) => {
283
- if (!item.pointEvents) return;
284
- const itemPositions = {};
285
- item.pointEvents.forEach((event, index) => {
286
- const percent = timeToPercent(event.time);
287
- const eventId = `${item.id}-event-${index}`;
288
- const showIcon = iconVisibleEvents.has(eventId);
289
- itemPositions[index] = {
290
- percent,
291
- left: showIcon ? `calc(${percent}% - 8px)` : `calc(${percent}% - 3px)`
292
- };
293
- });
294
- positions[item.id] = itemPositions;
295
- });
296
- return positions;
297
- }, [visibleData, timeToPercent, iconVisibleEvents]);
298
- const getBarHeight = react.useCallback(
299
- (itemId, barIndex) => {
300
- const layout = barLayouts[itemId]?.[barIndex];
301
- if (!layout) return 20;
302
- const heightStr = layout.height;
303
- if (typeof heightStr === "string") {
304
- if (heightStr.endsWith("px")) {
305
- return parseFloat(heightStr);
306
- } else if (heightStr.endsWith("%")) {
307
- return parseFloat(heightStr) / 100 * 32;
308
- }
309
- }
310
- return 20;
311
- },
312
- [barLayouts]
313
- );
314
- react.useEffect(() => {
315
- const container = timelineContainerRef.current;
316
- if (!container) return;
317
- const resizeObserver = new ResizeObserver((entries) => {
318
- if (entries[0]) {
319
- setTimelineWidth(entries[0].contentRect.width);
320
- }
321
- });
322
- resizeObserver.observe(container);
323
- setTimelineWidth(container.offsetWidth);
324
- return () => {
325
- resizeObserver.disconnect();
326
- };
327
- }, []);
328
- const handlePan = (direction) => {
329
- const panAmount = viewDuration * 0.1;
330
- if (direction === "left") {
331
- setViewStart((s) => s - panAmount);
332
- } else {
333
- setViewStart((s) => s + panAmount);
334
- }
335
- };
336
- const timeMarkers = react.useMemo(() => {
337
- const markers = [];
338
- const niceIntervals = [
339
- 1e-3,
340
- 2e-3,
341
- 5e-3,
342
- 0.01,
343
- 0.02,
344
- 0.05,
345
- 0.1,
346
- 0.2,
347
- 0.5,
348
- 1,
349
- 2,
350
- 5,
351
- 10,
352
- 20,
353
- 50,
354
- 100
355
- ];
356
- const targetMarkerCount = 10;
357
- const rawInterval = viewDuration / targetMarkerCount;
358
- const interval = niceIntervals.find((i) => i > rawInterval) || niceIntervals[niceIntervals.length - 1];
359
- const viewEnd = viewStart + viewDuration;
360
- const shownSeconds = /* @__PURE__ */ new Set();
361
- const formatTickLabel = (seconds) => {
362
- const sign = seconds < 0 ? "-" : "";
363
- const absSeconds = Math.abs(seconds);
364
- let s = Math.floor(absSeconds);
365
- let ms = Math.round((absSeconds - s) * 1e3);
366
- if (ms >= 1e3) {
367
- s += 1;
368
- ms -= 1e3;
369
- }
370
- if (absSeconds < 1 && absSeconds > -1) {
371
- return `${sign}${ms}ms`;
372
- }
373
- const baseSecond = s * (sign === "-" ? -1 : 1);
374
- if (shownSeconds.has(baseSecond)) {
375
- return ms > 0 ? `+${ms}ms` : "";
376
- }
377
- shownSeconds.add(baseSecond);
378
- if (ms === 0) {
379
- return `${sign}${s}s`;
380
- }
381
- return `${sign}${s}s`;
382
- };
383
- const firstMarkerTime = Math.floor(viewStart / interval) * interval;
384
- const lastMarkerTime = Math.ceil(viewEnd / interval) * interval;
385
- for (let time = firstMarkerTime; time <= lastMarkerTime; time += interval) {
386
- const roundedTime = Number.parseFloat(time.toPrecision(15));
387
- const label = formatTickLabel(roundedTime);
388
- if (label) {
389
- markers.push({ time: roundedTime, label });
390
- }
391
- }
392
- return markers;
393
- }, [viewStart, viewDuration]);
394
- const keyEventTimes = react.useMemo(() => {
395
- const events = [];
396
- const timeSet = /* @__PURE__ */ new Set();
397
- const addEvent = (time, type) => {
398
- const key = `${time.toFixed(6)}-${type}`;
399
- if (!timeSet.has(key)) {
400
- events.push({ time, type });
401
- timeSet.add(key);
402
- }
403
- };
404
- visibleData.forEach((item) => {
405
- (item.bars || []).forEach((bar) => {
406
- if (bar.createTime !== void 0) addEvent(bar.createTime, "create");
407
- addEvent(bar.startTime, "start");
408
- addEvent(bar.startTime + bar.duration, "end");
409
- });
410
- item.pointEvents?.forEach((event) => {
411
- addEvent(event.time, event.type);
412
- });
413
- });
414
- return events.sort((a, b) => a.time - b.time);
415
- }, [visibleData]);
416
- const cursorContainerRef = react.useRef(null);
417
- const lastClientX = react.useRef(0);
418
- const isMouseOver = react.useRef(false);
419
- const animationFrameRef = react.useRef(null);
420
- const updateCursor = react.useCallback(() => {
421
- if (!isMouseOver.current) return;
422
- const timelineEl = timelineContainerRef.current;
423
- const cursorEl = cursorContainerRef.current;
424
- if (!timelineEl || !cursorEl) return;
425
- const rect = timelineEl.getBoundingClientRect();
426
- const cursorX = lastClientX.current - rect.left;
427
- const rawHoverTime = viewStart + cursorX / timelineEl.offsetWidth * viewDuration;
428
- const snapThresholdInPixels = 8;
429
- const snapThresholdInTime = snapThresholdInPixels / timelineEl.offsetWidth * viewDuration;
430
- let closestSnap = null;
431
- let minDistance = Number.POSITIVE_INFINITY;
432
- for (const event of keyEventTimes) {
433
- const distance = Math.abs(event.time - rawHoverTime);
434
- if (distance < minDistance && distance < snapThresholdInTime) {
435
- minDistance = distance;
436
- closestSnap = event;
437
- }
438
- }
439
- const displayTime = closestSnap?.time ?? rawHoverTime;
440
- const percent = timeToPercent(displayTime);
441
- cursorEl.style.setProperty("--cursor-left", `${percent}%`);
442
- cursorEl.style.setProperty("--readout-text", `"${formatDuration(displayTime)}"`);
443
- cursorEl.style.setProperty("--magnet-opacity", closestSnap ? "1" : "0");
444
- cursorEl.classList.remove("opacity-0");
445
- }, [viewStart, viewDuration, keyEventTimes, timeToPercent]);
446
- react.useEffect(() => {
447
- const timelineEl = timelineContainerRef.current;
448
- if (!timelineEl) return;
449
- const handleMouseMove = (e) => {
450
- lastClientX.current = e.clientX;
451
- if (animationFrameRef.current) cancelAnimationFrame(animationFrameRef.current);
452
- animationFrameRef.current = requestAnimationFrame(updateCursor);
453
- };
454
- const handleMouseEnter = () => {
455
- isMouseOver.current = true;
456
- };
457
- const handleMouseLeave = () => {
458
- isMouseOver.current = false;
459
- if (animationFrameRef.current) cancelAnimationFrame(animationFrameRef.current);
460
- cursorContainerRef.current?.classList.add("opacity-0");
461
- };
462
- timelineEl.addEventListener("mousemove", handleMouseMove);
463
- timelineEl.addEventListener("mouseenter", handleMouseEnter);
464
- timelineEl.addEventListener("mouseleave", handleMouseLeave);
465
- return () => {
466
- timelineEl.removeEventListener("mousemove", handleMouseMove);
467
- timelineEl.removeEventListener("mouseenter", handleMouseEnter);
468
- timelineEl.removeEventListener("mouseleave", handleMouseLeave);
469
- if (animationFrameRef.current) cancelAnimationFrame(animationFrameRef.current);
470
- };
471
- }, [updateCursor]);
472
- react.useEffect(() => {
473
- const timelineEl = timelineContainerRef.current;
474
- if (!timelineEl) return;
475
- const wheelHandler = (e) => {
476
- e.preventDefault();
477
- const container = timelineContainerRef.current;
478
- if (!container) return;
479
- if (e.ctrlKey || e.altKey) {
480
- const rect = container.getBoundingClientRect();
481
- const cursorX = e.clientX - rect.left;
482
- const timeAtCursor = viewStart + cursorX / container.offsetWidth * viewDuration;
483
- const zoomFactor = 1.1;
484
- const newDuration = e.deltaY < 0 ? viewDuration / zoomFactor : viewDuration * zoomFactor;
485
- const minDuration = 0.01;
486
- const maxDuration = totalDuration * 10;
487
- if (newDuration < minDuration || newDuration > maxDuration) return;
488
- const newViewStart = timeAtCursor - cursorX / container.offsetWidth * newDuration;
489
- setViewDuration(newDuration);
490
- setViewStart(newViewStart);
491
- } else {
492
- const panX = e.deltaX / container.offsetWidth * viewDuration;
493
- const panY = e.deltaY / container.offsetWidth * viewDuration;
494
- setViewStart((s) => s + panX + panY);
495
- }
496
- };
497
- timelineEl.addEventListener("wheel", wheelHandler, { passive: false });
498
- return () => {
499
- timelineEl.removeEventListener("wheel", wheelHandler);
500
- };
501
- }, [viewStart, viewDuration, totalDuration]);
502
- react.useEffect(() => {
503
- if (isMouseOver.current) {
504
- if (animationFrameRef.current) cancelAnimationFrame(animationFrameRef.current);
505
- animationFrameRef.current = requestAnimationFrame(updateCursor);
506
- }
507
- }, [viewStart, viewDuration, updateCursor]);
508
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-bg-primary text-text-primary border-line-primary/50 rounded-uk-md mx-auto w-full overflow-hidden border font-sans shadow-[0_4px_16px_0_var(--color-shadow-secondary)]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(300px,30%)_1fr]", children: [
509
- /* @__PURE__ */ jsxRuntime.jsx(
510
- chunkD4W2G6CY_cjs.TreeView,
511
- {
512
- data,
513
- getIcon,
514
- onVisibleDataChange: setVisibleData,
515
- onItemHover: setHoveredId,
516
- hoveredId
517
- }
518
- ),
519
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
520
- /* @__PURE__ */ jsxRuntime.jsxs(
521
- "div",
522
- {
523
- className: "border-line-primary/50 scrollbar-hide relative cursor-crosshair overflow-x-auto border-l active:cursor-grabbing",
524
- ref: timelineContainerRef,
525
- children: [
526
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-bg-primary sticky top-0 z-10", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-line-primary/50 relative h-8 border-b", children: [
527
- keyEventTimes.map(({ time }, tickIndex) => {
528
- const percent = timeToPercent(time);
529
- if (percent < 0 || percent > 100) return null;
530
- return /* @__PURE__ */ jsxRuntime.jsx(
531
- "div",
532
- {
533
- className: "bg-bg-tertiary absolute top-1/2 z-0 h-1 w-1 -translate-y-1/2 rounded-full",
534
- style: { left: `${percent}%` }
535
- },
536
- `snap-${time}-${tickIndex}`
537
- );
538
- }),
539
- timeMarkers.map((marker, ind) => {
540
- const naturalCenterPercent = timeToPercent(marker.time);
541
- if (naturalCenterPercent < -20 || naturalCenterPercent > 120) {
542
- return null;
543
- }
544
- const labelHalfWidthPercent = 3;
545
- const clampedCenterPercent = Math.min(
546
- 100 - labelHalfWidthPercent,
547
- Math.max(labelHalfWidthPercent, naturalCenterPercent)
548
- );
549
- const zInd = ind < timeMarkers.length - 1 ? "10" : "0";
550
- return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
551
- /* @__PURE__ */ jsxRuntime.jsx(
552
- "div",
553
- {
554
- className: "bg-line-primary absolute top-0 h-full w-px",
555
- style: { left: `${naturalCenterPercent}%` }
556
- }
557
- ),
558
- /* @__PURE__ */ jsxRuntime.jsx(
559
- "div",
560
- {
561
- className: chunkOHIB3TEN_cjs.cn(
562
- "bg-bg-primary text-text-secondary rounded-uk-xs text-uk-sm pointer-events-none absolute top-1/2 -translate-x-1/2 -translate-y-1/2 px-1 backdrop-blur-sm",
563
- "z-" + zInd
564
- ),
565
- style: { left: `${clampedCenterPercent}%` },
566
- children: marker.label
567
- }
568
- )
569
- ] }, marker.time);
570
- })
571
- ] }) }),
572
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative pb-12", children: visibleData.map((item) => {
573
- const viewEnd = viewStart + viewDuration;
574
- const itemBarLayouts = barLayouts[item.id] || [];
575
- return /* @__PURE__ */ jsxRuntime.jsxs(
576
- "div",
577
- {
578
- className: chunkOHIB3TEN_cjs.cn(
579
- "relative h-[32px]",
580
- hoveredId === item.id && "bg-bg-secondary/80"
581
- ),
582
- onMouseEnter: () => setHoveredId(item.id),
583
- onMouseLeave: () => setHoveredId(null),
584
- children: [
585
- (item.bars || []).map((bar, index) => {
586
- const barStart = bar.startTime;
587
- const barEnd = bar.startTime + bar.duration;
588
- const isHaltedStep = bar.isHalted;
589
- const layoutStyle = itemBarLayouts[index] || {};
590
- const timeStyle = timeStyles[item.id]?.[index] || {};
591
- const combinedStyle = { ...timeStyle, ...layoutStyle };
592
- return /* @__PURE__ */ jsxRuntime.jsxs(
593
- "div",
594
- {
595
- className: "absolute",
596
- style: {
597
- ...combinedStyle
598
- },
599
- onMouseEnter: () => setHoveredBarInfo({ itemId: item.id, barIndex: index }),
600
- onMouseLeave: () => setHoveredBarInfo(null),
601
- children: [
602
- bar.createTime !== void 0 && bar.createTime < bar.startTime && bar.color && /* @__PURE__ */ jsxRuntime.jsxs(
603
- "div",
604
- {
605
- className: "absolute top-1/2 right-full h-2 -translate-y-1/2",
606
- style: {
607
- width: `${(bar.startTime - bar.createTime) / viewDuration * 100}%`
608
- },
609
- children: [
610
- /* @__PURE__ */ jsxRuntime.jsx(
611
- "div",
612
- {
613
- className: chunkOHIB3TEN_cjs.cn(
614
- "absolute top-1/2 left-0 h-2 w-px -translate-y-1/2",
615
- colorClasses[bar.color]
616
- )
617
- }
618
- ),
619
- /* @__PURE__ */ jsxRuntime.jsx(
620
- "div",
621
- {
622
- className: chunkOHIB3TEN_cjs.cn(
623
- "absolute top-1/2 w-full -translate-y-1/2 border-t",
624
- borderColorClasses[bar.color]
625
- )
626
- }
627
- ),
628
- /* @__PURE__ */ jsxRuntime.jsx(
629
- "div",
630
- {
631
- className: chunkOHIB3TEN_cjs.cn(
632
- "absolute top-1/2 right-0 h-2 w-px -translate-y-1/2",
633
- colorClasses[bar.color]
634
- )
635
- }
636
- )
637
- ]
638
- }
639
- ),
640
- !isHaltedStep && /* @__PURE__ */ jsxRuntime.jsx(
641
- "div",
642
- {
643
- className: chunkOHIB3TEN_cjs.cn(
644
- "rounded-uk-xs absolute top-0 left-0 flex h-full w-full items-center justify-center overflow-hidden",
645
- bar.color && colorClasses[bar.color],
646
- bar.hasStripes && "bg-[repeating-linear-gradient(-45deg,transparent,transparent_4px,rgba(0,0,0,0.1)_4px,rgba(0,0,0,0.1)_8px)]"
647
- )
648
- }
649
- ),
650
- !isHaltedStep && (() => {
651
- const visibleStart = Math.max(barStart, viewStart);
652
- const visibleEnd = Math.min(barEnd, viewEnd);
653
- if (visibleEnd <= visibleStart) return null;
654
- const visibleDuration = visibleEnd - visibleStart;
655
- const visibleWidthPercent = visibleDuration / viewDuration * 100;
656
- if (visibleWidthPercent < 4) return null;
657
- const barHeight = getBarHeight(item.id, index);
658
- if (barHeight < 12) return null;
659
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute top-0 left-0 flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
660
- "span",
661
- {
662
- className: chunkOHIB3TEN_cjs.cn(
663
- "text-uk-sm font-medium whitespace-nowrap",
664
- bar.color === "gray-light" || bar.color === "gray-medium" ? "text-slate-600 dark:text-slate-300" : "text-text-highlight"
665
- ),
666
- children: formatDuration(bar.duration)
667
- }
668
- ) });
669
- })(),
670
- !isHaltedStep && bar.color && /* @__PURE__ */ jsxRuntime.jsx(
671
- "div",
672
- {
673
- className: chunkOHIB3TEN_cjs.cn(
674
- "bg-bg-primary absolute top-1/2 z-10 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full border-2",
675
- borderColorClasses[bar.color]
676
- ),
677
- style: {
678
- left: "0%"
679
- }
680
- }
681
- ),
682
- isHaltedStep && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-0 left-0 flex h-full w-full items-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex h-full w-full items-center justify-center", children: [
683
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-line-secondary absolute top-1/2 left-0 h-2 w-px -translate-y-1/2" }),
684
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-line-secondary w-full border-t border-dashed" }),
685
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-line-secondary absolute top-1/2 right-0 h-2 w-px -translate-y-1/2" })
686
- ] }) }),
687
- isHaltedStep && (() => {
688
- const visibleStart = Math.max(barStart, viewStart);
689
- const visibleEnd = Math.min(barEnd, viewEnd);
690
- if (visibleEnd <= visibleStart) return null;
691
- const visibleDuration = visibleEnd - visibleStart;
692
- const visibleWidthPercent = visibleDuration / viewDuration * 100;
693
- if (visibleWidthPercent < 4) return null;
694
- const barHeight = getBarHeight(item.id, index);
695
- if (barHeight < 12) return null;
696
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute top-0 left-0 flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-text-highlight text-uk-sm flex h-5 items-center rounded-full bg-orange-500/85 px-2 font-medium whitespace-nowrap", children: formatDuration(bar.duration) }) });
697
- })()
698
- ]
699
- },
700
- index
701
- );
702
- }),
703
- item.pointEvents?.map((event, index) => {
704
- const position = pointEventPositions[item.id]?.[index];
705
- if (!position || position.percent < 0 || position.percent > 100) return null;
706
- const eventId = `${item.id}-event-${index}`;
707
- const showIcon = iconVisibleEvents.has(eventId);
708
- const colorName = event.color || pointEventTypeColorMap[event.type];
709
- return /* @__PURE__ */ jsxRuntime.jsx(chunkLCCNBVKZ_cjs.TooltipProvider, { delayDuration: 100, children: /* @__PURE__ */ jsxRuntime.jsxs(chunkLCCNBVKZ_cjs.Tooltip, { children: [
710
- /* @__PURE__ */ jsxRuntime.jsx(chunkLCCNBVKZ_cjs.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
711
- "div",
712
- {
713
- className: "absolute top-1/2 -translate-y-1/2",
714
- style: { left: position.left },
715
- children: showIcon ? getPointEventIcon(event) : /* @__PURE__ */ jsxRuntime.jsx(
716
- "div",
717
- {
718
- className: chunkOHIB3TEN_cjs.cn("size-1.5 rounded-full"),
719
- style: { backgroundColor: colorName }
720
- }
721
- )
722
- }
723
- ) }),
724
- /* @__PURE__ */ jsxRuntime.jsx(chunkLCCNBVKZ_cjs.TooltipContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: event.type }) })
725
- ] }) }, `${item.id}-event-${index}`);
726
- })
727
- ]
728
- },
729
- item.id
730
- );
731
- }) }),
732
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute top-0 left-0 z-10 h-full w-2", children: visibleData.map((item, index) => {
733
- const bars = item.bars || [];
734
- const offscreenBar = bars.find((bar) => bar.startTime + bar.duration < viewStart);
735
- const pointEventsStart = item.pointEvents?.reduce(
736
- (max, event) => Math.min(max, event.time),
737
- Infinity
738
- );
739
- const hasPointEventOffscreenLeft = pointEventsStart !== void 0 && pointEventsStart < viewStart;
740
- const wedgeColor = offscreenBar?.color || (hasPointEventOffscreenLeft ? item.color : void 0);
741
- if (wedgeColor) {
742
- return /* @__PURE__ */ jsxRuntime.jsx(
743
- "div",
744
- {
745
- className: chunkOHIB3TEN_cjs.cn(
746
- "absolute h-0 w-0 border-y-[6px] border-r-[5px] border-y-transparent",
747
- rightWedgeClasses[wedgeColor]
748
- ),
749
- style: {
750
- top: `${32 + index * 32 + 16}px`,
751
- transform: "translateY(-50%)"
752
- }
753
- },
754
- `left-wedge-${item.id}`
755
- );
756
- }
757
- return null;
758
- }) }),
759
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute top-0 right-0 z-10 h-full w-2", children: visibleData.map((item, index) => {
760
- const bars = item.bars || [];
761
- const viewEnd = viewStart + viewDuration;
762
- const offscreenBar = bars.find((bar) => bar.startTime > viewEnd);
763
- const pointEventsEnd = item.pointEvents?.reduce(
764
- (min, event) => Math.max(min, event.time),
765
- -Infinity
766
- );
767
- const hasPointEventOffscreenRight = pointEventsEnd !== void 0 && pointEventsEnd > viewEnd;
768
- const wedgeColor = offscreenBar?.color || (hasPointEventOffscreenRight ? item.color : void 0);
769
- if (wedgeColor) {
770
- return /* @__PURE__ */ jsxRuntime.jsx(
771
- "div",
772
- {
773
- className: chunkOHIB3TEN_cjs.cn(
774
- "absolute h-0 w-0 border-y-[6px] border-l-[5px] border-y-transparent",
775
- leftWedgeClasses[wedgeColor]
776
- ),
777
- style: {
778
- top: `${32 + index * 32 + 16}px`,
779
- transform: "translateY(-50%)"
780
- }
781
- },
782
- `right-wedge-${item.id}`
783
- );
784
- }
785
- return null;
786
- }) }),
787
- /* @__PURE__ */ jsxRuntime.jsxs(
788
- "div",
789
- {
790
- ref: cursorContainerRef,
791
- className: "pointer-events-none absolute top-0 left-0 z-10 h-full w-full opacity-0 transition-opacity duration-150",
792
- style: {
793
- "--cursor-left": "0%",
794
- "--readout-text": '""',
795
- "--magnet-opacity": "0"
796
- },
797
- children: [
798
- /* @__PURE__ */ jsxRuntime.jsx(
799
- "div",
800
- {
801
- className: "absolute top-0 h-full w-px bg-red-500",
802
- style: { left: "var(--cursor-left)" }
803
- }
804
- ),
805
- /* @__PURE__ */ jsxRuntime.jsxs(
806
- "div",
807
- {
808
- className: "bg-bg-primary border-line-primary/50 rounded-uk-sm text-uk-sm absolute top-1 flex items-center justify-center border px-2 py-0.5 whitespace-nowrap shadow-[0_4px_16px_0_var(--color-shadow-secondary)]",
809
- style: {
810
- left: "var(--cursor-left)",
811
- transform: "translateX(-50%)",
812
- minWidth: "11ch"
813
- },
814
- children: [
815
- /* @__PURE__ */ jsxRuntime.jsx(
816
- lucideReact.Magnet,
817
- {
818
- className: "text-text-secondary mr-1.5 size-3 transition-opacity",
819
- style: { opacity: "var(--magnet-opacity)" }
820
- }
821
- ),
822
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono tabular-nums after:content-[var(--readout-text)]" })
823
- ]
824
- }
825
- )
826
- ]
827
- }
828
- )
829
- ]
830
- }
831
- ),
832
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-4 left-1/2 z-20 w-max -translate-x-1/2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-bg-primary/75 flex items-center gap-2 rounded-full p-1 shadow-[0_4px_16px_0_var(--color-shadow-secondary)] backdrop-blur-[2px]", children: [
833
- /* @__PURE__ */ jsxRuntime.jsx(
834
- "button",
835
- {
836
- onClick: () => handlePan("left"),
837
- className: "hover:bg-bg-secondary rounded-full p-1",
838
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "size-4" })
839
- }
840
- ),
841
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-uk-sm w-24 text-center font-mono", children: formatDuration(viewDuration) }),
842
- /* @__PURE__ */ jsxRuntime.jsx(
843
- "button",
844
- {
845
- onClick: () => handlePan("right"),
846
- className: "hover:bg-bg-secondary rounded-full p-1",
847
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "size-4" })
848
- }
849
- )
850
- ] }) })
851
- ] })
852
- ] }) });
853
- }
854
-
855
- exports.Timeline = Timeline;