@expcat/tigercat-react 2.1.0 → 2.1.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.
Files changed (144) hide show
  1. package/dist/{chunk-RUAPTIQ7.mjs → chunk-246DAUEF.mjs} +2 -2
  2. package/dist/{chunk-PU3JY6RE.mjs → chunk-2JMI7TCM.mjs} +1 -1
  3. package/dist/{chunk-GCY55TBC.mjs → chunk-2XZHYYZ2.mjs} +106 -91
  4. package/dist/chunk-2YBLMVDT.mjs +428 -0
  5. package/dist/{chunk-25D5TXZH.mjs → chunk-32MCQMBJ.mjs} +8 -6
  6. package/dist/{chunk-6MGQAJ62.mjs → chunk-3GPGSNOQ.mjs} +71 -16
  7. package/dist/{chunk-M5MZWOHF.mjs → chunk-3HHEVMHE.mjs} +1 -1
  8. package/dist/{chunk-HSBN5MLS.mjs → chunk-3LACOSJQ.mjs} +1 -1
  9. package/dist/{chunk-F6WV53BS.mjs → chunk-3LDDXHW2.mjs} +28 -11
  10. package/dist/{chunk-IXQAECFP.mjs → chunk-3QNIFKVF.mjs} +12 -14
  11. package/dist/{chunk-UD4DTVJZ.mjs → chunk-4C2X5PZO.mjs} +57 -25
  12. package/dist/chunk-5JETWHLJ.mjs +28 -0
  13. package/dist/{chunk-VA6PZWOH.mjs → chunk-5SEMRHBD.mjs} +14 -6
  14. package/dist/{chunk-MXXAJSRS.mjs → chunk-6RMBUZZE.mjs} +11 -11
  15. package/dist/{chunk-EKILTLUO.mjs → chunk-72CJNKDY.mjs} +1 -1
  16. package/dist/{chunk-XE4YFBOZ.mjs → chunk-AUD3VOLO.mjs} +1 -1
  17. package/dist/{chunk-I4MWOYJS.mjs → chunk-AYFKHWJS.mjs} +13 -7
  18. package/dist/{chunk-RPSHILHD.mjs → chunk-BXAH2GH3.mjs} +8 -2
  19. package/dist/{chunk-EW5EO7VE.mjs → chunk-BYD7EAWK.mjs} +1 -1
  20. package/dist/{chunk-L55UK45A.mjs → chunk-CRIEUKMD.mjs} +5 -2
  21. package/dist/{chunk-DKNVSQSV.mjs → chunk-CUAXRBKO.mjs} +12 -0
  22. package/dist/{chunk-NWVNTZOP.mjs → chunk-DECUASRW.mjs} +14 -16
  23. package/dist/{chunk-XMTEMBQV.mjs → chunk-EAAWB3CK.mjs} +16 -13
  24. package/dist/{chunk-IR7VA6AO.mjs → chunk-EG7EMDKK.mjs} +1 -1
  25. package/dist/{chunk-HOYBHB7B.mjs → chunk-FNK2VWPP.mjs} +1 -1
  26. package/dist/{chunk-RJPNBYK5.mjs → chunk-FQS24AUH.mjs} +12 -3
  27. package/dist/{chunk-LADKKOJT.mjs → chunk-GBEDWXLL.mjs} +16 -10
  28. package/dist/{chunk-2ENQZECC.mjs → chunk-HAXRHSCN.mjs} +4 -3
  29. package/dist/{chunk-K4GIKSZE.mjs → chunk-I2BENK5X.mjs} +2 -1
  30. package/dist/{chunk-DNOPEJ5I.mjs → chunk-JZZPLKTW.mjs} +7 -4
  31. package/dist/{chunk-7KCQMXJA.mjs → chunk-KDURW5AS.mjs} +4 -3
  32. package/dist/{chunk-TFMEHUVZ.mjs → chunk-KKN7KLTB.mjs} +0 -1
  33. package/dist/{chunk-PFL4HNWM.mjs → chunk-M6ZPTGBV.mjs} +1 -2
  34. package/dist/{chunk-PXRZ6CKY.mjs → chunk-MJVSZ2UJ.mjs} +46 -16
  35. package/dist/{chunk-LZKBDQE4.mjs → chunk-MYI3FPG4.mjs} +23 -4
  36. package/dist/{chunk-OIGEBCAS.mjs → chunk-NADODEZX.mjs} +69 -1
  37. package/dist/{chunk-UKY2EPS3.mjs → chunk-NJWTZ5MO.mjs} +54 -42
  38. package/dist/{chunk-ASLRAZZN.mjs → chunk-NXJMVH26.mjs} +5 -2
  39. package/dist/{chunk-773LH7BK.mjs → chunk-O6VYD4E4.mjs} +24 -2
  40. package/dist/{chunk-G7D4QV7A.mjs → chunk-O7TV5OKS.mjs} +33 -6
  41. package/dist/{chunk-DPWRXXXW.mjs → chunk-OJ6SHHOZ.mjs} +3 -3
  42. package/dist/{chunk-UYJJLHVA.mjs → chunk-PMQJ6AYT.mjs} +23 -21
  43. package/dist/{chunk-KC55B62J.mjs → chunk-PY2VUNEJ.mjs} +143 -46
  44. package/dist/{chunk-BEJZPJIK.mjs → chunk-QOAOOD53.mjs} +10 -4
  45. package/dist/{chunk-JQJM65RJ.mjs → chunk-QU3QXUTC.mjs} +49 -23
  46. package/dist/{chunk-RQ4PUK6G.mjs → chunk-R7YZ6FKP.mjs} +24 -13
  47. package/dist/{chunk-YI6YWH66.mjs → chunk-RE5ZLA5D.mjs} +6 -6
  48. package/dist/{chunk-UCBW5RJN.mjs → chunk-RGVU4EMA.mjs} +11 -6
  49. package/dist/{chunk-IBSOUQGB.mjs → chunk-RRGPDFDI.mjs} +7 -4
  50. package/dist/{chunk-ZH5ZBLAN.mjs → chunk-RUQ3F3MV.mjs} +34 -7
  51. package/dist/{chunk-KVCI2346.mjs → chunk-S2V3HGLZ.mjs} +8 -7
  52. package/dist/{chunk-PGD5RPKF.mjs → chunk-SVIJ2UZA.mjs} +2 -1
  53. package/dist/{chunk-UETARXIK.mjs → chunk-SXWEFZOF.mjs} +246 -53
  54. package/dist/{chunk-H6MVW5YD.mjs → chunk-TEVEXDY2.mjs} +24 -13
  55. package/dist/{chunk-DJOFM2VO.mjs → chunk-TO6MZFNQ.mjs} +52 -40
  56. package/dist/{chunk-ZCGIZOMT.mjs → chunk-V7HJ5HLC.mjs} +6 -10
  57. package/dist/{chunk-SIDDYP3O.mjs → chunk-VJWSKJLJ.mjs} +1 -1
  58. package/dist/{chunk-ZG56T75O.mjs → chunk-WTHWLCRL.mjs} +51 -11
  59. package/dist/{chunk-KP6DEYWB.mjs → chunk-X4L3W7RQ.mjs} +1 -1
  60. package/dist/{chunk-ZMRTETN2.mjs → chunk-X6C6MNG5.mjs} +4 -3
  61. package/dist/{chunk-OGG2TQDG.mjs → chunk-XVHTJQ4T.mjs} +12 -1
  62. package/dist/{chunk-FSMJLJFL.mjs → chunk-Y6UH3EKE.mjs} +1 -1
  63. package/dist/{chunk-7EMCZVJ2.mjs → chunk-YH7FKFRM.mjs} +4 -4
  64. package/dist/chunk-YJ5T4XZN.mjs +81 -0
  65. package/dist/{chunk-VVNFXJMN.mjs → chunk-YNDPQVEK.mjs} +8 -1
  66. package/dist/{chunk-QGZ32NFQ.mjs → chunk-Z23KOLNU.mjs} +4 -3
  67. package/dist/{chunk-5CKMYMTS.mjs → chunk-ZATZRXMW.mjs} +27 -8
  68. package/dist/components/ActivityFeed.mjs +2 -2
  69. package/dist/components/Affix.mjs +1 -1
  70. package/dist/components/Anchor.mjs +1 -1
  71. package/dist/components/AreaChart.mjs +4 -3
  72. package/dist/components/AutoComplete.mjs +1 -1
  73. package/dist/components/BarChart.mjs +4 -3
  74. package/dist/components/Calendar.mjs +1 -1
  75. package/dist/components/Cascader.mjs +1 -1
  76. package/dist/components/ChartCanvas.mjs +1 -1
  77. package/dist/components/ChatWindow.mjs +3 -3
  78. package/dist/components/Code.mjs +3 -1
  79. package/dist/components/CollapsePanel.mjs +1 -1
  80. package/dist/components/ColorPicker.d.mts +3 -1
  81. package/dist/components/ColorPicker.mjs +3 -1
  82. package/dist/components/CommentThread.mjs +2 -2
  83. package/dist/components/DataExport.mjs +2 -2
  84. package/dist/components/DataTableWithToolbar.mjs +7 -7
  85. package/dist/components/DonutChart.mjs +4 -4
  86. package/dist/components/Dropdown.mjs +1 -1
  87. package/dist/components/FileManager.mjs +2 -1
  88. package/dist/components/FloatButton.mjs +1 -1
  89. package/dist/components/FormItem.mjs +1 -1
  90. package/dist/components/FormWizard.mjs +1 -1
  91. package/dist/components/FunnelChart.mjs +3 -3
  92. package/dist/components/Gantt.d.mts +3 -1
  93. package/dist/components/Gantt.mjs +2 -2
  94. package/dist/components/GaugeChart.mjs +2 -2
  95. package/dist/components/HeatmapChart.mjs +3 -3
  96. package/dist/components/Image.mjs +4 -4
  97. package/dist/components/ImageGroup.mjs +2 -2
  98. package/dist/components/ImagePreview.mjs +1 -1
  99. package/dist/components/Input.mjs +1 -1
  100. package/dist/components/InputNumber.d.mts +1 -1
  101. package/dist/components/InputNumber.mjs +1 -1
  102. package/dist/components/Kanban.mjs +2 -2
  103. package/dist/components/LineChart.mjs +4 -3
  104. package/dist/components/List.mjs +2 -2
  105. package/dist/components/Loading.mjs +1 -1
  106. package/dist/components/MarkdownEditor.mjs +1 -1
  107. package/dist/components/MaskInput.mjs +1 -1
  108. package/dist/components/NotificationCenter.mjs +4 -4
  109. package/dist/components/OrgChart.mjs +2 -2
  110. package/dist/components/Pagination.mjs +1 -1
  111. package/dist/components/PieChart.mjs +3 -3
  112. package/dist/components/Popconfirm.mjs +2 -2
  113. package/dist/components/Popover.mjs +2 -2
  114. package/dist/components/QRCode.d.mts +2 -2
  115. package/dist/components/QRCode.mjs +1 -1
  116. package/dist/components/RadarChart.mjs +3 -3
  117. package/dist/components/Rate.mjs +1 -1
  118. package/dist/components/RichTextEditor.mjs +1 -1
  119. package/dist/components/ScatterChart.mjs +4 -3
  120. package/dist/components/ScrollSpy.mjs +1 -1
  121. package/dist/components/Select.mjs +1 -1
  122. package/dist/components/Signature.mjs +1 -1
  123. package/dist/components/SplitButton.mjs +2 -2
  124. package/dist/components/Splitter.mjs +1 -1
  125. package/dist/components/Stepper.d.mts +2 -0
  126. package/dist/components/Stepper.mjs +2 -1
  127. package/dist/components/SunburstChart.mjs +3 -3
  128. package/dist/components/Switch.d.mts +5 -1
  129. package/dist/components/Switch.mjs +2 -1
  130. package/dist/components/Table.mjs +3 -3
  131. package/dist/components/TaskBoard.mjs +1 -1
  132. package/dist/components/Textarea.mjs +1 -1
  133. package/dist/components/Tooltip.mjs +2 -2
  134. package/dist/components/Tour.mjs +1 -1
  135. package/dist/components/TreeMapChart.mjs +3 -3
  136. package/dist/components/TreeSelect.mjs +1 -1
  137. package/dist/components/Upload.mjs +1 -1
  138. package/dist/hooks/useChartInteraction.d.mts +5 -0
  139. package/dist/hooks/useChartInteraction.mjs +1 -1
  140. package/dist/index.d.mts +1 -1
  141. package/dist/index.mjs +57 -0
  142. package/package.json +2 -2
  143. package/dist/chunk-CB4SK5AU.mjs +0 -235
  144. package/dist/chunk-KPACLRQH.mjs +0 -55
@@ -0,0 +1,428 @@
1
+ import {
2
+ ChartCanvas
3
+ } from "./chunk-CUAXRBKO.mjs";
4
+
5
+ // src/components/Gantt.tsx
6
+ import { useEffect, useMemo, useRef, useState } from "react";
7
+ import {
8
+ applyGanttTaskDateOverlay,
9
+ classNames,
10
+ clampGanttDragDeltaX,
11
+ computeGanttLayout,
12
+ ganttAxisTextClasses,
13
+ ganttDateValuesEqual,
14
+ ganttDependencyClasses,
15
+ ganttLabelClasses,
16
+ ganttProgressClasses,
17
+ ganttRowClasses,
18
+ ganttTodayLineClasses,
19
+ getChartInnerRect,
20
+ getGanttTaskAriaLabel,
21
+ getGanttTaskClasses,
22
+ isBrowser,
23
+ moveGanttTaskByPx
24
+ } from "@expcat/tigercat-core";
25
+ import { jsx, jsxs } from "react/jsx-runtime";
26
+ var GANTT_BAR_CLICK_PX = 4;
27
+ function Gantt({
28
+ data,
29
+ width = 760,
30
+ height = 360,
31
+ padding = 24,
32
+ scale = "week",
33
+ rowHeight = 40,
34
+ barHeight = 18,
35
+ taskLabelWidth = 140,
36
+ timelineHeight = 36,
37
+ minDate,
38
+ maxDate,
39
+ minBarWidth = 6,
40
+ showToday = false,
41
+ showProgress = true,
42
+ showDependencies = true,
43
+ hoverable = false,
44
+ selectable = false,
45
+ selectedId,
46
+ activeOpacity = 1,
47
+ inactiveOpacity = 0.35,
48
+ dateFormatter,
49
+ colors,
50
+ title,
51
+ desc,
52
+ ariaLabel = "Gantt chart",
53
+ className,
54
+ onTaskClick,
55
+ onTaskHover,
56
+ onSelectedIdChange,
57
+ onTaskChange,
58
+ onDataChange
59
+ }) {
60
+ const [innerSelectedId, setInnerSelectedId] = useState(null);
61
+ const [hoveredId, setHoveredId] = useState(null);
62
+ const [dateOverlay, setDateOverlay] = useState(
63
+ () => /* @__PURE__ */ new Map()
64
+ );
65
+ const [dragPreview, setDragPreview] = useState(
66
+ null
67
+ );
68
+ const dragSessionRef = useRef(null);
69
+ const documentPointerListeningRef = useRef(false);
70
+ const suppressClickRef = useRef(false);
71
+ const dragFnsRef = useRef({
72
+ move: (_event) => {
73
+ },
74
+ finish: (_event) => {
75
+ }
76
+ });
77
+ const onDocumentPointerMove = useRef((event) => {
78
+ dragFnsRef.current.move(event);
79
+ }).current;
80
+ const onDocumentPointerEnd = useRef((event) => {
81
+ dragFnsRef.current.finish(event);
82
+ }).current;
83
+ const dataRef = useRef(data);
84
+ dataRef.current = data;
85
+ const dateOverlayRef = useRef(dateOverlay);
86
+ dateOverlayRef.current = dateOverlay;
87
+ const onTaskChangeRef = useRef(onTaskChange);
88
+ onTaskChangeRef.current = onTaskChange;
89
+ const onDataChangeRef = useRef(onDataChange);
90
+ onDataChangeRef.current = onDataChange;
91
+ const onTaskClickRef = useRef(onTaskClick);
92
+ onTaskClickRef.current = onTaskClick;
93
+ const onSelectedIdChangeRef = useRef(onSelectedIdChange);
94
+ onSelectedIdChangeRef.current = onSelectedIdChange;
95
+ const selectedIdRef = useRef(selectedId);
96
+ selectedIdRef.current = selectedId;
97
+ const selectableRef = useRef(selectable);
98
+ selectableRef.current = selectable;
99
+ const resolvedSelectedId = selectedId === void 0 ? innerSelectedId : selectedId;
100
+ const resolvedSelectedIdRef = useRef(resolvedSelectedId);
101
+ resolvedSelectedIdRef.current = resolvedSelectedId;
102
+ useEffect(
103
+ () => () => {
104
+ if (!documentPointerListeningRef.current || !isBrowser()) return;
105
+ document.removeEventListener("pointermove", onDocumentPointerMove);
106
+ document.removeEventListener("pointerup", onDocumentPointerEnd);
107
+ document.removeEventListener("pointercancel", onDocumentPointerEnd);
108
+ documentPointerListeningRef.current = false;
109
+ },
110
+ [onDocumentPointerEnd, onDocumentPointerMove]
111
+ );
112
+ const resolvedData = useMemo(
113
+ () => applyGanttTaskDateOverlay(data, dateOverlay),
114
+ [data, dateOverlay]
115
+ );
116
+ const innerRect = useMemo(
117
+ () => getChartInnerRect(width, height, padding),
118
+ [height, padding, width]
119
+ );
120
+ const layout = useMemo(
121
+ () => computeGanttLayout(resolvedData, {
122
+ width: innerRect.width,
123
+ rowHeight,
124
+ barHeight,
125
+ taskLabelWidth,
126
+ timelineHeight,
127
+ minDate,
128
+ maxDate,
129
+ minBarWidth,
130
+ scale,
131
+ colors,
132
+ today: showToday ? /* @__PURE__ */ new Date() : void 0,
133
+ dateFormatter
134
+ }),
135
+ [
136
+ barHeight,
137
+ colors,
138
+ dateFormatter,
139
+ innerRect.width,
140
+ maxDate,
141
+ minBarWidth,
142
+ minDate,
143
+ resolvedData,
144
+ rowHeight,
145
+ scale,
146
+ showToday,
147
+ taskLabelWidth,
148
+ timelineHeight
149
+ ]
150
+ );
151
+ const activeId = resolvedSelectedId ?? hoveredId;
152
+ const selectTask = (task) => {
153
+ if (selectableRef.current && !task.task.disabled) {
154
+ const nextId = resolvedSelectedIdRef.current === task.id ? null : task.id;
155
+ if (selectedIdRef.current === void 0) setInnerSelectedId(nextId);
156
+ onSelectedIdChangeRef.current?.(nextId);
157
+ }
158
+ onTaskClickRef.current?.(task.task);
159
+ };
160
+ const setHoveredTask = (task) => {
161
+ if (!hoverable) return;
162
+ setHoveredId(task?.id ?? null);
163
+ onTaskHover?.(task?.task ?? null);
164
+ };
165
+ const getTaskOpacity = (task) => {
166
+ if (activeId === null) return activeOpacity;
167
+ return activeId === task.id ? activeOpacity : inactiveOpacity;
168
+ };
169
+ const pointerScale = (currentTarget) => {
170
+ const svg = currentTarget instanceof SVGElement ? currentTarget.ownerSVGElement ?? currentTarget.closest("svg") : currentTarget instanceof Element ? currentTarget.closest("svg") : null;
171
+ const clientWidth = svg?.clientWidth ?? 0;
172
+ if (!(clientWidth > 0)) return 1;
173
+ const viewBoxWidth = svg?.viewBox?.baseVal?.width;
174
+ const resolvedViewBox = typeof viewBoxWidth === "number" && viewBoxWidth > 0 ? viewBoxWidth : width;
175
+ return resolvedViewBox / clientWidth;
176
+ };
177
+ const captureBarPointer = (target, pointerId) => {
178
+ if (!(target instanceof Element) || typeof target.setPointerCapture !== "function") return;
179
+ try {
180
+ target.setPointerCapture(pointerId);
181
+ } catch {
182
+ }
183
+ };
184
+ const releaseBarPointer = (target, pointerId) => {
185
+ if (!target || typeof target.releasePointerCapture !== "function") return;
186
+ try {
187
+ target.releasePointerCapture(pointerId);
188
+ } catch {
189
+ }
190
+ };
191
+ const moveBarDrag = (event) => {
192
+ const session = dragSessionRef.current;
193
+ if (!session || event.pointerId !== session.pointerId) return;
194
+ const rawDelta = (event.clientX - session.startClientX) * session.scale;
195
+ const deltaX = clampGanttDragDeltaX(
196
+ rawDelta,
197
+ session.barX,
198
+ session.barWidth,
199
+ session.taskLabelWidth,
200
+ session.layoutWidth
201
+ );
202
+ session.deltaX = deltaX;
203
+ setDragPreview({ id: session.task.id, deltaX });
204
+ };
205
+ const detachDocumentPointerListeners = () => {
206
+ if (!documentPointerListeningRef.current || !isBrowser()) return;
207
+ document.removeEventListener("pointermove", onDocumentPointerMove);
208
+ document.removeEventListener("pointerup", onDocumentPointerEnd);
209
+ document.removeEventListener("pointercancel", onDocumentPointerEnd);
210
+ documentPointerListeningRef.current = false;
211
+ };
212
+ const finishBarDrag = (event) => {
213
+ const session = dragSessionRef.current;
214
+ if (!session || event.pointerId !== session.pointerId) return;
215
+ moveBarDrag(event);
216
+ const deltaX = session.deltaX;
217
+ dragSessionRef.current = null;
218
+ setDragPreview(null);
219
+ detachDocumentPointerListeners();
220
+ releaseBarPointer(session.captureTarget, session.pointerId);
221
+ suppressClickRef.current = true;
222
+ if (Math.abs(deltaX) < GANTT_BAR_CLICK_PX) {
223
+ selectTask(session.task);
224
+ return;
225
+ }
226
+ const nextTask = moveGanttTaskByPx(session.sourceTask, deltaX, {
227
+ minMs: session.minMs,
228
+ maxMs: session.maxMs,
229
+ timelineWidth: session.timelineWidth
230
+ });
231
+ if (ganttDateValuesEqual(nextTask.start, session.sourceTask.start) && ganttDateValuesEqual(nextTask.end, session.sourceTask.end)) {
232
+ selectTask(session.task);
233
+ return;
234
+ }
235
+ const incoming = dataRef.current.find((item) => item.id === nextTask.id);
236
+ const previous = dateOverlayRef.current.get(nextTask.id);
237
+ const nextOverlay = new Map(dateOverlayRef.current);
238
+ nextOverlay.set(nextTask.id, {
239
+ start: nextTask.start,
240
+ end: nextTask.end,
241
+ baseStart: previous?.baseStart ?? incoming?.start ?? session.sourceTask.start,
242
+ baseEnd: previous?.baseEnd ?? incoming?.end ?? session.sourceTask.end
243
+ });
244
+ setDateOverlay(nextOverlay);
245
+ const nextData = applyGanttTaskDateOverlay(dataRef.current, nextOverlay);
246
+ onTaskChangeRef.current?.(nextTask);
247
+ onDataChangeRef.current?.(nextData);
248
+ };
249
+ dragFnsRef.current.move = moveBarDrag;
250
+ dragFnsRef.current.finish = finishBarDrag;
251
+ const attachDocumentPointerListeners = () => {
252
+ if (documentPointerListeningRef.current || !isBrowser()) return;
253
+ document.addEventListener("pointermove", onDocumentPointerMove);
254
+ document.addEventListener("pointerup", onDocumentPointerEnd);
255
+ document.addEventListener("pointercancel", onDocumentPointerEnd);
256
+ documentPointerListeningRef.current = true;
257
+ };
258
+ const startBarDrag = (event, task) => {
259
+ if (task.task.disabled || dragSessionRef.current) return;
260
+ if (event.button !== void 0 && event.button !== 0) return;
261
+ event.preventDefault();
262
+ const captureTarget = event.currentTarget instanceof Element ? event.currentTarget : null;
263
+ dragSessionRef.current = {
264
+ pointerId: event.pointerId,
265
+ startClientX: event.clientX,
266
+ scale: pointerScale(event.currentTarget),
267
+ task,
268
+ sourceTask: task.task,
269
+ barX: task.x,
270
+ barWidth: task.width,
271
+ taskLabelWidth,
272
+ layoutWidth: layout.width,
273
+ minMs: layout.minMs,
274
+ maxMs: layout.maxMs,
275
+ timelineWidth: layout.timelineWidth,
276
+ deltaX: 0,
277
+ captureTarget
278
+ };
279
+ setDragPreview({ id: task.id, deltaX: 0 });
280
+ captureBarPointer(event.currentTarget, event.pointerId);
281
+ attachDocumentPointerListeners();
282
+ };
283
+ const handleBarClick = (event, task) => {
284
+ if (suppressClickRef.current) {
285
+ suppressClickRef.current = false;
286
+ event.preventDefault();
287
+ event.stopPropagation();
288
+ return;
289
+ }
290
+ selectTask(task);
291
+ };
292
+ return /* @__PURE__ */ jsx(
293
+ ChartCanvas,
294
+ {
295
+ width,
296
+ height,
297
+ padding,
298
+ title,
299
+ desc,
300
+ className: classNames(className),
301
+ role: "img",
302
+ "aria-label": ariaLabel,
303
+ children: /* @__PURE__ */ jsxs("g", { "data-series-type": "gantt", children: [
304
+ /* @__PURE__ */ jsxs("g", { "data-gantt-axis": "true", children: [
305
+ /* @__PURE__ */ jsx(
306
+ "line",
307
+ {
308
+ x1: taskLabelWidth,
309
+ x2: layout.width,
310
+ y1: timelineHeight - 1,
311
+ y2: timelineHeight - 1,
312
+ stroke: "var(--tiger-border,#d1d5db)"
313
+ }
314
+ ),
315
+ layout.ticks.map((tick) => /* @__PURE__ */ jsxs("g", { children: [
316
+ /* @__PURE__ */ jsx(
317
+ "line",
318
+ {
319
+ x1: tick.x,
320
+ x2: tick.x,
321
+ y1: 0,
322
+ y2: layout.height,
323
+ stroke: "var(--tiger-border,#e5e7eb)"
324
+ }
325
+ ),
326
+ /* @__PURE__ */ jsx("text", { x: tick.x + 4, y: 16, className: ganttAxisTextClasses, children: tick.label })
327
+ ] }, `${tick.label}-${tick.x}`))
328
+ ] }),
329
+ /* @__PURE__ */ jsx("g", { "data-gantt-rows": "true", children: layout.tasks.map((task) => /* @__PURE__ */ jsx(
330
+ "rect",
331
+ {
332
+ x: 0,
333
+ y: timelineHeight + task.index * rowHeight,
334
+ width: layout.width,
335
+ height: rowHeight,
336
+ className: task.index % 2 === 0 ? ganttRowClasses : void 0,
337
+ opacity: task.index % 2 === 0 ? 0.75 : 0
338
+ },
339
+ `row-${task.id}`
340
+ )) }),
341
+ showToday && layout.todayX !== null ? /* @__PURE__ */ jsx(
342
+ "line",
343
+ {
344
+ x1: layout.todayX,
345
+ x2: layout.todayX,
346
+ y1: 0,
347
+ y2: layout.height,
348
+ className: ganttTodayLineClasses,
349
+ "data-gantt-today": "true"
350
+ }
351
+ ) : null,
352
+ showDependencies ? /* @__PURE__ */ jsx("g", { "data-gantt-dependencies": "true", children: layout.dependencies.map((dependency) => /* @__PURE__ */ jsx(
353
+ "path",
354
+ {
355
+ d: dependency.path,
356
+ className: ganttDependencyClasses
357
+ },
358
+ `${dependency.sourceId}-${dependency.targetId}`
359
+ )) }) : null,
360
+ /* @__PURE__ */ jsx("g", { "data-gantt-tasks": "true", children: layout.tasks.map((task) => {
361
+ const selected = resolvedSelectedId === task.id;
362
+ const interactive = (hoverable || selectable) && !task.task.disabled;
363
+ const movable = !task.task.disabled;
364
+ const grabbing = dragPreview?.id === task.id;
365
+ const previewDeltaX = grabbing ? dragPreview?.deltaX ?? 0 : 0;
366
+ return /* @__PURE__ */ jsxs("g", { opacity: getTaskOpacity(task), children: [
367
+ /* @__PURE__ */ jsx("text", { x: 0, y: task.y + task.height / 2 + 4, className: ganttLabelClasses, children: task.task.label }),
368
+ /* @__PURE__ */ jsxs(
369
+ "g",
370
+ {
371
+ className: getGanttTaskClasses(interactive, selected, movable, grabbing),
372
+ role: interactive ? "button" : "group",
373
+ tabIndex: interactive ? 0 : void 0,
374
+ "aria-label": getGanttTaskAriaLabel(task.task),
375
+ "data-gantt-task-id": task.id,
376
+ transform: previewDeltaX !== 0 ? `translate(${previewDeltaX} 0)` : void 0,
377
+ onMouseEnter: () => setHoveredTask(task),
378
+ onMouseLeave: () => setHoveredTask(null),
379
+ onPointerDown: (event) => startBarDrag(event, task),
380
+ onPointerMove: (event) => moveBarDrag(event.nativeEvent),
381
+ onPointerUp: (event) => finishBarDrag(event.nativeEvent),
382
+ onPointerCancel: (event) => finishBarDrag(event.nativeEvent),
383
+ onClick: (event) => handleBarClick(event, task),
384
+ onKeyDown: (event) => {
385
+ if (event.key === "Enter" || event.key === " ") {
386
+ event.preventDefault();
387
+ selectTask(task);
388
+ }
389
+ },
390
+ children: [
391
+ /* @__PURE__ */ jsx(
392
+ "rect",
393
+ {
394
+ x: task.x,
395
+ y: task.y,
396
+ width: task.width,
397
+ height: task.height,
398
+ rx: 4,
399
+ fill: task.color,
400
+ stroke: selected ? "var(--tiger-text,#111827)" : void 0,
401
+ strokeWidth: selected ? 2 : void 0
402
+ }
403
+ ),
404
+ showProgress && task.progressWidth > 0 ? /* @__PURE__ */ jsx(
405
+ "rect",
406
+ {
407
+ x: task.x,
408
+ y: task.y,
409
+ width: task.progressWidth,
410
+ height: task.height,
411
+ rx: 4,
412
+ className: ganttProgressClasses
413
+ }
414
+ ) : null
415
+ ]
416
+ }
417
+ )
418
+ ] }, task.id);
419
+ }) })
420
+ ] })
421
+ }
422
+ );
423
+ }
424
+ Gantt.displayName = "Gantt";
425
+
426
+ export {
427
+ Gantt
428
+ };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  useChartInteraction
3
- } from "./chunk-DNOPEJ5I.mjs";
3
+ } from "./chunk-JZZPLKTW.mjs";
4
4
  import {
5
5
  ChartTooltip
6
6
  } from "./chunk-YORCCCQX.mjs";
7
7
  import {
8
8
  ChartCanvas
9
- } from "./chunk-DKNVSQSV.mjs";
9
+ } from "./chunk-CUAXRBKO.mjs";
10
10
 
11
11
  // src/components/HeatmapChart.tsx
12
12
  import React, { useCallback, useEffect, useMemo, useRef } from "react";
@@ -63,6 +63,7 @@ var HeatmapChart = ({
63
63
  handleClick
64
64
  } = useChartInteraction({
65
65
  hoverable,
66
+ showTooltip,
66
67
  hoveredIndexProp,
67
68
  selectable,
68
69
  selectedIndexProp,
@@ -111,6 +112,7 @@ var HeatmapChart = ({
111
112
  [resolvedHoveredIndex, cells, valueFormatter]
112
113
  );
113
114
  const interactive = hoverable || selectable;
115
+ const pointerInteractive = interactive || showTooltip;
114
116
  const rect = innerRect;
115
117
  const cellW = (rect.width - cellGap * (xLabels.length - 1)) / xLabels.length;
116
118
  const cellH = (rect.height - cellGap * (yLabels.length - 1)) / yLabels.length;
@@ -288,7 +290,7 @@ var HeatmapChart = ({
288
290
  ]
289
291
  }
290
292
  );
291
- const tooltip = showTooltip && hoverable ? /* @__PURE__ */ jsx(
293
+ const tooltip = showTooltip ? /* @__PURE__ */ jsx(
292
294
  ChartTooltip,
293
295
  {
294
296
  content: tooltipContent,
@@ -314,10 +316,10 @@ var HeatmapChart = ({
314
316
  top: `${rect.y}px`,
315
317
  width: `${rect.width}px`,
316
318
  height: `${rect.height}px`,
317
- pointerEvents: interactive ? "auto" : "none"
319
+ pointerEvents: pointerInteractive ? "auto" : "none"
318
320
  },
319
- onMouseMove: interactive ? handleCanvasMouseMove : void 0,
320
- onMouseLeave: interactive ? handleMouseLeave : void 0,
321
+ onMouseMove: pointerInteractive ? handleCanvasMouseMove : void 0,
322
+ onMouseLeave: pointerInteractive ? handleMouseLeave : void 0,
321
323
  onClick: interactive ? handleCanvasClick : void 0
322
324
  }
323
325
  ),
@@ -2,6 +2,9 @@ import {
2
2
  renderOverlayPortal,
3
3
  useAnchoredOverlay
4
4
  } from "./chunk-HKAZXG74.mjs";
5
+ import {
6
+ useTigerConfig
7
+ } from "./chunk-YSIXURBW.mjs";
5
8
 
6
9
  // src/components/ColorPicker.tsx
7
10
  import { useState, useMemo, useRef, useEffect } from "react";
@@ -11,15 +14,27 @@ import {
11
14
  colorPickerPanelClasses,
12
15
  colorPickerInputClasses,
13
16
  colorPickerPresetClasses,
14
- hexToRgb,
15
17
  rgbToHex,
16
18
  rgbToHsv,
17
19
  hsvToRgb,
18
20
  formatColorString,
19
21
  parseColorInput,
20
- classNames
22
+ parseColorParts,
23
+ classNames,
24
+ mergeTigerLocale,
25
+ getColorPickerLabels,
26
+ formatColorPickerSelectPreset
21
27
  } from "@expcat/tigercat-core";
22
28
  import { jsx, jsxs } from "react/jsx-runtime";
29
+ function rgbFromValue(value) {
30
+ const parts = parseColorParts(value);
31
+ return parts ? { r: parts.r, g: parts.g, b: parts.b } : { r: 0, g: 0, b: 0 };
32
+ }
33
+ function explicitAlphaFromValue(value) {
34
+ if (!/^(rgba|hsla)\(/i.test(value.trim())) return null;
35
+ const parts = parseColorParts(value);
36
+ return parts ? parts.a : null;
37
+ }
23
38
  var ColorPicker = ({
24
39
  value = "#2563eb",
25
40
  disabled = false,
@@ -28,10 +43,21 @@ var ColorPicker = ({
28
43
  format = "hex",
29
44
  presets,
30
45
  className,
46
+ locale,
47
+ labels: labelsOverride,
31
48
  onChange
32
49
  }) => {
50
+ const config = useTigerConfig();
51
+ const mergedLocale = useMemo(
52
+ () => mergeTigerLocale(config.locale, locale),
53
+ [config.locale, locale]
54
+ );
55
+ const labels = useMemo(
56
+ () => getColorPickerLabels(mergedLocale, labelsOverride),
57
+ [mergedLocale, labelsOverride]
58
+ );
33
59
  const [isOpen, setIsOpen] = useState(false);
34
- const [alpha, setAlpha] = useState(1);
60
+ const [alpha, setAlpha] = useState(() => explicitAlphaFromValue(value) ?? 1);
35
61
  const containerRef = useRef(null);
36
62
  const triggerRef = useRef(null);
37
63
  const panelRef = useRef(null);
@@ -47,8 +73,12 @@ var ColorPicker = ({
47
73
  restoreFocusOnDismiss: true,
48
74
  onDismiss: () => setIsOpen(false)
49
75
  });
50
- const rgb = useMemo(() => hexToRgb(value), [value]);
76
+ const rgb = useMemo(() => rgbFromValue(value), [value]);
51
77
  const hsv = useMemo(() => rgbToHsv(rgb.r, rgb.g, rgb.b), [rgb]);
78
+ useEffect(() => {
79
+ const next = explicitAlphaFromValue(value);
80
+ if (next !== null) setAlpha(next);
81
+ }, [value]);
52
82
  const displayValue = useMemo(
53
83
  () => formatColorString(rgb.r, rgb.g, rgb.b, format, showAlpha ? alpha : void 0),
54
84
  [rgb, format, showAlpha, alpha]
@@ -80,13 +110,17 @@ var ColorPicker = ({
80
110
  function handleInputChange(e) {
81
111
  const val = e.target.value;
82
112
  setInputValue(val);
83
- const hex = parseColorInput(val);
84
- if (hex) {
85
- onChange?.(hex);
113
+ const parsed = parseColorInput(val);
114
+ if (parsed) {
115
+ onChange?.(parsed);
86
116
  }
87
117
  }
88
118
  function handleAlphaChange(e) {
89
- setAlpha(Number(e.target.value) / 100);
119
+ const nextAlpha = Number(e.target.value) / 100;
120
+ setAlpha(nextAlpha);
121
+ const emitFormat = format === "hex" ? "rgb" : format;
122
+ const next = formatColorString(rgb.r, rgb.g, rgb.b, emitFormat, nextAlpha);
123
+ onChange?.(next);
90
124
  }
91
125
  function handlePresetClick(color) {
92
126
  onChange?.(color);
@@ -97,6 +131,9 @@ var ColorPicker = ({
97
131
  handlePresetClick(color);
98
132
  }
99
133
  }
134
+ function handleClear() {
135
+ onChange?.("");
136
+ }
100
137
  return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: classNames(colorPickerBaseClasses, className), children: [
101
138
  /* @__PURE__ */ jsx(
102
139
  "div",
@@ -105,7 +142,9 @@ var ColorPicker = ({
105
142
  className: getColorPickerTriggerClasses(size, disabled),
106
143
  style: { backgroundColor: swatchColor },
107
144
  role: "button",
108
- "aria-label": "Pick color",
145
+ "data-tiger-colorpicker-trigger": "",
146
+ "aria-label": labels.trigger,
147
+ title: labels.trigger,
109
148
  "aria-haspopup": "dialog",
110
149
  "aria-expanded": isOpen,
111
150
  "aria-disabled": disabled || void 0,
@@ -122,9 +161,25 @@ var ColorPicker = ({
122
161
  className: classNames(colorPickerPanelClasses, overlay.floatingClasses),
123
162
  style: overlay.floatingStyles,
124
163
  "data-positioned": overlay.positioned,
164
+ "data-tiger-colorpicker-panel": "",
165
+ role: "dialog",
166
+ "aria-label": labels.panelTitle,
125
167
  children: [
168
+ /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", children: [
169
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-[var(--tiger-text,#111827)]", children: labels.panelTitle }),
170
+ /* @__PURE__ */ jsx(
171
+ "button",
172
+ {
173
+ type: "button",
174
+ className: "text-xs text-[var(--tiger-primary,#2563eb)] hover:underline focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--tiger-primary,#2563eb)]",
175
+ "data-tiger-colorpicker-clear": "",
176
+ onClick: handleClear,
177
+ children: labels.clear
178
+ }
179
+ )
180
+ ] }),
126
181
  /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
127
- /* @__PURE__ */ jsx("label", { className: "block text-xs text-[var(--tiger-text-muted,#6b7280)] mb-1", children: "Hue" }),
182
+ /* @__PURE__ */ jsx("label", { className: "block text-xs text-[var(--tiger-text-muted,#6b7280)] mb-1", children: labels.hue }),
128
183
  /* @__PURE__ */ jsx(
129
184
  "input",
130
185
  {
@@ -133,13 +188,13 @@ var ColorPicker = ({
133
188
  max: 360,
134
189
  value: hsv.h,
135
190
  className: "w-full h-2 rounded-full cursor-pointer accent-[var(--tiger-primary,#2563eb)]",
136
- "aria-label": "Hue",
191
+ "aria-label": labels.hue,
137
192
  onChange: handleHueChange
138
193
  }
139
194
  )
140
195
  ] }),
141
196
  showAlpha && /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
142
- /* @__PURE__ */ jsx("label", { className: "block text-xs text-[var(--tiger-text-muted,#6b7280)] mb-1", children: "Alpha" }),
197
+ /* @__PURE__ */ jsx("label", { className: "block text-xs text-[var(--tiger-text-muted,#6b7280)] mb-1", children: labels.alpha }),
143
198
  /* @__PURE__ */ jsx(
144
199
  "input",
145
200
  {
@@ -148,7 +203,7 @@ var ColorPicker = ({
148
203
  max: 100,
149
204
  value: Math.round(alpha * 100),
150
205
  className: "w-full h-2 rounded-full cursor-pointer accent-[var(--tiger-primary,#2563eb)]",
151
- "aria-label": "Alpha",
206
+ "aria-label": labels.alpha,
152
207
  onChange: handleAlphaChange
153
208
  }
154
209
  )
@@ -161,7 +216,7 @@ var ColorPicker = ({
161
216
  type: "text",
162
217
  className: colorPickerInputClasses,
163
218
  value: inputValue,
164
- "aria-label": "Color value",
219
+ "aria-label": labels.value,
165
220
  onChange: handleInputChange
166
221
  }
167
222
  )
@@ -172,7 +227,7 @@ var ColorPicker = ({
172
227
  {
173
228
  className: "w-8 h-8 rounded border border-[var(--tiger-border,#d1d5db)]",
174
229
  style: { backgroundColor: swatchColor },
175
- "aria-label": "Color preview"
230
+ "aria-label": labels.preview
176
231
  }
177
232
  ),
178
233
  /* @__PURE__ */ jsx("span", { className: "text-xs font-mono text-[var(--tiger-text,#111827)]", children: displayValue })
@@ -184,7 +239,7 @@ var ColorPicker = ({
184
239
  style: { backgroundColor: color },
185
240
  role: "button",
186
241
  tabIndex: 0,
187
- "aria-label": `Select ${color}`,
242
+ "aria-label": formatColorPickerSelectPreset(labels.selectPreset, color),
188
243
  onClick: () => handlePresetClick(color),
189
244
  onKeyDown: (e) => handlePresetKeyDown(e, color)
190
245
  },
@@ -2,7 +2,7 @@ import {
2
2
  Dropdown,
3
3
  DropdownItem,
4
4
  DropdownMenu
5
- } from "./chunk-YI6YWH66.mjs";
5
+ } from "./chunk-RE5ZLA5D.mjs";
6
6
  import {
7
7
  Button
8
8
  } from "./chunk-5TE7KLE5.mjs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ImagePreview
3
- } from "./chunk-ZCGIZOMT.mjs";
3
+ } from "./chunk-V7HJ5HLC.mjs";
4
4
 
5
5
  // src/components/ImageGroup.tsx
6
6
  import { useState, useCallback, useMemo, createContext, useRef } from "react";