@toclocoinc/lattice-grid 1.54.0 → 1.55.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 +6 -4
  2. package/docs/API.html +85 -33
  3. package/docs/api-detail.html +76 -13
  4. package/lattice-grid.d.ts +41 -13
  5. package/lattice-grid.esm.min.js +257 -54
  6. package/lattice-grid.min.cjs +257 -54
  7. package/lattice-grid.min.css +1 -1
  8. package/lattice-grid.min.js +257 -54
  9. package/modules/ai.esm.min.js +19 -4
  10. package/modules/ai.min.cjs +19 -4
  11. package/modules/ai.min.js +19 -4
  12. package/modules/angular.esm.min.js +2 -2
  13. package/modules/angular.min.cjs +2 -2
  14. package/modules/angular.min.js +2 -2
  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 +104 -23
  34. package/modules/charts.min.cjs +104 -23
  35. package/modules/charts.min.js +104 -23
  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 +32 -6
  46. package/modules/gantt.min.cjs +32 -6
  47. package/modules/gantt.min.js +32 -6
  48. package/modules/htmx.esm.min.js +257 -54
  49. package/modules/htmx.min.cjs +257 -54
  50. package/modules/htmx.min.js +257 -54
  51. package/modules/kanban.esm.min.js +49 -9
  52. package/modules/kanban.min.cjs +49 -9
  53. package/modules/kanban.min.js +49 -9
  54. package/modules/kpi.esm.min.js +4104 -13
  55. package/modules/kpi.min.cjs +4104 -13
  56. package/modules/kpi.min.js +4104 -13
  57. package/modules/layout.esm.min.js +12 -8
  58. package/modules/layout.min.cjs +12 -8
  59. package/modules/layout.min.js +12 -8
  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 +2 -2
  64. package/modules/react.min.cjs +2 -2
  65. package/modules/react.min.js +2 -2
  66. package/modules/svelte.esm.min.js +2 -2
  67. package/modules/svelte.min.cjs +2 -2
  68. package/modules/svelte.min.js +2 -2
  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 +2 -2
  73. package/modules/vue.min.cjs +2 -2
  74. package/modules/vue.min.js +2 -2
  75. package/modules/webcomponent.esm.min.js +257 -54
  76. package/modules/webcomponent.min.cjs +257 -54
  77. package/modules/webcomponent.min.js +257 -54
  78. package/package.json +1 -1
@@ -437,7 +437,7 @@
437
437
  <div class="shell">
438
438
  <aside class="rail">
439
439
  <p class="rail__brand">Lattice Grid</p>
440
- <p class="rail__sub">Developer guide · v1.54.0</p>
440
+ <p class="rail__sub">Developer guide · v1.55.0</p>
441
441
  <nav>
442
442
  <div class="rail__group">
443
443
  <span class="rail__label">Start here</span>
@@ -553,7 +553,7 @@
553
553
  <a href="API.html">reference tables</a> are the shorter version for when you already know.
554
554
  </p>
555
555
  <p class="chips">
556
- <span class="chip">Version 1.7.1</span>
556
+ <span class="chip">Version 1.55.0</span>
557
557
  <span class="chip">Zero dependencies</span>
558
558
  <span class="chip">No build step</span>
559
559
  </p>
@@ -585,6 +585,10 @@ createGrid(element, { locale: 'fr-FR', messages: FR_FR });</code></pre>
585
585
 
586
586
  <p><code>MESSAGE_KEYS</code> lists every key. <code>auditCatalogue(yours)</code> returns what is missing and what is not a real key, which is the quickest way to check a translation before shipping it.</p>
587
587
 
588
+ <h3>Keys seeded in English, awaiting translation</h3>
589
+ <p>A key added after a catalogue was written ships in British English only until a translator supplies it; <code>Messages</code> merges every catalogue over the default, so the grid says it in English rather than showing the key. The shipped catalogues do not carry an English copy under the guise of a translation, and the build's completeness test lists exactly which keys are in this state. As of 1.55 the most recent additions are the strings that had shipped as template literals, untranslated in every locale (BACKLOG-0001106): the presence live region and roster note, <code>a11y.presence.refused</code>, <code>presence.someoneElse</code> and <code>presence.hidden</code>; the comment panel's changed-since note, <code>comments.valueMoved</code>; the facet band's accessible name, <code>facets.filter</code>; the heading tooltip that names a reduction, <code>header.totalOf</code>; the audit-mode tooltip, <code>diff.before</code> and <code>diff.empty</code>; the kanban list names, <code>kanban.columnCards</code> and <code>kanban.laneCards</code>, both plural objects selected by <code>count</code>; and the gantt lag label, <code>gantt.lag</code> and <code>gantt.lead</code>. Supply any of them in <code>messages</code> to translate it today.</p>
590
+ <p>The kanban board and the gantt view are modules and do not import the catalogue. A board bound to a grid, or a plan created with one, borrows that grid's <code>messages</code>; otherwise pass <code>messages</code> — a grid's own, or any object with <code>t(key, params)</code> — to <code>createKanban</code> or to <code>gantt.mount</code>. With neither they render the English.</p>
591
+
588
592
  <div class="why">
589
593
  <p><strong>The grid is checked in the other direction too.</strong> <code>auditCatalogue</code> tells you a catalogue is complete: that a translator covered every key. It cannot tell you the grid only ever renders text that came from a catalogue in the first place, and a string written into the source passes every test, because the tests assert on the English the grid happens to produce.</p>
590
594
  <p>So the build refuses one. Any literal reaching an element's text, or an announced attribute such as <code>aria-label</code>, <code>title</code> or <code>placeholder</code>, has to come from the catalogue. That is what stops a localised grid drifting back into English one plausible change at a time.</p>
@@ -668,8 +672,8 @@ createGrid(element, { direction: 'rtl' }); <span class="cmt">// or say so out
668
672
 
669
673
  <div class="example">
670
674
  <p class="example__label">jsDelivr, no npm install, no bundler</p>
671
- <pre><code>&lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.7.1/lattice-grid.min.css"&gt;
672
- &lt;script src="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.7.1/lattice-grid.min.js"&gt;&lt;/script&gt;
675
+ <pre><code>&lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1/lattice-grid.min.css"&gt;
676
+ &lt;script src="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1/lattice-grid.min.js"&gt;&lt;/script&gt;
673
677
 
674
678
  &lt;script&gt;
675
679
  <span class="kw">const</span> grid = LatticeGrid.createGrid(document.getElementById('grid'), config);
@@ -694,9 +698,10 @@ createGrid(element, { direction: 'rtl' }); <span class="cmt">// or say so out
694
698
 
695
699
  <div class="note">
696
700
  <p><strong>jsDelivr mirrors every version published to npm</strong> at
697
- <code>cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@&lt;version&gt;/&lt;file&gt;</code>: pin an
698
- exact version, e.g. <code>@1.7.1</code> rather than <code>@latest</code>, so a later release
699
- does not change what a page already in production loads. The same convention reaches a
701
+ <code>cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1/&lt;file&gt;</code>. <code>@1</code> pins
702
+ the major: a page in production picks up fixes within 1.x and never a breaking release, where
703
+ <code>@latest</code> would. To freeze a page on one exact build, replace <code>@1</code> with
704
+ the full version <code>getVersion()</code> reports. The same convention reaches a
700
705
  module: <code>.../modules/htmx.esm.min.js</code>, <code>.../modules/dhtmlx-compat.esm.min.js</code>,
701
706
  and so on. Type declarations resolve automatically through npm's own <code>types</code> field;
702
707
  for editor tooling against the CDN or a plain script tag, point your <code>tsconfig</code> at
@@ -1273,7 +1278,7 @@ off(); <span class="cmt">// every subscrip
1273
1278
  </p>
1274
1279
  <div class="example">
1275
1280
  <p class="example__label">Which version am I running?</p>
1276
- <pre><code>grid.getVersion(); <span class="cmt">// '1.7.1'</span>
1281
+ <pre><code>grid.getVersion(); <span class="cmt">// '1.55.0'</span>
1277
1282
  LatticeGrid.getVersion(); <span class="cmt">// the same, when you have no grid to hand</span></code></pre>
1278
1283
  </div>
1279
1284
  <p class="lead-in">
@@ -1354,6 +1359,31 @@ LatticeGrid.getVersion(); <span class="cmt">// the same, when you have no grid
1354
1359
  <code>grid.columns.fit()</code> distributes the viewport width across visible columns, and
1355
1360
  <code>autoSize</code> measures content.
1356
1361
  </p>
1362
+ <p>The width <code>fit()</code> distributes is the space the cells actually occupy: the body
1363
+ viewport&rsquo;s client width, read when you call it. When the grid has enough rows to
1364
+ scroll vertically, that width excludes the scrollbar, so the columns end flush with it
1365
+ instead of running under it; when there is no vertical scrollbar, it is the full inner
1366
+ width. Rows you passed to <code>createGrid</code> or <code>grid.rows.load()</code> before
1367
+ the call are counted, so calling it straight after either works.</p>
1368
+ <p>Every column the grid draws counts toward that width, not only the ones <code>fit()</code>
1369
+ sizes. It sizes your resizable columns. A column it does not size keeps its width, and that
1370
+ width comes off the target first: a column declared <code>resizable: false</code>, and the
1371
+ grid&rsquo;s own selection checkbox, detail expander, group and tree columns. Your resizable
1372
+ columns then share what is left in proportion to their current widths, within each
1373
+ <code>min</code> and <code>max</code>; a column held at a bound stays there and the others
1374
+ share the rest, so all the drawn columns together still come to the viewport width
1375
+ exactly. Under a pivot every column drawn is one the grid generates, so <code>fit()</code>
1376
+ has nothing to size and leaves the widths as they are.</p>
1377
+ <p>If what is left is less than those columns&rsquo; minimums, which happens when the columns
1378
+ <code>fit()</code> does not size already take the width, each resizable column is set to its
1379
+ <code>min</code> (40px when it declares none). None goes below its minimum, and none is
1380
+ squeezed to nothing: the grid scrolls horizontally instead, and a <code>[lattice]</code>
1381
+ warning in the console names the widths that ran out.</p>
1382
+ <p><code>fit()</code> is one-shot. It sets a fixed width on each column once, including a
1383
+ <code>flex</code> column, and does not follow the grid afterwards. If the width changes
1384
+ later, because the container is resized or because rows that arrive afterwards bring a
1385
+ vertical scrollbar in, call it again. A column that should keep tracking the width by
1386
+ itself wants <code>flex</code> instead of <code>fit()</code>.</p>
1357
1387
  <p>Both are also on the column menu: Move left, Move right, Move to start, Move to end, and
1358
1388
  a Width submenu, and bound to the keyboard with a heading focused: <kbd>Alt</kbd> with a
1359
1389
  left or right arrow resizes, <kbd>Shift</kbd> with one moves the column. Neither operation
@@ -1969,9 +1999,16 @@ grid.edit.setCells([
1969
1999
  <span class="cmt">// → the number of cells written</span></code></pre>
1970
2000
  </div>
1971
2001
  <p class="lead-in">
1972
- This is the full path, not a shortcut: it validates, emits <code>cell:changed</code>,
2002
+ This is the full path, not a shortcut: it validates, emits <code>cell:changed</code> per cell,
1973
2003
  re-sorts if the column is sorted on, records one undo entry, and returns <code>0</code> for a
1974
- column the user may not write.
2004
+ column the user may not write. It then announces the whole call <strong>once</strong> as
2005
+ <code>rows:changed</code> (<code>identified: true</code>, <code>edit: true</code>, the
2006
+ <code>updated</code> rows and the <code>columns</code> written), after the per-cell events, so
2007
+ a derived grid, a statistic tile or anything else that follows <code>rows:changed</code>
2008
+ re-reads once for a twenty-cell paste rather than twenty times. An editor commit, a fill, a
2009
+ paste, an undo, a redo and an optimistic rollback each announce themselves the same way, once
2010
+ per batch. Earlier releases announced nothing here, and a derived view of an edited grid went
2011
+ silently stale.
1975
2012
  </p>
1976
2013
 
1977
2014
  <h3>High-frequency updates</h3>
@@ -3306,7 +3343,17 @@ createGrid(right, {
3306
3343
  <code>refresh</code> to <code>live</code>, <code>manual</code> or a number of milliseconds to
3307
3344
  change the coalescing; <code>idle</code> is the default and settles to a frame.</p>
3308
3345
  <p><strong>Derived grids are read-only.</strong> There is one copy of the data and it lives in
3309
- the source. Write there and the derived grid follows.</p>
3346
+ the source. Write there and the derived grid follows: an edit through the source's editing
3347
+ API (<code>edit.setCells</code>, an inline commit, a fill, a paste, an undo, a redo or an
3348
+ optimistic rollback) is announced once per batch, after the per-cell
3349
+ <code>cell:changed</code> events, and the derived grid re-derives once for the batch. A
3350
+ grouped derivation patches the groups the edited rows belong to; a derivation with a
3351
+ <code>where</code>, an <code>unnest</code>, a producer, or an edit to a column the source
3352
+ filters on re-reads in full, at the cost measured above. <strong>Use <code>idle</code> when a
3353
+ derived child follows an editable grid.</strong> Under <code>live</code> the derivation runs
3354
+ synchronously inside the edit call, so a keystroke's commit on a 200k-row source pays the
3355
+ whole re-read before the editor closes; <code>idle</code> defers it to the next frame and
3356
+ folds a burst of edits into one.</p>
3310
3357
  <p><strong>The key comes for free.</strong> A derived grid keys on <code>__key</code>, which
3311
3358
  the source writes onto every row it produces: the group value, the profiled column, or the
3312
3359
  source row's own key when nothing is grouped. Set <code>rowKey</code> only to override it.</p>
@@ -5368,6 +5415,17 @@ grid.annotate.use(null); <span class="cmt">// hand the grid
5368
5415
  <h3>Keyboard</h3>
5369
5416
  <p>Every operation is reachable without a pointer. Resizing and reordering a column were once
5370
5417
  drag-only; both now have key bindings and menu items, so nothing depends on dragging.</p>
5418
+ <p><strong>Entering the grid.</strong> The grid is one stop in the page's tab order. Pressing
5419
+ <kbd>Tab</kbd> into a grid that has not been used yet puts focus on the grid itself, and the
5420
+ grid draws a focus ring around its own edge at once, in the theme's focus colour, so a keyboard
5421
+ user can see where focus went before pressing anything else. In Windows High Contrast Mode
5422
+ the ring is drawn in the system text colour. A screen reader announces the grid (or tree grid),
5423
+ its row and column counts and whether it is read-only. The first arrow key, <kbd>Home</kbd>
5424
+ or <kbd>Ctrl</kbd>+<kbd>Home</kbd> moves focus to a cell, and the ring moves with it. From then
5425
+ on the cell you were on is the grid's tab stop: <kbd>Shift</kbd>+<kbd>Tab</kbd> from the first
5426
+ cell leaves the grid, and <kbd>Tab</kbd> back into the grid returns to that cell. The grid takes
5427
+ the tab stop back only when that cell is outside the rendered rows, and then draws its own
5428
+ ring again.</p>
5371
5429
  <div class="table-wrap">
5372
5430
  <table>
5373
5431
  <thead><tr><th>Keys</th><th>Does</th></tr></thead>
@@ -5717,10 +5775,11 @@ grid.edit.pasteInto(text); <span class="cmt">// Excel's t
5717
5775
  <tr><td class="sig">Delete / Backspace</td><td class="desc">Clear the selected cells.</td></tr>
5718
5776
  <tr><td class="sig">Enter</td><td class="desc">Start editing; commit and step down.</td></tr>
5719
5777
  <tr><td class="sig">Tab</td><td class="desc">Commit and step across.</td></tr>
5720
- <tr><td class="sig">Escape</td><td class="desc">Cancel the edit; restore a maximised grid once nothing else wants it.</td></tr>
5778
+ <tr><td class="sig">Escape</td><td class="desc">Cancel the edit; restore a maximised grid once nothing else wants it. Coming back from full screen, whether by Escape or the rail's restore button, puts focus back on the cell you were on, not on the page.</td></tr>
5721
5779
  <tr><td class="sig">Ctrl/Cmd + F</td><td class="desc">Open the <a href="#find">find bar</a>; in it, Enter / Shift+Enter step through the matches and Escape closes.</td></tr>
5722
5780
  <tr><td class="sig">Space</td><td class="desc">Toggle the row's selection.</td></tr>
5723
5781
  <tr><td class="sig">Home / End, Page Up / Down</td><td class="desc">Jump; with Ctrl, to the ends of the grid.</td></tr>
5782
+ <tr><td class="sig">Ctrl/Cmd + Alt + H</td><td class="desc">Move focus to the column heading. On a heading, ArrowLeft / ArrowRight move between headings, Enter or Space sort by the column (Shift to add it to the sort), Alt + arrows resize, Shift + arrows move the column, Alt + ArrowDown opens the column menu, and ArrowDown or Escape return you to the data. The full list is in the <a href="#accessibility-guide">accessibility guide</a>.</td></tr>
5724
5783
  </tbody>
5725
5784
  </table>
5726
5785
  </div>
@@ -5728,6 +5787,10 @@ grid.edit.pasteInto(text); <span class="cmt">// Excel's t
5728
5787
  <p>None of these fire while you are typing into an input, a filter box, an open editor, the
5729
5788
  view-name field. The grid checks where the keystroke came from before claiming it, which
5730
5789
  sounds obvious and is the sort of thing that is usually wrong.</p>
5790
+ <p>A key a heading handles acts once, on the heading: Enter sorts and does not also open an
5791
+ editor on a body cell, ArrowRight reaches the next heading and not a cell beneath it. A key
5792
+ the heading declines still travels, which is how Escape reaches a maximised grid from a
5793
+ heading.</p>
5731
5794
  </div>
5732
5795
 
5733
5796
  <h2 id="rules-guide">Conditional formatting</h2>
@@ -7473,7 +7536,7 @@ grid.licence.state(); <span class="cmt">// 'licensed' | 'localhost' | 'trial'<
7473
7536
 
7474
7537
  <footer>
7475
7538
  <p>
7476
- Lattice Grid 1.7.1 · Copyright © 2026 TOCLOCO Inc. All rights reserved.
7539
+ Lattice Grid 1.55.0 · Copyright © 2026 TOCLOCO Inc. All rights reserved.
7477
7540
  Written against the shipped source. Where this guide and the code disagree, the code wins,
7478
7541
  please <a href="https://www.latticegrid.dev">tell us</a>.
7479
7542
  </p>
package/lattice-grid.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.54.0, type declarations
2
+ * Lattice Grid 1.55.0, type declarations
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -250,11 +250,6 @@ export interface NumberFormat {
250
250
  * leaves the remainder in English rather than showing raw keys.
251
251
  */
252
252
  messages?: Record<string, string | Record<string, string>>;
253
- /**
254
- * Writing direction. Omit to settle it from the element's own `dir` and then
255
- * from `locale`: `ar`, `he`, `fa` and the rest resolve to `rtl`.
256
- */
257
- direction?: 'ltr' | 'rtl';
258
253
  scale?: number;
259
254
  }
260
255
 
@@ -1747,6 +1742,14 @@ export interface GridConfig {
1747
1742
  /** Page the rows rather than scrolling them. */
1748
1743
  pagination?: PaginationConfig | boolean;
1749
1744
  locale?: string;
1745
+ /**
1746
+ * Writing direction. Omit it, or say `'auto'`, to settle it from the
1747
+ * element's own computed `dir` and then from `locale`: `ar`, `he`, `fa` and
1748
+ * the rest resolve to `rtl`. In a right-to-left grid the logical alignments
1749
+ * `start`/`end` mirror while the physical `left`/`right` do not (see
1750
+ * {@link Align}).
1751
+ */
1752
+ direction?: 'ltr' | 'rtl' | 'auto';
1750
1753
  /**
1751
1754
  * IANA zone every date column formats in, e.g. 'Europe/London' or 'UTC'.
1752
1755
  * Omit to use each viewer's own zone. A column's own `format.timeZone` wins.
@@ -4410,6 +4413,22 @@ export interface ColumnsApi {
4410
4413
  */
4411
4414
  decorate(id: string, decoration: DecorationName | DecorationSpec | null, opts?: { variant?: VariantSpec }): void;
4412
4415
  autoSize(ids?: string | string[]): void;
4416
+ /**
4417
+ * Size the visible resizable columns so that every column the grid draws,
4418
+ * together, exactly fills the width the cells occupy: the body viewport's
4419
+ * client width at the moment of the call, which excludes the vertical
4420
+ * scrollbar when the grid draws one and is the full inner width when it does
4421
+ * not. Columns it does not size keep their width and are taken out of that
4422
+ * width first: `resizable: false` columns and the grid's own selection
4423
+ * checkbox, detail expander, group and tree columns. The rest share what is
4424
+ * left in proportion to their current widths, within each `min`/`max`. If
4425
+ * that leaves less than their minimums, each is set to its minimum (never
4426
+ * below), the grid scrolls horizontally, and a `[lattice]` warning says so.
4427
+ * Rows given to `createGrid` or `rows.load()` before the call are counted.
4428
+ * One-shot: it sets fixed widths once (a `flex` column included) and does not
4429
+ * follow later changes; after a resize, or after rows arriving later bring a
4430
+ * vertical scrollbar in, call it again.
4431
+ */
4413
4432
  fit(): void;
4414
4433
  group(ids: string | string[]): void;
4415
4434
  pivot(ids: string | string[]): void;
@@ -5520,13 +5539,21 @@ export interface PaginationApi {
5520
5539
  /** What a cell-menu builder and a host item's `action` are handed. */
5521
5540
  export interface CellMenuParams {
5522
5541
  key: string;
5523
- colId: string;
5542
+ /**
5543
+ * The column under the pointer, or `null` when the row belongs to no column:
5544
+ * a right-click in the empty tail of a row beyond the last column
5545
+ * (BACKLOG-0001153), or on a group row, pivot group row or full-width row.
5546
+ * The grid-level menu stands in that case (BACKLOG-0001068).
5547
+ */
5548
+ colId: string | null;
5549
+ /** The cell's value; `undefined` when there is no column. */
5524
5550
  value: unknown;
5525
5551
  /** The row wrapper. */
5526
5552
  row: Row;
5527
5553
  /** Your original row object. */
5528
5554
  data: unknown;
5529
- column: ResolvedColumn;
5555
+ /** The resolved column; `undefined` when `colId` is `null`. */
5556
+ column: ResolvedColumn | undefined;
5530
5557
  index: number;
5531
5558
  grid: Grid;
5532
5559
  }
@@ -9560,11 +9587,12 @@ declare module 'lattice-grid/modules/layout' {
9560
9587
  *
9561
9588
  * **Nothing moves**: no compaction runs, no placement changes, and the
9562
9589
  * payload container is the same DOM node throughout. **Escape restores it**,
9563
- * from anywhere inside the layout, unless a payload has already claimed the
9564
- * key — a grid marks every Escape as handled, at two independent sites (a
9565
- * focused body cell and a focused header cell), so from inside a maximised
9566
- * grid the way back is the restore control. A minimised window is expanded first,
9567
- * and maximising a second window restores the first.
9590
+ * from anywhere inside the layout — a focused grid body cell or column
9591
+ * heading included — unless a payload has already claimed the key: an open
9592
+ * cell editor, filter menu or column menu closes first, and the next Escape
9593
+ * restores the window. Afterwards focus lands on the window's maximise
9594
+ * control. A minimised window is expanded first, and maximising a second
9595
+ * window restores the first.
9568
9596
  */
9569
9597
  maximise(id: string): boolean;
9570
9598
  /**