@expcat/tigercat-react 2.1.0 → 2.1.1

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 (137) 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-2YBLMVDT.mjs +428 -0
  4. package/dist/{chunk-25D5TXZH.mjs → chunk-32MCQMBJ.mjs} +8 -6
  5. package/dist/{chunk-M5MZWOHF.mjs → chunk-3HHEVMHE.mjs} +1 -1
  6. package/dist/{chunk-HSBN5MLS.mjs → chunk-3LACOSJQ.mjs} +1 -1
  7. package/dist/{chunk-F6WV53BS.mjs → chunk-3LDDXHW2.mjs} +28 -11
  8. package/dist/{chunk-IXQAECFP.mjs → chunk-3QNIFKVF.mjs} +12 -14
  9. package/dist/{chunk-UD4DTVJZ.mjs → chunk-4C2X5PZO.mjs} +57 -25
  10. package/dist/chunk-5JETWHLJ.mjs +28 -0
  11. package/dist/{chunk-VA6PZWOH.mjs → chunk-5SEMRHBD.mjs} +14 -6
  12. package/dist/{chunk-EKILTLUO.mjs → chunk-72CJNKDY.mjs} +1 -1
  13. package/dist/{chunk-XE4YFBOZ.mjs → chunk-AUD3VOLO.mjs} +1 -1
  14. package/dist/{chunk-I4MWOYJS.mjs → chunk-AYFKHWJS.mjs} +13 -7
  15. package/dist/{chunk-RPSHILHD.mjs → chunk-BXAH2GH3.mjs} +8 -2
  16. package/dist/{chunk-EW5EO7VE.mjs → chunk-BYD7EAWK.mjs} +1 -1
  17. package/dist/{chunk-GCY55TBC.mjs → chunk-CQOLQAB5.mjs} +105 -90
  18. package/dist/{chunk-L55UK45A.mjs → chunk-CRIEUKMD.mjs} +5 -2
  19. package/dist/{chunk-DKNVSQSV.mjs → chunk-CUAXRBKO.mjs} +12 -0
  20. package/dist/{chunk-NWVNTZOP.mjs → chunk-DECUASRW.mjs} +14 -16
  21. package/dist/{chunk-XMTEMBQV.mjs → chunk-EAAWB3CK.mjs} +16 -13
  22. package/dist/{chunk-IR7VA6AO.mjs → chunk-EG7EMDKK.mjs} +1 -1
  23. package/dist/{chunk-HOYBHB7B.mjs → chunk-FNK2VWPP.mjs} +1 -1
  24. package/dist/{chunk-RJPNBYK5.mjs → chunk-FQS24AUH.mjs} +12 -3
  25. package/dist/{chunk-LADKKOJT.mjs → chunk-GBEDWXLL.mjs} +16 -10
  26. package/dist/{chunk-2ENQZECC.mjs → chunk-HAXRHSCN.mjs} +4 -3
  27. package/dist/{chunk-K4GIKSZE.mjs → chunk-I2BENK5X.mjs} +2 -1
  28. package/dist/{chunk-DNOPEJ5I.mjs → chunk-JZZPLKTW.mjs} +7 -4
  29. package/dist/{chunk-7KCQMXJA.mjs → chunk-KDURW5AS.mjs} +4 -3
  30. package/dist/{chunk-TFMEHUVZ.mjs → chunk-KKN7KLTB.mjs} +0 -1
  31. package/dist/{chunk-6MGQAJ62.mjs → chunk-KL6YJIZ3.mjs} +24 -7
  32. package/dist/{chunk-PFL4HNWM.mjs → chunk-M6ZPTGBV.mjs} +1 -2
  33. package/dist/{chunk-PXRZ6CKY.mjs → chunk-MJVSZ2UJ.mjs} +46 -16
  34. package/dist/{chunk-LZKBDQE4.mjs → chunk-MYI3FPG4.mjs} +23 -4
  35. package/dist/{chunk-OIGEBCAS.mjs → chunk-NADODEZX.mjs} +69 -1
  36. package/dist/{chunk-UKY2EPS3.mjs → chunk-NJWTZ5MO.mjs} +54 -42
  37. package/dist/{chunk-773LH7BK.mjs → chunk-O6VYD4E4.mjs} +24 -2
  38. package/dist/{chunk-G7D4QV7A.mjs → chunk-O7TV5OKS.mjs} +33 -6
  39. package/dist/{chunk-DPWRXXXW.mjs → chunk-OJ6SHHOZ.mjs} +3 -3
  40. package/dist/{chunk-UYJJLHVA.mjs → chunk-PMQJ6AYT.mjs} +23 -21
  41. package/dist/{chunk-KC55B62J.mjs → chunk-PY2VUNEJ.mjs} +143 -46
  42. package/dist/{chunk-BEJZPJIK.mjs → chunk-QOAOOD53.mjs} +10 -4
  43. package/dist/{chunk-JQJM65RJ.mjs → chunk-QU3QXUTC.mjs} +49 -23
  44. package/dist/{chunk-7EMCZVJ2.mjs → chunk-QXSUG7SN.mjs} +3 -3
  45. package/dist/{chunk-RQ4PUK6G.mjs → chunk-R7YZ6FKP.mjs} +24 -13
  46. package/dist/{chunk-YI6YWH66.mjs → chunk-RE5ZLA5D.mjs} +6 -6
  47. package/dist/{chunk-UCBW5RJN.mjs → chunk-RGVU4EMA.mjs} +11 -6
  48. package/dist/{chunk-IBSOUQGB.mjs → chunk-RRGPDFDI.mjs} +7 -4
  49. package/dist/{chunk-ZH5ZBLAN.mjs → chunk-RUQ3F3MV.mjs} +34 -7
  50. package/dist/{chunk-PGD5RPKF.mjs → chunk-SVIJ2UZA.mjs} +2 -1
  51. package/dist/{chunk-UETARXIK.mjs → chunk-SXWEFZOF.mjs} +246 -53
  52. package/dist/{chunk-H6MVW5YD.mjs → chunk-TEVEXDY2.mjs} +24 -13
  53. package/dist/{chunk-DJOFM2VO.mjs → chunk-TO6MZFNQ.mjs} +52 -40
  54. package/dist/{chunk-ZCGIZOMT.mjs → chunk-V7HJ5HLC.mjs} +6 -10
  55. package/dist/{chunk-SIDDYP3O.mjs → chunk-VJWSKJLJ.mjs} +1 -1
  56. package/dist/{chunk-ZG56T75O.mjs → chunk-WTHWLCRL.mjs} +51 -11
  57. package/dist/{chunk-KP6DEYWB.mjs → chunk-X4L3W7RQ.mjs} +1 -1
  58. package/dist/{chunk-ZMRTETN2.mjs → chunk-X6C6MNG5.mjs} +4 -3
  59. package/dist/{chunk-OGG2TQDG.mjs → chunk-XVHTJQ4T.mjs} +12 -1
  60. package/dist/{chunk-FSMJLJFL.mjs → chunk-Y6UH3EKE.mjs} +1 -1
  61. package/dist/chunk-YJ5T4XZN.mjs +81 -0
  62. package/dist/{chunk-VVNFXJMN.mjs → chunk-YNDPQVEK.mjs} +8 -1
  63. package/dist/{chunk-QGZ32NFQ.mjs → chunk-Z23KOLNU.mjs} +4 -3
  64. package/dist/{chunk-5CKMYMTS.mjs → chunk-ZATZRXMW.mjs} +27 -8
  65. package/dist/components/ActivityFeed.mjs +2 -2
  66. package/dist/components/Affix.mjs +1 -1
  67. package/dist/components/Anchor.mjs +1 -1
  68. package/dist/components/AreaChart.mjs +4 -3
  69. package/dist/components/AutoComplete.mjs +1 -1
  70. package/dist/components/BarChart.mjs +4 -3
  71. package/dist/components/Calendar.mjs +1 -1
  72. package/dist/components/Cascader.mjs +1 -1
  73. package/dist/components/ChartCanvas.mjs +1 -1
  74. package/dist/components/ChatWindow.mjs +3 -3
  75. package/dist/components/Code.mjs +3 -1
  76. package/dist/components/CollapsePanel.mjs +1 -1
  77. package/dist/components/ColorPicker.mjs +1 -1
  78. package/dist/components/CommentThread.mjs +2 -2
  79. package/dist/components/DataExport.mjs +2 -2
  80. package/dist/components/DataTableWithToolbar.mjs +6 -6
  81. package/dist/components/DonutChart.mjs +4 -4
  82. package/dist/components/Dropdown.mjs +1 -1
  83. package/dist/components/FileManager.mjs +2 -1
  84. package/dist/components/FloatButton.mjs +1 -1
  85. package/dist/components/FormItem.mjs +1 -1
  86. package/dist/components/FormWizard.mjs +1 -1
  87. package/dist/components/FunnelChart.mjs +3 -3
  88. package/dist/components/Gantt.d.mts +3 -1
  89. package/dist/components/Gantt.mjs +2 -2
  90. package/dist/components/GaugeChart.mjs +2 -2
  91. package/dist/components/HeatmapChart.mjs +3 -3
  92. package/dist/components/Image.mjs +4 -4
  93. package/dist/components/ImageGroup.mjs +2 -2
  94. package/dist/components/ImagePreview.mjs +1 -1
  95. package/dist/components/Input.mjs +1 -1
  96. package/dist/components/InputNumber.d.mts +1 -1
  97. package/dist/components/InputNumber.mjs +1 -1
  98. package/dist/components/Kanban.mjs +2 -2
  99. package/dist/components/LineChart.mjs +4 -3
  100. package/dist/components/List.mjs +2 -2
  101. package/dist/components/Loading.mjs +1 -1
  102. package/dist/components/MaskInput.mjs +1 -1
  103. package/dist/components/NotificationCenter.mjs +4 -4
  104. package/dist/components/OrgChart.mjs +2 -2
  105. package/dist/components/Pagination.mjs +1 -1
  106. package/dist/components/PieChart.mjs +3 -3
  107. package/dist/components/Popconfirm.mjs +2 -2
  108. package/dist/components/Popover.mjs +2 -2
  109. package/dist/components/QRCode.d.mts +2 -2
  110. package/dist/components/QRCode.mjs +1 -1
  111. package/dist/components/RadarChart.mjs +3 -3
  112. package/dist/components/Rate.mjs +1 -1
  113. package/dist/components/ScatterChart.mjs +4 -3
  114. package/dist/components/ScrollSpy.mjs +1 -1
  115. package/dist/components/Signature.mjs +1 -1
  116. package/dist/components/SplitButton.mjs +2 -2
  117. package/dist/components/Splitter.mjs +1 -1
  118. package/dist/components/Stepper.d.mts +2 -0
  119. package/dist/components/Stepper.mjs +2 -1
  120. package/dist/components/SunburstChart.mjs +3 -3
  121. package/dist/components/Switch.d.mts +5 -1
  122. package/dist/components/Switch.mjs +2 -1
  123. package/dist/components/Table.mjs +2 -2
  124. package/dist/components/TaskBoard.mjs +1 -1
  125. package/dist/components/Textarea.mjs +1 -1
  126. package/dist/components/Tooltip.mjs +2 -2
  127. package/dist/components/Tour.mjs +1 -1
  128. package/dist/components/TreeMapChart.mjs +3 -3
  129. package/dist/components/TreeSelect.mjs +1 -1
  130. package/dist/components/Upload.mjs +1 -1
  131. package/dist/hooks/useChartInteraction.d.mts +5 -0
  132. package/dist/hooks/useChartInteraction.mjs +1 -1
  133. package/dist/index.d.mts +1 -1
  134. package/dist/index.mjs +51 -0
  135. package/package.json +2 -2
  136. package/dist/chunk-CB4SK5AU.mjs +0 -235
  137. package/dist/chunk-KPACLRQH.mjs +0 -55
@@ -144,7 +144,6 @@ var MaskInput = ({
144
144
  placeholder,
145
145
  disabled,
146
146
  readOnly: readonly,
147
- name,
148
147
  id,
149
148
  autoComplete,
150
149
  autoFocus,
@@ -160,7 +159,8 @@ var MaskInput = ({
160
159
  onBlur
161
160
  }
162
161
  ),
163
- activeError ? /* @__PURE__ */ jsx("div", { id: errorMsgId, className: getInputErrorClasses(effectiveSize), children: errorMessage }) : showClear && /* @__PURE__ */ jsx(
162
+ name ? /* @__PURE__ */ jsx("input", { type: "hidden", name, value: rawValue }) : null,
163
+ activeError ? /* @__PURE__ */ jsx("div", { id: errorMsgId, className: getInputErrorClasses(effectiveSize), "aria-live": "polite", children: errorMessage }) : showClear && /* @__PURE__ */ jsx(
164
164
  "button",
165
165
  {
166
166
  type: "button",
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  TaskBoard
3
- } from "./chunk-773LH7BK.mjs";
3
+ } from "./chunk-O6VYD4E4.mjs";
4
4
 
5
5
  // src/components/Kanban.tsx
6
6
  import { jsx } from "react/jsx-runtime";
@@ -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,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";
@@ -12,7 +12,7 @@ import {
12
12
  import { useState, useEffect, useRef, useCallback, useId } from "react";
13
13
  import {
14
14
  classNames,
15
- getInputClasses,
15
+ getInputFieldClasses,
16
16
  getInputWrapperClasses,
17
17
  getInputAffixClasses,
18
18
  getInputErrorClasses,
@@ -103,16 +103,13 @@ var Input = ({
103
103
  const showClear = clearable && !disabled && !readonly && currentValStr.length > 0;
104
104
  const showPasswordToggle = showPassword && type === "password" && !disabled;
105
105
  const effectiveType = showPassword && type === "password" ? passwordVisible ? "text" : "password" : type;
106
- const inputClasses = getInputClasses({
106
+ const inputClasses = getInputFieldClasses({
107
107
  size: effectiveSize,
108
108
  status,
109
109
  hasPrefix,
110
110
  hasSuffix
111
111
  });
112
112
  const renderSuffix = () => {
113
- if (activeError) {
114
- return /* @__PURE__ */ jsx("div", { id: errorMsgId, className: getInputErrorClasses(effectiveSize), children: errorMessage });
115
- }
116
113
  if (showClear) {
117
114
  return /* @__PURE__ */ jsx(
118
115
  "button",
@@ -148,7 +145,7 @@ var Input = ({
148
145
  "div",
149
146
  {
150
147
  ref: wrapperRef,
151
- className: classNames(getInputWrapperClasses(), className),
148
+ className: classNames(getInputWrapperClasses(status), className),
152
149
  style,
153
150
  onAnimationEnd: handleAnimationEnd,
154
151
  children: [
@@ -183,16 +180,36 @@ var Input = ({
183
180
  ]
184
181
  }
185
182
  );
183
+ const extras = [];
184
+ if (activeError) {
185
+ extras.push(
186
+ /* @__PURE__ */ jsx(
187
+ "div",
188
+ {
189
+ id: errorMsgId,
190
+ className: getInputErrorClasses(effectiveSize),
191
+ "aria-live": "polite",
192
+ children: errorMessage
193
+ },
194
+ "error"
195
+ )
196
+ );
197
+ }
186
198
  if (showCount) {
187
199
  const count = currentValStr.length;
188
200
  const isOver = maxLength !== void 0 && count > maxLength;
189
201
  const countText = maxLength !== void 0 ? `${count} / ${maxLength}` : `${count}`;
190
- return /* @__PURE__ */ jsxs("div", { children: [
191
- wrapperNode,
192
- /* @__PURE__ */ jsx("div", { className: getInputCountClasses(isOver), children: countText })
193
- ] });
202
+ extras.push(
203
+ /* @__PURE__ */ jsx("div", { className: getInputCountClasses(isOver), children: countText }, "count")
204
+ );
205
+ }
206
+ if (extras.length === 0) {
207
+ return wrapperNode;
194
208
  }
195
- return wrapperNode;
209
+ return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
210
+ wrapperNode,
211
+ extras
212
+ ] });
196
213
  };
197
214
 
198
215
  export {
@@ -16,6 +16,7 @@ import {
16
16
  getAnchorLinkClasses,
17
17
  getAnchorLinkListClasses,
18
18
  createAnchorObserver,
19
+ createProgrammaticScrollLock,
19
20
  scrollToAnchor
20
21
  } from "@expcat/tigercat-core";
21
22
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -86,7 +87,7 @@ var AnchorLink = ({
86
87
  };
87
88
  var Anchor = ({
88
89
  affix = true,
89
- bounds: _bounds = 5,
90
+ bounds = 5,
90
91
  offsetTop = 0,
91
92
  showInkInFixed = false,
92
93
  targetOffset,
@@ -103,10 +104,9 @@ var Anchor = ({
103
104
  const [links, setLinks] = useState([]);
104
105
  const anchorRef = useRef(null);
105
106
  const inkRef = useRef(null);
106
- const isScrollingRef = useRef(false);
107
- const scrollTimeoutRef = useRef(null);
108
107
  const getContainerRef = useRef(getContainer);
109
108
  getContainerRef.current = getContainer;
109
+ const scrollLockRef = useRef(createProgrammaticScrollLock(() => getContainerRef.current()));
110
110
  const getCurrentAnchorRef = useRef(getCurrentAnchor);
111
111
  getCurrentAnchorRef.current = getCurrentAnchor;
112
112
  const onChangeRef = useRef(onChange);
@@ -133,14 +133,9 @@ var Anchor = ({
133
133
  const handleLinkClick = useCallback(
134
134
  (href, event) => {
135
135
  onClick?.(event, href);
136
- isScrollingRef.current = true;
136
+ scrollLockRef.current.lock();
137
137
  setActiveLink(href);
138
138
  scrollTo(href);
139
- if (scrollTimeoutRef.current !== null) clearTimeout(scrollTimeoutRef.current);
140
- scrollTimeoutRef.current = setTimeout(() => {
141
- isScrollingRef.current = false;
142
- scrollTimeoutRef.current = null;
143
- }, 500);
144
139
  },
145
140
  [onClick, scrollTo]
146
141
  );
@@ -151,9 +146,10 @@ var Anchor = ({
151
146
  const root = container === window ? null : container;
152
147
  stop = createAnchorObserver(links, {
153
148
  offsetTop: scrollOffset,
149
+ bounds,
154
150
  root,
155
151
  onChange: (newActiveLink) => {
156
- if (isScrollingRef.current) return;
152
+ if (scrollLockRef.current.isLocked()) return;
157
153
  const finalActiveLink = getCurrentAnchorRef.current ? getCurrentAnchorRef.current(newActiveLink) : newActiveLink;
158
154
  setActiveLink((prev) => {
159
155
  if (finalActiveLink !== prev) {
@@ -168,11 +164,13 @@ var Anchor = ({
168
164
  return () => {
169
165
  clearTimeout(timeoutId);
170
166
  stop?.();
171
- if (scrollTimeoutRef.current !== null) {
172
- clearTimeout(scrollTimeoutRef.current);
173
- }
174
167
  };
175
- }, [links, scrollOffset]);
168
+ }, [bounds, links, scrollOffset]);
169
+ useEffect(() => {
170
+ return () => {
171
+ scrollLockRef.current.dispose();
172
+ };
173
+ }, []);
176
174
  useEffect(() => {
177
175
  if (!inkRef.current || !anchorRef.current || !activeLink) {
178
176
  return;