dishui 0.0.97 → 0.0.104

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 (84) hide show
  1. package/dist/.release-verified.json +2 -2
  2. package/dist/ai.js +17 -15
  3. package/dist/components/Card/Ticket.d.ts +52 -0
  4. package/dist/components/Card/Ticket2.js +218 -0
  5. package/dist/components/Card/Ticket2.js.map +1 -0
  6. package/dist/components/Card/index.d.ts +12 -0
  7. package/dist/components/Card/index.js +142 -139
  8. package/dist/components/Card/index.js.map +1 -1
  9. package/dist/components/ai/AgentRunCard/index.d.ts +38 -0
  10. package/dist/components/ai/AgentRunCard/index.js +100 -0
  11. package/dist/components/ai/AgentRunCard/index.js.map +1 -0
  12. package/dist/components/ai/IssueCard/index.d.ts +39 -0
  13. package/dist/components/ai/IssueCard/index.js +78 -0
  14. package/dist/components/ai/IssueCard/index.js.map +1 -0
  15. package/dist/components/ai/index.d.ts +4 -0
  16. package/dist/components/pro/Flow/constants.js +3 -3
  17. package/dist/components/pro/Flow/constants.js.map +1 -1
  18. package/dist/components/pro/Flow/context/FlowAIContext.d.ts +2 -0
  19. package/dist/components/pro/Flow/context/FlowAIContext.js +9 -4
  20. package/dist/components/pro/Flow/context/FlowAIContext.js.map +1 -1
  21. package/dist/components/pro/Flow/nodes/MediaContent.d.ts +3 -2
  22. package/dist/components/pro/Flow/nodes/MediaContent.js +16 -16
  23. package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
  24. package/dist/components/pro/Flow/nodes/MediaOverlay.js +25 -23
  25. package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
  26. package/dist/components/pro/Flow/nodes/shapes.js +3 -3
  27. package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
  28. package/dist/components/pro/Flow/panels/InspectorPanel.js +396 -384
  29. package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
  30. package/dist/components/pro/Flow/utils/themeColor.d.ts +2 -2
  31. package/dist/components/pro/Flow/utils/themeColor.js +2 -2
  32. package/dist/components/pro/Flow/utils/themeColor.js.map +1 -1
  33. package/dist/components/pro/Kanban/Kanban.d.ts +3 -0
  34. package/dist/components/pro/Kanban/Kanban.js +339 -0
  35. package/dist/components/pro/Kanban/Kanban.js.map +1 -0
  36. package/dist/components/pro/Kanban/Swimlanes.d.ts +3 -0
  37. package/dist/components/pro/Kanban/Swimlanes.js +60 -0
  38. package/dist/components/pro/Kanban/Swimlanes.js.map +1 -0
  39. package/dist/components/pro/Kanban/index.d.ts +5 -0
  40. package/dist/components/pro/Kanban/types.d.ts +103 -0
  41. package/dist/components/pro/Kanban/useKanbanDrag.d.ts +17 -0
  42. package/dist/components/pro/Kanban/useKanbanDrag.js +69 -0
  43. package/dist/components/pro/Kanban/useKanbanDrag.js.map +1 -0
  44. package/dist/components/pro/Kanban/utils.d.ts +13 -0
  45. package/dist/components/pro/Kanban/utils.js +48 -0
  46. package/dist/components/pro/Kanban/utils.js.map +1 -0
  47. package/dist/components/pro/RichTextEditor/AIRewrite.js +158 -127
  48. package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
  49. package/dist/components/pro/RichTextEditor/BlockHandle.d.ts +2 -0
  50. package/dist/components/pro/RichTextEditor/BlockHandle.js +156 -115
  51. package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
  52. package/dist/components/pro/RichTextEditor/RichTextEditor.js +136 -159
  53. package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
  54. package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js +44 -41
  55. package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
  56. package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js +59 -53
  57. package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
  58. package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js +48 -44
  59. package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
  60. package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js +67 -63
  61. package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
  62. package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.d.ts +1 -0
  63. package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js +182 -129
  64. package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
  65. package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.d.ts +1 -0
  66. package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js +3 -3
  67. package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js.map +1 -1
  68. package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.d.ts +3 -0
  69. package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js +31 -0
  70. package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js.map +1 -0
  71. package/dist/components/pro/RichTextEditor/index.d.ts +1 -1
  72. package/dist/components/pro/RichTextEditor/types.d.ts +78 -11
  73. package/dist/components/pro/RichTextEditor/types.js +11 -0
  74. package/dist/components/pro/RichTextEditor/types.js.map +1 -1
  75. package/dist/dishui.css +1 -1
  76. package/dist/index-nostyled.d.ts +1 -1
  77. package/dist/index.d.ts +4 -2
  78. package/dist/index.js +128 -122
  79. package/dist/kanban.js +5 -0
  80. package/dist/utils/i18n.js +20 -0
  81. package/dist/utils/i18n.js.map +1 -1
  82. package/dist/utils/menu.js +1 -1
  83. package/dist/utils/menu.js.map +1 -1
  84. package/package.json +5 -1
@@ -0,0 +1,339 @@
1
+ import e from "../../Card/index.js";
2
+ import { cardsAt as t, createCardMove as n, getCardLocation as r, idText as i, idsEqual as a, locationEquals as o } from "./utils.js";
3
+ /* empty css */
4
+ import s from "./Swimlanes.js";
5
+ import { useKanbanDrag as c } from "./useKanbanDrag.js";
6
+ import l, { useCallback as u, useEffect as d, useMemo as ee, useRef as te, useState as f } from "react";
7
+ import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
8
+ //#region src/components/pro/Kanban/Kanban.tsx
9
+ var ne = {
10
+ loading: "Loading board",
11
+ empty: "No cards",
12
+ error: "Could not load the board.",
13
+ stale: "Outdated data",
14
+ retry: "Try again",
15
+ unnamedColumn: "Untitled column",
16
+ unnamedLane: "Untitled lane",
17
+ card: "card",
18
+ lift: "Lifted",
19
+ move: "Move with the arrow keys.",
20
+ drop: "Dropped",
21
+ cancel: "Move cancelled"
22
+ }, g = e.Ticket;
23
+ function _(e) {
24
+ return typeof e == "number" ? `${e}px` : e;
25
+ }
26
+ function v(e, t) {
27
+ if (e !== void 0) return t.find((t) => String(t.id) === String(e))?.id ?? e;
28
+ }
29
+ function y(e, t) {
30
+ return typeof e == "string" || typeof e == "number" ? String(e) : t;
31
+ }
32
+ function re(e) {
33
+ return /* @__PURE__ */ m(g, {
34
+ issueKey: e.issueKey ?? e.id,
35
+ title: e.title,
36
+ description: e.description,
37
+ status: e.status,
38
+ issueType: e.issueType,
39
+ assignees: e.assignees,
40
+ priority: e.priority,
41
+ labels: e.labels,
42
+ dueDate: e.dueDate,
43
+ estimate: e.estimate,
44
+ subtaskProgress: e.subtaskProgress,
45
+ disabled: e.disabled
46
+ });
47
+ }
48
+ function b({ columns: e, lanes: g, cards: b, onCardMove: S, renderCard: C, renderColumnHeader: w, renderLaneHeader: T, readOnly: E = !1, loading: D = !1, error: O, stale: ie = !1, empty: k, onRetry: A, labels: j, dragThreshold: M = 5, columnWidth: N = 280, height: P, collapsedLaneIds: F, defaultCollapsedLaneIds: I, onCollapsedLaneIdsChange: L, className: ae = "", style: R, ...oe }) {
49
+ let z = ee(() => ({
50
+ ...ne,
51
+ ...j
52
+ }), [j]), [B, V] = f(null), [H, U] = f(null), [se, W] = f(""), G = te(null), K = u((t, r) => {
53
+ let i = {
54
+ columnId: v(r.columnId, e),
55
+ laneId: g ? v(r.laneId, g) : void 0,
56
+ index: r.index
57
+ }, a = n(b, t, i);
58
+ a && !o(a.from, a.to) && S?.(a);
59
+ }, [
60
+ b,
61
+ e,
62
+ g,
63
+ S
64
+ ]), q = c({
65
+ threshold: M,
66
+ disabled: E || !S,
67
+ onDrop: K
68
+ }), J = q.draggingId ?? B, Y = q.target ?? H, X = u((e = !0) => {
69
+ B !== null && (V(null), U(null), e && W(z.cancel), requestAnimationFrame(() => G.current?.focus()));
70
+ }, [B, z.cancel]);
71
+ d(() => {
72
+ let e = () => X(!1);
73
+ return window.addEventListener("blur", e), () => window.removeEventListener("blur", e);
74
+ }, [X]);
75
+ let Z = u((t) => {
76
+ let n = e.find((e) => a(e.id, t.columnId)), r = g?.find((e) => a(e.id, t.laneId));
77
+ return `${y(n?.title, z.unnamedColumn)}${r ? `, ${y(r.title, z.unnamedLane)}` : ""}, position ${t.index + 1}`;
78
+ }, [
79
+ e,
80
+ g,
81
+ z.unnamedColumn,
82
+ z.unnamedLane
83
+ ]), Q = u((n) => {
84
+ if (B === null || !H) return;
85
+ let r = Math.max(0, e.findIndex((e) => a(e.id, H.columnId))), i = g ? Math.max(0, g.findIndex((e) => a(e.id, H.laneId))) : 0, o = r, s = i, c = H.index;
86
+ if (n === "ArrowLeft" && (o = Math.max(0, r - 1)), n === "ArrowRight" && (o = Math.min(e.length - 1, r + 1)), n === "ArrowUp" && (c > 0 ? --c : g && i > 0 && --s), n === "ArrowDown") {
87
+ let e = t(b.filter((e) => !a(e.id, B)), H.columnId, H.laneId).length;
88
+ c < e ? c += 1 : g && i < g.length - 1 && (s += 1);
89
+ }
90
+ let l = e[o]?.id ?? H.columnId, u = g?.[s]?.id;
91
+ if (o !== r || s !== i) {
92
+ let e = t(b.filter((e) => !a(e.id, B)), l, u).length;
93
+ c = Math.min(c, e);
94
+ }
95
+ let d = {
96
+ columnId: l,
97
+ laneId: u,
98
+ index: c
99
+ };
100
+ U(d), W(Z(d));
101
+ }, [
102
+ b,
103
+ e,
104
+ Z,
105
+ B,
106
+ H,
107
+ g
108
+ ]), ce = u((e, t) => {
109
+ if (!(e.target !== e.currentTarget || t.disabled || E || !S)) {
110
+ if (e.key === "Escape") {
111
+ e.preventDefault(), X();
112
+ return;
113
+ }
114
+ if (e.key === " " || e.key === "Enter") {
115
+ if (e.preventDefault(), e.repeat) return;
116
+ if (B === null) {
117
+ let n = r(b, t.id);
118
+ if (!n) return;
119
+ G.current = e.currentTarget, V(t.id), U(n), W(`${z.lift} ${y(t.title, z.card)}. ${z.move}`);
120
+ } else a(B, t.id) && H && (K(t.id, H), V(null), U(null), W(`${z.drop} ${y(t.title, z.card)}. ${Z(H)}.`), requestAnimationFrame(() => G.current?.focus()));
121
+ return;
122
+ }
123
+ B !== null && [
124
+ "ArrowLeft",
125
+ "ArrowRight",
126
+ "ArrowUp",
127
+ "ArrowDown"
128
+ ].includes(e.key) && (e.preventDefault(), Q(e.key));
129
+ }
130
+ }, [
131
+ X,
132
+ b,
133
+ K,
134
+ Z,
135
+ B,
136
+ H,
137
+ z,
138
+ Q,
139
+ S,
140
+ E
141
+ ]), $ = (e, n) => {
142
+ let r = t(b, e.id, n?.id), s = E || !!e.disabled || !!n?.disabled || !S, c = 0;
143
+ return /* @__PURE__ */ h("div", {
144
+ className: "dishui-kanban__column",
145
+ role: "group",
146
+ "aria-label": y(e.title, z.unnamedColumn),
147
+ "data-column-id": i(e.id),
148
+ "data-lane-id": i(n?.id),
149
+ "data-disabled": s || void 0,
150
+ children: [!g && /* @__PURE__ */ m("div", {
151
+ className: "dishui-kanban__column-header",
152
+ children: w ? w(e, r) : /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("span", { children: e.title }), /* @__PURE__ */ m("span", {
153
+ className: "dishui-kanban__count",
154
+ children: r.length
155
+ })] })
156
+ }), /* @__PURE__ */ h("div", {
157
+ className: "dishui-kanban__cards",
158
+ children: [
159
+ r.length === 0 && J === null && /* @__PURE__ */ m("span", {
160
+ className: "dishui-kanban__cell-empty",
161
+ children: z.empty
162
+ }),
163
+ /* @__PURE__ */ m(x, {
164
+ columnId: e.id,
165
+ laneId: n?.id,
166
+ index: 0,
167
+ active: o(Y, {
168
+ columnId: e.id,
169
+ laneId: n?.id,
170
+ index: 0
171
+ })
172
+ }),
173
+ r.map((t) => {
174
+ let r = J !== null && a(J, t.id), i = c;
175
+ r || (c += 1);
176
+ let u = s || !!t.disabled;
177
+ return /* @__PURE__ */ h(l.Fragment, { children: [/* @__PURE__ */ m("div", {
178
+ className: "dishui-kanban__card",
179
+ role: "button",
180
+ tabIndex: u ? -1 : 0,
181
+ "aria-disabled": u,
182
+ "aria-describedby": "dishui-kanban-instructions",
183
+ "data-kanban-disabled": u || void 0,
184
+ "data-dragging": r || void 0,
185
+ onPointerDown: (e) => q.onPointerDown(e, t.id),
186
+ onPointerMove: q.onPointerMove,
187
+ onPointerUp: q.onPointerUp,
188
+ onPointerCancel: q.onPointerCancel,
189
+ onLostPointerCapture: q.onLostPointerCapture,
190
+ onKeyDown: (e) => ce(e, t),
191
+ children: C ? C(t, {
192
+ dragging: r,
193
+ keyboardDragging: a(B ?? void 0, t.id),
194
+ disabled: u
195
+ }) : re(t)
196
+ }), !r && /* @__PURE__ */ m(x, {
197
+ columnId: e.id,
198
+ laneId: n?.id,
199
+ index: i + 1,
200
+ active: o(Y, {
201
+ columnId: e.id,
202
+ laneId: n?.id,
203
+ index: i + 1
204
+ })
205
+ })] }, String(t.id));
206
+ })
207
+ ]
208
+ })]
209
+ }, `${i(n?.id)}:${i(e.id)}`);
210
+ }, le = {
211
+ ...R,
212
+ height: _(P) ?? R?.height,
213
+ "--dishui-kanban-column-width": _(N)
214
+ };
215
+ return /* @__PURE__ */ h("div", {
216
+ ...oe,
217
+ className: `dishui-kanban ${ae}`.trim(),
218
+ style: le,
219
+ "aria-busy": D || void 0,
220
+ children: [
221
+ /* @__PURE__ */ m("span", {
222
+ id: "dishui-kanban-instructions",
223
+ className: "dishui-kanban__sr-only",
224
+ children: "Press Space or Enter to lift and drop. Use arrow keys to choose a destination. Press Escape to cancel."
225
+ }),
226
+ /* @__PURE__ */ m("div", {
227
+ className: "dishui-kanban__sr-only",
228
+ role: "status",
229
+ "aria-live": "polite",
230
+ "aria-atomic": "true",
231
+ children: se
232
+ }),
233
+ ie && /* @__PURE__ */ m("div", {
234
+ className: "dishui-kanban__stale",
235
+ role: "status",
236
+ children: z.stale
237
+ }),
238
+ D ? /* @__PURE__ */ h("div", {
239
+ className: "dishui-kanban__state",
240
+ role: "status",
241
+ children: [/* @__PURE__ */ m("span", { children: z.loading }), /* @__PURE__ */ h("div", {
242
+ className: "dishui-kanban__skeletons",
243
+ "aria-hidden": "true",
244
+ children: [
245
+ /* @__PURE__ */ m("i", {}),
246
+ /* @__PURE__ */ m("i", {}),
247
+ /* @__PURE__ */ m("i", {})
248
+ ]
249
+ })]
250
+ }) : O ? /* @__PURE__ */ h("div", {
251
+ className: "dishui-kanban__state dishui-kanban__state--error",
252
+ role: "alert",
253
+ children: [
254
+ /* @__PURE__ */ m("strong", { children: z.error }),
255
+ /* @__PURE__ */ m("span", { children: O }),
256
+ A && /* @__PURE__ */ m("button", {
257
+ type: "button",
258
+ onClick: A,
259
+ children: z.retry
260
+ })
261
+ ]
262
+ }) : e.length === 0 || b.length === 0 ? /* @__PURE__ */ m("div", {
263
+ className: "dishui-kanban__state dishui-kanban__state--empty",
264
+ children: k ?? z.empty
265
+ }) : /* @__PURE__ */ h("div", {
266
+ className: "dishui-kanban__scroll",
267
+ "data-dragging": J !== null || void 0,
268
+ children: [g && g.length > 0 && /* @__PURE__ */ m("div", {
269
+ className: "dishui-kanban__column-headers",
270
+ style: { gridTemplateColumns: `repeat(${e.length}, minmax(var(--dishui-kanban-column-width), 1fr))` },
271
+ children: e.map((e) => {
272
+ let t = b.filter((t) => a(t.columnId, e.id));
273
+ return /* @__PURE__ */ m("div", {
274
+ className: "dishui-kanban__column-header",
275
+ children: w ? w(e, t) : /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("span", { children: e.title }), /* @__PURE__ */ m("span", {
276
+ className: "dishui-kanban__count",
277
+ children: t.length
278
+ })] })
279
+ }, String(e.id));
280
+ })
281
+ }), g && g.length > 0 ? /* @__PURE__ */ m(s, {
282
+ lanes: g,
283
+ collapsedLaneIds: F,
284
+ defaultCollapsedLaneIds: I,
285
+ onCollapsedLaneIdsChange: L,
286
+ renderLaneHeader: (e, t) => {
287
+ let n = b.filter((t) => a(t.laneId, e.id));
288
+ return /* @__PURE__ */ h("button", {
289
+ className: "dishui-swimlane__toggle",
290
+ type: "button",
291
+ "aria-expanded": !t.collapsed,
292
+ onClick: t.toggle,
293
+ children: [
294
+ /* @__PURE__ */ m("span", {
295
+ className: "dishui-swimlane__chevron",
296
+ "aria-hidden": "true",
297
+ children: "▾"
298
+ }),
299
+ /* @__PURE__ */ m("span", {
300
+ className: "dishui-swimlane__header-content",
301
+ children: T ? T(e, n) : e.title
302
+ }),
303
+ /* @__PURE__ */ m("span", {
304
+ className: "dishui-kanban__count",
305
+ children: n.length
306
+ })
307
+ ]
308
+ });
309
+ },
310
+ children: ({ lane: t }) => /* @__PURE__ */ m("div", {
311
+ className: "dishui-kanban__grid",
312
+ style: { gridTemplateColumns: `repeat(${e.length}, minmax(var(--dishui-kanban-column-width), 1fr))` },
313
+ children: e.map((e) => $(e, t))
314
+ })
315
+ }) : /* @__PURE__ */ m("div", {
316
+ className: "dishui-kanban__grid",
317
+ style: { gridTemplateColumns: `repeat(${e.length}, minmax(var(--dishui-kanban-column-width), 1fr))` },
318
+ children: e.map((e) => $(e))
319
+ })]
320
+ })
321
+ ]
322
+ });
323
+ }
324
+ function x({ columnId: e, laneId: t, index: n, active: r }) {
325
+ return /* @__PURE__ */ m("div", {
326
+ className: "dishui-kanban__drop-zone",
327
+ "data-kanban-drop": "true",
328
+ "data-column-id": String(e),
329
+ "data-lane-id": t === void 0 ? "" : String(t),
330
+ "data-index": n,
331
+ "data-active": r || void 0,
332
+ "aria-hidden": "true",
333
+ children: /* @__PURE__ */ m("span", {})
334
+ });
335
+ }
336
+ //#endregion
337
+ export { b as default };
338
+
339
+ //# sourceMappingURL=Kanban.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Kanban.js","names":[],"sources":["../../../../src/components/pro/Kanban/Kanban.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport Card from \"../../Card\";\nimport Swimlanes from \"./Swimlanes\";\nimport type {\n KanbanCard,\n KanbanColumn,\n KanbanDragTarget,\n KanbanId,\n KanbanLane,\n KanbanLabels,\n KanbanLocation,\n KanbanProps,\n} from \"./types\";\nimport { useKanbanDrag } from \"./useKanbanDrag\";\nimport { cardsAt, createCardMove, getCardLocation, idText, idsEqual, locationEquals } from \"./utils\";\nimport \"./styles.css\";\n\nconst DEFAULT_LABELS: Required<KanbanLabels> = {\n loading: \"Loading board\",\n empty: \"No cards\",\n error: \"Could not load the board.\",\n stale: \"Outdated data\",\n retry: \"Try again\",\n unnamedColumn: \"Untitled column\",\n unnamedLane: \"Untitled lane\",\n card: \"card\",\n lift: \"Lifted\",\n move: \"Move with the arrow keys.\",\n drop: \"Dropped\",\n cancel: \"Move cancelled\",\n};\n\nconst DefaultTicket = Card.Ticket;\n\nfunction cssSize(value: number | string | undefined): string | undefined {\n return typeof value === \"number\" ? `${value}px` : value;\n}\n\nfunction resolveId(value: KanbanId | undefined, items: readonly { id: KanbanId }[]): KanbanId | undefined {\n if (value === undefined) return undefined;\n return items.find(item => String(item.id) === String(value))?.id ?? value;\n}\n\nfunction displayText(value: React.ReactNode, fallback: string): string {\n return typeof value === \"string\" || typeof value === \"number\" ? String(value) : fallback;\n}\n\nfunction renderDefaultCard(card: KanbanCard) {\n return (\n <DefaultTicket\n issueKey={card.issueKey ?? card.id}\n title={card.title}\n description={card.description}\n status={card.status}\n issueType={card.issueType}\n assignees={card.assignees}\n priority={card.priority}\n labels={card.labels}\n dueDate={card.dueDate}\n estimate={card.estimate}\n subtaskProgress={card.subtaskProgress}\n disabled={card.disabled}\n />\n );\n}\n\nexport default function Kanban({\n columns,\n lanes,\n cards,\n onCardMove,\n renderCard,\n renderColumnHeader,\n renderLaneHeader,\n readOnly = false,\n loading = false,\n error,\n stale = false,\n empty,\n onRetry,\n labels: labelsInput,\n dragThreshold = 5,\n columnWidth = 280,\n height,\n collapsedLaneIds,\n defaultCollapsedLaneIds,\n onCollapsedLaneIdsChange,\n className = \"\",\n style,\n ...rest\n}: KanbanProps) {\n const labels = useMemo(() => ({ ...DEFAULT_LABELS, ...labelsInput }), [labelsInput]);\n const [keyboardCardId, setKeyboardCardId] = useState<KanbanId | null>(null);\n const [keyboardTarget, setKeyboardTarget] = useState<KanbanLocation | null>(null);\n const [announcement, setAnnouncement] = useState(\"\");\n const keyboardCardRef = useRef<HTMLElement | null>(null);\n\n const commitMove = useCallback((cardId: KanbanId, rawTarget: KanbanDragTarget) => {\n const target: KanbanLocation = {\n columnId: resolveId(rawTarget.columnId, columns) as KanbanId,\n laneId: lanes ? resolveId(rawTarget.laneId, lanes) : undefined,\n index: rawTarget.index,\n };\n const move = createCardMove(cards, cardId, target);\n if (!move || locationEquals(move.from, move.to)) return;\n onCardMove?.(move);\n }, [cards, columns, lanes, onCardMove]);\n\n const drag = useKanbanDrag({\n threshold: dragThreshold,\n disabled: readOnly || !onCardMove,\n onDrop: commitMove,\n });\n\n const activeCardId = drag.draggingId ?? keyboardCardId;\n const activeTarget = drag.target ?? keyboardTarget;\n\n const cancelKeyboard = useCallback((announce = true) => {\n if (keyboardCardId === null) return;\n setKeyboardCardId(null);\n setKeyboardTarget(null);\n if (announce) setAnnouncement(labels.cancel);\n requestAnimationFrame(() => keyboardCardRef.current?.focus());\n }, [keyboardCardId, labels.cancel]);\n\n useEffect(() => {\n const onBlur = () => cancelKeyboard(false);\n window.addEventListener(\"blur\", onBlur);\n return () => window.removeEventListener(\"blur\", onBlur);\n }, [cancelKeyboard]);\n\n const describeLocation = useCallback((target: KanbanLocation) => {\n const column = columns.find(item => idsEqual(item.id, target.columnId));\n const lane = lanes?.find(item => idsEqual(item.id, target.laneId));\n const columnName = displayText(column?.title, labels.unnamedColumn);\n const laneName = lane ? `, ${displayText(lane.title, labels.unnamedLane)}` : \"\";\n return `${columnName}${laneName}, position ${target.index + 1}`;\n }, [columns, lanes, labels.unnamedColumn, labels.unnamedLane]);\n\n const moveKeyboardTarget = useCallback((key: string) => {\n if (keyboardCardId === null || !keyboardTarget) return;\n const columnIndex = Math.max(0, columns.findIndex(column => idsEqual(column.id, keyboardTarget.columnId)));\n const laneIndex = lanes ? Math.max(0, lanes.findIndex(lane => idsEqual(lane.id, keyboardTarget.laneId))) : 0;\n let nextColumnIndex = columnIndex;\n let nextLaneIndex = laneIndex;\n let nextIndex = keyboardTarget.index;\n\n if (key === \"ArrowLeft\") nextColumnIndex = Math.max(0, columnIndex - 1);\n if (key === \"ArrowRight\") nextColumnIndex = Math.min(columns.length - 1, columnIndex + 1);\n if (key === \"ArrowUp\") {\n if (nextIndex > 0) nextIndex -= 1;\n else if (lanes && laneIndex > 0) nextLaneIndex -= 1;\n }\n if (key === \"ArrowDown\") {\n const count = cardsAt(cards.filter(card => !idsEqual(card.id, keyboardCardId)), keyboardTarget.columnId, keyboardTarget.laneId).length;\n if (nextIndex < count) nextIndex += 1;\n else if (lanes && laneIndex < lanes.length - 1) nextLaneIndex += 1;\n }\n\n const columnId = columns[nextColumnIndex]?.id ?? keyboardTarget.columnId;\n const laneId = lanes?.[nextLaneIndex]?.id;\n if (nextColumnIndex !== columnIndex || nextLaneIndex !== laneIndex) {\n const targetCount = cardsAt(cards.filter(card => !idsEqual(card.id, keyboardCardId)), columnId, laneId).length;\n nextIndex = Math.min(nextIndex, targetCount);\n }\n const next = { columnId, laneId, index: nextIndex };\n setKeyboardTarget(next);\n setAnnouncement(describeLocation(next));\n }, [cards, columns, describeLocation, keyboardCardId, keyboardTarget, lanes]);\n\n const onCardKeyDown = useCallback((event: React.KeyboardEvent<HTMLElement>, card: KanbanCard) => {\n if (event.target !== event.currentTarget || card.disabled || readOnly || !onCardMove) return;\n if (event.key === \"Escape\") {\n event.preventDefault();\n cancelKeyboard();\n return;\n }\n if (event.key === \" \" || event.key === \"Enter\") {\n event.preventDefault();\n if (event.repeat) return;\n if (keyboardCardId === null) {\n const from = getCardLocation(cards, card.id);\n if (!from) return;\n keyboardCardRef.current = event.currentTarget;\n setKeyboardCardId(card.id);\n setKeyboardTarget(from);\n setAnnouncement(`${labels.lift} ${displayText(card.title, labels.card)}. ${labels.move}`);\n } else if (idsEqual(keyboardCardId, card.id) && keyboardTarget) {\n commitMove(card.id, keyboardTarget);\n setKeyboardCardId(null);\n setKeyboardTarget(null);\n setAnnouncement(`${labels.drop} ${displayText(card.title, labels.card)}. ${describeLocation(keyboardTarget)}.`);\n requestAnimationFrame(() => keyboardCardRef.current?.focus());\n }\n return;\n }\n if (keyboardCardId !== null && [\"ArrowLeft\", \"ArrowRight\", \"ArrowUp\", \"ArrowDown\"].includes(event.key)) {\n event.preventDefault();\n moveKeyboardTarget(event.key);\n }\n }, [cancelKeyboard, cards, commitMove, describeLocation, keyboardCardId, keyboardTarget, labels, moveKeyboardTarget, onCardMove, readOnly]);\n\n\n const renderCell = (column: KanbanColumn, lane?: KanbanLane) => {\n const cellCards = cardsAt(cards, column.id, lane?.id);\n const disabledCell = readOnly || !!column.disabled || !!lane?.disabled || !onCardMove;\n let insertionIndex = 0;\n return (\n <div\n className=\"dishui-kanban__column\"\n key={`${idText(lane?.id)}:${idText(column.id)}`}\n role=\"group\"\n aria-label={displayText(column.title, labels.unnamedColumn)}\n data-column-id={idText(column.id)}\n data-lane-id={idText(lane?.id)}\n data-disabled={disabledCell || undefined}\n >\n {!lanes && (\n <div className=\"dishui-kanban__column-header\">\n {renderColumnHeader ? renderColumnHeader(column, cellCards) : (\n <><span>{column.title}</span><span className=\"dishui-kanban__count\">{cellCards.length}</span></>\n )}\n </div>\n )}\n <div className=\"dishui-kanban__cards\">\n {cellCards.length === 0 && activeCardId === null && <span className=\"dishui-kanban__cell-empty\">{labels.empty}</span>}\n <DropIndicator columnId={column.id} laneId={lane?.id} index={0} active={locationEquals(activeTarget, { columnId: column.id, laneId: lane?.id, index: 0 })} />\n {cellCards.map(card => {\n const isActive = activeCardId !== null && idsEqual(activeCardId, card.id);\n const cardIndex = insertionIndex;\n if (!isActive) insertionIndex += 1;\n const cardDisabled = disabledCell || !!card.disabled;\n return (\n <React.Fragment key={String(card.id)}>\n <div\n className=\"dishui-kanban__card\"\n role=\"button\"\n tabIndex={cardDisabled ? -1 : 0}\n aria-disabled={cardDisabled}\n aria-describedby=\"dishui-kanban-instructions\"\n data-kanban-disabled={cardDisabled || undefined}\n data-dragging={isActive || undefined}\n onPointerDown={event => drag.onPointerDown(event, card.id)}\n onPointerMove={drag.onPointerMove}\n onPointerUp={drag.onPointerUp}\n onPointerCancel={drag.onPointerCancel}\n onLostPointerCapture={drag.onLostPointerCapture}\n onKeyDown={event => onCardKeyDown(event, card)}\n >\n {renderCard ? renderCard(card, { dragging: isActive, keyboardDragging: idsEqual(keyboardCardId ?? undefined, card.id), disabled: cardDisabled }) : renderDefaultCard(card)}\n </div>\n {!isActive && (\n <DropIndicator\n columnId={column.id}\n laneId={lane?.id}\n index={cardIndex + 1}\n active={locationEquals(activeTarget, { columnId: column.id, laneId: lane?.id, index: cardIndex + 1 })}\n />\n )}\n </React.Fragment>\n );\n })}\n </div>\n </div>\n );\n };\n\n const boardStyle = {\n ...style,\n height: cssSize(height) ?? style?.height,\n \"--dishui-kanban-column-width\": cssSize(columnWidth),\n } as React.CSSProperties;\n\n return (\n <div {...rest} className={`dishui-kanban ${className}`.trim()} style={boardStyle} aria-busy={loading || undefined}>\n <span id=\"dishui-kanban-instructions\" className=\"dishui-kanban__sr-only\">\n Press Space or Enter to lift and drop. Use arrow keys to choose a destination. Press Escape to cancel.\n </span>\n <div className=\"dishui-kanban__sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">{announcement}</div>\n\n {stale && <div className=\"dishui-kanban__stale\" role=\"status\">{labels.stale}</div>}\n {loading ? (\n <div className=\"dishui-kanban__state\" role=\"status\">\n <span>{labels.loading}</span>\n <div className=\"dishui-kanban__skeletons\" aria-hidden=\"true\"><i /><i /><i /></div>\n </div>\n ) : error ? (\n <div className=\"dishui-kanban__state dishui-kanban__state--error\" role=\"alert\">\n <strong>{labels.error}</strong><span>{error}</span>\n {onRetry && <button type=\"button\" onClick={onRetry}>{labels.retry}</button>}\n </div>\n ) : columns.length === 0 || cards.length === 0 ? (\n <div className=\"dishui-kanban__state dishui-kanban__state--empty\">{empty ?? labels.empty}</div>\n ) : (\n <div className=\"dishui-kanban__scroll\" data-dragging={activeCardId !== null || undefined}>\n {lanes && lanes.length > 0 && (\n <div className=\"dishui-kanban__column-headers\" style={{ gridTemplateColumns: `repeat(${columns.length}, minmax(var(--dishui-kanban-column-width), 1fr))` }}>\n {columns.map(column => {\n const columnCards = cards.filter(card => idsEqual(card.columnId, column.id));\n return <div className=\"dishui-kanban__column-header\" key={String(column.id)}>{renderColumnHeader ? renderColumnHeader(column, columnCards) : <><span>{column.title}</span><span className=\"dishui-kanban__count\">{columnCards.length}</span></>}</div>;\n })}\n </div>\n )}\n {lanes && lanes.length > 0 ? (\n <Swimlanes\n lanes={lanes}\n collapsedLaneIds={collapsedLaneIds}\n defaultCollapsedLaneIds={defaultCollapsedLaneIds}\n onCollapsedLaneIdsChange={onCollapsedLaneIdsChange}\n renderLaneHeader={(lane, context) => {\n const laneCards = cards.filter(card => idsEqual(card.laneId, lane.id));\n return (\n <button className=\"dishui-swimlane__toggle\" type=\"button\" aria-expanded={!context.collapsed} onClick={context.toggle}>\n <span className=\"dishui-swimlane__chevron\" aria-hidden=\"true\">▾</span>\n <span className=\"dishui-swimlane__header-content\">{renderLaneHeader ? renderLaneHeader(lane, laneCards) : lane.title}</span>\n <span className=\"dishui-kanban__count\">{laneCards.length}</span>\n </button>\n );\n }}\n >\n {({ lane }) => <div className=\"dishui-kanban__grid\" style={{ gridTemplateColumns: `repeat(${columns.length}, minmax(var(--dishui-kanban-column-width), 1fr))` }}>{columns.map(column => renderCell(column, lane))}</div>}\n </Swimlanes>\n ) : (\n <div className=\"dishui-kanban__grid\" style={{ gridTemplateColumns: `repeat(${columns.length}, minmax(var(--dishui-kanban-column-width), 1fr))` }}>{columns.map(column => renderCell(column))}</div>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction DropIndicator({ columnId, laneId, index, active }: KanbanLocation & { active: boolean }) {\n return (\n <div\n className=\"dishui-kanban__drop-zone\"\n data-kanban-drop=\"true\"\n data-column-id={String(columnId)}\n data-lane-id={laneId === undefined ? \"\" : String(laneId)}\n data-index={index}\n data-active={active || undefined}\n aria-hidden=\"true\"\n ><span /></div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ import type { KanbanLane, SwimlanesProps } from "./types";
3
+ export default function Swimlanes<TLane extends KanbanLane = KanbanLane>({ lanes, children, renderLaneHeader, collapsedLaneIds, defaultCollapsedLaneIds, onCollapsedLaneIdsChange, collapsible, empty, className, laneClassName, ...rest }: SwimlanesProps<TLane>): React.JSX.Element;
@@ -0,0 +1,60 @@
1
+ import { idsEqual as e } from "./utils.js";
2
+ /* empty css */
3
+ import { useCallback as t, useState as n } from "react";
4
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
5
+ //#region src/components/pro/Kanban/Swimlanes.tsx
6
+ var a = [];
7
+ function o({ lanes: o, children: s, renderLaneHeader: c, collapsedLaneIds: l, defaultCollapsedLaneIds: u = a, onCollapsedLaneIdsChange: d, collapsible: f = !0, empty: p = "No lanes", className: m = "", laneClassName: h = "", ...g }) {
8
+ let _ = l !== void 0, [v, y] = n(u), b = (_ ? l : v).filter((t) => o.some((n) => e(n.id, t))), x = t((t) => {
9
+ let n = b.some((n) => e(n, t)) ? b.filter((n) => !e(n, t)) : [...b, t];
10
+ _ || y(n), d?.(n);
11
+ }, [
12
+ b,
13
+ _,
14
+ d
15
+ ]);
16
+ return /* @__PURE__ */ r("div", {
17
+ ...g,
18
+ className: `dishui-swimlanes ${m}`.trim(),
19
+ children: o.length === 0 ? /* @__PURE__ */ r("div", {
20
+ className: "dishui-swimlanes__empty",
21
+ children: p
22
+ }) : o.map((t) => {
23
+ let n = b.some((n) => e(n, t.id)), a = {
24
+ lane: t,
25
+ collapsed: n,
26
+ toggle: () => x(t.id)
27
+ };
28
+ return /* @__PURE__ */ i("section", {
29
+ className: `dishui-swimlane ${h}`.trim(),
30
+ "data-lane-id": String(t.id),
31
+ "data-collapsed": n || void 0,
32
+ children: [/* @__PURE__ */ r("header", {
33
+ className: "dishui-swimlane__header",
34
+ children: c ? c(t, a) : /* @__PURE__ */ i("button", {
35
+ className: "dishui-swimlane__toggle",
36
+ type: "button",
37
+ disabled: !f,
38
+ "aria-expanded": !n,
39
+ "aria-controls": `dishui-swimlane-${String(t.id)}`,
40
+ onClick: a.toggle,
41
+ children: [/* @__PURE__ */ r("span", {
42
+ className: "dishui-swimlane__chevron",
43
+ "aria-hidden": "true",
44
+ children: "▾"
45
+ }), /* @__PURE__ */ r("span", { children: t.title })]
46
+ })
47
+ }), /* @__PURE__ */ r("div", {
48
+ id: `dishui-swimlane-${String(t.id)}`,
49
+ className: "dishui-swimlane__content",
50
+ hidden: n,
51
+ children: typeof s == "function" ? s(a) : s
52
+ })]
53
+ }, String(t.id));
54
+ })
55
+ });
56
+ }
57
+ //#endregion
58
+ export { o as default };
59
+
60
+ //# sourceMappingURL=Swimlanes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Swimlanes.js","names":[],"sources":["../../../../src/components/pro/Kanban/Swimlanes.tsx"],"sourcesContent":["import React, { useCallback, useState } from \"react\";\nimport type { KanbanId, KanbanLane, SwimlanesProps } from \"./types\";\nimport { idsEqual } from \"./utils\";\nimport \"./styles.css\";\n\nconst EMPTY_IDS: KanbanId[] = [];\n\nexport default function Swimlanes<TLane extends KanbanLane = KanbanLane>({\n lanes,\n children,\n renderLaneHeader,\n collapsedLaneIds,\n defaultCollapsedLaneIds = EMPTY_IDS,\n onCollapsedLaneIdsChange,\n collapsible = true,\n empty = \"No lanes\",\n className = \"\",\n laneClassName = \"\",\n ...rest\n}: SwimlanesProps<TLane>) {\n const controlled = collapsedLaneIds !== undefined;\n const [internalIds, setInternalIds] = useState<KanbanId[]>(defaultCollapsedLaneIds);\n const sourceIds = controlled ? collapsedLaneIds : internalIds;\n const collapsedIds = sourceIds.filter(id => lanes.some(lane => idsEqual(lane.id, id)));\n\n const toggleLane = useCallback((id: KanbanId) => {\n const next = collapsedIds.some(item => idsEqual(item, id))\n ? collapsedIds.filter(item => !idsEqual(item, id))\n : [...collapsedIds, id];\n if (!controlled) setInternalIds(next);\n onCollapsedLaneIdsChange?.(next);\n }, [collapsedIds, controlled, onCollapsedLaneIdsChange]);\n\n return (\n <div {...rest} className={`dishui-swimlanes ${className}`.trim()}>\n {lanes.length === 0 ? <div className=\"dishui-swimlanes__empty\">{empty}</div> : lanes.map(lane => {\n const collapsed = collapsedIds.some(id => idsEqual(id, lane.id));\n const context = { lane, collapsed, toggle: () => toggleLane(lane.id) };\n return (\n <section\n className={`dishui-swimlane ${laneClassName}`.trim()}\n key={String(lane.id)}\n data-lane-id={String(lane.id)}\n data-collapsed={collapsed || undefined}\n >\n <header className=\"dishui-swimlane__header\">\n {renderLaneHeader ? renderLaneHeader(lane, context) : (\n <button\n className=\"dishui-swimlane__toggle\"\n type=\"button\"\n disabled={!collapsible}\n aria-expanded={!collapsed}\n aria-controls={`dishui-swimlane-${String(lane.id)}`}\n onClick={context.toggle}\n >\n <span className=\"dishui-swimlane__chevron\" aria-hidden=\"true\">▾</span>\n <span>{lane.title}</span>\n </button>\n )}\n </header>\n <div id={`dishui-swimlane-${String(lane.id)}`} className=\"dishui-swimlane__content\" hidden={collapsed}>\n {typeof children === \"function\" ? children(context) : children}\n </div>\n </section>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;AAKA,IAAM,IAAwB,CAAC;AAE/B,SAAwB,EAAiD,EACvE,UACA,aACA,qBACA,qBACA,6BAA0B,GAC1B,6BACA,iBAAc,IACd,WAAQ,YACR,eAAY,IACZ,mBAAgB,IAChB,GAAG,KACqB;CACxB,IAAM,IAAa,MAAqB,KAAA,GAClC,CAAC,GAAa,KAAkB,EAAqB,CAAuB,GAE5E,KADY,IAAa,IAAmB,EAAA,CACnB,QAAO,MAAM,EAAM,MAAK,MAAQ,EAAS,EAAK,IAAI,CAAE,CAAC,CAAC,GAE/E,IAAa,GAAa,MAAiB;EAC/C,IAAM,IAAO,EAAa,MAAK,MAAQ,EAAS,GAAM,CAAE,CAAC,IACrD,EAAa,QAAO,MAAQ,CAAC,EAAS,GAAM,CAAE,CAAC,IAC/C,CAAC,GAAG,GAAc,CAAE;EAExB,AADK,KAAY,EAAe,CAAI,GACpC,IAA2B,CAAI;CACjC,GAAG;EAAC;EAAc;EAAY;CAAwB,CAAC;CAEvD,OACE,kBAAC,OAAD;EAAK,GAAI;EAAM,WAAW,oBAAoB,IAAY,KAAK;EAC5D,UAAA,EAAM,WAAW,IAAI,kBAAC,OAAD;GAAK,WAAU;GAA2B,UAAA;EAAW,CAAA,IAAI,EAAM,KAAI,MAAQ;GAC/F,IAAM,IAAY,EAAa,MAAK,MAAM,EAAS,GAAI,EAAK,EAAE,CAAC,GACzD,IAAU;IAAE;IAAM;IAAW,cAAc,EAAW,EAAK,EAAE;GAAE;GACrE,OACE,kBAAC,WAAD;IACE,WAAW,mBAAmB,IAAgB,KAAK;IAEnD,gBAAc,OAAO,EAAK,EAAE;IAC5B,kBAAgB,KAAa,KAAA;IAJ/B,UAAA,CAME,kBAAC,UAAD;KAAQ,WAAU;KACf,UAAA,IAAmB,EAAiB,GAAM,CAAO,IAChD,kBAAC,UAAD;MACE,WAAU;MACV,MAAK;MACL,UAAU,CAAC;MACX,iBAAe,CAAC;MAChB,iBAAe,mBAAmB,OAAO,EAAK,EAAE;MAChD,SAAS,EAAQ;MANnB,UAAA,CAQE,kBAAC,QAAD;OAAM,WAAU;OAA2B,eAAY;OAAO,UAAA;MAAO,CAAA,GACrE,kBAAC,QAAD,EAAA,UAAO,EAAK,MAAY,CAAA,CAClB;;IAEJ,CAAA,GACR,kBAAC,OAAD;KAAK,IAAI,mBAAmB,OAAO,EAAK,EAAE;KAAK,WAAU;KAA2B,QAAQ;KACzF,UAAA,OAAO,KAAa,aAAa,EAAS,CAAO,IAAI;IACnD,CAAA,CACE;GAtBF,GAAA,OAAO,EAAK,EAAE,CAsBZ;EAEb,CAAC;CACE,CAAA;AAET"}
@@ -0,0 +1,5 @@
1
+ export { default as Kanban } from "./Kanban";
2
+ export { default as Swimlanes } from "./Swimlanes";
3
+ export { useKanbanDrag } from "./useKanbanDrag";
4
+ export { moveKanbanCard, cardsAt, getCardLocation, createCardMove } from "./utils";
5
+ export * from "./types";
@@ -0,0 +1,103 @@
1
+ import type React from "react";
2
+ import type { CardTicketAssignee, CardTicketIssueType, CardTicketLabel, CardTicketPriority, CardTicketStatus, CardTicketSubtaskProgress } from "../../Card";
3
+ export type KanbanId = string | number;
4
+ export interface KanbanColumn {
5
+ id: KanbanId;
6
+ title: React.ReactNode;
7
+ disabled?: boolean;
8
+ [key: string]: unknown;
9
+ }
10
+ export interface KanbanLane {
11
+ id: KanbanId;
12
+ title: React.ReactNode;
13
+ disabled?: boolean;
14
+ [key: string]: unknown;
15
+ }
16
+ export interface KanbanCard {
17
+ id: KanbanId;
18
+ columnId: KanbanId;
19
+ laneId?: KanbanId;
20
+ title: React.ReactNode;
21
+ description?: React.ReactNode;
22
+ issueKey?: React.ReactNode;
23
+ status?: CardTicketStatus | React.ReactNode;
24
+ issueType?: CardTicketIssueType | React.ReactNode;
25
+ assignees?: CardTicketAssignee[];
26
+ priority?: CardTicketPriority;
27
+ labels?: Array<CardTicketLabel | React.ReactNode>;
28
+ dueDate?: React.ReactNode;
29
+ estimate?: React.ReactNode;
30
+ subtaskProgress?: CardTicketSubtaskProgress;
31
+ disabled?: boolean;
32
+ [key: string]: unknown;
33
+ }
34
+ export interface KanbanLocation {
35
+ columnId: KanbanId;
36
+ laneId?: KanbanId;
37
+ index: number;
38
+ }
39
+ export interface KanbanCardMove {
40
+ card: KanbanCard;
41
+ from: KanbanLocation;
42
+ to: KanbanLocation;
43
+ cards: KanbanCard[];
44
+ }
45
+ export interface KanbanRenderContext {
46
+ dragging: boolean;
47
+ keyboardDragging: boolean;
48
+ disabled: boolean;
49
+ }
50
+ export interface KanbanLabels {
51
+ loading?: string;
52
+ empty?: string;
53
+ error?: string;
54
+ stale?: string;
55
+ retry?: string;
56
+ unnamedColumn?: string;
57
+ unnamedLane?: string;
58
+ card?: string;
59
+ lift?: string;
60
+ move?: string;
61
+ drop?: string;
62
+ cancel?: string;
63
+ }
64
+ export interface KanbanProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "onError"> {
65
+ columns: KanbanColumn[];
66
+ lanes?: KanbanLane[];
67
+ cards: KanbanCard[];
68
+ onCardMove?: (move: KanbanCardMove) => void;
69
+ renderCard?: (card: KanbanCard, context: KanbanRenderContext) => React.ReactNode;
70
+ renderColumnHeader?: (column: KanbanColumn, cards: KanbanCard[]) => React.ReactNode;
71
+ renderLaneHeader?: (lane: KanbanLane, cards: KanbanCard[]) => React.ReactNode;
72
+ readOnly?: boolean;
73
+ loading?: boolean;
74
+ error?: React.ReactNode;
75
+ stale?: boolean;
76
+ empty?: React.ReactNode;
77
+ onRetry?: () => void;
78
+ labels?: KanbanLabels;
79
+ dragThreshold?: number;
80
+ columnWidth?: number | string;
81
+ height?: number | string;
82
+ collapsedLaneIds?: KanbanId[];
83
+ defaultCollapsedLaneIds?: KanbanId[];
84
+ onCollapsedLaneIdsChange?: (ids: KanbanId[]) => void;
85
+ }
86
+ export interface SwimlaneRenderContext<TLane> {
87
+ lane: TLane;
88
+ collapsed: boolean;
89
+ toggle: () => void;
90
+ }
91
+ export interface SwimlanesProps<TLane extends KanbanLane = KanbanLane> extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
92
+ lanes: TLane[];
93
+ children?: React.ReactNode | ((context: SwimlaneRenderContext<TLane>) => React.ReactNode);
94
+ renderLaneHeader?: (lane: TLane, context: SwimlaneRenderContext<TLane>) => React.ReactNode;
95
+ collapsedLaneIds?: KanbanId[];
96
+ defaultCollapsedLaneIds?: KanbanId[];
97
+ onCollapsedLaneIdsChange?: (ids: KanbanId[]) => void;
98
+ collapsible?: boolean;
99
+ empty?: React.ReactNode;
100
+ laneClassName?: string;
101
+ }
102
+ export interface KanbanDragTarget extends KanbanLocation {
103
+ }
@@ -0,0 +1,17 @@
1
+ import type React from "react";
2
+ import type { KanbanDragTarget, KanbanId } from "./types";
3
+ export interface UseKanbanDragOptions {
4
+ threshold?: number;
5
+ disabled?: boolean;
6
+ onDrop: (cardId: KanbanId, target: KanbanDragTarget) => void;
7
+ }
8
+ export declare function useKanbanDrag({ threshold, disabled, onDrop }: UseKanbanDragOptions): {
9
+ draggingId: KanbanId | null;
10
+ target: KanbanDragTarget | null;
11
+ onPointerDown: (event: React.PointerEvent<HTMLElement>, cardId: KanbanId) => void;
12
+ onPointerMove: (event: React.PointerEvent<HTMLElement>) => void;
13
+ onPointerUp: (event: React.PointerEvent<HTMLElement>) => void;
14
+ onPointerCancel: () => void;
15
+ onLostPointerCapture: () => void;
16
+ cancelDrag: () => void;
17
+ };
@@ -0,0 +1,69 @@
1
+ import { useCallback as e, useEffect as t, useRef as n, useState as r } from "react";
2
+ //#region src/components/pro/Kanban/useKanbanDrag.ts
3
+ function i(e, t) {
4
+ let n = document.elementFromPoint(e, t), r = n?.closest(".dishui-kanban");
5
+ if (!r) return null;
6
+ let i = n?.closest("[data-kanban-drop]"), a = i?.closest("[data-disabled='true']") ? null : i;
7
+ if (!a) {
8
+ let n = Infinity;
9
+ r.querySelectorAll("[data-kanban-drop]").forEach((r) => {
10
+ if (r.closest("[data-disabled='true']")) return;
11
+ let i = r.getBoundingClientRect(), o = e < i.left ? i.left - e : e > i.right ? e - i.right : 0, s = Math.abs(t - (i.top + i.bottom) / 2), c = o * o + s * s;
12
+ c < n && (n = c, a = r);
13
+ });
14
+ }
15
+ let o = a?.dataset.columnId, s = a?.dataset.laneId, c = Number(a?.dataset.index);
16
+ return o === void 0 || !Number.isFinite(c) ? null : {
17
+ columnId: o,
18
+ laneId: s || void 0,
19
+ index: c
20
+ };
21
+ }
22
+ function a({ threshold: a = 5, disabled: o = !1, onDrop: s }) {
23
+ let [c, l] = r(null), [u, d] = r(null), f = n(null), p = n(!1), m = n(null), h = e(() => {
24
+ let e = f.current;
25
+ f.current = null, p.current = !1, m.current = null, l(null), d(null), e?.element.hasPointerCapture(e.pointerId) && e.element.releasePointerCapture(e.pointerId);
26
+ }, []), g = e((e, t) => {
27
+ if (o || e.button !== 0 || e.currentTarget.closest("[data-kanban-disabled='true']")) return;
28
+ let n = e.currentTarget;
29
+ f.current = {
30
+ cardId: t,
31
+ pointerId: e.pointerId,
32
+ startX: e.clientX,
33
+ startY: e.clientY,
34
+ element: n
35
+ }, n.setPointerCapture(e.pointerId);
36
+ }, [o]), _ = e((e) => {
37
+ let t = f.current;
38
+ if (!t || t.pointerId !== e.pointerId) return;
39
+ let n = Math.hypot(e.clientX - t.startX, e.clientY - t.startY);
40
+ if (!p.current && n < Math.max(4, Math.min(6, a))) return;
41
+ e.preventDefault(), p.current || (p.current = !0, l(t.cardId));
42
+ let r = i(e.clientX, e.clientY);
43
+ m.current = r, d(r);
44
+ }, [a]), v = e((e) => {
45
+ let t = f.current;
46
+ t && t.pointerId === e.pointerId && (p.current && m.current && s(t.cardId, m.current), h());
47
+ }, [h, s]);
48
+ return t(() => {
49
+ let e = () => h(), t = (e) => {
50
+ e.key === "Escape" && h();
51
+ };
52
+ return window.addEventListener("blur", e), window.addEventListener("keydown", t), () => {
53
+ window.removeEventListener("blur", e), window.removeEventListener("keydown", t), h();
54
+ };
55
+ }, [h]), {
56
+ draggingId: c,
57
+ target: u,
58
+ onPointerDown: g,
59
+ onPointerMove: _,
60
+ onPointerUp: v,
61
+ onPointerCancel: h,
62
+ onLostPointerCapture: h,
63
+ cancelDrag: h
64
+ };
65
+ }
66
+ //#endregion
67
+ export { a as useKanbanDrag };
68
+
69
+ //# sourceMappingURL=useKanbanDrag.js.map