@toclocoinc/lattice-grid 1.59.0 → 1.61.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.
Files changed (112) hide show
  1. package/README.md +3 -3
  2. package/docs/API.html +1623 -91
  3. package/docs/api-detail.html +270 -5
  4. package/lattice-grid.d.ts +100 -2880
  5. package/lattice-grid.esm.min.js +449 -66
  6. package/lattice-grid.min.cjs +449 -66
  7. package/lattice-grid.min.js +449 -66
  8. package/modules/ai.d.ts +401 -0
  9. package/modules/ai.esm.min.js +43 -6
  10. package/modules/ai.min.cjs +43 -6
  11. package/modules/ai.min.js +43 -6
  12. package/modules/angular.d.ts +31 -0
  13. package/modules/angular.esm.min.js +3 -3
  14. package/modules/angular.min.cjs +3 -3
  15. package/modules/angular.min.js +3 -3
  16. package/modules/chart-alluvial.d.ts +18 -0
  17. package/modules/chart-alluvial.esm.min.js +1 -1
  18. package/modules/chart-arc.d.ts +18 -0
  19. package/modules/chart-arc.esm.min.js +1 -1
  20. package/modules/chart-bubblemap.d.ts +18 -0
  21. package/modules/chart-bubblemap.esm.min.js +1 -1
  22. package/modules/chart-bump.d.ts +12 -0
  23. package/modules/chart-bump.esm.min.js +1 -1
  24. package/modules/chart-calendar.d.ts +12 -0
  25. package/modules/chart-calendar.esm.min.js +1 -1
  26. package/modules/chart-decomposition.d.ts +20 -0
  27. package/modules/chart-decomposition.esm.min.js +1 -1
  28. package/modules/chart-diverging.d.ts +12 -0
  29. package/modules/chart-diverging.esm.min.js +1 -1
  30. package/modules/chart-dumbbell.d.ts +18 -0
  31. package/modules/chart-dumbbell.esm.min.js +1 -1
  32. package/modules/chart-fan.d.ts +18 -0
  33. package/modules/chart-fan.esm.min.js +1 -1
  34. package/modules/chart-hexbin.d.ts +18 -0
  35. package/modules/chart-hexbin.esm.min.js +1 -1
  36. package/modules/chart-hexmap.d.ts +18 -0
  37. package/modules/chart-hexmap.esm.min.js +1 -1
  38. package/modules/chart-icicle.d.ts +12 -0
  39. package/modules/chart-icicle.esm.min.js +1 -1
  40. package/modules/chart-parallel.d.ts +19 -0
  41. package/modules/chart-parallel.esm.min.js +1 -1
  42. package/modules/chart-ridgeline.d.ts +14 -0
  43. package/modules/chart-ridgeline.esm.min.js +1 -1
  44. package/modules/chart-roc.d.ts +20 -0
  45. package/modules/chart-roc.esm.min.js +1 -1
  46. package/modules/chart-slope.d.ts +12 -0
  47. package/modules/chart-slope.esm.min.js +1 -1
  48. package/modules/chart-splom.d.ts +19 -0
  49. package/modules/chart-splom.esm.min.js +1 -1
  50. package/modules/chart-waffle.d.ts +12 -0
  51. package/modules/chart-waffle.esm.min.js +1 -1
  52. package/modules/charts.d.ts +122 -0
  53. package/modules/charts.esm.min.js +35 -8
  54. package/modules/charts.min.cjs +35 -8
  55. package/modules/charts.min.js +35 -8
  56. package/modules/data-router.d.ts +91 -0
  57. package/modules/data-router.esm.min.js +109 -17
  58. package/modules/data-router.min.cjs +109 -17
  59. package/modules/data-router.min.js +109 -17
  60. package/modules/devtools.d.ts +28 -0
  61. package/modules/devtools.esm.min.js +2 -2
  62. package/modules/devtools.min.cjs +2 -2
  63. package/modules/devtools.min.js +2 -2
  64. package/modules/dhtmlx-compat.d.ts +19 -0
  65. package/modules/dhtmlx-compat.esm.min.js +4 -4
  66. package/modules/dhtmlx-compat.min.cjs +4 -4
  67. package/modules/dhtmlx-compat.min.js +4 -4
  68. package/modules/gantt.d.ts +647 -0
  69. package/modules/gantt.esm.min.js +1070 -201
  70. package/modules/gantt.min.cjs +1070 -201
  71. package/modules/gantt.min.js +1070 -201
  72. package/modules/htmx.d.ts +176 -0
  73. package/modules/htmx.esm.min.js +449 -66
  74. package/modules/htmx.min.cjs +449 -66
  75. package/modules/htmx.min.js +449 -66
  76. package/modules/kanban.d.ts +492 -0
  77. package/modules/kanban.esm.min.js +4 -4
  78. package/modules/kanban.min.cjs +4 -4
  79. package/modules/kanban.min.js +4 -4
  80. package/modules/kpi.d.ts +255 -0
  81. package/modules/kpi.esm.min.js +40 -7
  82. package/modules/kpi.min.cjs +40 -7
  83. package/modules/kpi.min.js +40 -7
  84. package/modules/layout.d.ts +332 -0
  85. package/modules/layout.esm.min.js +4 -4
  86. package/modules/layout.min.cjs +4 -4
  87. package/modules/layout.min.js +4 -4
  88. package/modules/mock-socket.d.ts +114 -0
  89. package/modules/mock-socket.esm.min.js +2 -2
  90. package/modules/mock-socket.min.cjs +2 -2
  91. package/modules/mock-socket.min.js +2 -2
  92. package/modules/react.d.ts +25 -0
  93. package/modules/react.esm.min.js +3 -3
  94. package/modules/react.min.cjs +3 -3
  95. package/modules/react.min.js +3 -3
  96. package/modules/svelte.d.ts +26 -0
  97. package/modules/svelte.esm.min.js +3 -3
  98. package/modules/svelte.min.cjs +3 -3
  99. package/modules/svelte.min.js +3 -3
  100. package/modules/tabs.d.ts +133 -0
  101. package/modules/tabs.esm.min.js +11 -4
  102. package/modules/tabs.min.cjs +11 -4
  103. package/modules/tabs.min.js +11 -4
  104. package/modules/vue.d.ts +24 -0
  105. package/modules/vue.esm.min.js +3 -3
  106. package/modules/vue.min.cjs +3 -3
  107. package/modules/vue.min.js +3 -3
  108. package/modules/webcomponent.d.ts +47 -0
  109. package/modules/webcomponent.esm.min.js +449 -66
  110. package/modules/webcomponent.min.cjs +449 -66
  111. package/modules/webcomponent.min.js +449 -66
  112. package/package.json +2 -2
@@ -0,0 +1,492 @@
1
+ /*!
2
+ * Lattice Grid 1.61.0, kanban module type declarations
3
+ * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
+ * https://latticegrid.dev
5
+ */
6
+ /** A row backing a card: any object. Its column comes from `columnProperty` and its identity from `rowKey`. */
7
+ type KanbanRow = Record<string, unknown>;
8
+
9
+ /**
10
+ * A card model — one row as it appears on the board. `fields` holds the
11
+ * resolved display text for each mapped card field; `columnId` is the column
12
+ * the card sits in; `points` is the numeric points value (0 when absent).
13
+ * `swimlane`/`sprint`/`epic`/`order` are read from their configured properties
14
+ * and carried for the later cycles that render them.
15
+ */
16
+ interface KanbanCard {
17
+ key: unknown;
18
+ row: KanbanRow;
19
+ columnId: string | null;
20
+ points: number;
21
+ hasPoints: boolean;
22
+ order?: unknown;
23
+ swimlane?: unknown;
24
+ sprint?: unknown;
25
+ epic?: unknown;
26
+ fields: Record<string, string>;
27
+ }
28
+
29
+ /** A column with its cards and aggregates. `over` is true when `count` exceeds `wipLimit`. */
30
+ interface KanbanColumn {
31
+ id: string;
32
+ title: string;
33
+ color: string | null;
34
+ wipLimit: number | null;
35
+ collapsed: boolean;
36
+ cards: KanbanCard[];
37
+ count: number;
38
+ points: number;
39
+ over: boolean;
40
+ }
41
+
42
+ /** A column definition: an id string, or an object configuring one column. */
43
+ type KanbanColumnDef = string | {
44
+ id: string;
45
+ title?: string;
46
+ color?: string;
47
+ wipLimit?: number;
48
+ collapsed?: boolean;
49
+ /**
50
+ * A per-column SLA override (BACKLOG-0000960): a lone threshold read as the
51
+ * breach level, or a `{ warn, breach }` pair. Overrides the global `sla`
52
+ * thresholds for cards in this column (precedence: lane → column → global).
53
+ */
54
+ sla?: KanbanSlaThreshold | { warn?: KanbanSlaThreshold; breach?: KanbanSlaThreshold };
55
+ /** A per-column warn threshold — the shorthand for `sla: { warn }`. */
56
+ slaWarn?: KanbanSlaThreshold;
57
+ /** A per-column breach threshold — the shorthand for `sla: { breach }`. */
58
+ slaBreach?: KanbanSlaThreshold;
59
+ };
60
+
61
+ /** A card field editor handle returned by a host editor factory. */
62
+ interface KanbanEditor {
63
+ el: HTMLElement;
64
+ focus?: () => void;
65
+ destroy?: () => void;
66
+ }
67
+
68
+ /** A card field mapping: a property path, a function, or an object opting into inline edit. */
69
+ type KanbanFieldMap = string | ((row: KanbanRow) => unknown) | {
70
+ field: string;
71
+ edit?: boolean;
72
+ editor?: (ctx: { card: KanbanCard; field: string; value: string; commit: (value: unknown) => void; cancel: () => void }) => KanbanEditor;
73
+ };
74
+
75
+ /** The field-to-property mapping that drives the card template. */
76
+ interface KanbanCardMap {
77
+ title?: KanbanFieldMap;
78
+ subtitle?: KanbanFieldMap;
79
+ labels?: KanbanFieldMap;
80
+ assignee?: KanbanFieldMap;
81
+ due?: KanbanFieldMap;
82
+ cover?: KanbanFieldMap;
83
+ progress?: KanbanFieldMap;
84
+ badges?: KanbanFieldMap;
85
+ accent?: KanbanFieldMap;
86
+ [field: string]: KanbanFieldMap | undefined;
87
+ }
88
+
89
+ /** Granular readonly: the whole board, or selectively by column id and card key. */
90
+ type KanbanReadonly = boolean | {
91
+ board?: boolean;
92
+ columns?: Record<string, boolean>;
93
+ cards?: Record<string, boolean>;
94
+ };
95
+
96
+ /** The payload every board event carries. */
97
+ interface KanbanEvent {
98
+ card: KanbanCard;
99
+ column: string | null;
100
+ el?: unknown;
101
+ originalEvent?: unknown;
102
+ }
103
+
104
+ /**
105
+ * A card-aging / SLA threshold (BACKLOG-0000960): a raw millisecond count, or
106
+ * a `{ weeks, days, hours, minutes, seconds, ms }` spec whose fields are summed
107
+ * (`{ days: 3, hours: 12 }` → 3.5 days). A negative or non-finite value means
108
+ * "no threshold at this level".
109
+ */
110
+ type KanbanSlaThreshold = number | {
111
+ weeks?: number; week?: number; w?: number;
112
+ days?: number; day?: number; d?: number;
113
+ hours?: number; hour?: number; h?: number;
114
+ minutes?: number; minute?: number; m?: number; min?: number;
115
+ seconds?: number; second?: number; s?: number; sec?: number;
116
+ ms?: number; milliseconds?: number;
117
+ };
118
+
119
+ /**
120
+ * Card-aging / SLA configuration (BACKLOG-0000960). A card is measured against a
121
+ * `warn` and a `breach` threshold; the view puts an age chip on aged cards and a
122
+ * highlight on breached ones, and a rising crossing fires the `card:sla` event
123
+ * and the matching `onWarn`/`onBreach` callback (signature `(level, rows)`, the
124
+ * Data Router alert handler's). Thresholds resolve most-specific-first:
125
+ * lane → column → global. Reached at runtime as {@link Kanban#sla}.
126
+ */
127
+ interface KanbanSlaConfig {
128
+ /** The global warn threshold. */
129
+ warn?: KanbanSlaThreshold;
130
+ /** The global breach threshold. */
131
+ breach?: KanbanSlaThreshold;
132
+ /** Per-column overrides by column id (each a threshold or a `{ warn, breach }` pair). */
133
+ columns?: Record<string, KanbanSlaThreshold | { warn?: KanbanSlaThreshold; breach?: KanbanSlaThreshold }>;
134
+ /** Per-swimlane overrides by lane id (each a threshold or a `{ warn, breach }` pair). */
135
+ lanes?: Record<string, KanbanSlaThreshold | { warn?: KanbanSlaThreshold; breach?: KanbanSlaThreshold }>;
136
+ /**
137
+ * Where the ageing clock starts: `'column'` (default) measures time in the
138
+ * card's current column; `'board'` measures age since the card arrived/was
139
+ * created.
140
+ */
141
+ basis?: 'column' | 'board';
142
+ /** A row property holding the wall-clock time the card entered its column. */
143
+ enteredProperty?: string;
144
+ /** A row property holding the wall-clock time the card was created. */
145
+ createdProperty?: string;
146
+ /** Whether cards in a done column are exempt from ageing (default true). */
147
+ ignoreDone?: boolean;
148
+ /** Whether the flow transition log drives the ageing basis when present (default true). */
149
+ useTransitionLog?: boolean;
150
+ /** Show the age chip on every aged card (`'always'`), or only on warn/breach (`'threshold'`, default). */
151
+ showAge?: 'always' | 'threshold';
152
+ /** A wall-clock epoch clock, injectable for deterministic tests (default `Date.now`). */
153
+ now?: () => number;
154
+ /** A re-check interval in ms so a card breaching by sitting still still lights up (0 = off). */
155
+ tick?: number;
156
+ /** Called on a rising crossing to warn level, `(level, rows)` — the router alert handler's shape. */
157
+ onWarn?: (level: 'warn' | 'breach', rows: KanbanRow[]) => void;
158
+ /** Called on a rising crossing to breach level, `(level, rows)` — the router alert handler's shape. */
159
+ onBreach?: (level: 'warn' | 'breach', rows: KanbanRow[]) => void;
160
+ }
161
+
162
+ /** The computed SLA state of one card (BACKLOG-0000960). */
163
+ interface KanbanSlaState {
164
+ key: unknown;
165
+ columnId: string | null;
166
+ lane?: unknown;
167
+ /** The ageing-clock start epoch (ms), or null when no time source could be resolved. */
168
+ start: number | null;
169
+ /** The card's age in ms, or null when unknown. */
170
+ ageMs: number | null;
171
+ /** A short human age label (`2d`, `5h`, …), '' when unknown. */
172
+ ageText: string;
173
+ /** The resolved warn threshold in ms, or null. */
174
+ warnMs: number | null;
175
+ /** The resolved breach threshold in ms, or null. */
176
+ breachMs: number | null;
177
+ /** The classified level, or null when the card cannot be aged. */
178
+ level: 'ok' | 'warn' | 'breach' | null;
179
+ /** True when `level` is `'breach'`. */
180
+ breached: boolean;
181
+ }
182
+
183
+ /**
184
+ * The card-aging / SLA monitor (BACKLOG-0000960), reached as {@link Kanban#sla}
185
+ * when a `sla` config is supplied. Pure and DOM-free: it computes each card's
186
+ * ageing state from the board's card model and the flow transition log, and the
187
+ * view paints it.
188
+ */
189
+ interface KanbanSla {
190
+ /** The normalised SLA config (read-only). */
191
+ readonly config: object;
192
+ /** Recompute every card's SLA state without emitting anything. */
193
+ sync(): KanbanSla;
194
+ /** Recompute and fire `card:sla`/`onWarn`/`onBreach` on each rising crossing. */
195
+ evaluate(opts?: { emit?: boolean }): KanbanSlaState[];
196
+ /** Establish the baseline, notify on the current state, and start the optional tick. */
197
+ start(): KanbanSla;
198
+ /** The SLA state of one card (by card model or key), or null when unknown. */
199
+ stateFor(cardOrKey: KanbanCard | unknown): KanbanSlaState | null;
200
+ /** Every card's current SLA state. */
201
+ states(): KanbanSlaState[];
202
+ /** The cards currently at breach level. */
203
+ breaches(): KanbanSlaState[];
204
+ /** The cards currently at warn level (not yet breached). */
205
+ warnings(): KanbanSlaState[];
206
+ /** Stop the tick and drop the board subscriptions. */
207
+ destroy(): void;
208
+ }
209
+
210
+ /**
211
+ * Kanban configuration. Every structural property is named here so the same
212
+ * board maps DemandFlow (a status field, `points`, `sprint`, `epic`, a
213
+ * swimlane property) and any customer schema without code change.
214
+ */
215
+ interface KanbanConfig {
216
+ rows?: KanbanRow[];
217
+ grid?: unknown;
218
+ rowKey?: string | ((row: KanbanRow) => unknown);
219
+ columnProperty?: string;
220
+ columns?: KanbanColumnDef[];
221
+ columnOrder?: string[];
222
+ pointsProperty?: string;
223
+ showPoints?: boolean;
224
+ orderProperty?: string;
225
+ swimlaneProperty?: string;
226
+ /** Render the 2D swimlane layout using `swimlaneProperty` (default false). */
227
+ swimlanes?: boolean;
228
+ /** Explicit lane definitions; otherwise lanes come from the distinct swimlane values. */
229
+ lanes?: (string | { id: string; title?: string })[];
230
+ /** An explicit lane order by id (also set by a lane-header-drag reorder). */
231
+ laneOrder?: string[];
232
+ /** Enforce `wipLimit` as a hard gate: a move that would exceed it is refused (default false). */
233
+ enforceWip?: boolean;
234
+ /** A custom card template: return an HTML string or a DOM node to own the whole card body. */
235
+ cardRenderer?: (card: KanbanCard, ctx: { column: KanbanColumn; readonly: boolean; el: HTMLElement; doc: Document }) => string | Node | void;
236
+ sprintProperty?: string;
237
+ epicProperty?: string;
238
+ /** A configurable sprint dataset: the canonical sprint list (order + titles), shown even when empty. */
239
+ sprints?: (string | { id: unknown; title?: string })[];
240
+ /** The initially selected sprint id, `Kanban.BACKLOG`, or undefined for all. */
241
+ sprint?: unknown;
242
+ /** The initially selected epic id, or undefined for all. */
243
+ epic?: unknown;
244
+ /** Column ids that count as "done" for a rollup's progress (also a column def's `done: true`). */
245
+ doneColumns?: string[];
246
+ /** Card pop-out: a nested child grid or board (master-detail by composition). */
247
+ children?: KanbanChildren;
248
+ /** Card virtualization for tall columns: true, or `{ rowHeight, overscan, threshold, viewport }`. */
249
+ virtualize?: boolean | { rowHeight?: number; overscan?: number; threshold?: number; viewport?: number };
250
+ /**
251
+ * Card aging / SLA highlighting (BACKLOG-0000960): warn/breach thresholds
252
+ * (globally, per column and/or per lane) that age each card and fire
253
+ * `card:sla` on a rising crossing. Opt-in; reached at runtime as
254
+ * {@link Kanban#sla}. See {@link KanbanSlaConfig}.
255
+ */
256
+ sla?: KanbanSlaConfig;
257
+ /** A saved board state (from `getState`) to restore on construction. */
258
+ state?: object;
259
+ /** Show a per-column add-card affordance. */
260
+ addCard?: boolean;
261
+ /** Persist a standalone inline edit; return false or a rejected promise to revert. */
262
+ onCardEdit?: (event: { card: KanbanCard; key: unknown; field: string; fieldPath: string; value: unknown }) => boolean | void | Promise<boolean | void>;
263
+ /**
264
+ * Create a card for a column on add-card; return the row to create (with
265
+ * its key), a Promise of that row, or nothing to auto-generate. A rejected
266
+ * Promise creates no card and leaves the board unchanged (BACKLOG-0001230).
267
+ */
268
+ onAddCard?: (columnId: string) => KanbanRow | Promise<KanbanRow> | void;
269
+ /** A predicate filter over cards; only matching cards are shown. */
270
+ filter?: (row: KanbanRow, card: KanbanCard) => boolean;
271
+ /** Quick-filter text matched case-insensitively across card fields. */
272
+ quickFilter?: string;
273
+ card?: KanbanCardMap;
274
+ readonly?: KanbanReadonly;
275
+ ariaLabel?: string;
276
+ emptyText?: string;
277
+ /** Whether card selection is enabled (default true). */
278
+ selectable?: boolean;
279
+ /** Host-localised words for the move announcements (grabbed/moved/dropped/reverted/cancelled). */
280
+ labels?: Record<string, string>;
281
+ /**
282
+ * Veto/confirm a move before any write. Return `false` (or a promise of it)
283
+ * to refuse; `from`/`to` are column ids, `index` the target position.
284
+ */
285
+ onBeforeMove?: (card: KanbanCard, from: string | null, to: string, index: number | null) => boolean | Promise<boolean>;
286
+ /**
287
+ * Persist a move on a standalone (non-grid) board. Return `false` or a
288
+ * rejected promise to revert the optimistic move. On a grid-bound board the
289
+ * grid's write-back pipeline persists instead and this is not called.
290
+ */
291
+ onCardMove?: (event: KanbanMoveEvent) => boolean | void | Promise<boolean | void>;
292
+ /** A per-card context menu: items, or `fn(card, selectedCards)` returning items. Suppresses `card:contextmenu`. */
293
+ contextMenu?: KanbanMenuItem[] | ((card: KanbanCard, selected: KanbanCard[]) => KanbanMenuItem[]);
294
+ onCardClick?: (event: KanbanEvent) => void;
295
+ onCardDblClick?: (event: KanbanEvent) => void;
296
+ onCardContextMenu?: (event: KanbanEvent) => void;
297
+ }
298
+
299
+ /**
300
+ * Card pop-out configuration. The child view is a full composed grid (via
301
+ * `factory`, a `createGrid`), a nested board (`asBoard`), or a custom `render`.
302
+ * The child set is the rows whose `property` equals the card key, or the
303
+ * `load(card)` result. Recursion falls out: a nested board can pop its own
304
+ * children.
305
+ */
306
+ interface KanbanChildren {
307
+ /** Parent-id property linking child rows to a card within the same dataset. */
308
+ property?: string;
309
+ /** Per-card child rows, sync or async — an alternative (or addition) to `property`. */
310
+ load?: (card: KanbanCard) => KanbanRow[] | Promise<KanbanRow[]>;
311
+ /** Whether a card can be expanded, overriding the property/load inference. */
312
+ hasChildren?: (card: KanbanCard) => boolean;
313
+ /** Where the pop-out appears (default `drawer`). */
314
+ present?: 'drawer' | 'modal' | 'inline';
315
+ /** The grid factory (a `createGrid`) that builds the child grid. */
316
+ factory?: (container: HTMLElement, options: object) => { destroy?: () => void };
317
+ /** Make the child a nested board (recursive) instead of a grid. */
318
+ asBoard?: boolean;
319
+ /** Options for the child grid/board — an object or `fn(card)`. */
320
+ gridOptions?: object | ((card: KanbanCard) => object);
321
+ /** Fully custom child render; returns a cleanup function. */
322
+ render?: (container: HTMLElement, ctx: { card: KanbanCard; rows: KanbanRow[]; board: Kanban; depth: number }) => (void | (() => void));
323
+ /** The pop-out title (default the card title). */
324
+ title?: (card: KanbanCard) => string;
325
+ }
326
+
327
+ /** One context-menu item. `action` receives the card, the selected cards, and the board. */
328
+ interface KanbanMenuItem {
329
+ label: string;
330
+ action?: (ctx: { card: KanbanCard; cards: KanbanCard[]; board: Kanban }) => void;
331
+ disabled?: boolean;
332
+ }
333
+
334
+ /** The payload of a `card:move` (and `card:reverted`) event. */
335
+ interface KanbanMoveEvent {
336
+ keys: unknown[];
337
+ cards: KanbanCard[];
338
+ from: (string | null)[];
339
+ to: string;
340
+ index: number | null;
341
+ orders: number[] | null;
342
+ }
343
+
344
+ /** The keyed-diff consumer surface a board shares with a grid, so a Data Router routes to it directly. */
345
+ interface KanbanRows {
346
+ apply(change: { add?: KanbanRow[]; update?: KanbanRow[]; remove?: unknown[] }): void;
347
+ forEach(fn: (row: KanbanRow, key: unknown) => void): void;
348
+ readonly count: number;
349
+ }
350
+
351
+ /**
352
+ * Named card predicates, composed with AND (BACKLOG-0001229), following the
353
+ * grid's `filters.where` convention (BACKLOG-0001202). Several may be
354
+ * registered under different names at once; each can be replaced or removed
355
+ * without touching the others. `setFilter(fn)` is unchanged sugar for
356
+ * `where(DEFAULT, fn)` / `where(DEFAULT, null)`.
357
+ */
358
+ interface KanbanFilters {
359
+ /** The reserved name `board.setFilter` registers/removes under. */
360
+ readonly DEFAULT: string;
361
+ /** The registered names, in registration order. */
362
+ where(): string[];
363
+ /** Register or replace the predicate under `name`. */
364
+ where(name: string, predicate: (row: KanbanRow, card: KanbanCard) => boolean): Kanban;
365
+ /** Remove whatever is registered under `name`; a no-op if nothing was. */
366
+ where(name: string, predicate: null): Kanban;
367
+ /** Re-run every named predicate (or one, by name) and re-render. */
368
+ reapply(name?: string): boolean;
369
+ }
370
+
371
+ /**
372
+ * A board instance: a kanban view of grid rows as cards grouped into columns.
373
+ * It consumes data through the same keyed-diff `rows.apply` contract a grid
374
+ * exposes, so `dataRouter.attach(value, board)` drives it like any other
375
+ * viewer.
376
+ */
377
+ interface Kanban {
378
+ readonly el: unknown | null;
379
+ readonly rowKey: string | ((row: KanbanRow) => unknown);
380
+ rows: KanbanRows;
381
+ /** The card-aging / SLA monitor, present only when a `sla` config was supplied (BACKLOG-0000960). */
382
+ sla?: KanbanSla;
383
+ columns(): KanbanColumn[];
384
+ column(id: string): KanbanColumn | undefined;
385
+ count(id: string): number;
386
+ points(id: string): number;
387
+ cards(): KanbanCard[];
388
+ card(key: unknown): KanbanCard | undefined;
389
+ on(name: string, fn: (event: KanbanEvent) => void): () => void;
390
+ off(name: string, fn: (event: KanbanEvent) => void): void;
391
+ readonly(scope?: { column?: string; card?: unknown }): boolean;
392
+ /**
393
+ * Move one or more cards to a column (and, with an order property, to a
394
+ * position within it), through the `onBeforeMove` veto and the grid's
395
+ * shipped write-back path. The single entry point behind drag-and-drop and
396
+ * keyboard move.
397
+ */
398
+ move(keys: unknown | unknown[], toColumn: string, toIndex?: number | null, toLane?: string): Promise<{ moved: unknown[]; reverted: boolean }>;
399
+ /** The selected card keys. */
400
+ selection(): unknown[];
401
+ /** Whether a card is selected. */
402
+ isSelected(key: unknown): boolean;
403
+ /** Change the selection: `set` (replace), `add`, `toggle` or `remove`. */
404
+ select(keys: unknown | unknown[], mode?: 'set' | 'add' | 'toggle' | 'remove'): Kanban;
405
+ /** Clear the selection. */
406
+ clearSelection(): Kanban;
407
+ /** Collapse, expand or toggle a column (emits `column:collapse`). */
408
+ collapseColumn(id: string, collapsed?: boolean): Kanban;
409
+ /** Collapse, expand or toggle a swimlane (emits `swimlane:collapse`). */
410
+ collapseLane(id: string, collapsed?: boolean): Kanban;
411
+ /** Reorder the columns to the given id order (emits `column:reorder`). */
412
+ reorderColumns(order: string[]): Kanban;
413
+ /** Move one column before another (or to the end); emits `column:reorder`. */
414
+ moveColumn(id: string, beforeId: string | null): Kanban;
415
+ /** Reorder the swimlanes to the given id order (emits `swimlane:reorder`). */
416
+ reorderLanes(order: string[]): Kanban;
417
+ /** Move one swimlane before another (or to the end); emits `swimlane:reorder`. */
418
+ moveLane(id: string, beforeId: string | null): Kanban;
419
+ /** Named card predicates, composed with AND (BACKLOG-0001229). See {@link KanbanFilters}. */
420
+ filters: KanbanFilters;
421
+ /** Set a predicate filter over cards, or clear it with null. Sugar for `filters.where(filters.DEFAULT, fn)`. */
422
+ setFilter(fn: ((row: KanbanRow, card: KanbanCard) => boolean) | null): Kanban;
423
+ /** Set the quick-filter text matched across card fields. Independent of every `filters.where` predicate. */
424
+ setQuickFilter(text: string): Kanban;
425
+ /** Distinct values of a property with card counts — the raw material for a facet control. */
426
+ facets(property: string): { value: unknown; count: number }[];
427
+ /** The sentinel `setSprint` value that selects the backlog (cards with no sprint). */
428
+ readonly BACKLOG: unknown;
429
+ /** Select the shown sprint (`BACKLOG` for the backlog, undefined for all); emits `sprint:changed`. */
430
+ setSprint(sprint: unknown): Kanban;
431
+ /** Show only the backlog (cards with no sprint). */
432
+ showBacklog(): Kanban;
433
+ /** Select the shown epic (undefined for all); emits `epic:changed`. */
434
+ setEpic(epic: unknown): Kanban;
435
+ /** The distinct sprint values (the switcher's options); a configured `sprints` dataset pins the order. */
436
+ sprints(): unknown[];
437
+ /** The sprint dataset as `{ id, title }` descriptors — the configured list plus any data-only sprint. */
438
+ sprintDefs(): { id: unknown; title: string }[];
439
+ /** The distinct epic values. */
440
+ epics(): unknown[];
441
+ /** Roll rows up by a property: per-bucket count, points, done and progress. */
442
+ rollup(property: string): { value: unknown; count: number; points: number; doneCount: number; donePoints: number; progress: number }[];
443
+ /** The epic rollup (empty when no epic property is configured). */
444
+ epicRollup(): { value: unknown; count: number; points: number; doneCount: number; donePoints: number; progress: number }[];
445
+ /** Whether a card can be expanded to a child pop-out. */
446
+ canExpand(card: KanbanCard): boolean;
447
+ /** Open a card's children in a pop-out (drawer/modal/inline); emits `card:expand`/`card:drill`. */
448
+ expand(key: unknown): Promise<object | null>;
449
+ /** Close any open card pop-out. */
450
+ closeDetail(): Kanban;
451
+ /** Whether a mapped card field is opted into inline edit and writable. */
452
+ isFieldEditable(name: string): boolean;
453
+ /** Start inline editing a card's field (the grid's own field editor when bound); no-op headless. */
454
+ editCard(key: unknown, name?: string): object | null;
455
+ /** Commit an inline edit through the write-back path (grid.edit.setCells when bound); emits `card:edit`. */
456
+ applyEdit(key: unknown, name: string, value: unknown): Promise<boolean>;
457
+ /**
458
+ * Add a card to a column and open it in inline edit; emits `card:add`.
459
+ * Returns the new key directly, or a Promise of it when `onAddCard`
460
+ * returns a Promise or a `beforeAdd` handler defers (BACKLOG-0001230); a
461
+ * rejected `onAddCard` Promise resolves this to `null` with no card added.
462
+ */
463
+ addCard(columnId: string, seed?: KanbanRow): unknown | Promise<unknown>;
464
+ /** Serialise the restorable state: collapsed columns/lanes, order, filter, sprint/epic, selection. */
465
+ getState(): object;
466
+ /** Restore a state snapshot from {@link Kanban#getState}. */
467
+ setState(snapshot: object): Kanban;
468
+ /** Mark the board loading (renders a host-localised loading state). */
469
+ setLoading(loading: boolean): Kanban;
470
+ /** Set (or clear with null) an error state, rendered as a host-supplied message. */
471
+ setError(message: string | null): Kanban;
472
+ setRows(rows: KanbanRow[]): Kanban;
473
+ /**
474
+ * Replace the board's configured column set (BACKLOG-0001228). Keeps card
475
+ * placement and interaction state (collapsed columns, column order, quick
476
+ * filter, selection) for every column id that survives; a dropped id is
477
+ * not specially handled — a card whose value has nowhere configured to go
478
+ * re-derives an ad hoc column rather than becoming `unplaced` (the same
479
+ * "never silently drop a card" rule an unconfigured value already gets).
480
+ */
481
+ setColumns(defs: KanbanColumnDef[]): Kanban;
482
+ refresh(): Kanban;
483
+ destroy(): void;
484
+ }
485
+
486
+ /**
487
+ * Create a board (kanban) view of rows, grouped into columns by a configurable
488
+ * property. Pass a DOM element to render into, or `null` for a headless board
489
+ * that computes the same column/card model without a DOM.
490
+ */
491
+ export function createKanban(el: HTMLElement | null, config?: KanbanConfig): Kanban;
492
+ export default createKanban;