@expcat/tigercat-react 0.3.70 → 0.4.0

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.
@@ -0,0 +1,543 @@
1
+ 'use strict';
2
+
3
+ var chunkQL6UEG3U_js = require('./chunk-QL6UEG3U.js');
4
+ var React = require('react');
5
+ var tigercatCore = require('@expcat/tigercat-core');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
+
10
+ var React__default = /*#__PURE__*/_interopDefault(React);
11
+
12
+ var CardItem = React__default.default.memo(
13
+ ({
14
+ card,
15
+ column,
16
+ isDragging,
17
+ isKbGrabbed,
18
+ draggable,
19
+ dragHintText,
20
+ renderCard,
21
+ onDragStart,
22
+ onDragEnd,
23
+ onTouchStart,
24
+ onTouchMove,
25
+ onTouchEnd,
26
+ onKeyDown
27
+ }) => {
28
+ const cardClasses = tigercatCore.classNames(
29
+ tigercatCore.taskBoardCardClasses,
30
+ isDragging && tigercatCore.taskBoardCardDraggingClasses,
31
+ isKbGrabbed && "ring-2 ring-[var(--tiger-primary,#2563eb)]"
32
+ );
33
+ return /* @__PURE__ */ jsxRuntime.jsx(
34
+ "div",
35
+ {
36
+ className: cardClasses,
37
+ draggable,
38
+ tabIndex: 0,
39
+ role: "listitem",
40
+ "aria-roledescription": dragHintText,
41
+ "aria-grabbed": isKbGrabbed ? "true" : void 0,
42
+ "data-tiger-taskboard-card": "",
43
+ "data-tiger-taskboard-card-id": String(card.id),
44
+ onDragStart: (e) => onDragStart(e, card, column),
45
+ onDragEnd,
46
+ onTouchStart: (e) => onTouchStart(e, card, column),
47
+ onTouchMove,
48
+ onTouchEnd,
49
+ onKeyDown: (e) => onKeyDown(e, card, column),
50
+ children: renderCard ? renderCard(card, column.id) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
51
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-sm text-[var(--tiger-text,#1f2937)]", children: card.title }),
52
+ card.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-[var(--tiger-text-muted,#6b7280)] line-clamp-2", children: card.description })
53
+ ] })
54
+ }
55
+ );
56
+ },
57
+ (prev, next) => prev.card.id === next.card.id && prev.isDragging === next.isDragging && prev.isKbGrabbed === next.isKbGrabbed && prev.draggable === next.draggable && prev.card === next.card
58
+ );
59
+ CardItem.displayName = "TaskBoardCardItem";
60
+ var ColumnItem = React__default.default.memo(
61
+ ({
62
+ column,
63
+ colIndex,
64
+ isDropTarget,
65
+ isColDragging,
66
+ dropIdx,
67
+ draggable,
68
+ columnDraggable,
69
+ labels,
70
+ renderCardProp,
71
+ renderColumnHeader,
72
+ renderColumnFooter,
73
+ renderEmptyColumn,
74
+ onCardAdd,
75
+ dragType,
76
+ onCardDragStart,
77
+ onCardDragOver,
78
+ onCardDrop,
79
+ onDragEnd,
80
+ onDragLeave,
81
+ onColumnDragStart,
82
+ onColumnDragOver,
83
+ onColumnDrop,
84
+ onCardTouchStart,
85
+ onCardTouchMove,
86
+ onCardTouchEnd,
87
+ onColumnTouchStart,
88
+ onColumnTouchMove,
89
+ onColumnTouchEnd,
90
+ onCardKeyDown,
91
+ dragStateId,
92
+ kbDragStateId
93
+ }) => {
94
+ const wipOver = tigercatCore.isWipExceeded(column);
95
+ const colClasses = tigercatCore.classNames(
96
+ tigercatCore.taskBoardColumnClasses,
97
+ isDropTarget && tigercatCore.taskBoardColumnDropTargetClasses,
98
+ isColDragging && tigercatCore.taskBoardColumnDraggingClasses
99
+ );
100
+ let cardsContent;
101
+ if (column.cards.length > 0) {
102
+ const nodes = [];
103
+ column.cards.forEach((card, i) => {
104
+ if (isDropTarget && dropIdx === i) {
105
+ nodes.push(/* @__PURE__ */ jsxRuntime.jsx("div", { className: tigercatCore.taskBoardDropIndicatorClasses }, `drop-${i}`));
106
+ }
107
+ const isDragging = dragStateId === card.id;
108
+ const isKbGrabbed = kbDragStateId === card.id;
109
+ nodes.push(
110
+ /* @__PURE__ */ jsxRuntime.jsx(
111
+ CardItem,
112
+ {
113
+ card,
114
+ column,
115
+ isDragging,
116
+ isKbGrabbed,
117
+ draggable,
118
+ dragHintText: labels.dragHintText,
119
+ renderCard: renderCardProp,
120
+ onDragStart: onCardDragStart,
121
+ onDragEnd,
122
+ onTouchStart: onCardTouchStart,
123
+ onTouchMove: onCardTouchMove,
124
+ onTouchEnd: onCardTouchEnd,
125
+ onKeyDown: onCardKeyDown
126
+ },
127
+ String(card.id)
128
+ )
129
+ );
130
+ });
131
+ if (isDropTarget && dropIdx >= column.cards.length) {
132
+ nodes.push(/* @__PURE__ */ jsxRuntime.jsx("div", { className: tigercatCore.taskBoardDropIndicatorClasses }, "drop-end"));
133
+ }
134
+ cardsContent = nodes;
135
+ } else {
136
+ cardsContent = isDropTarget ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: tigercatCore.taskBoardDropIndicatorClasses }, "drop-empty") : renderEmptyColumn ? renderEmptyColumn(column) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: tigercatCore.taskBoardEmptyClasses, children: tigercatCore.resolveLocaleText(labels.emptyColumnText) });
137
+ }
138
+ const wipTitle = column.wipLimit != null ? tigercatCore.resolveLocaleText(labels.wipLimitText.replace("{limit}", String(column.wipLimit))) : void 0;
139
+ return /* @__PURE__ */ jsxRuntime.jsxs(
140
+ "div",
141
+ {
142
+ className: colClasses,
143
+ "data-tiger-taskboard-column": "",
144
+ "data-tiger-taskboard-column-id": String(column.id),
145
+ onDragOver: dragType === "column" ? onColumnDragOver : void 0,
146
+ onDrop: dragType === "column" ? onColumnDrop : void 0,
147
+ children: [
148
+ /* @__PURE__ */ jsxRuntime.jsx(
149
+ "div",
150
+ {
151
+ className: tigercatCore.taskBoardColumnHeaderClasses,
152
+ draggable: columnDraggable,
153
+ onDragStart: (e) => onColumnDragStart(e, column, colIndex),
154
+ onDragEnd,
155
+ onTouchStart: (e) => onColumnTouchStart(e, column, colIndex),
156
+ onTouchMove: onColumnTouchMove,
157
+ onTouchEnd: onColumnTouchEnd,
158
+ style: columnDraggable ? { cursor: "grab" } : void 0,
159
+ children: renderColumnHeader ? renderColumnHeader(column) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
160
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: wipOver ? tigercatCore.taskBoardWipExceededClasses : void 0, children: [
161
+ column.title,
162
+ column.wipLimit != null ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-2 text-xs font-normal opacity-70", title: wipTitle, children: [
163
+ "(",
164
+ column.cards.length,
165
+ "/",
166
+ column.wipLimit,
167
+ ")"
168
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2 text-xs font-normal opacity-50", children: column.cards.length })
169
+ ] }),
170
+ column.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-normal text-[var(--tiger-text-muted,#6b7280)] truncate max-w-[120px]", children: column.description })
171
+ ] })
172
+ }
173
+ ),
174
+ /* @__PURE__ */ jsxRuntime.jsx(
175
+ "div",
176
+ {
177
+ className: tigercatCore.taskBoardColumnBodyClasses,
178
+ role: "list",
179
+ "aria-label": column.title,
180
+ onDragOver: (e) => onCardDragOver(e, column),
181
+ onDrop: (e) => onCardDrop(e, column),
182
+ onDragLeave,
183
+ children: cardsContent
184
+ }
185
+ ),
186
+ renderColumnFooter ? renderColumnFooter(column) : onCardAdd ? /* @__PURE__ */ jsxRuntime.jsxs(
187
+ "div",
188
+ {
189
+ className: tigercatCore.classNames(
190
+ "border-t border-[var(--tiger-border,#e5e7eb)]",
191
+ tigercatCore.taskBoardAddCardClasses
192
+ ),
193
+ onClick: () => onCardAdd(column.id),
194
+ children: [
195
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "+" }),
196
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: tigercatCore.resolveLocaleText(labels.addCardText) })
197
+ ]
198
+ }
199
+ ) : null
200
+ ]
201
+ }
202
+ );
203
+ },
204
+ (prev, next) => prev.column === next.column && prev.colIndex === next.colIndex && prev.isDropTarget === next.isDropTarget && prev.isColDragging === next.isColDragging && prev.dropIdx === next.dropIdx && prev.draggable === next.draggable && prev.columnDraggable === next.columnDraggable && prev.dragType === next.dragType && prev.dragStateId === next.dragStateId && prev.kbDragStateId === next.kbDragStateId && prev.onCardAdd === next.onCardAdd
205
+ );
206
+ ColumnItem.displayName = "TaskBoardColumnItem";
207
+ var TaskBoard = ({
208
+ columns: controlledColumns,
209
+ defaultColumns = [],
210
+ draggable = true,
211
+ columnDraggable = true,
212
+ enforceWipLimit = false,
213
+ beforeCardMove,
214
+ beforeColumnMove,
215
+ onCardMove,
216
+ onColumnMove,
217
+ onColumnsChange,
218
+ onCardAdd,
219
+ renderCard: renderCardProp,
220
+ renderColumnHeader,
221
+ renderColumnFooter,
222
+ renderEmptyColumn,
223
+ locale,
224
+ className,
225
+ style,
226
+ ...rest
227
+ }) => {
228
+ const config = chunkQL6UEG3U_js.useTigerConfig();
229
+ const mergedLocale = React.useMemo(
230
+ () => tigercatCore.mergeTigerLocale(config.locale, locale),
231
+ [config.locale, locale]
232
+ );
233
+ const labels = React.useMemo(() => tigercatCore.getTaskBoardLabels(mergedLocale), [mergedLocale]);
234
+ const [innerColumns, setInnerColumns] = React.useState(defaultColumns);
235
+ React.useEffect(() => {
236
+ if (controlledColumns !== void 0) setInnerColumns(controlledColumns);
237
+ }, [controlledColumns]);
238
+ const currentColumns = controlledColumns ?? innerColumns;
239
+ const columnsRef = React.useRef(currentColumns);
240
+ columnsRef.current = currentColumns;
241
+ const updateColumns = React.useCallback(
242
+ (next) => {
243
+ setInnerColumns(next);
244
+ onColumnsChange?.(next);
245
+ },
246
+ [onColumnsChange]
247
+ );
248
+ const [dragState, setDragState] = React.useState(null);
249
+ const [dropTargetColumnId, setDropTargetColumnId] = React.useState(null);
250
+ const [dropIdx, setDropIdx] = React.useState(-1);
251
+ const [kbDragState, setKbDragState] = React.useState(null);
252
+ const boardRef = React.useRef(null);
253
+ const touchTrackerRef = React.useRef(null);
254
+ const touchRafRef = React.useRef(0);
255
+ const beforeCardMoveRef = React.useRef(beforeCardMove);
256
+ beforeCardMoveRef.current = beforeCardMove;
257
+ const beforeColumnMoveRef = React.useRef(beforeColumnMove);
258
+ beforeColumnMoveRef.current = beforeColumnMove;
259
+ const onCardMoveRef = React.useRef(onCardMove);
260
+ onCardMoveRef.current = onCardMove;
261
+ const onColumnMoveRef = React.useRef(onColumnMove);
262
+ onColumnMoveRef.current = onColumnMove;
263
+ const enforceWipLimitRef = React.useRef(enforceWipLimit);
264
+ enforceWipLimitRef.current = enforceWipLimit;
265
+ React.useEffect(() => {
266
+ if (typeof window !== "undefined" && ("ontouchstart" in window || navigator.maxTouchPoints > 0)) {
267
+ touchTrackerRef.current = tigercatCore.createTouchDragTracker();
268
+ }
269
+ return () => cancelAnimationFrame(touchRafRef.current);
270
+ }, []);
271
+ const resetDrag = React.useCallback(() => {
272
+ setDragState(null);
273
+ setDropTargetColumnId(null);
274
+ setDropIdx(-1);
275
+ }, []);
276
+ const applyCardMove = React.useCallback(
277
+ async (cardId, fromColumnId, toColumnId, toIdx) => {
278
+ const result = tigercatCore.moveCard(columnsRef.current, cardId, fromColumnId, toColumnId, toIdx, {
279
+ enforceWipLimit: enforceWipLimitRef.current
280
+ });
281
+ if (!result) return;
282
+ if (beforeCardMoveRef.current) {
283
+ const ok = await beforeCardMoveRef.current(result.event);
284
+ if (!ok) return;
285
+ }
286
+ updateColumns(result.columns);
287
+ onCardMoveRef.current?.(result.event);
288
+ },
289
+ [updateColumns]
290
+ );
291
+ const applyColumnMove = React.useCallback(
292
+ async (fromIdx, toIdx) => {
293
+ const cols = columnsRef.current;
294
+ const result = tigercatCore.reorderColumns(cols, fromIdx, Math.min(toIdx, cols.length - 1));
295
+ if (!result) return;
296
+ if (beforeColumnMoveRef.current) {
297
+ const ok = await beforeColumnMoveRef.current(result.event);
298
+ if (!ok) return;
299
+ }
300
+ updateColumns(result.columns);
301
+ onColumnMoveRef.current?.(result.event);
302
+ },
303
+ [updateColumns]
304
+ );
305
+ const handleCardDragStart = React.useCallback(
306
+ (e, card, column) => {
307
+ if (!draggable) return;
308
+ const idx = column.cards.findIndex((c) => c.id === card.id);
309
+ tigercatCore.setDragData(e.dataTransfer, tigercatCore.createCardDragData(card.id, column.id, idx));
310
+ setDragState({ type: "card", id: card.id, fromColumnId: column.id, fromIndex: idx });
311
+ },
312
+ [draggable]
313
+ );
314
+ const handleCardDragOver = React.useCallback(
315
+ (e, column) => {
316
+ e.preventDefault();
317
+ if (!dragState || dragState.type !== "card") return;
318
+ setDropTargetColumnId(column.id);
319
+ const target = e.currentTarget;
320
+ const cardEls = target.querySelectorAll("[data-tiger-taskboard-card]");
321
+ const rects = [];
322
+ cardEls.forEach((el) => rects.push(el.getBoundingClientRect()));
323
+ setDropIdx(tigercatCore.getDropIndex(e.clientY, rects));
324
+ },
325
+ [dragState]
326
+ );
327
+ const handleCardDrop = React.useCallback(
328
+ (e, column) => {
329
+ e.preventDefault();
330
+ const data = tigercatCore.parseDragData(e.dataTransfer);
331
+ if (!data || data.type !== "card") return;
332
+ applyCardMove(
333
+ data.cardId,
334
+ data.columnId,
335
+ column.id,
336
+ dropIdx >= 0 ? dropIdx : column.cards.length
337
+ );
338
+ resetDrag();
339
+ },
340
+ [dropIdx, applyCardMove, resetDrag]
341
+ );
342
+ const handleColumnDragStart = React.useCallback(
343
+ (e, column, index) => {
344
+ if (!columnDraggable) return;
345
+ tigercatCore.setDragData(e.dataTransfer, tigercatCore.createColumnDragData(column.id, index));
346
+ setDragState({ type: "column", id: column.id, fromIndex: index });
347
+ },
348
+ [columnDraggable]
349
+ );
350
+ const handleColumnDragOver = React.useCallback(
351
+ (e) => {
352
+ if (!dragState || dragState.type !== "column") return;
353
+ e.preventDefault();
354
+ },
355
+ [dragState]
356
+ );
357
+ const handleColumnDrop = React.useCallback(
358
+ (e) => {
359
+ e.preventDefault();
360
+ const data = tigercatCore.parseDragData(e.dataTransfer);
361
+ if (!data || data.type !== "column") return;
362
+ const colEls = boardRef.current?.querySelectorAll("[data-tiger-taskboard-column]");
363
+ if (!colEls) return;
364
+ const rects = [];
365
+ colEls.forEach((el) => rects.push(el.getBoundingClientRect()));
366
+ const toIdx = tigercatCore.getColumnDropIndex(e.clientX, rects);
367
+ applyColumnMove(data.index, toIdx);
368
+ resetDrag();
369
+ },
370
+ [applyColumnMove, resetDrag]
371
+ );
372
+ const handleDragEnd = React.useCallback(() => resetDrag(), [resetDrag]);
373
+ const handleDragLeave = React.useCallback(
374
+ (e) => {
375
+ const related = e.relatedTarget;
376
+ if (!related || !e.currentTarget.contains(related)) {
377
+ if (dragState?.type === "card") {
378
+ setDropTargetColumnId(null);
379
+ setDropIdx(-1);
380
+ }
381
+ }
382
+ },
383
+ [dragState]
384
+ );
385
+ const handleTouchStart = React.useCallback(
386
+ (e, card, column) => {
387
+ if (!draggable || !touchTrackerRef.current) return;
388
+ const idx = column.cards.findIndex((c) => c.id === card.id);
389
+ touchTrackerRef.current.onTouchStart(e.nativeEvent, e.currentTarget);
390
+ setDragState({ type: "card", id: card.id, fromColumnId: column.id, fromIndex: idx });
391
+ },
392
+ [draggable]
393
+ );
394
+ const handleTouchMove = React.useCallback(
395
+ (e) => {
396
+ if (!touchTrackerRef.current || !dragState) return;
397
+ touchTrackerRef.current.onTouchMove(e.nativeEvent);
398
+ cancelAnimationFrame(touchRafRef.current);
399
+ touchRafRef.current = requestAnimationFrame(() => {
400
+ const st = touchTrackerRef.current.getState();
401
+ if (dragState?.type === "card") {
402
+ const colEl = tigercatCore.findColumnFromPoint(st.currentX, st.currentY, boardRef.current);
403
+ if (colEl) {
404
+ const colId = colEl.getAttribute("data-tiger-taskboard-column-id");
405
+ setDropTargetColumnId(colId ?? null);
406
+ const cardEls = colEl.querySelectorAll("[data-tiger-taskboard-card]");
407
+ const rects = [];
408
+ cardEls.forEach((el) => rects.push(el.getBoundingClientRect()));
409
+ setDropIdx(tigercatCore.getDropIndex(st.currentY, rects));
410
+ }
411
+ }
412
+ });
413
+ },
414
+ [dragState]
415
+ );
416
+ const handleTouchEnd = React.useCallback(() => {
417
+ if (!touchTrackerRef.current || !dragState) return;
418
+ touchTrackerRef.current.onTouchEnd();
419
+ if (dragState.type === "card" && dropTargetColumnId != null) {
420
+ applyCardMove(
421
+ dragState.id,
422
+ dragState.fromColumnId,
423
+ dropTargetColumnId,
424
+ dropIdx >= 0 ? dropIdx : 0
425
+ );
426
+ }
427
+ resetDrag();
428
+ }, [dragState, dropIdx, dropTargetColumnId, applyCardMove, resetDrag]);
429
+ const handleColumnTouchStart = React.useCallback(
430
+ (e, column, index) => {
431
+ if (!columnDraggable || !touchTrackerRef.current) return;
432
+ touchTrackerRef.current.onTouchStart(e.nativeEvent, e.currentTarget);
433
+ setDragState({ type: "column", id: column.id, fromIndex: index });
434
+ },
435
+ [columnDraggable]
436
+ );
437
+ const handleColumnTouchMove = React.useCallback(
438
+ (e) => {
439
+ if (!touchTrackerRef.current || !dragState || dragState.type !== "column") return;
440
+ touchTrackerRef.current.onTouchMove(e.nativeEvent);
441
+ },
442
+ [dragState]
443
+ );
444
+ const handleColumnTouchEnd = React.useCallback(() => {
445
+ if (!touchTrackerRef.current || !dragState || dragState.type !== "column") return;
446
+ const st = touchTrackerRef.current.onTouchEnd();
447
+ const colEls = boardRef.current?.querySelectorAll("[data-tiger-taskboard-column]");
448
+ if (!colEls) {
449
+ resetDrag();
450
+ return;
451
+ }
452
+ const rects = [];
453
+ colEls.forEach((el) => rects.push(el.getBoundingClientRect()));
454
+ const toIdx = tigercatCore.getColumnDropIndex(st.currentX, rects);
455
+ applyColumnMove(dragState.fromIndex, Math.min(toIdx, columnsRef.current.length - 1));
456
+ resetDrag();
457
+ }, [dragState, applyColumnMove, resetDrag]);
458
+ const handleCardKeyDown = React.useCallback(
459
+ (e, card, column) => {
460
+ if (!draggable) return;
461
+ if (e.key === "Enter" || e.key === " ") {
462
+ e.preventDefault();
463
+ if (!kbDragState) {
464
+ const idx = column.cards.findIndex((c) => c.id === card.id);
465
+ setKbDragState({ type: "card", id: card.id, fromColumnId: column.id, fromIndex: idx });
466
+ } else {
467
+ const cardIdx = column.cards.findIndex((c) => c.id === card.id);
468
+ if (kbDragState.fromColumnId !== void 0) {
469
+ applyCardMove(kbDragState.id, kbDragState.fromColumnId, column.id, cardIdx);
470
+ }
471
+ setKbDragState(null);
472
+ }
473
+ return;
474
+ }
475
+ if (e.key === "Escape" && kbDragState) {
476
+ e.preventDefault();
477
+ setKbDragState(null);
478
+ }
479
+ },
480
+ [draggable, kbDragState, applyCardMove]
481
+ );
482
+ const wrapperClasses = React.useMemo(() => tigercatCore.classNames(tigercatCore.taskBoardBaseClasses, className), [className]);
483
+ const dragType = dragState?.type ?? null;
484
+ const dragStateId = dragState?.type === "card" ? dragState.id : null;
485
+ const kbDragStateId = kbDragState?.id ?? null;
486
+ return /* @__PURE__ */ jsxRuntime.jsx(
487
+ "div",
488
+ {
489
+ ref: boardRef,
490
+ className: wrapperClasses,
491
+ style,
492
+ role: "region",
493
+ "aria-label": tigercatCore.resolveLocaleText(labels.boardAriaLabel),
494
+ "data-tiger-task-board": "",
495
+ ...rest,
496
+ children: currentColumns.map((col, i) => {
497
+ const isDropTarget = dragState?.type === "card" && dropTargetColumnId === col.id;
498
+ const isColDragging = dragState?.type === "column" && dragState.id === col.id;
499
+ return /* @__PURE__ */ jsxRuntime.jsx(
500
+ ColumnItem,
501
+ {
502
+ column: col,
503
+ colIndex: i,
504
+ isDropTarget,
505
+ isColDragging,
506
+ dropIdx: isDropTarget ? dropIdx : -1,
507
+ draggable,
508
+ columnDraggable,
509
+ labels,
510
+ renderCardProp,
511
+ renderColumnHeader,
512
+ renderColumnFooter,
513
+ renderEmptyColumn,
514
+ onCardAdd,
515
+ dragType,
516
+ onCardDragStart: handleCardDragStart,
517
+ onCardDragOver: handleCardDragOver,
518
+ onCardDrop: handleCardDrop,
519
+ onDragEnd: handleDragEnd,
520
+ onDragLeave: handleDragLeave,
521
+ onColumnDragStart: handleColumnDragStart,
522
+ onColumnDragOver: handleColumnDragOver,
523
+ onColumnDrop: handleColumnDrop,
524
+ onCardTouchStart: handleTouchStart,
525
+ onCardTouchMove: handleTouchMove,
526
+ onCardTouchEnd: handleTouchEnd,
527
+ onColumnTouchStart: handleColumnTouchStart,
528
+ onColumnTouchMove: handleColumnTouchMove,
529
+ onColumnTouchEnd: handleColumnTouchEnd,
530
+ onCardKeyDown: handleCardKeyDown,
531
+ dragStateId,
532
+ kbDragStateId
533
+ },
534
+ String(col.id)
535
+ );
536
+ })
537
+ }
538
+ );
539
+ };
540
+ var TaskBoard_default = TaskBoard;
541
+
542
+ exports.TaskBoard = TaskBoard;
543
+ exports.TaskBoard_default = TaskBoard_default;
@@ -0,0 +1,536 @@
1
+ import { useTigerConfig } from './chunk-VEGBO77D.mjs';
2
+ import React, { useMemo, useState, useEffect, useRef, useCallback } from 'react';
3
+ import { classNames, taskBoardCardClasses, taskBoardCardDraggingClasses, isWipExceeded, taskBoardColumnClasses, taskBoardColumnDropTargetClasses, taskBoardColumnDraggingClasses, taskBoardDropIndicatorClasses, resolveLocaleText, taskBoardEmptyClasses, taskBoardColumnHeaderClasses, taskBoardWipExceededClasses, taskBoardColumnBodyClasses, taskBoardAddCardClasses, mergeTigerLocale, getTaskBoardLabels, createTouchDragTracker, moveCard, reorderColumns, setDragData, createCardDragData, getDropIndex, parseDragData, createColumnDragData, getColumnDropIndex, findColumnFromPoint, taskBoardBaseClasses } from '@expcat/tigercat-core';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
+
6
+ var CardItem = React.memo(
7
+ ({
8
+ card,
9
+ column,
10
+ isDragging,
11
+ isKbGrabbed,
12
+ draggable,
13
+ dragHintText,
14
+ renderCard,
15
+ onDragStart,
16
+ onDragEnd,
17
+ onTouchStart,
18
+ onTouchMove,
19
+ onTouchEnd,
20
+ onKeyDown
21
+ }) => {
22
+ const cardClasses = classNames(
23
+ taskBoardCardClasses,
24
+ isDragging && taskBoardCardDraggingClasses,
25
+ isKbGrabbed && "ring-2 ring-[var(--tiger-primary,#2563eb)]"
26
+ );
27
+ return /* @__PURE__ */ jsx(
28
+ "div",
29
+ {
30
+ className: cardClasses,
31
+ draggable,
32
+ tabIndex: 0,
33
+ role: "listitem",
34
+ "aria-roledescription": dragHintText,
35
+ "aria-grabbed": isKbGrabbed ? "true" : void 0,
36
+ "data-tiger-taskboard-card": "",
37
+ "data-tiger-taskboard-card-id": String(card.id),
38
+ onDragStart: (e) => onDragStart(e, card, column),
39
+ onDragEnd,
40
+ onTouchStart: (e) => onTouchStart(e, card, column),
41
+ onTouchMove,
42
+ onTouchEnd,
43
+ onKeyDown: (e) => onKeyDown(e, card, column),
44
+ children: renderCard ? renderCard(card, column.id) : /* @__PURE__ */ jsxs(Fragment, { children: [
45
+ /* @__PURE__ */ jsx("div", { className: "font-medium text-sm text-[var(--tiger-text,#1f2937)]", children: card.title }),
46
+ card.description && /* @__PURE__ */ jsx("div", { className: "mt-1 text-xs text-[var(--tiger-text-muted,#6b7280)] line-clamp-2", children: card.description })
47
+ ] })
48
+ }
49
+ );
50
+ },
51
+ (prev, next) => prev.card.id === next.card.id && prev.isDragging === next.isDragging && prev.isKbGrabbed === next.isKbGrabbed && prev.draggable === next.draggable && prev.card === next.card
52
+ );
53
+ CardItem.displayName = "TaskBoardCardItem";
54
+ var ColumnItem = React.memo(
55
+ ({
56
+ column,
57
+ colIndex,
58
+ isDropTarget,
59
+ isColDragging,
60
+ dropIdx,
61
+ draggable,
62
+ columnDraggable,
63
+ labels,
64
+ renderCardProp,
65
+ renderColumnHeader,
66
+ renderColumnFooter,
67
+ renderEmptyColumn,
68
+ onCardAdd,
69
+ dragType,
70
+ onCardDragStart,
71
+ onCardDragOver,
72
+ onCardDrop,
73
+ onDragEnd,
74
+ onDragLeave,
75
+ onColumnDragStart,
76
+ onColumnDragOver,
77
+ onColumnDrop,
78
+ onCardTouchStart,
79
+ onCardTouchMove,
80
+ onCardTouchEnd,
81
+ onColumnTouchStart,
82
+ onColumnTouchMove,
83
+ onColumnTouchEnd,
84
+ onCardKeyDown,
85
+ dragStateId,
86
+ kbDragStateId
87
+ }) => {
88
+ const wipOver = isWipExceeded(column);
89
+ const colClasses = classNames(
90
+ taskBoardColumnClasses,
91
+ isDropTarget && taskBoardColumnDropTargetClasses,
92
+ isColDragging && taskBoardColumnDraggingClasses
93
+ );
94
+ let cardsContent;
95
+ if (column.cards.length > 0) {
96
+ const nodes = [];
97
+ column.cards.forEach((card, i) => {
98
+ if (isDropTarget && dropIdx === i) {
99
+ nodes.push(/* @__PURE__ */ jsx("div", { className: taskBoardDropIndicatorClasses }, `drop-${i}`));
100
+ }
101
+ const isDragging = dragStateId === card.id;
102
+ const isKbGrabbed = kbDragStateId === card.id;
103
+ nodes.push(
104
+ /* @__PURE__ */ jsx(
105
+ CardItem,
106
+ {
107
+ card,
108
+ column,
109
+ isDragging,
110
+ isKbGrabbed,
111
+ draggable,
112
+ dragHintText: labels.dragHintText,
113
+ renderCard: renderCardProp,
114
+ onDragStart: onCardDragStart,
115
+ onDragEnd,
116
+ onTouchStart: onCardTouchStart,
117
+ onTouchMove: onCardTouchMove,
118
+ onTouchEnd: onCardTouchEnd,
119
+ onKeyDown: onCardKeyDown
120
+ },
121
+ String(card.id)
122
+ )
123
+ );
124
+ });
125
+ if (isDropTarget && dropIdx >= column.cards.length) {
126
+ nodes.push(/* @__PURE__ */ jsx("div", { className: taskBoardDropIndicatorClasses }, "drop-end"));
127
+ }
128
+ cardsContent = nodes;
129
+ } else {
130
+ cardsContent = isDropTarget ? /* @__PURE__ */ jsx("div", { className: taskBoardDropIndicatorClasses }, "drop-empty") : renderEmptyColumn ? renderEmptyColumn(column) : /* @__PURE__ */ jsx("div", { className: taskBoardEmptyClasses, children: resolveLocaleText(labels.emptyColumnText) });
131
+ }
132
+ const wipTitle = column.wipLimit != null ? resolveLocaleText(labels.wipLimitText.replace("{limit}", String(column.wipLimit))) : void 0;
133
+ return /* @__PURE__ */ jsxs(
134
+ "div",
135
+ {
136
+ className: colClasses,
137
+ "data-tiger-taskboard-column": "",
138
+ "data-tiger-taskboard-column-id": String(column.id),
139
+ onDragOver: dragType === "column" ? onColumnDragOver : void 0,
140
+ onDrop: dragType === "column" ? onColumnDrop : void 0,
141
+ children: [
142
+ /* @__PURE__ */ jsx(
143
+ "div",
144
+ {
145
+ className: taskBoardColumnHeaderClasses,
146
+ draggable: columnDraggable,
147
+ onDragStart: (e) => onColumnDragStart(e, column, colIndex),
148
+ onDragEnd,
149
+ onTouchStart: (e) => onColumnTouchStart(e, column, colIndex),
150
+ onTouchMove: onColumnTouchMove,
151
+ onTouchEnd: onColumnTouchEnd,
152
+ style: columnDraggable ? { cursor: "grab" } : void 0,
153
+ children: renderColumnHeader ? renderColumnHeader(column) : /* @__PURE__ */ jsxs(Fragment, { children: [
154
+ /* @__PURE__ */ jsxs("span", { className: wipOver ? taskBoardWipExceededClasses : void 0, children: [
155
+ column.title,
156
+ column.wipLimit != null ? /* @__PURE__ */ jsxs("span", { className: "ml-2 text-xs font-normal opacity-70", title: wipTitle, children: [
157
+ "(",
158
+ column.cards.length,
159
+ "/",
160
+ column.wipLimit,
161
+ ")"
162
+ ] }) : /* @__PURE__ */ jsx("span", { className: "ml-2 text-xs font-normal opacity-50", children: column.cards.length })
163
+ ] }),
164
+ column.description && /* @__PURE__ */ jsx("span", { className: "text-xs font-normal text-[var(--tiger-text-muted,#6b7280)] truncate max-w-[120px]", children: column.description })
165
+ ] })
166
+ }
167
+ ),
168
+ /* @__PURE__ */ jsx(
169
+ "div",
170
+ {
171
+ className: taskBoardColumnBodyClasses,
172
+ role: "list",
173
+ "aria-label": column.title,
174
+ onDragOver: (e) => onCardDragOver(e, column),
175
+ onDrop: (e) => onCardDrop(e, column),
176
+ onDragLeave,
177
+ children: cardsContent
178
+ }
179
+ ),
180
+ renderColumnFooter ? renderColumnFooter(column) : onCardAdd ? /* @__PURE__ */ jsxs(
181
+ "div",
182
+ {
183
+ className: classNames(
184
+ "border-t border-[var(--tiger-border,#e5e7eb)]",
185
+ taskBoardAddCardClasses
186
+ ),
187
+ onClick: () => onCardAdd(column.id),
188
+ children: [
189
+ /* @__PURE__ */ jsx("span", { children: "+" }),
190
+ /* @__PURE__ */ jsx("span", { children: resolveLocaleText(labels.addCardText) })
191
+ ]
192
+ }
193
+ ) : null
194
+ ]
195
+ }
196
+ );
197
+ },
198
+ (prev, next) => prev.column === next.column && prev.colIndex === next.colIndex && prev.isDropTarget === next.isDropTarget && prev.isColDragging === next.isColDragging && prev.dropIdx === next.dropIdx && prev.draggable === next.draggable && prev.columnDraggable === next.columnDraggable && prev.dragType === next.dragType && prev.dragStateId === next.dragStateId && prev.kbDragStateId === next.kbDragStateId && prev.onCardAdd === next.onCardAdd
199
+ );
200
+ ColumnItem.displayName = "TaskBoardColumnItem";
201
+ var TaskBoard = ({
202
+ columns: controlledColumns,
203
+ defaultColumns = [],
204
+ draggable = true,
205
+ columnDraggable = true,
206
+ enforceWipLimit = false,
207
+ beforeCardMove,
208
+ beforeColumnMove,
209
+ onCardMove,
210
+ onColumnMove,
211
+ onColumnsChange,
212
+ onCardAdd,
213
+ renderCard: renderCardProp,
214
+ renderColumnHeader,
215
+ renderColumnFooter,
216
+ renderEmptyColumn,
217
+ locale,
218
+ className,
219
+ style,
220
+ ...rest
221
+ }) => {
222
+ const config = useTigerConfig();
223
+ const mergedLocale = useMemo(
224
+ () => mergeTigerLocale(config.locale, locale),
225
+ [config.locale, locale]
226
+ );
227
+ const labels = useMemo(() => getTaskBoardLabels(mergedLocale), [mergedLocale]);
228
+ const [innerColumns, setInnerColumns] = useState(defaultColumns);
229
+ useEffect(() => {
230
+ if (controlledColumns !== void 0) setInnerColumns(controlledColumns);
231
+ }, [controlledColumns]);
232
+ const currentColumns = controlledColumns ?? innerColumns;
233
+ const columnsRef = useRef(currentColumns);
234
+ columnsRef.current = currentColumns;
235
+ const updateColumns = useCallback(
236
+ (next) => {
237
+ setInnerColumns(next);
238
+ onColumnsChange?.(next);
239
+ },
240
+ [onColumnsChange]
241
+ );
242
+ const [dragState, setDragState] = useState(null);
243
+ const [dropTargetColumnId, setDropTargetColumnId] = useState(null);
244
+ const [dropIdx, setDropIdx] = useState(-1);
245
+ const [kbDragState, setKbDragState] = useState(null);
246
+ const boardRef = useRef(null);
247
+ const touchTrackerRef = useRef(null);
248
+ const touchRafRef = useRef(0);
249
+ const beforeCardMoveRef = useRef(beforeCardMove);
250
+ beforeCardMoveRef.current = beforeCardMove;
251
+ const beforeColumnMoveRef = useRef(beforeColumnMove);
252
+ beforeColumnMoveRef.current = beforeColumnMove;
253
+ const onCardMoveRef = useRef(onCardMove);
254
+ onCardMoveRef.current = onCardMove;
255
+ const onColumnMoveRef = useRef(onColumnMove);
256
+ onColumnMoveRef.current = onColumnMove;
257
+ const enforceWipLimitRef = useRef(enforceWipLimit);
258
+ enforceWipLimitRef.current = enforceWipLimit;
259
+ useEffect(() => {
260
+ if (typeof window !== "undefined" && ("ontouchstart" in window || navigator.maxTouchPoints > 0)) {
261
+ touchTrackerRef.current = createTouchDragTracker();
262
+ }
263
+ return () => cancelAnimationFrame(touchRafRef.current);
264
+ }, []);
265
+ const resetDrag = useCallback(() => {
266
+ setDragState(null);
267
+ setDropTargetColumnId(null);
268
+ setDropIdx(-1);
269
+ }, []);
270
+ const applyCardMove = useCallback(
271
+ async (cardId, fromColumnId, toColumnId, toIdx) => {
272
+ const result = moveCard(columnsRef.current, cardId, fromColumnId, toColumnId, toIdx, {
273
+ enforceWipLimit: enforceWipLimitRef.current
274
+ });
275
+ if (!result) return;
276
+ if (beforeCardMoveRef.current) {
277
+ const ok = await beforeCardMoveRef.current(result.event);
278
+ if (!ok) return;
279
+ }
280
+ updateColumns(result.columns);
281
+ onCardMoveRef.current?.(result.event);
282
+ },
283
+ [updateColumns]
284
+ );
285
+ const applyColumnMove = useCallback(
286
+ async (fromIdx, toIdx) => {
287
+ const cols = columnsRef.current;
288
+ const result = reorderColumns(cols, fromIdx, Math.min(toIdx, cols.length - 1));
289
+ if (!result) return;
290
+ if (beforeColumnMoveRef.current) {
291
+ const ok = await beforeColumnMoveRef.current(result.event);
292
+ if (!ok) return;
293
+ }
294
+ updateColumns(result.columns);
295
+ onColumnMoveRef.current?.(result.event);
296
+ },
297
+ [updateColumns]
298
+ );
299
+ const handleCardDragStart = useCallback(
300
+ (e, card, column) => {
301
+ if (!draggable) return;
302
+ const idx = column.cards.findIndex((c) => c.id === card.id);
303
+ setDragData(e.dataTransfer, createCardDragData(card.id, column.id, idx));
304
+ setDragState({ type: "card", id: card.id, fromColumnId: column.id, fromIndex: idx });
305
+ },
306
+ [draggable]
307
+ );
308
+ const handleCardDragOver = useCallback(
309
+ (e, column) => {
310
+ e.preventDefault();
311
+ if (!dragState || dragState.type !== "card") return;
312
+ setDropTargetColumnId(column.id);
313
+ const target = e.currentTarget;
314
+ const cardEls = target.querySelectorAll("[data-tiger-taskboard-card]");
315
+ const rects = [];
316
+ cardEls.forEach((el) => rects.push(el.getBoundingClientRect()));
317
+ setDropIdx(getDropIndex(e.clientY, rects));
318
+ },
319
+ [dragState]
320
+ );
321
+ const handleCardDrop = useCallback(
322
+ (e, column) => {
323
+ e.preventDefault();
324
+ const data = parseDragData(e.dataTransfer);
325
+ if (!data || data.type !== "card") return;
326
+ applyCardMove(
327
+ data.cardId,
328
+ data.columnId,
329
+ column.id,
330
+ dropIdx >= 0 ? dropIdx : column.cards.length
331
+ );
332
+ resetDrag();
333
+ },
334
+ [dropIdx, applyCardMove, resetDrag]
335
+ );
336
+ const handleColumnDragStart = useCallback(
337
+ (e, column, index) => {
338
+ if (!columnDraggable) return;
339
+ setDragData(e.dataTransfer, createColumnDragData(column.id, index));
340
+ setDragState({ type: "column", id: column.id, fromIndex: index });
341
+ },
342
+ [columnDraggable]
343
+ );
344
+ const handleColumnDragOver = useCallback(
345
+ (e) => {
346
+ if (!dragState || dragState.type !== "column") return;
347
+ e.preventDefault();
348
+ },
349
+ [dragState]
350
+ );
351
+ const handleColumnDrop = useCallback(
352
+ (e) => {
353
+ e.preventDefault();
354
+ const data = parseDragData(e.dataTransfer);
355
+ if (!data || data.type !== "column") return;
356
+ const colEls = boardRef.current?.querySelectorAll("[data-tiger-taskboard-column]");
357
+ if (!colEls) return;
358
+ const rects = [];
359
+ colEls.forEach((el) => rects.push(el.getBoundingClientRect()));
360
+ const toIdx = getColumnDropIndex(e.clientX, rects);
361
+ applyColumnMove(data.index, toIdx);
362
+ resetDrag();
363
+ },
364
+ [applyColumnMove, resetDrag]
365
+ );
366
+ const handleDragEnd = useCallback(() => resetDrag(), [resetDrag]);
367
+ const handleDragLeave = useCallback(
368
+ (e) => {
369
+ const related = e.relatedTarget;
370
+ if (!related || !e.currentTarget.contains(related)) {
371
+ if (dragState?.type === "card") {
372
+ setDropTargetColumnId(null);
373
+ setDropIdx(-1);
374
+ }
375
+ }
376
+ },
377
+ [dragState]
378
+ );
379
+ const handleTouchStart = useCallback(
380
+ (e, card, column) => {
381
+ if (!draggable || !touchTrackerRef.current) return;
382
+ const idx = column.cards.findIndex((c) => c.id === card.id);
383
+ touchTrackerRef.current.onTouchStart(e.nativeEvent, e.currentTarget);
384
+ setDragState({ type: "card", id: card.id, fromColumnId: column.id, fromIndex: idx });
385
+ },
386
+ [draggable]
387
+ );
388
+ const handleTouchMove = useCallback(
389
+ (e) => {
390
+ if (!touchTrackerRef.current || !dragState) return;
391
+ touchTrackerRef.current.onTouchMove(e.nativeEvent);
392
+ cancelAnimationFrame(touchRafRef.current);
393
+ touchRafRef.current = requestAnimationFrame(() => {
394
+ const st = touchTrackerRef.current.getState();
395
+ if (dragState?.type === "card") {
396
+ const colEl = findColumnFromPoint(st.currentX, st.currentY, boardRef.current);
397
+ if (colEl) {
398
+ const colId = colEl.getAttribute("data-tiger-taskboard-column-id");
399
+ setDropTargetColumnId(colId ?? null);
400
+ const cardEls = colEl.querySelectorAll("[data-tiger-taskboard-card]");
401
+ const rects = [];
402
+ cardEls.forEach((el) => rects.push(el.getBoundingClientRect()));
403
+ setDropIdx(getDropIndex(st.currentY, rects));
404
+ }
405
+ }
406
+ });
407
+ },
408
+ [dragState]
409
+ );
410
+ const handleTouchEnd = useCallback(() => {
411
+ if (!touchTrackerRef.current || !dragState) return;
412
+ touchTrackerRef.current.onTouchEnd();
413
+ if (dragState.type === "card" && dropTargetColumnId != null) {
414
+ applyCardMove(
415
+ dragState.id,
416
+ dragState.fromColumnId,
417
+ dropTargetColumnId,
418
+ dropIdx >= 0 ? dropIdx : 0
419
+ );
420
+ }
421
+ resetDrag();
422
+ }, [dragState, dropIdx, dropTargetColumnId, applyCardMove, resetDrag]);
423
+ const handleColumnTouchStart = useCallback(
424
+ (e, column, index) => {
425
+ if (!columnDraggable || !touchTrackerRef.current) return;
426
+ touchTrackerRef.current.onTouchStart(e.nativeEvent, e.currentTarget);
427
+ setDragState({ type: "column", id: column.id, fromIndex: index });
428
+ },
429
+ [columnDraggable]
430
+ );
431
+ const handleColumnTouchMove = useCallback(
432
+ (e) => {
433
+ if (!touchTrackerRef.current || !dragState || dragState.type !== "column") return;
434
+ touchTrackerRef.current.onTouchMove(e.nativeEvent);
435
+ },
436
+ [dragState]
437
+ );
438
+ const handleColumnTouchEnd = useCallback(() => {
439
+ if (!touchTrackerRef.current || !dragState || dragState.type !== "column") return;
440
+ const st = touchTrackerRef.current.onTouchEnd();
441
+ const colEls = boardRef.current?.querySelectorAll("[data-tiger-taskboard-column]");
442
+ if (!colEls) {
443
+ resetDrag();
444
+ return;
445
+ }
446
+ const rects = [];
447
+ colEls.forEach((el) => rects.push(el.getBoundingClientRect()));
448
+ const toIdx = getColumnDropIndex(st.currentX, rects);
449
+ applyColumnMove(dragState.fromIndex, Math.min(toIdx, columnsRef.current.length - 1));
450
+ resetDrag();
451
+ }, [dragState, applyColumnMove, resetDrag]);
452
+ const handleCardKeyDown = useCallback(
453
+ (e, card, column) => {
454
+ if (!draggable) return;
455
+ if (e.key === "Enter" || e.key === " ") {
456
+ e.preventDefault();
457
+ if (!kbDragState) {
458
+ const idx = column.cards.findIndex((c) => c.id === card.id);
459
+ setKbDragState({ type: "card", id: card.id, fromColumnId: column.id, fromIndex: idx });
460
+ } else {
461
+ const cardIdx = column.cards.findIndex((c) => c.id === card.id);
462
+ if (kbDragState.fromColumnId !== void 0) {
463
+ applyCardMove(kbDragState.id, kbDragState.fromColumnId, column.id, cardIdx);
464
+ }
465
+ setKbDragState(null);
466
+ }
467
+ return;
468
+ }
469
+ if (e.key === "Escape" && kbDragState) {
470
+ e.preventDefault();
471
+ setKbDragState(null);
472
+ }
473
+ },
474
+ [draggable, kbDragState, applyCardMove]
475
+ );
476
+ const wrapperClasses = useMemo(() => classNames(taskBoardBaseClasses, className), [className]);
477
+ const dragType = dragState?.type ?? null;
478
+ const dragStateId = dragState?.type === "card" ? dragState.id : null;
479
+ const kbDragStateId = kbDragState?.id ?? null;
480
+ return /* @__PURE__ */ jsx(
481
+ "div",
482
+ {
483
+ ref: boardRef,
484
+ className: wrapperClasses,
485
+ style,
486
+ role: "region",
487
+ "aria-label": resolveLocaleText(labels.boardAriaLabel),
488
+ "data-tiger-task-board": "",
489
+ ...rest,
490
+ children: currentColumns.map((col, i) => {
491
+ const isDropTarget = dragState?.type === "card" && dropTargetColumnId === col.id;
492
+ const isColDragging = dragState?.type === "column" && dragState.id === col.id;
493
+ return /* @__PURE__ */ jsx(
494
+ ColumnItem,
495
+ {
496
+ column: col,
497
+ colIndex: i,
498
+ isDropTarget,
499
+ isColDragging,
500
+ dropIdx: isDropTarget ? dropIdx : -1,
501
+ draggable,
502
+ columnDraggable,
503
+ labels,
504
+ renderCardProp,
505
+ renderColumnHeader,
506
+ renderColumnFooter,
507
+ renderEmptyColumn,
508
+ onCardAdd,
509
+ dragType,
510
+ onCardDragStart: handleCardDragStart,
511
+ onCardDragOver: handleCardDragOver,
512
+ onCardDrop: handleCardDrop,
513
+ onDragEnd: handleDragEnd,
514
+ onDragLeave: handleDragLeave,
515
+ onColumnDragStart: handleColumnDragStart,
516
+ onColumnDragOver: handleColumnDragOver,
517
+ onColumnDrop: handleColumnDrop,
518
+ onCardTouchStart: handleTouchStart,
519
+ onCardTouchMove: handleTouchMove,
520
+ onCardTouchEnd: handleTouchEnd,
521
+ onColumnTouchStart: handleColumnTouchStart,
522
+ onColumnTouchMove: handleColumnTouchMove,
523
+ onColumnTouchEnd: handleColumnTouchEnd,
524
+ onCardKeyDown: handleCardKeyDown,
525
+ dragStateId,
526
+ kbDragStateId
527
+ },
528
+ String(col.id)
529
+ );
530
+ })
531
+ }
532
+ );
533
+ };
534
+ var TaskBoard_default = TaskBoard;
535
+
536
+ export { TaskBoard, TaskBoard_default };
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { TaskBoardProps as TaskBoardProps$1, TaskBoardCard, TaskBoardColumn } from '@expcat/tigercat-core';
3
+
4
+ interface TaskBoardProps extends Omit<TaskBoardProps$1, 'style' | 'renderCard' | 'renderColumnHeader' | 'renderColumnFooter' | 'renderEmptyColumn'>, Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'style' | 'draggable'> {
5
+ renderCard?: (card: TaskBoardCard, columnId: string | number) => React.ReactNode;
6
+ renderColumnHeader?: (column: TaskBoardColumn) => React.ReactNode;
7
+ renderColumnFooter?: (column: TaskBoardColumn) => React.ReactNode;
8
+ renderEmptyColumn?: (column: TaskBoardColumn) => React.ReactNode;
9
+ style?: React.CSSProperties;
10
+ }
11
+ declare const TaskBoard: React.FC<TaskBoardProps>;
12
+
13
+ export { TaskBoard, type TaskBoardProps, TaskBoard as default };
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { TaskBoardProps as TaskBoardProps$1, TaskBoardCard, TaskBoardColumn } from '@expcat/tigercat-core';
3
+
4
+ interface TaskBoardProps extends Omit<TaskBoardProps$1, 'style' | 'renderCard' | 'renderColumnHeader' | 'renderColumnFooter' | 'renderEmptyColumn'>, Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'style' | 'draggable'> {
5
+ renderCard?: (card: TaskBoardCard, columnId: string | number) => React.ReactNode;
6
+ renderColumnHeader?: (column: TaskBoardColumn) => React.ReactNode;
7
+ renderColumnFooter?: (column: TaskBoardColumn) => React.ReactNode;
8
+ renderEmptyColumn?: (column: TaskBoardColumn) => React.ReactNode;
9
+ style?: React.CSSProperties;
10
+ }
11
+ declare const TaskBoard: React.FC<TaskBoardProps>;
12
+
13
+ export { TaskBoard, type TaskBoardProps, TaskBoard as default };
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var chunkJWFEJ4XG_js = require('../chunk-JWFEJ4XG.js');
6
+ require('../chunk-QL6UEG3U.js');
7
+
8
+
9
+
10
+ Object.defineProperty(exports, "TaskBoard", {
11
+ enumerable: true,
12
+ get: function () { return chunkJWFEJ4XG_js.TaskBoard; }
13
+ });
14
+ Object.defineProperty(exports, "default", {
15
+ enumerable: true,
16
+ get: function () { return chunkJWFEJ4XG_js.TaskBoard_default; }
17
+ });
@@ -0,0 +1,2 @@
1
+ export { TaskBoard, TaskBoard_default as default } from '../chunk-PJCY45UP.mjs';
2
+ import '../chunk-VEGBO77D.mjs';
package/dist/index.d.mts CHANGED
@@ -94,6 +94,7 @@ export { Carousel, CarouselProps, CarouselRef } from './components/Carousel.mjs'
94
94
  export { default as BackTop, BackTopProps } from './components/BackTop.mjs';
95
95
  export { default as Anchor, AnchorContextValue, AnchorProps, useAnchorContext } from './components/Anchor.mjs';
96
96
  export { default as AnchorLink, AnchorLinkProps } from './components/AnchorLink.mjs';
97
+ export { default as TaskBoard, TaskBoardProps } from './components/TaskBoard.mjs';
97
98
  import 'react';
98
99
  import 'react/jsx-runtime';
99
100
 
package/dist/index.d.ts CHANGED
@@ -94,6 +94,7 @@ export { Carousel, CarouselProps, CarouselRef } from './components/Carousel.js';
94
94
  export { default as BackTop, BackTopProps } from './components/BackTop.js';
95
95
  export { default as Anchor, AnchorContextValue, AnchorProps, useAnchorContext } from './components/Anchor.js';
96
96
  export { default as AnchorLink, AnchorLinkProps } from './components/AnchorLink.js';
97
+ export { default as TaskBoard, TaskBoardProps } from './components/TaskBoard.js';
97
98
  import 'react';
98
99
  import 'react/jsx-runtime';
99
100
 
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var chunkJWFEJ4XG_js = require('./chunk-JWFEJ4XG.js');
3
4
  var chunkDXXYPVJJ_js = require('./chunk-DXXYPVJJ.js');
4
5
  var chunkDQNA57CA_js = require('./chunk-DQNA57CA.js');
5
6
  var chunkQM4GOQDT_js = require('./chunk-QM4GOQDT.js');
@@ -100,6 +101,10 @@ var tigercatCore = require('@expcat/tigercat-core');
100
101
 
101
102
  var version = "0.0.1";
102
103
 
104
+ Object.defineProperty(exports, "TaskBoard", {
105
+ enumerable: true,
106
+ get: function () { return chunkJWFEJ4XG_js.TaskBoard; }
107
+ });
103
108
  Object.defineProperty(exports, "TimePicker", {
104
109
  enumerable: true,
105
110
  get: function () { return chunkDXXYPVJJ_js.TimePicker; }
package/dist/index.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ export { TaskBoard } from './chunk-PJCY45UP.mjs';
1
2
  export { TimePicker } from './chunk-UE234MW4.mjs';
2
3
  export { Tooltip } from './chunk-IP3MAJSH.mjs';
3
4
  export { Tree } from './chunk-6IH5QPTR.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expcat/tigercat-react",
3
- "version": "0.3.70",
3
+ "version": "0.4.0",
4
4
  "description": "React components for Tigercat UI library",
5
5
  "license": "MIT",
6
6
  "author": "Yizhe Wang",
@@ -42,7 +42,7 @@
42
42
  "access": "public"
43
43
  },
44
44
  "dependencies": {
45
- "@expcat/tigercat-core": "0.3.70"
45
+ "@expcat/tigercat-core": "0.4.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/node": "^25.0.3",