@toclocoinc/lattice-grid 1.56.0 → 1.57.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 (78) hide show
  1. package/README.md +1 -1
  2. package/docs/API.html +118 -17
  3. package/docs/api-detail.html +102 -7
  4. package/lattice-grid.d.ts +282 -15
  5. package/lattice-grid.esm.min.js +750 -512
  6. package/lattice-grid.min.cjs +749 -512
  7. package/lattice-grid.min.css +1 -1
  8. package/lattice-grid.min.js +749 -512
  9. package/modules/ai.esm.min.js +6 -4
  10. package/modules/ai.min.cjs +6 -4
  11. package/modules/ai.min.js +6 -4
  12. package/modules/angular.esm.min.js +7 -4
  13. package/modules/angular.min.cjs +7 -4
  14. package/modules/angular.min.js +7 -4
  15. package/modules/chart-alluvial.esm.min.js +1 -1
  16. package/modules/chart-arc.esm.min.js +1 -1
  17. package/modules/chart-bubblemap.esm.min.js +1 -1
  18. package/modules/chart-bump.esm.min.js +1 -1
  19. package/modules/chart-calendar.esm.min.js +1 -1
  20. package/modules/chart-decomposition.esm.min.js +1 -1
  21. package/modules/chart-diverging.esm.min.js +1 -1
  22. package/modules/chart-dumbbell.esm.min.js +1 -1
  23. package/modules/chart-fan.esm.min.js +1 -1
  24. package/modules/chart-hexbin.esm.min.js +1 -1
  25. package/modules/chart-hexmap.esm.min.js +1 -1
  26. package/modules/chart-icicle.esm.min.js +1 -1
  27. package/modules/chart-parallel.esm.min.js +1 -1
  28. package/modules/chart-ridgeline.esm.min.js +1 -1
  29. package/modules/chart-roc.esm.min.js +1 -1
  30. package/modules/chart-slope.esm.min.js +1 -1
  31. package/modules/chart-splom.esm.min.js +1 -1
  32. package/modules/chart-waffle.esm.min.js +1 -1
  33. package/modules/charts.esm.min.js +4 -4
  34. package/modules/charts.min.cjs +4 -4
  35. package/modules/charts.min.js +4 -4
  36. package/modules/data-router.esm.min.js +4 -4
  37. package/modules/data-router.min.cjs +4 -4
  38. package/modules/data-router.min.js +4 -4
  39. package/modules/devtools.esm.min.js +2 -2
  40. package/modules/devtools.min.cjs +2 -2
  41. package/modules/devtools.min.js +2 -2
  42. package/modules/dhtmlx-compat.esm.min.js +4 -4
  43. package/modules/dhtmlx-compat.min.cjs +4 -4
  44. package/modules/dhtmlx-compat.min.js +4 -4
  45. package/modules/gantt.esm.min.js +4 -4
  46. package/modules/gantt.min.cjs +4 -4
  47. package/modules/gantt.min.js +4 -4
  48. package/modules/htmx.esm.min.js +746 -512
  49. package/modules/htmx.min.cjs +746 -512
  50. package/modules/htmx.min.js +746 -512
  51. package/modules/kanban.esm.min.js +106 -25
  52. package/modules/kanban.min.cjs +106 -25
  53. package/modules/kanban.min.js +106 -25
  54. package/modules/kpi.esm.min.js +4 -4
  55. package/modules/kpi.min.cjs +4 -4
  56. package/modules/kpi.min.js +4 -4
  57. package/modules/layout.esm.min.js +4 -4
  58. package/modules/layout.min.cjs +4 -4
  59. package/modules/layout.min.js +4 -4
  60. package/modules/mock-socket.esm.min.js +2 -2
  61. package/modules/mock-socket.min.cjs +2 -2
  62. package/modules/mock-socket.min.js +2 -2
  63. package/modules/react.esm.min.js +7 -4
  64. package/modules/react.min.cjs +7 -4
  65. package/modules/react.min.js +7 -4
  66. package/modules/svelte.esm.min.js +7 -4
  67. package/modules/svelte.min.cjs +7 -4
  68. package/modules/svelte.min.js +7 -4
  69. package/modules/tabs.esm.min.js +4 -4
  70. package/modules/tabs.min.cjs +4 -4
  71. package/modules/tabs.min.js +4 -4
  72. package/modules/vue.esm.min.js +7 -4
  73. package/modules/vue.min.cjs +7 -4
  74. package/modules/vue.min.js +7 -4
  75. package/modules/webcomponent.esm.min.js +749 -512
  76. package/modules/webcomponent.min.cjs +749 -512
  77. package/modules/webcomponent.min.js +749 -512
  78. package/package.json +1 -1
package/lattice-grid.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.56.0, type declarations
2
+ * Lattice Grid 1.57.0, type declarations
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -340,7 +340,8 @@ export interface Option {
340
340
  label: string;
341
341
  disabled?: boolean;
342
342
  variant?: VariantName;
343
- icon?: string;
343
+ /** A glyph name from the icon registry (see {@link IconName}), shown before the label. */
344
+ icon?: IconName;
344
345
  group?: string;
345
346
  }
346
347
 
@@ -364,6 +365,32 @@ export interface LookupSpec {
364
365
  export type DecorationName = 'plain' | 'fill' | 'pill' | 'dot' | 'bar' | 'heat' | 'icon';
365
366
  export type VariantName = 'neutral' | 'info' | 'success' | 'warning' | 'danger' | 'accent' | 'none' | (string & {});
366
367
 
368
+ /**
369
+ * A glyph name from the icon sprite registry (`packages/dom/src/cell/icons.js`).
370
+ *
371
+ * The union below is every built-in name, generated from `iconNames()` so an
372
+ * editor can autocomplete and typo-check them — see
373
+ * `test/icon-name-type-drift.test.js`, which fails if this list and the
374
+ * registry ever disagree. It is deliberately **not closed**: the registry is
375
+ * extensible at runtime via `registerIcon`, `registerIcons`, `config.icons` and
376
+ * `grid.icons`, and `(string & {})` widens the type so a custom registered name
377
+ * still typechecks without losing autocomplete on the built-ins. A name the
378
+ * registry has never heard of — built-in or custom — draws a blank glyph and
379
+ * warns once at runtime; it is not a type error.
380
+ */
381
+ export type IconName =
382
+ | 'chevronRight' | 'chevronDown' | 'chevronUp' | 'chevronLeft'
383
+ | 'check' | 'dash' | 'close' | 'plus' | 'minus'
384
+ | 'info' | 'success' | 'warning' | 'danger' | 'clock' | 'lock'
385
+ | 'link' | 'external' | 'filter' | 'pause' | 'play' | 'chart' | 'palette'
386
+ | 'undo' | 'redo' | 'columns' | 'download' | 'restore' | 'spreadsheet' | 'print'
387
+ | 'maximise' | 'minimise' | 'views' | 'search' | 'pencil' | 'trash' | 'share'
388
+ | 'pin' | 'sortAsc' | 'sortDesc' | 'menu' | 'drag'
389
+ | 'star' | 'heart' | 'circleFilled' | 'square' | 'bolt' | 'flag'
390
+ | 'arrow' | 'highlight' | 'thumbUp' | 'eye' | 'eyeOff' | 'copy' | 'present'
391
+ | 'blank'
392
+ | (string & {});
393
+
367
394
  /** A built-in threshold icon set, mapping value bands to built-in glyphs. */
368
395
  export type IconSetName = 'trafficLights' | 'arrows' | 'trafficArrows' | 'ratings' | (string & {});
369
396
 
@@ -375,7 +402,8 @@ export type IconSetName = 'trafficLights' | 'arrows' | 'trafficArrows' | 'rating
375
402
  */
376
403
  export interface IconBand {
377
404
  min?: number;
378
- icon: string;
405
+ /** A glyph name from the icon registry (see {@link IconName}). */
406
+ icon: IconName;
379
407
  label?: string;
380
408
  variant?: VariantName;
381
409
  }
@@ -387,7 +415,12 @@ export interface DecorationSpec {
387
415
  outline?: boolean;
388
416
  edge?: boolean;
389
417
  position?: 'start' | 'end';
390
- name?: string | Record<string, string>;
418
+ /**
419
+ * `icon` decoration only: either a single glyph name (see {@link IconName})
420
+ * used for every value, or a value -> glyph name map for exact-value icons.
421
+ * Omit both `name` and `bands` to use `iconSet`/its default instead.
422
+ */
423
+ name?: IconName | Record<string, IconName>;
391
424
  /** icon only: a built-in threshold icon set, expanded to `bands`. */
392
425
  iconSet?: IconSetName;
393
426
  /** icon only: value bands mapped to glyphs, first match by descending `min`. */
@@ -4156,6 +4189,11 @@ export type EventName =
4156
4189
  | 'model:changed' | 'rows:changed' | 'rows:queued' | 'rows:deferred'
4157
4190
  | 'rows:paused' | 'rows:resumed' | 'row:received' | 'row:sent' | 'row:copied'
4158
4191
  | 'row:moved' | 'source:error' | 'stream:chunk' | 'stream:end' | 'stream:evicted'
4192
+ /* The row-drag gesture as it happens (BACKLOG-0001224). Notifications only:
4193
+ * the drop is already vetoable by `beforeRowMove` and `beforeRowReceive`, and
4194
+ * a third veto on the same gesture would be a fourth place to look. All four
4195
+ * fire on the grid the drag started in and carry a {@link RowDragEvent}. */
4196
+ | 'rowDrag:started' | 'rowDrag:moved' | 'rowDrag:left' | 'rowDrag:ended'
4159
4197
  /* Cells and editing */
4160
4198
  | 'cell:changed' | 'cell:pending' | 'cell:confirmed' | 'cell:reverted' | 'cell:conflict'
4161
4199
  | 'cell:clicked' | 'cell:dblclicked' | 'cell:contextmenu'
@@ -4212,11 +4250,14 @@ export type EventName =
4212
4250
  | 'beforeEdit' | 'beforeSort' | 'beforeFilter'
4213
4251
  | 'beforeColumnMove' | 'beforeColumnResize' | 'beforeColumnHide'
4214
4252
  | 'beforeSelect' | 'beforeRowAdd' | 'beforeDelete' | 'beforeRowMove' | 'beforeGroup'
4253
+ /* A row dropped in from another grid, on the receiving grid (BACKLOG-0001225):
4254
+ * a {@link BeforeRowReceiveEvent}. */
4255
+ | 'beforeRowReceive'
4215
4256
  /* Their cancellation notifications (past-tense, non-cancellable). */
4216
4257
  | 'edit:cancelled' | 'sort:cancelled' | 'filter:cancelled'
4217
4258
  | 'columnMove:cancelled' | 'columnResize:cancelled' | 'columnHide:cancelled'
4218
4259
  | 'selection:cancelled' | 'rowAdd:cancelled' | 'delete:cancelled'
4219
- | 'rowMove:cancelled' | 'group:cancelled'
4260
+ | 'rowMove:cancelled' | 'group:cancelled' | 'rowReceive:cancelled'
4220
4261
  /* Every event at once, for logging and debugging. */
4221
4262
  | '*';
4222
4263
 
@@ -4258,6 +4299,157 @@ export interface BeforeEvent extends GridEvent {
4258
4299
  reason: string | null;
4259
4300
  }
4260
4301
 
4302
+ /**
4303
+ * The `beforeRowReceive` event (BACKLOG-0001225): a row dragged from another
4304
+ * grid is about to be inserted into this one. Fires on the **receiving** grid,
4305
+ * before the insert, with the row under the pointer named — so a drop that
4306
+ * means "assign this to that" can be recorded by the host and the insert
4307
+ * stopped with `preventDefault(reason)`.
4308
+ *
4309
+ * A veto leaves the source grid untouched: the row stays where it was, and
4310
+ * neither `row:sent` nor `row:copied` fires there. The source removes its row
4311
+ * only after the target has admitted it, and a veto is a refusal to admit.
4312
+ * The paired `rowReceive:cancelled` carries the same context plus the reason.
4313
+ *
4314
+ * Like every {@link BeforeEvent}, the handler may be `async`; the insert is
4315
+ * held until it settles, and is cancelled as `'stale'` (BACKLOG-0001242) if
4316
+ * the source row is gone by then, or if the row under the pointer is gone or
4317
+ * has moved to a different index — `at` names a slot as "before `overKey`",
4318
+ * and once that is no longer where `overKey`'s row sits, `at` is a stale index
4319
+ * into a list that changed while the handler was thinking, not the slot the
4320
+ * drop meant. `overKey: null` (the drop landed on no row) has no row to drift
4321
+ * against and is never stale on that account.
4322
+ */
4323
+ export interface BeforeRowReceiveEvent extends BeforeEvent {
4324
+ /**
4325
+ * The row about to be inserted: a shallow copy of the source row's data,
4326
+ * and the very object that is inserted if no handler vetoes, so a change
4327
+ * made to it here lands with the row.
4328
+ */
4329
+ data: Record<string, unknown>;
4330
+ /**
4331
+ * The display index the row would be inserted at: the index of the row
4332
+ * under the pointer, or `rows.count()` when the drop landed on no row. When
4333
+ * `overKey` names a row, this is guaranteed to still be that row's index at
4334
+ * the moment the insert actually runs — an async handler that leaves the
4335
+ * named row at a different index causes the drop to be cancelled as
4336
+ * `'stale'` (BACKLOG-0001242) rather than inserted at this index regardless.
4337
+ */
4338
+ at: number;
4339
+ /**
4340
+ * The key of the row under the pointer when the drop happened — the row the
4341
+ * user meant. Null when the drop landed past the last row, on empty space,
4342
+ * on the header, or on a pinned row: there is no row to name, and a nearest
4343
+ * guess would be wrong in a way that looks right.
4344
+ */
4345
+ overKey: string | null;
4346
+ /** The grid the row is being dragged from. */
4347
+ source: Grid;
4348
+ }
4349
+
4350
+ /**
4351
+ * The `rowReceive:cancelled` event (BACKLOG-0001225): a `beforeRowReceive`
4352
+ * was vetoed, or went stale during an async handler. Nothing was inserted and
4353
+ * the source grid is untouched.
4354
+ */
4355
+ export interface RowReceiveCancelledEvent extends GridEvent {
4356
+ /** The row that was not inserted, as the handler saw it. */
4357
+ data: Record<string, unknown>;
4358
+ /** The display index it would have taken. */
4359
+ at: number;
4360
+ /** The key of the row under the pointer, or null. */
4361
+ overKey: string | null;
4362
+ /** The grid the row would have come from; it still holds the row. */
4363
+ source: Grid;
4364
+ /**
4365
+ * The reason given to `preventDefault`, `'prevented'` when none was given,
4366
+ * or `'stale'` when the row under the pointer or the source row was gone by
4367
+ * the time an async handler settled.
4368
+ */
4369
+ reason: string;
4370
+ }
4371
+
4372
+ /**
4373
+ * The row-drag lifecycle events (BACKLOG-0001224): `rowDrag:started`,
4374
+ * `rowDrag:moved`, `rowDrag:left` and `rowDrag:ended`, which report a row drag
4375
+ * *as it happens* rather than once it has settled. Before them a host got the
4376
+ * handle the grid draws and then one settled event, with nothing in between to
4377
+ * highlight a candidate target, drive a custom drop indicator, or react when
4378
+ * the pointer left the grid.
4379
+ *
4380
+ * **All four fire on the grid the drag started in**, whether the row is being
4381
+ * reordered within that grid or dragged into another one. A drag is one gesture
4382
+ * with one owner, and the source grid is the only grid present for the whole of
4383
+ * it — the pointer may cross several others, or none. `over` names whichever
4384
+ * grid the event is about, so a single subscription can drive decoration on any
4385
+ * of them.
4386
+ *
4387
+ * **Notifications, not gates.** None of these is cancellable and none carries
4388
+ * `preventDefault`. The drop is already vetoable twice over — `beforeRowMove`
4389
+ * for a reorder, `beforeRowReceive` for a drop into another grid — and a third
4390
+ * veto on the same gesture would be a third place to look when a drop does not
4391
+ * happen.
4392
+ *
4393
+ * **What is safe to do in a handler.** Read, measure and draw: highlight a
4394
+ * candidate row, move an indicator, update a side panel. Do not mutate rows,
4395
+ * columns, sort, filters or grouping from one of these. The drag resolves where
4396
+ * it would land against the display order, so changing that order mid-gesture
4397
+ * moves the ground under the drop; and `data` is the source row's own object
4398
+ * rather than a copy, so writing to it edits the row that is still in the grid
4399
+ * without announcing it. Work that changes the grid belongs in
4400
+ * `beforeRowReceive`, which is asked before the insert, or in the settled
4401
+ * events afterwards.
4402
+ *
4403
+ * **`rowDrag:moved` is coalesced to one event per animation frame**, carrying
4404
+ * the latest pointer position of that frame, so a handler runs at the display's
4405
+ * rate rather than the pointer's several hundred events a second. The other
4406
+ * three fire on the transition itself.
4407
+ *
4408
+ * The sequence for any gesture is `rowDrag:started`, then `rowDrag:moved` and
4409
+ * `rowDrag:left` as the pointer travels, then exactly one `rowDrag:ended` —
4410
+ * including when the pointer is released outside every grid. No `rowDrag:moved`
4411
+ * is delivered after `rowDrag:ended`. A press that never passes the drag
4412
+ * threshold is a click and raises none of them; a grid destroyed mid-drag
4413
+ * raises no `rowDrag:ended`.
4414
+ */
4415
+ export interface RowDragEvent extends GridEvent {
4416
+ /** The key of the row being dragged. */
4417
+ key: string;
4418
+ /**
4419
+ * The dragged row's data as it stands in the source grid — that row's own
4420
+ * object, not a copy. Null if the row has left the source during the drag.
4421
+ */
4422
+ data: Record<string, unknown> | null;
4423
+ /**
4424
+ * The grid the event is about: the grid under the pointer for
4425
+ * `rowDrag:started`, `rowDrag:moved` and `rowDrag:ended`, and the grid just
4426
+ * left for `rowDrag:left`. Null when the pointer is over no grid at all.
4427
+ */
4428
+ over: Grid | null;
4429
+ /**
4430
+ * Where the row would land in `over`: the display index it would take. Null
4431
+ * when there is no candidate to report — the pointer is over no grid, over a
4432
+ * grid that will refuse the row, or over a header; and on `rowDrag:left`,
4433
+ * which is about a grid the pointer has already gone from.
4434
+ */
4435
+ at: number | null;
4436
+ /**
4437
+ * The key of the row under the pointer in `over`, or null where there is no
4438
+ * row to name: past the last row, on empty space, on a header, on a pinned
4439
+ * row, on a grid that will refuse the drop, or on `rowDrag:left`.
4440
+ */
4441
+ overKey: string | null;
4442
+ /**
4443
+ * `rowDrag:ended` only: whether the release is being acted on — a transfer
4444
+ * the target accepts, or a same-grid reorder that is a real move and is not
4445
+ * refused by a sort, filter or grouping. False when the row was released over
4446
+ * no grid, over a grid that refuses it, or back where it started. What became
4447
+ * of an acted-on drop is reported by `row:moved`, `row:sent`, `row:received`
4448
+ * and `rowReceive:cancelled`.
4449
+ */
4450
+ dropped?: boolean;
4451
+ }
4452
+
4261
4453
  /**
4262
4454
  * The `state:changed` event (BACKLOG-0001182).
4263
4455
  *
@@ -4270,9 +4462,10 @@ export interface BeforeEvent extends GridEvent {
4270
4462
  * `state.apply()` — applying a saved view, an undo, a reset — announces itself
4271
4463
  * once, carrying the outermost cause rather than the inner mechanism's.
4272
4464
  *
4273
- * **One known gap** (BACKLOG-0001235): a host predicate registered through
4274
- * `filters.where(name, fn)` changes the `where` section and the rows on screen
4275
- * without raising this event, so a persistence layer does not yet see it.
4465
+ * A host predicate registered, replaced or removed through
4466
+ * `filters.where(name, fn)`, and a `filters.reapply()` that re-runs one, go
4467
+ * through the same tracked door as `sort` and `filters`: each fires this
4468
+ * event once, `cause: 'user'`, with `'where'` in `sections` (BACKLOG-0001235).
4276
4469
  */
4277
4470
  export interface StateChangedEvent extends GridEvent {
4278
4471
  /** Why the state changed. `'reset'` is the one a save should ignore. */
@@ -5776,7 +5969,18 @@ export interface RailActionParams {
5776
5969
  export interface RailAction {
5777
5970
  name: string;
5778
5971
  title: string | (() => string);
5779
- icon?: string | (() => string);
5972
+ /**
5973
+ * A glyph name from the icon registry (see {@link IconName}) — a built-in
5974
+ * name, or one registered with `registerIcon`/`registerIcons`,
5975
+ * `config.icons` or `grid.icons`. A function form is re-read on every
5976
+ * repaint, the same as `title`, so a toggle can swap its glyph with its
5977
+ * state. When omitted, the rail tries `name` as the icon name instead (so an
5978
+ * action named after a built-in, e.g. `'undo'`, needs no separate `icon`);
5979
+ * an unrecognised name — from either `icon` or the `name` fallback — draws a
5980
+ * blank glyph, and only an explicitly-given unrecognised `icon` warns once
5981
+ * in the console.
5982
+ */
5983
+ icon?: IconName | (() => IconName);
5780
5984
  run(params: RailActionParams): void;
5781
5985
  enabled?(): boolean;
5782
5986
  /**
@@ -6537,6 +6741,28 @@ export function graphqlAdapter(options: {
6537
6741
  export function createGrid(element: HTMLElement, config?: GridConfig): Grid;
6538
6742
  export function createHeadlessGrid(config?: GridConfig): Grid;
6539
6743
 
6744
+ /**
6745
+ * House-wide defaults, merged beneath every grid built afterwards.
6746
+ *
6747
+ * For an application with many grids that should agree on theme, density or
6748
+ * row key. The exported factories cannot be wrapped in place — `createGrid` is
6749
+ * exported through a getter with no setter, so assigning over it is discarded
6750
+ * in a plain script and throws in a module — so this is the supported route.
6751
+ *
6752
+ * - **The per-grid config always wins.** Defaults sit *beneath* what
6753
+ * `createGrid`/`createHeadlessGrid` is passed; a key the grid names keeps the
6754
+ * grid's value, a key it omits takes the house value.
6755
+ * - **Plain objects deep-merge; arrays and everything else replace.** A house
6756
+ * `views: { storage }` and a grid's `views: { local: true }` both survive;
6757
+ * a grid's `columns` array replaces the house one rather than extending it.
6758
+ * - **Calling it again replaces the set, it does not accumulate.** Extend
6759
+ * explicitly with `defaults({ ...defaults(), density: 'compact' })`.
6760
+ * - **Never retroactive.** Grids already built are untouched.
6761
+ *
6762
+ * `defaults()` reads the current set; `defaults(null)` clears it.
6763
+ */
6764
+ export function defaults(config?: Partial<GridConfig> | null): Partial<GridConfig>;
6765
+
6540
6766
  /**
6541
6767
  * The library version, e.g. `'1.13.1'`.
6542
6768
  *
@@ -6620,6 +6846,7 @@ export function version(): string;
6620
6846
  export const LatticeGrid: {
6621
6847
  createGrid: typeof createGrid;
6622
6848
  createHeadlessGrid: typeof createHeadlessGrid;
6849
+ defaults: typeof defaults;
6623
6850
  registerModules: typeof registerModules;
6624
6851
  setLicence: typeof setLicence;
6625
6852
  version: typeof version;
@@ -8640,8 +8867,12 @@ declare module 'lattice-grid/modules/kanban' {
8640
8867
  addCard?: boolean;
8641
8868
  /** Persist a standalone inline edit; return false or a rejected promise to revert. */
8642
8869
  onCardEdit?: (event: { card: KanbanCard; key: unknown; field: string; fieldPath: string; value: unknown }) => boolean | void | Promise<boolean | void>;
8643
- /** Create a card for a column on add-card; return the row to create (with its key), or nothing to auto-generate. */
8644
- onAddCard?: (columnId: string) => KanbanRow | void;
8870
+ /**
8871
+ * Create a card for a column on add-card; return the row to create (with
8872
+ * its key), a Promise of that row, or nothing to auto-generate. A rejected
8873
+ * Promise creates no card and leaves the board unchanged (BACKLOG-0001230).
8874
+ */
8875
+ onAddCard?: (columnId: string) => KanbanRow | Promise<KanbanRow> | void;
8645
8876
  /** A predicate filter over cards; only matching cards are shown. */
8646
8877
  filter?: (row: KanbanRow, card: KanbanCard) => boolean;
8647
8878
  /** Quick-filter text matched case-insensitively across card fields. */
@@ -8724,6 +8955,26 @@ declare module 'lattice-grid/modules/kanban' {
8724
8955
  readonly count: number;
8725
8956
  }
8726
8957
 
8958
+ /**
8959
+ * Named card predicates, composed with AND (BACKLOG-0001229), following the
8960
+ * grid's `filters.where` convention (BACKLOG-0001202). Several may be
8961
+ * registered under different names at once; each can be replaced or removed
8962
+ * without touching the others. `setFilter(fn)` is unchanged sugar for
8963
+ * `where(DEFAULT, fn)` / `where(DEFAULT, null)`.
8964
+ */
8965
+ interface KanbanFilters {
8966
+ /** The reserved name `board.setFilter` registers/removes under. */
8967
+ readonly DEFAULT: string;
8968
+ /** The registered names, in registration order. */
8969
+ where(): string[];
8970
+ /** Register or replace the predicate under `name`. */
8971
+ where(name: string, predicate: (row: KanbanRow, card: KanbanCard) => boolean): Kanban;
8972
+ /** Remove whatever is registered under `name`; a no-op if nothing was. */
8973
+ where(name: string, predicate: null): Kanban;
8974
+ /** Re-run every named predicate (or one, by name) and re-render. */
8975
+ reapply(name?: string): boolean;
8976
+ }
8977
+
8727
8978
  /**
8728
8979
  * A board instance: a kanban view of grid rows as cards grouped into columns.
8729
8980
  * It consumes data through the same keyed-diff `rows.apply` contract a grid
@@ -8772,9 +9023,11 @@ declare module 'lattice-grid/modules/kanban' {
8772
9023
  reorderLanes(order: string[]): Kanban;
8773
9024
  /** Move one swimlane before another (or to the end); emits `swimlane:reorder`. */
8774
9025
  moveLane(id: string, beforeId: string | null): Kanban;
8775
- /** Set a predicate filter over cards, or clear it with null. */
9026
+ /** Named card predicates, composed with AND (BACKLOG-0001229). See {@link KanbanFilters}. */
9027
+ filters: KanbanFilters;
9028
+ /** Set a predicate filter over cards, or clear it with null. Sugar for `filters.where(filters.DEFAULT, fn)`. */
8776
9029
  setFilter(fn: ((row: KanbanRow, card: KanbanCard) => boolean) | null): Kanban;
8777
- /** Set the quick-filter text matched across card fields. */
9030
+ /** Set the quick-filter text matched across card fields. Independent of every `filters.where` predicate. */
8778
9031
  setQuickFilter(text: string): Kanban;
8779
9032
  /** Distinct values of a property with card counts — the raw material for a facet control. */
8780
9033
  facets(property: string): { value: unknown; count: number }[];
@@ -8808,8 +9061,13 @@ declare module 'lattice-grid/modules/kanban' {
8808
9061
  editCard(key: unknown, name?: string): object | null;
8809
9062
  /** Commit an inline edit through the write-back path (grid.edit.setCells when bound); emits `card:edit`. */
8810
9063
  applyEdit(key: unknown, name: string, value: unknown): Promise<boolean>;
8811
- /** Add a card to a column and open it in inline edit; emits `card:add`. */
8812
- addCard(columnId: string, seed?: KanbanRow): unknown;
9064
+ /**
9065
+ * Add a card to a column and open it in inline edit; emits `card:add`.
9066
+ * Returns the new key directly, or a Promise of it when `onAddCard`
9067
+ * returns a Promise or a `beforeAdd` handler defers (BACKLOG-0001230); a
9068
+ * rejected `onAddCard` Promise resolves this to `null` with no card added.
9069
+ */
9070
+ addCard(columnId: string, seed?: KanbanRow): unknown | Promise<unknown>;
8813
9071
  /** Serialise the restorable state: collapsed columns/lanes, order, filter, sprint/epic, selection. */
8814
9072
  getState(): object;
8815
9073
  /** Restore a state snapshot from {@link Kanban#getState}. */
@@ -8819,6 +9077,15 @@ declare module 'lattice-grid/modules/kanban' {
8819
9077
  /** Set (or clear with null) an error state, rendered as a host-supplied message. */
8820
9078
  setError(message: string | null): Kanban;
8821
9079
  setRows(rows: KanbanRow[]): Kanban;
9080
+ /**
9081
+ * Replace the board's configured column set (BACKLOG-0001228). Keeps card
9082
+ * placement and interaction state (collapsed columns, column order, quick
9083
+ * filter, selection) for every column id that survives; a dropped id is
9084
+ * not specially handled — a card whose value has nowhere configured to go
9085
+ * re-derives an ad hoc column rather than becoming `unplaced` (the same
9086
+ * "never silently drop a card" rule an unconfigured value already gets).
9087
+ */
9088
+ setColumns(defs: KanbanColumnDef[]): Kanban;
8822
9089
  refresh(): Kanban;
8823
9090
  destroy(): void;
8824
9091
  }