apex-grid 3.2.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/README.md +229 -52
  3. package/components/cell.d.ts +16 -3
  4. package/components/cell.js +78 -8
  5. package/components/cell.js.map +1 -1
  6. package/components/filter-row.d.ts +3 -6
  7. package/components/filter-row.js +144 -115
  8. package/components/filter-row.js.map +1 -1
  9. package/components/grid.d.ts +421 -77
  10. package/components/grid.js +432 -13
  11. package/components/grid.js.map +1 -1
  12. package/components/group-header-row.d.ts +34 -0
  13. package/components/group-header-row.js +125 -0
  14. package/components/group-header-row.js.map +1 -0
  15. package/components/header-row.d.ts +13 -2
  16. package/components/header-row.js +33 -18
  17. package/components/header-row.js.map +1 -1
  18. package/components/header.d.ts +11 -0
  19. package/components/header.js +209 -8
  20. package/components/header.js.map +1 -1
  21. package/components/paginator.d.ts +6 -1
  22. package/components/paginator.js +17 -11
  23. package/components/paginator.js.map +1 -1
  24. package/components/row.d.ts +28 -0
  25. package/components/row.js +100 -3
  26. package/components/row.js.map +1 -1
  27. package/components/toolbar.d.ts +8 -1
  28. package/components/toolbar.js +25 -7
  29. package/components/toolbar.js.map +1 -1
  30. package/controllers/data-operation.js +1 -0
  31. package/controllers/data-operation.js.map +1 -1
  32. package/controllers/dom.d.ts +24 -6
  33. package/controllers/dom.js +62 -5
  34. package/controllers/dom.js.map +1 -1
  35. package/controllers/editing.d.ts +68 -1
  36. package/controllers/editing.js +129 -44
  37. package/controllers/editing.js.map +1 -1
  38. package/controllers/expansion.js +4 -4
  39. package/controllers/expansion.js.map +1 -1
  40. package/controllers/filter.d.ts +1 -1
  41. package/controllers/filter.js +27 -5
  42. package/controllers/filter.js.map +1 -1
  43. package/controllers/history.d.ts +86 -0
  44. package/controllers/history.js +125 -0
  45. package/controllers/history.js.map +1 -0
  46. package/controllers/navigation.d.ts +49 -2
  47. package/controllers/navigation.js +145 -3
  48. package/controllers/navigation.js.map +1 -1
  49. package/controllers/pagination.js +1 -1
  50. package/controllers/pagination.js.map +1 -1
  51. package/controllers/reorder.js +3 -1
  52. package/controllers/reorder.js.map +1 -1
  53. package/controllers/row-pin.d.ts +59 -0
  54. package/controllers/row-pin.js +75 -0
  55. package/controllers/row-pin.js.map +1 -0
  56. package/controllers/row-reorder.d.ts +161 -0
  57. package/controllers/row-reorder.js +332 -0
  58. package/controllers/row-reorder.js.map +1 -0
  59. package/controllers/selection.js +3 -3
  60. package/controllers/selection.js.map +1 -1
  61. package/controllers/sort.js +13 -3
  62. package/controllers/sort.js.map +1 -1
  63. package/controllers/state.d.ts +33 -0
  64. package/controllers/state.js +37 -2
  65. package/controllers/state.js.map +1 -1
  66. package/controllers/tree.d.ts +8 -0
  67. package/controllers/tree.js +0 -0
  68. package/controllers/tree.js.map +1 -1
  69. package/custom-elements.json +4667 -926
  70. package/docs/assets/hierarchy.js +1 -1
  71. package/docs/assets/highlight.css +28 -0
  72. package/docs/assets/navigation.js +1 -1
  73. package/docs/assets/search.js +1 -1
  74. package/docs/functions/custom.html +3 -0
  75. package/docs/functions/interpolate.html +4 -0
  76. package/docs/functions/localize.html +8 -0
  77. package/docs/functions/max.html +3 -0
  78. package/docs/functions/min.html +3 -0
  79. package/docs/functions/pattern.html +3 -0
  80. package/docs/functions/required.html +3 -0
  81. package/docs/hierarchy.html +1 -1
  82. package/docs/index.html +245 -54
  83. package/docs/interfaces/ApexCellValidationFailedEvent.html +13 -0
  84. package/docs/interfaces/ApexCellValueChangedEvent.html +1 -1
  85. package/docs/interfaces/ApexCellValueChangingEvent.html +2 -2
  86. package/docs/interfaces/ApexColumnGroupContext.html +6 -0
  87. package/docs/interfaces/ApexColumnMovedEvent.html +2 -2
  88. package/docs/interfaces/ApexColumnMovingEvent.html +1 -1
  89. package/docs/interfaces/ApexDetailContext.html +2 -2
  90. package/docs/interfaces/ApexGridEventMap.html +37 -9
  91. package/docs/interfaces/ApexHistoryChangedEvent.html +6 -0
  92. package/docs/interfaces/ApexPageChangedEvent.html +1 -1
  93. package/docs/interfaces/ApexRowMovingEvent.html +9 -0
  94. package/docs/interfaces/ApexRowPinningEvent.html +8 -0
  95. package/docs/interfaces/ApexStateChangedEvent.html +4 -0
  96. package/docs/interfaces/BaseApexCellContext.html +1 -1
  97. package/docs/interfaces/BaseApexEditorContext.html +1 -1
  98. package/docs/interfaces/BaseColumnConfiguration.html +42 -17
  99. package/docs/interfaces/CSVExportOptions.html +2 -2
  100. package/docs/interfaces/ColumnGroupConfiguration.html +12 -0
  101. package/docs/interfaces/ColumnLayoutState.html +2 -0
  102. package/docs/interfaces/ColumnSchema.html +22 -0
  103. package/docs/interfaces/DataPipelineConfiguration.html +2 -2
  104. package/docs/interfaces/EditingHistoryConfiguration.html +10 -0
  105. package/docs/interfaces/ExportFormat.html +2 -2
  106. package/docs/interfaces/ExportOptions.html +1 -1
  107. package/docs/interfaces/FilterStateSnapshot.html +4 -0
  108. package/docs/interfaces/GetStateOptions.html +4 -0
  109. package/docs/interfaces/GridCapabilities.html +8 -0
  110. package/docs/interfaces/GridEditingConfiguration.html +4 -2
  111. package/docs/interfaces/GridRowPinningConfiguration.html +5 -0
  112. package/docs/interfaces/GridRowReorderingConfiguration.html +22 -0
  113. package/docs/interfaces/GridSchema.html +19 -0
  114. package/docs/interfaces/GridState.html +41 -0
  115. package/docs/interfaces/GridTreeConfiguration.html +2 -2
  116. package/docs/interfaces/PaginationConfiguration.html +1 -1
  117. package/docs/interfaces/PaginationState.html +1 -1
  118. package/docs/interfaces/SetStateOptions.html +9 -0
  119. package/docs/interfaces/SetStateResult.html +11 -0
  120. package/docs/interfaces/SortStateSnapshot.html +2 -0
  121. package/docs/interfaces/ValidatorContext.html +8 -0
  122. package/docs/media/_tokens.scss +70 -81
  123. package/docs/media/package.json +2 -2
  124. package/docs/media/state-persistence.html +189 -0
  125. package/docs/modules.html +1 -1
  126. package/docs/types/DataPipelineParams.html +2 -2
  127. package/docs/types/EditMode.html +2 -2
  128. package/docs/types/GridLocaleKey.html +3 -0
  129. package/docs/types/GridLocaleText.html +5 -0
  130. package/docs/types/LocaleParams.html +2 -0
  131. package/docs/types/PaginationMode.html +1 -1
  132. package/docs/types/RowDropPosition.html +2 -0
  133. package/docs/types/RowPinPosition.html +2 -0
  134. package/docs/types/RowRef.html +3 -0
  135. package/docs/types/Validator.html +4 -0
  136. package/docs/variables/EN_LOCALE.html +9 -0
  137. package/docs/variables/esLocale.html +8 -0
  138. package/i18n/en.d.ts +245 -0
  139. package/i18n/en.js +219 -0
  140. package/i18n/en.js.map +1 -0
  141. package/i18n/es.d.ts +18 -0
  142. package/i18n/es.js +219 -0
  143. package/i18n/es.js.map +1 -0
  144. package/i18n/index.d.ts +3 -0
  145. package/i18n/index.js +4 -0
  146. package/i18n/index.js.map +1 -0
  147. package/i18n/localize.d.ts +23 -0
  148. package/i18n/localize.js +15 -0
  149. package/i18n/localize.js.map +1 -0
  150. package/index.d.ts +8 -2
  151. package/index.js +2 -0
  152. package/index.js.map +1 -1
  153. package/internal/column-types.js +1 -1
  154. package/internal/column-types.js.map +1 -1
  155. package/internal/feature-module.d.ts +46 -0
  156. package/internal/feature-module.js +11 -0
  157. package/internal/feature-module.js.map +1 -1
  158. package/internal/flip.js +1 -1
  159. package/internal/flip.js.map +1 -1
  160. package/internal/icons.d.ts +9 -7
  161. package/internal/icons.js +75 -35
  162. package/internal/icons.js.map +1 -1
  163. package/internal/index.d.ts +5 -3
  164. package/internal/index.js +2 -1
  165. package/internal/index.js.map +1 -1
  166. package/internal/state-schema.d.ts +85 -0
  167. package/internal/state-schema.js +27 -0
  168. package/internal/state-schema.js.map +1 -0
  169. package/internal/state-snapshot.d.ts +152 -0
  170. package/internal/state-snapshot.js +115 -0
  171. package/internal/state-snapshot.js.map +1 -0
  172. package/internal/tags.d.ts +1 -0
  173. package/internal/tags.js +1 -0
  174. package/internal/tags.js.map +1 -1
  175. package/internal/types.d.ts +162 -2
  176. package/internal/types.js.map +1 -1
  177. package/internal/utils.d.ts +12 -0
  178. package/internal/utils.js +17 -0
  179. package/internal/utils.js.map +1 -1
  180. package/internal/validators.d.ts +31 -0
  181. package/internal/validators.js +44 -0
  182. package/internal/validators.js.map +1 -0
  183. package/package.json +1 -1
  184. package/styles/_tokens.css.js +1 -1
  185. package/styles/_tokens.css.js.map +1 -1
  186. package/styles/body-cell/body-cell.css.js +1 -1
  187. package/styles/body-cell/body-cell.css.js.map +1 -1
  188. package/styles/body-row/body-row.css.js +1 -1
  189. package/styles/body-row/body-row.css.js.map +1 -1
  190. package/styles/filter-row/filter-row.css.js +1 -1
  191. package/styles/filter-row/filter-row.css.js.map +1 -1
  192. package/styles/grid/_grid.base.css.js +1 -1
  193. package/styles/grid/_grid.base.css.js.map +1 -1
  194. package/styles/grid/grid.css.js +1 -1
  195. package/styles/grid/grid.css.js.map +1 -1
  196. package/styles/group-header-row/group-header-row.css.d.ts +1 -0
  197. package/styles/group-header-row/group-header-row.css.js +3 -0
  198. package/styles/group-header-row/group-header-row.css.js.map +1 -0
  199. package/styles/header-cell/header-cell.css.js +1 -1
  200. package/styles/header-cell/header-cell.css.js.map +1 -1
  201. package/styles/header-row/header-row.base.css.js +1 -1
  202. package/styles/header-row/header-row.base.css.js.map +1 -1
  203. package/styles/toolbar/toolbar.css.js +1 -1
  204. package/styles/toolbar/toolbar.css.js.map +1 -1
  205. package/docs/classes/ApexGrid.html +0 -399
package/docs/index.html CHANGED
@@ -5,22 +5,29 @@
5
5
  <p>A Lit-based, framework-agnostic web component data grid. Ships as a single custom element <code>&lt;apex-grid&gt;</code> with a rich, opt-in feature set and full TypeScript types.</p>
6
6
  <h2 id="features" class="tsd-anchor-link">Features<a href="#features" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
7
7
  <ul>
8
- <li><strong>Row virtualization</strong> via <code>@lit-labs/virtualizer</code> — only ~20 rows in the DOM at any time, regardless of dataset size.</li>
9
- <li><strong>Sorting</strong> — single or multi-column, tri-state (asc / desc / none), per-column comparers.</li>
10
- <li><strong>Filtering</strong> — per-column filter chips with string / number / boolean / date operands, plus a quick-filter (global search) input.</li>
11
- <li><strong>Pagination</strong> — local slicing or remote mode with a <code>pageChanging</code> / <code>pageChanged</code> event pair; built-in <code>&lt;apex-grid-paginator&gt;</code>.</li>
12
- <li><strong>Column pinning</strong> — pin to start or end; visual reordering only, source <code>columns</code> array is preserved.</li>
13
- <li><strong>Column reordering</strong> — drag-and-drop with per-column opt-out, constrained to the column's pinning group.</li>
14
- <li><strong>Column resizing</strong> — pointer-driven, with a min-width safeguard.</li>
15
- <li><strong>Inline editing</strong> — cell or row mode, click or double-click trigger, per-column opt-in.</li>
16
- <li><strong>Row selection</strong> — single or multiple, optional checkbox column, full programmatic API.</li>
17
- <li><strong>Row expansion (master-detail)</strong> — opt-in chevron column with a <code>detailTemplate</code>.</li>
18
- <li><strong>Tree data (nested rows)</strong> — AG Grid–style <code>getDataPath</code> pattern over a flat array.</li>
19
- <li><strong>CSV export</strong> — programmatic method plus an optional toolbar dropdown. (Excel/XLSX export is in <code>apex-grid-enterprise</code>.)</li>
20
- <li><strong>Toolbar</strong> — opt-in <code>&lt;apex-grid-toolbar&gt;</code> with debounced quick filter and export menu.</li>
21
- <li><strong>Templating</strong> — slot-based templates for cells, headers, editors, and detail panels.</li>
22
- <li><strong>Theming</strong> — styled out-of-the-box; fully customizable through <code>--ag-*</code> CSS custom properties (no theme import or build step). Auto-matches an <code>igniteui-webcomponents</code> host app when one is present.</li>
23
- <li><strong>Accessibility</strong> — WCAG 2.2 AA semantics (<code>role=&quot;grid&quot;</code> / <code>role=&quot;treegrid&quot;</code>, <code>aria-rowcount</code>, <code>aria-colcount</code>, focus + keyboard navigation).</li>
8
+ <li><strong>Row virtualization</strong> via <code>@lit-labs/virtualizer</code>: only ~20 rows in the DOM at any time, regardless of dataset size.</li>
9
+ <li><strong>Sorting</strong>: single or multi-column, tri-state (asc / desc / none), per-column comparers.</li>
10
+ <li><strong>Filtering</strong>: per-column filter chips with string / number / boolean / date operands, plus a quick-filter (global search) input.</li>
11
+ <li><strong>Pagination</strong>: local slicing or remote mode with a <code>pageChanging</code> / <code>pageChanged</code> event pair; built-in <code>&lt;apex-grid-paginator&gt;</code>.</li>
12
+ <li><strong>Column pinning</strong>: pin to start or end; visual reordering only, source <code>columns</code> array is preserved.</li>
13
+ <li><strong>Column reordering</strong>: drag-and-drop with per-column opt-out, constrained to the column's pinning group.</li>
14
+ <li><strong>Column resizing</strong>: pointer-driven, with a min-width safeguard.</li>
15
+ <li><strong>Column groups</strong>: spanning multi-level headers over a flat <code>columns</code> array, respecting pin regions.</li>
16
+ <li><strong>Inline editing</strong>: cell or row mode, click or double-click trigger, per-column opt-in.</li>
17
+ <li><strong>Cell validation</strong>: declarative per-column <code>validators</code> (built-ins plus custom), surfaced with <code>aria-invalid</code> and an event.</li>
18
+ <li><strong>Undo / redo</strong>: opt-in history for cell edits, with keyboard shortcuts (Ctrl/Cmd+Z, etc.).</li>
19
+ <li><strong>Row selection</strong>: single or multiple, optional checkbox column, full programmatic API.</li>
20
+ <li><strong>Row pinning</strong>: sticky top / bottom bands rendered outside the virtualizer.</li>
21
+ <li><strong>Row drag-reorder</strong>: pointer and keyboard reordering with a manual order, mutually exclusive with sorting.</li>
22
+ <li><strong>Row expansion (master-detail)</strong>: opt-in chevron column with a <code>detailTemplate</code>.</li>
23
+ <li><strong>Tree data (nested rows)</strong>: <code>getDataPath</code> pattern over a flat array.</li>
24
+ <li><strong>State &amp; persistence</strong>: <code>getState()</code> / <code>setState()</code> snapshot round-trip, a <code>stateChanged</code> event, and a <code>getSchema()</code> capability descriptor.</li>
25
+ <li><strong>Localization (i18n)</strong>: override any built-in string via <code>localeText</code>; bundled dictionaries (e.g. <code>esLocale</code>).</li>
26
+ <li><strong>CSV export</strong>: programmatic method plus an optional toolbar dropdown. (Excel/XLSX export is in <code>apex-grid-enterprise</code>.)</li>
27
+ <li><strong>Toolbar</strong>: opt-in <code>&lt;apex-grid-toolbar&gt;</code> with debounced quick filter and export menu.</li>
28
+ <li><strong>Templating</strong>: slot-based templates for cells, headers, editors, and detail panels.</li>
29
+ <li><strong>Theming</strong>: styled out-of-the-box; fully customizable through <code>--ag-*</code> CSS custom properties (no theme import or build step). Auto-matches an <code>igniteui-webcomponents</code> host app when one is present.</li>
30
+ <li><strong>Accessibility</strong>: WCAG 2.2 AA semantics (<code>role=&quot;grid&quot;</code> / <code>role=&quot;treegrid&quot;</code>, <code>aria-rowcount</code>, <code>aria-colcount</code>, focus + keyboard navigation).</li>
24
31
  <li><strong>Provenance-signed npm releases</strong> with OIDC trusted publishing.</li>
25
32
  </ul>
26
33
  <hr>
@@ -29,7 +36,7 @@
29
36
  <pre><code class="ts"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">setup</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;apex-grid&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-4">setup</span><span class="hl-1">();</span>
30
37
  </code><button type="button">Copy</button></pre>
31
38
 
32
- <p>That single call registers <code>&lt;apex-grid&gt;</code> and adopts a default host stylesheet (<code>height: 100%; min-height: 240px</code>). The grid is styled out-of-the-box — no theme CSS import is required.</p>
39
+ <p>That single call registers <code>&lt;apex-grid&gt;</code> and adopts a default host stylesheet (<code>height: 100%; min-height: 240px</code>). The grid is styled out-of-the-box; no theme CSS import is required.</p>
33
40
  <h3 id="render-the-grid" class="tsd-anchor-link">Render the grid<a href="#render-the-grid" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
34
41
  <pre><code class="ts"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">html</span><span class="hl-1">, </span><span class="hl-2">render</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;lit&#39;</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> </span><span class="hl-3">&#39;apex-grid/define&#39;</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> </span><span class="hl-0">type</span><span class="hl-1"> { </span><span class="hl-2">ColumnConfiguration</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;apex-grid&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-5">type</span><span class="hl-1"> </span><span class="hl-6">User</span><span class="hl-1"> = { </span><span class="hl-2">id</span><span class="hl-1">: </span><span class="hl-6">number</span><span class="hl-1">; </span><span class="hl-2">name</span><span class="hl-1">: </span><span class="hl-6">string</span><span class="hl-1">; </span><span class="hl-2">age</span><span class="hl-1">: </span><span class="hl-6">number</span><span class="hl-1">; </span><span class="hl-2">subscribed</span><span class="hl-1">: </span><span class="hl-6">boolean</span><span class="hl-1"> };</span><br/><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">data</span><span class="hl-1">: </span><span class="hl-6">User</span><span class="hl-1">[] = [</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-8">1</span><span class="hl-1">, </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">&#39;Ada Lovelace&#39;</span><span class="hl-1">, </span><span class="hl-2">age:</span><span class="hl-1"> </span><span class="hl-8">36</span><span class="hl-1">, </span><span class="hl-2">subscribed:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-8">2</span><span class="hl-1">, </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">&#39;Carl Sagan&#39;</span><span class="hl-1">, </span><span class="hl-2">age:</span><span class="hl-1"> </span><span class="hl-8">62</span><span class="hl-1">, </span><span class="hl-2">subscribed:</span><span class="hl-1"> </span><span class="hl-5">false</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-8">3</span><span class="hl-1">, </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">&#39;Grace Hopper&#39;</span><span class="hl-1">, </span><span class="hl-2">age:</span><span class="hl-1"> </span><span class="hl-8">85</span><span class="hl-1">, </span><span class="hl-2">subscribed:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> },</span><br/><span class="hl-1">];</span><br/><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">columns</span><span class="hl-1">: </span><span class="hl-6">ColumnConfiguration</span><span class="hl-1">&lt;</span><span class="hl-6">User</span><span class="hl-1">&gt;[] = [</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;id&#39;</span><span class="hl-1">, </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-3">&#39;number&#39;</span><span class="hl-1">, </span><span class="hl-2">headerText:</span><span class="hl-1"> </span><span class="hl-3">&#39;ID&#39;</span><span class="hl-1">, </span><span class="hl-2">width:</span><span class="hl-1"> </span><span class="hl-3">&#39;80px&#39;</span><span class="hl-1">, </span><span class="hl-2">sort:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">filter:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1">, </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-3">&#39;string&#39;</span><span class="hl-1">, </span><span class="hl-2">headerText:</span><span class="hl-1"> </span><span class="hl-3">&#39;Name&#39;</span><span class="hl-1">, </span><span class="hl-2">width:</span><span class="hl-1"> </span><span class="hl-3">&#39;240px&#39;</span><span class="hl-1">, </span><span class="hl-2">sort:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">filter:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;age&#39;</span><span class="hl-1">, </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-3">&#39;number&#39;</span><span class="hl-1">, </span><span class="hl-2">headerText:</span><span class="hl-1"> </span><span class="hl-3">&#39;Age&#39;</span><span class="hl-1">, </span><span class="hl-2">width:</span><span class="hl-1"> </span><span class="hl-3">&#39;100px&#39;</span><span class="hl-1">, </span><span class="hl-2">sort:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">filter:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;subscribed&#39;</span><span class="hl-1">, </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-3">&#39;boolean&#39;</span><span class="hl-1">, </span><span class="hl-2">headerText:</span><span class="hl-1"> </span><span class="hl-3">&#39;Subscribed&#39;</span><span class="hl-1">, </span><span class="hl-2">width:</span><span class="hl-1"> </span><span class="hl-3">&#39;140px&#39;</span><span class="hl-1">, </span><span class="hl-2">sort:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">filter:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> },</span><br/><span class="hl-1">];</span><br/><br/><span class="hl-4">render</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-4">html</span><span class="hl-3">`&lt;apex-grid .data=</span><span class="hl-5">${</span><span class="hl-2">data</span><span class="hl-5">}</span><span class="hl-3"> .columns=</span><span class="hl-5">${</span><span class="hl-2">columns</span><span class="hl-5">}</span><span class="hl-3">&gt;&lt;/apex-grid&gt;`</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">document</span><span class="hl-1">.</span><span class="hl-4">getElementById</span><span class="hl-1">(</span><span class="hl-3">&#39;app&#39;</span><span class="hl-1">)!,</span><br/><span class="hl-1">);</span>
35
42
  </code><button type="button">Copy</button></pre>
@@ -44,7 +51,7 @@
44
51
  <pre><code class="bash"><span class="hl-4">npm</span><span class="hl-1"> </span><span class="hl-3">install</span><span class="hl-1"> </span><span class="hl-3">apex-grid</span><span class="hl-1"> </span><span class="hl-3">lit</span>
45
52
  </code><button type="button">Copy</button></pre>
46
53
 
47
- <p><code>igniteui-webcomponents</code> ships as a transitive dependency — no separate install.</p>
54
+ <p><code>igniteui-webcomponents</code> ships as a transitive dependency; no separate install.</p>
48
55
  <h3 id="2-register-the-custom-element" class="tsd-anchor-link">2. Register the custom element<a href="#2-register-the-custom-element" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
49
56
  <pre><code class="ts"><span class="hl-0">import</span><span class="hl-1"> </span><span class="hl-3">&#39;apex-grid/define&#39;</span><span class="hl-1">;</span>
50
57
  </code><button type="button">Copy</button></pre>
@@ -55,16 +62,16 @@
55
62
 
56
63
  <p>Without this, <code>&lt;apex-grid&gt;</code> is an inert unknown element.</p>
57
64
  <h3 id="3-optional-customize-the-look" class="tsd-anchor-link">3. (Optional) Customize the look<a href="#3-optional-customize-the-look" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
58
- <p>The grid is styled out-of-the-box — there is no theme to import. Customize it by overriding the <code>--ag-*</code> CSS custom properties on <code>apex-grid</code> (or any ancestor); a one-line brand override cascades to every tint:</p>
65
+ <p>The grid is styled out-of-the-box; there is no theme to import. Customize it by overriding the <code>--ag-*</code> CSS custom properties on <code>apex-grid</code> (or any ancestor); a one-line brand override cascades to every tint:</p>
59
66
  <pre><code class="css"><span class="hl-10">apex-grid</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-12">--ag-brand</span><span class="hl-1">: </span><span class="hl-14">#7c3aed</span><span class="hl-1">; </span><span class="hl-15">/* selection, focus, accents */</span><br/><span class="hl-1"> </span><span class="hl-12">--ag-brand-strong</span><span class="hl-1">: </span><span class="hl-14">#6d28d9</span><span class="hl-1">; </span><span class="hl-15">/* hover / pressed */</span><br/><span class="hl-1"> </span><span class="hl-12">--ag-radius</span><span class="hl-1">: </span><span class="hl-8">12px</span><span class="hl-1">; </span><span class="hl-15">/* outer card radius */</span><br/><span class="hl-1"> </span><span class="hl-12">--ag-row-h</span><span class="hl-1">: </span><span class="hl-8">40px</span><span class="hl-1">; </span><span class="hl-15">/* row height */</span><br/><span class="hl-1">}</span>
60
67
  </code><button type="button">Copy</button></pre>
61
68
 
62
69
  <p>See <a href="media/_tokens.scss"><code>src/styles/_tokens.scss</code></a> for the full token list (brand, surfaces, text, semantic state colors, typography, spacing, motion).</p>
63
- <p><strong>Grid edge / shadow.</strong> By default the grid shows a flat 1px hairline edge (no drop shadow). Control it with the <code>--ag-grid-shadow</code> hook — this is an opt-in override, not one of the <code>_tokens.scss</code> defaults:</p>
70
+ <p><strong>Grid edge / shadow.</strong> By default the grid shows a flat 1px hairline edge (no drop shadow). Control it with the <code>--ag-grid-shadow</code> hook, an opt-in override that is not one of the <code>_tokens.scss</code> defaults:</p>
64
71
  <pre><code class="css"><span class="hl-10">apex-grid</span><span class="hl-1"> { </span><span class="hl-12">--ag-grid-shadow</span><span class="hl-1">: </span><span class="hl-4">var</span><span class="hl-1">(</span><span class="hl-12">--ag-shadow-card</span><span class="hl-1">); } </span><span class="hl-15">/* elevated floating-card look */</span><br/><span class="hl-10">apex-grid</span><span class="hl-1"> { </span><span class="hl-12">--ag-grid-shadow</span><span class="hl-1">: </span><span class="hl-14">none</span><span class="hl-1">; } </span><span class="hl-15">/* remove the edge entirely */</span>
65
72
  </code><button type="button">Copy</button></pre>
66
73
 
67
- <p>If you embed the grid alongside <code>igniteui-webcomponents</code>, the brand tokens automatically re-tint from the igniteui palette (<code>--ig-primary-500</code>) — no configuration needed.</p>
74
+ <p>If you embed the grid alongside <code>igniteui-webcomponents</code>, the brand tokens automatically re-tint from the igniteui palette (<code>--ig-primary-500</code>); no configuration needed.</p>
68
75
  <h3 id="4-size-the-host" class="tsd-anchor-link">4. Size the host<a href="#4-size-the-host" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
69
76
  <p><code>@lit-labs/virtualizer</code> requires a <strong>bounded height</strong>. Without one, the virtualizer collapses to its natural content height (~150px) and only a few rows ever render.</p>
70
77
  <pre><code class="css"><span class="hl-10">apex-grid</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-12">height</span><span class="hl-1">: </span><span class="hl-8">480px</span><span class="hl-1">; </span><span class="hl-15">/* any explicit pixel height; % works if the parent has a height */</span><br/><span class="hl-1">}</span>
@@ -83,7 +90,7 @@
83
90
  <li><strong>Sort arrows</strong> (↕) next to each header when <code>sort: true</code>.</li>
84
91
  <li>A <strong>filter row</strong> below the headers with a &quot;Filter&quot; chip per column when <code>filter: true</code>.</li>
85
92
  <li><strong>Hover state</strong> on rows.</li>
86
- <li><strong>Smooth scrolling</strong> — DevTools shows only ~20 <code>&lt;apex-grid-row&gt;</code> elements at any time.</li>
93
+ <li><strong>Smooth scrolling</strong>: DevTools shows only ~20 <code>&lt;apex-grid-row&gt;</code> elements at any time.</li>
87
94
  </ul>
88
95
  <h3 id="troubleshooting" class="tsd-anchor-link">Troubleshooting<a href="#troubleshooting" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
89
96
  <table>
@@ -96,35 +103,37 @@
96
103
  <tbody>
97
104
  <tr>
98
105
  <td>Want a different look / brand color</td>
99
- <td>Step 3 — override the <code>--ag-*</code> CSS variables</td>
106
+ <td>Step 3: override the <code>--ag-*</code> CSS variables</td>
100
107
  </tr>
101
108
  <tr>
102
109
  <td>Only ~3 rows visible regardless of data size</td>
103
- <td>Step 4 — no bounded height, <strong>or</strong> consumer CSS sets <code>display</code> on <code>&lt;apex-grid&gt;</code> (check console for the warning)</td>
110
+ <td>Step 4: no bounded height, <strong>or</strong> consumer CSS sets <code>display</code> on <code>&lt;apex-grid&gt;</code> (check console for the warning)</td>
104
111
  </tr>
105
112
  <tr>
106
113
  <td><code>&lt;apex-grid&gt;</code> blank tag in DOM</td>
107
- <td>Step 2 — element not registered</td>
114
+ <td>Step 2: element not registered</td>
108
115
  </tr>
109
116
  <tr>
110
117
  <td>Columns shown as literal <code>[object Object]</code></td>
111
- <td><code>columns=</code> used as an attribute — must be a <strong>property</strong> (<code>.columns=${...}</code> in Lit, <code>[columns]=</code> in Angular, <code>:columns.prop=</code> in Vue, <code>el.columns = ...</code> in vanilla JS)</td>
118
+ <td><code>columns=</code> used as an attribute; must be a <strong>property</strong> (<code>.columns=${...}</code> in Lit, <code>[columns]=</code> in Angular, <code>:columns.prop=</code> in Vue, <code>el.columns = ...</code> in vanilla JS)</td>
112
119
  </tr>
113
120
  </tbody>
114
121
  </table>
115
122
  <hr>
116
123
  <h2 id="features-in-depth" class="tsd-anchor-link">Features in depth<a href="#features-in-depth" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
117
- <p>Each feature below is fully opt-in — you only pay for what you turn on. Snippets assume <code>const grid = document.querySelector('apex-grid')!</code>.</p>
124
+ <p>Each feature below is fully opt-in: you only pay for what you turn on. Snippets assume <code>const grid = document.querySelector('apex-grid')!</code>.</p>
118
125
  <h3 id="sorting" class="tsd-anchor-link">Sorting<a href="#sorting" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
119
126
  <pre><code class="ts"><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">columns</span><span class="hl-1"> = [</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1">, </span><span class="hl-2">sort:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> }, </span><span class="hl-15">// UI sort + tri-state</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;age&#39;</span><span class="hl-1">, </span><span class="hl-2">sort:</span><span class="hl-1"> { </span><span class="hl-2">direction:</span><span class="hl-1"> </span><span class="hl-3">&#39;desc&#39;</span><span class="hl-1"> } }, </span><span class="hl-15">// initial state</span><br/><span class="hl-1">];</span><br/><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">sortConfiguration</span><span class="hl-1"> = { </span><span class="hl-2">multiple:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">triState:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> };</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">sort</span><span class="hl-1">({ </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;age&#39;</span><span class="hl-1">, </span><span class="hl-2">direction:</span><span class="hl-1"> </span><span class="hl-3">&#39;asc&#39;</span><span class="hl-1"> });</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">clearSort</span><span class="hl-1">(); </span><span class="hl-15">// or grid.clearSort(&#39;age&#39;)</span>
120
127
  </code><button type="button">Copy</button></pre>
121
128
 
122
129
  <p>When <code>multiple</code> is enabled, a plain header click sorts by that column alone; hold Ctrl/Cmd and click to append additional columns as lower-priority sort keys. Events: <code>sorting</code> (cancellable), <code>sorted</code>.</p>
130
+ <p>Columns show a column menu (the three-dot / kebab button) in the header. Out of the box it offers <strong>Sort Ascending</strong>, <strong>Sort Descending</strong>, and <strong>Autosize Column</strong> (on sortable or resizable columns). A feature module can supply the menu instead through the <code>ColumnMenuProvider</code> seam: <code>apex-grid-enterprise</code> fills it with pin, hide, group, and chart actions on every column, shared with the right-click context menu. The button is always visible; set <code>columnMenu</code> to <code>false</code> to hide it entirely (a module's menu stays reachable by right-click).</p>
123
131
  <h3 id="filtering" class="tsd-anchor-link">Filtering<a href="#filtering" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
124
132
  <pre><code class="ts"><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">columns</span><span class="hl-1"> = [</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1">, </span><span class="hl-2">filter:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> }, </span><span class="hl-15">// UI filter chip</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;age&#39;</span><span class="hl-1">, </span><span class="hl-2">filter:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-3">&#39;number&#39;</span><span class="hl-1"> }, </span><span class="hl-15">// operands by type</span><br/><span class="hl-1">];</span><br/><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">StringOperands</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;apex-grid&#39;</span><span class="hl-1">;</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">filter</span><span class="hl-1">({ </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1">, </span><span class="hl-2">condition:</span><span class="hl-1"> </span><span class="hl-2">StringOperands</span><span class="hl-1">.</span><span class="hl-2">contains</span><span class="hl-1">, </span><span class="hl-2">searchTerm:</span><span class="hl-1"> </span><span class="hl-3">&#39;Ada&#39;</span><span class="hl-1"> });</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">clearFilter</span><span class="hl-1">();</span>
125
133
  </code><button type="button">Copy</button></pre>
126
134
 
127
135
  <p>Operand classes: <code>StringOperands</code>, <code>NumberOperands</code>, <code>BooleanOperands</code>. Events: <code>filtering</code> (cancellable), <code>filtered</code>.</p>
136
+ <p>Filterable columns show a per-column filter button in the header that opens the filter panel; an active filter is highlighted (with a count badge when more than one condition is set).</p>
128
137
  <h3 id="quick-filter-global-search" class="tsd-anchor-link">Quick filter (global search)<a href="#quick-filter-global-search" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
129
138
  <pre><code class="ts"><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">showQuickFilter</span><span class="hl-1"> = </span><span class="hl-5">true</span><span class="hl-1">; </span><span class="hl-15">// renders the toolbar input</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">quickFilter</span><span class="hl-1"> = </span><span class="hl-3">&#39;ada&#39;</span><span class="hl-1">; </span><span class="hl-15">// or: await grid.setQuickFilter(&#39;ada&#39;)</span>
130
139
  </code><button type="button">Copy</button></pre>
@@ -143,7 +152,7 @@
143
152
  <pre><code class="ts"><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">columns</span><span class="hl-1"> = [</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;id&#39;</span><span class="hl-1">, </span><span class="hl-2">pinned:</span><span class="hl-1"> </span><span class="hl-3">&#39;start&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;actions&#39;</span><span class="hl-1">, </span><span class="hl-2">pinned:</span><span class="hl-1"> </span><span class="hl-3">&#39;end&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1">];</span><br/><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">pinColumn</span><span class="hl-1">(</span><span class="hl-3">&#39;name&#39;</span><span class="hl-1">, </span><span class="hl-3">&#39;start&#39;</span><span class="hl-1">);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">unpinColumn</span><span class="hl-1">(</span><span class="hl-3">&#39;name&#39;</span><span class="hl-1">); </span><span class="hl-15">// or pinColumn(&#39;name&#39;, null)</span>
144
153
  </code><button type="button">Copy</button></pre>
145
154
 
146
- <p>The source <code>columns</code> array is <strong>not</strong> reordered — only the visual render order changes. Read <code>grid.displayColumns</code> for the render order. Events: <code>columnPinning</code> (cancellable), <code>columnPinned</code>.</p>
155
+ <p>The source <code>columns</code> array is <strong>not</strong> reordered; only the visual render order changes. Read <code>grid.displayColumns</code> for the render order. Events: <code>columnPinning</code> (cancellable), <code>columnPinned</code>.</p>
147
156
  <h3 id="column-reordering" class="tsd-anchor-link">Column reordering<a href="#column-reordering" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
148
157
  <pre><code class="html"><span class="hl-9">&lt;</span><span class="hl-10">apex-grid</span><span class="hl-1"> </span><span class="hl-12">column-reordering</span><span class="hl-9">&gt;&lt;/</span><span class="hl-10">apex-grid</span><span class="hl-9">&gt;</span>
149
158
  </code><button type="button">Copy</button></pre>
@@ -153,24 +162,116 @@
153
162
  </code><button type="button">Copy</button></pre>
154
163
 
155
164
  <p>Per-column opt-out: <code>{ key: 'id', reorderable: false }</code>. Reordering is constrained to the column's own pinning group (start / unpinned / end). Events: <code>columnMoving</code> (cancellable), <code>columnMoved</code>. Attribute: <code>column-reordering</code>.</p>
165
+ <h3 id="column-separators" class="tsd-anchor-link">Column separators<a href="#column-separators" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
166
+ <p>A persistent vertical divider on each column header's trailing edge, on by default. On columns that opt into resizing (<code>{ key, resizable: true }</code>) the divider doubles as the resize handle: it takes the <code>col-resize</code> cursor and can be dragged.</p>
167
+ <pre><code class="ts"><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">columnSeparator</span><span class="hl-1"> = </span><span class="hl-5">false</span><span class="hl-1">; </span><span class="hl-15">// hide the dividers</span>
168
+ </code><button type="button">Copy</button></pre>
169
+
170
+ <p>Theme the line with <code>--ag-header-separator</code> (or the <code>--header-separator-color</code> / <code>--igx-header-separator-color</code> override hooks) and set its vertical inset with <code>--apex-header-separator-inset</code>. Because the default is <code>true</code>, disable it through the property rather than markup (a default-on boolean attribute cannot be turned off by attribute alone). Attribute: <code>column-separator</code>.</p>
171
+ <h3 id="column-groups-spanning-headers" class="tsd-anchor-link">Column groups (spanning headers)<a href="#column-groups-spanning-headers" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
172
+ <pre><code class="ts"><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">columns</span><span class="hl-1"> = [</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;first&#39;</span><span class="hl-1">, </span><span class="hl-2">group:</span><span class="hl-1"> </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;last&#39;</span><span class="hl-1">, </span><span class="hl-2">group:</span><span class="hl-1"> </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;city&#39;</span><span class="hl-1">, </span><span class="hl-2">group:</span><span class="hl-1"> </span><span class="hl-3">&#39;address&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;zip&#39;</span><span class="hl-1">, </span><span class="hl-2">group:</span><span class="hl-1"> </span><span class="hl-3">&#39;address&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1">];</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">columnGroups</span><span class="hl-1"> = [</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1">, </span><span class="hl-2">headerText:</span><span class="hl-1"> </span><span class="hl-3">&#39;Name&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-3">&#39;address&#39;</span><span class="hl-1">, </span><span class="hl-2">headerText:</span><span class="hl-1"> </span><span class="hl-3">&#39;Address&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1">];</span>
173
+ </code><button type="button">Copy</button></pre>
174
+
175
+ <p>A spanning header row renders above the column headers. <code>columns</code> stays flat, so width / pinning / resize / reorder are unaffected; membership is by reference (<code>column.group</code> points at a <code>columnGroups</code> entry). A group's members must be contiguous within one pin region (non-contiguous groups warn and skip the spanning cell); ungrouped columns get a blank spacer. Member reordering is confined to its group.</p>
156
176
  <h3 id="inline-editing" class="tsd-anchor-link">Inline editing<a href="#inline-editing" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
157
177
  <pre><code class="ts"><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">columns</span><span class="hl-1"> = [</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1">, </span><span class="hl-2">editable:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;age&#39;</span><span class="hl-1">, </span><span class="hl-2">editable:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-3">&#39;number&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1">];</span><br/><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">editing</span><span class="hl-1"> = { </span><span class="hl-2">enabled:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">mode:</span><span class="hl-1"> </span><span class="hl-3">&#39;cell&#39;</span><span class="hl-1">, </span><span class="hl-2">trigger:</span><span class="hl-1"> </span><span class="hl-3">&#39;doubleClick&#39;</span><span class="hl-1"> };</span><br/><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">editCell</span><span class="hl-1">(</span><span class="hl-8">0</span><span class="hl-1">, </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1">);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">commitEdit</span><span class="hl-1">();</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">cancelEdit</span><span class="hl-1">();</span>
158
178
  </code><button type="button">Copy</button></pre>
159
179
 
160
180
  <p><code>mode: 'row'</code> puts all editable cells in the row into edit together. Properties: <code>editingCell</code>, <code>editingRow</code>. Events: <code>cellValueChanging</code> (cancellable), <code>cellValueChanged</code>, plus <code>rowEditStarted</code> / <code>rowEditEnded</code> in row mode.</p>
181
+ <h3 id="keyboard-navigation-and-accessibility" class="tsd-anchor-link">Keyboard navigation and accessibility<a href="#keyboard-navigation-and-accessibility" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
182
+ <p>The grid body is a single tab stop: Tab enters the grid, and the active cell
183
+ holds real focus (a roving tabindex), so screen readers follow the cursor as
184
+ it moves. Keys, with editing enabled where relevant:</p>
185
+ <table>
186
+ <thead>
187
+ <tr>
188
+ <th>Keys</th>
189
+ <th>Action</th>
190
+ </tr>
191
+ </thead>
192
+ <tbody>
193
+ <tr>
194
+ <td>Arrow keys</td>
195
+ <td>Move the active cell</td>
196
+ </tr>
197
+ <tr>
198
+ <td>Home / End</td>
199
+ <td>First / last cell <strong>in the row</strong></td>
200
+ </tr>
201
+ <tr>
202
+ <td>Ctrl/Cmd+Home / Ctrl/Cmd+End</td>
203
+ <td>First / last cell of the grid</td>
204
+ </tr>
205
+ <tr>
206
+ <td>PageUp / PageDown</td>
207
+ <td>Move up / down by a viewport page</td>
208
+ </tr>
209
+ <tr>
210
+ <td>Enter or F2</td>
211
+ <td>Open the active cell's editor</td>
212
+ </tr>
213
+ <tr>
214
+ <td>Enter / Tab (while editing)</td>
215
+ <td>Commit (Tab commits and moves)</td>
216
+ </tr>
217
+ <tr>
218
+ <td>Escape (while editing)</td>
219
+ <td>Cancel the edit</td>
220
+ </tr>
221
+ <tr>
222
+ <td>Space</td>
223
+ <td>Toggle row selection (selection column)</td>
224
+ </tr>
225
+ <tr>
226
+ <td>Ctrl/Cmd+Z / Ctrl/Cmd+Y</td>
227
+ <td>Undo / redo (with history enabled)</td>
228
+ </tr>
229
+ </tbody>
230
+ </table>
231
+ <p>A keyboard-driven commit or cancel returns focus to the cell, so navigation
232
+ continues from where you were. Sorting, filtering, selection, paging, row
233
+ pinning, reorder, expansion, and undo / redo are announced through a polite
234
+ live region, and every announcement and control label is localizable (the
235
+ <code>announce.*</code> and <code>header.*</code> locale keys). The host gets a localized
236
+ <code>aria-label</code> (&quot;Data grid&quot;) unless you provide <code>aria-label</code> /
237
+ <code>aria-labelledby</code> yourself.</p>
238
+ <blockquote>
239
+ <p>Changed in 3.4.0: Home / End used to jump to the first / last row; they now
240
+ stay within the row. Use Ctrl/Cmd+Home / Ctrl/Cmd+End for the grid corners.</p>
241
+ </blockquote>
242
+ <h3 id="cell-validation" class="tsd-anchor-link">Cell validation<a href="#cell-validation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
243
+ <pre><code class="ts"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">required</span><span class="hl-1">, </span><span class="hl-2">min</span><span class="hl-1">, </span><span class="hl-2">max</span><span class="hl-1">, </span><span class="hl-2">pattern</span><span class="hl-1">, </span><span class="hl-2">custom</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;apex-grid&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">columns</span><span class="hl-1"> = [</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1">, </span><span class="hl-2">editable:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">validators:</span><span class="hl-1"> [</span><span class="hl-4">required</span><span class="hl-1">(</span><span class="hl-3">&#39;Name is required&#39;</span><span class="hl-1">)] },</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;age&#39;</span><span class="hl-1">, </span><span class="hl-2">editable:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-3">&#39;number&#39;</span><span class="hl-1">, </span><span class="hl-2">validators:</span><span class="hl-1"> [</span><span class="hl-4">min</span><span class="hl-1">(</span><span class="hl-8">18</span><span class="hl-1">), </span><span class="hl-4">max</span><span class="hl-1">(</span><span class="hl-8">99</span><span class="hl-1">)] },</span><br/><span class="hl-1"> { </span><span class="hl-2">key:</span><span class="hl-1"> </span><span class="hl-3">&#39;email&#39;</span><span class="hl-1">, </span><span class="hl-2">editable:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">validators:</span><span class="hl-1"> [</span><span class="hl-4">pattern</span><span class="hl-1">(</span><span class="hl-16">/</span><span class="hl-17">^</span><span class="hl-18">[^</span><span class="hl-16">@\s</span><span class="hl-18">]</span><span class="hl-19">+</span><span class="hl-16">@</span><span class="hl-18">[^</span><span class="hl-16">@\s</span><span class="hl-18">]</span><span class="hl-19">+</span><span class="hl-17">$</span><span class="hl-16">/</span><span class="hl-1">, </span><span class="hl-3">&#39;Invalid email&#39;</span><span class="hl-1">)] },</span><br/><span class="hl-1">];</span>
244
+ </code><button type="button">Copy</button></pre>
245
+
246
+ <p>Validators run inside the commit path, before the cancellable <code>cellValueChanging</code> gate. A failure keeps the editor open, marks the cell (<code>aria-invalid</code> + an error message node), and fires <code>cellValidationFailed { key, rowIndex, data, value, errors }</code>. Built-ins: <code>required</code>, <code>min</code>, <code>max</code>, <code>pattern</code>, <code>custom</code>, or any <code>(value, ctx) =&gt; string | null</code>. In row mode all pending cells are validated atomically (no partial write); enterprise paste / fill validate per cell.</p>
247
+ <h3 id="undo-redo" class="tsd-anchor-link">Undo / redo<a href="#undo-redo" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
248
+ <pre><code class="ts"><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">editing</span><span class="hl-1"> = { </span><span class="hl-2">enabled:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">mode:</span><span class="hl-1"> </span><span class="hl-3">&#39;cell&#39;</span><span class="hl-1">, </span><span class="hl-2">history:</span><span class="hl-1"> { </span><span class="hl-2">enabled:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> } };</span><br/><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">undo</span><span class="hl-1">(); </span><span class="hl-15">// or Ctrl/Cmd+Z</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">redo</span><span class="hl-1">(); </span><span class="hl-15">// or Ctrl/Cmd+Shift+Z / Ctrl+Y</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">clearHistory</span><span class="hl-1">();</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">canUndo</span><span class="hl-1">; </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">canRedo</span><span class="hl-1">;</span>
249
+ </code><button type="button">Copy</button></pre>
250
+
251
+ <p>Opt in via <code>editing.history</code>. Every committed cell edit is recorded (single, row-mode, and enterprise paste / fill collapse to one step). Keyboard shortcuts work while the grid body has focus, so an open editor's native undo is untouched. The stack holds 100 commands by default (<code>history: { enabled: true, stackSize: 200 }</code>). Event: <code>historyChanged { canUndo, canRedo }</code>.</p>
161
252
  <h3 id="row-selection" class="tsd-anchor-link">Row selection<a href="#row-selection" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
162
253
  <pre><code class="ts"><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">selection</span><span class="hl-1"> = { </span><span class="hl-2">enabled:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">, </span><span class="hl-2">mode:</span><span class="hl-1"> </span><span class="hl-3">&#39;multiple&#39;</span><span class="hl-1">, </span><span class="hl-2">showCheckboxColumn:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> };</span><br/><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">selectRow</span><span class="hl-1">(</span><span class="hl-2">data</span><span class="hl-1">[</span><span class="hl-8">0</span><span class="hl-1">]);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">toggleRowSelection</span><span class="hl-1">(</span><span class="hl-2">data</span><span class="hl-1">[</span><span class="hl-8">1</span><span class="hl-1">]);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">selectAllRows</span><span class="hl-1">();</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">clearSelection</span><span class="hl-1">();</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">selectedRows</span><span class="hl-1">; </span><span class="hl-15">// snapshot</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">selectedRows</span><span class="hl-1"> = [</span><span class="hl-2">data</span><span class="hl-1">[</span><span class="hl-8">2</span><span class="hl-1">]]; </span><span class="hl-15">// replace selection (goes through `rowSelecting`)</span>
163
254
  </code><button type="button">Copy</button></pre>
164
255
 
165
256
  <p>Events: <code>rowSelecting</code> (cancellable), <code>rowSelected</code>.</p>
257
+ <h3 id="row-pinning-top-bottom" class="tsd-anchor-link">Row pinning (top / bottom)<a href="#row-pinning-top-bottom" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
258
+ <pre><code class="ts"><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">rowPinning</span><span class="hl-1"> = { </span><span class="hl-2">enabled:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> };</span><br/><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">pinRow</span><span class="hl-1">(</span><span class="hl-2">data</span><span class="hl-1">[</span><span class="hl-8">0</span><span class="hl-1">], </span><span class="hl-3">&#39;top&#39;</span><span class="hl-1">);</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">pinRow</span><span class="hl-1">(</span><span class="hl-2">data</span><span class="hl-1">[</span><span class="hl-8">5</span><span class="hl-1">], </span><span class="hl-3">&#39;bottom&#39;</span><span class="hl-1">);</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">unpinRow</span><span class="hl-1">(</span><span class="hl-2">data</span><span class="hl-1">[</span><span class="hl-8">0</span><span class="hl-1">]);</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">pinnedRows</span><span class="hl-1">; </span><span class="hl-15">// { top: T[], bottom: T[] }</span>
259
+ </code><button type="button">Copy</button></pre>
260
+
261
+ <p>Pinned rows render in sticky top / bottom bands outside the virtualizer and are lifted out of the scrollable set (no duplication). Selection and styling work by row reference. Events: <code>rowPinning</code> (cancellable), <code>rowPinned</code>.</p>
262
+ <h3 id="row-drag-reorder" class="tsd-anchor-link">Row drag-reorder<a href="#row-drag-reorder" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
263
+ <pre><code class="ts"><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">rowReordering</span><span class="hl-1"> = { </span><span class="hl-2">enabled:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1"> }; </span><span class="hl-15">// add applyToData: true to splice grid.data in place</span><br/><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">moveRow</span><span class="hl-1">(</span><span class="hl-8">0</span><span class="hl-1">, </span><span class="hl-8">4</span><span class="hl-1">, </span><span class="hl-3">&#39;after&#39;</span><span class="hl-1">);</span>
264
+ </code><button type="button">Copy</button></pre>
265
+
266
+ <p>By default (<code>rowReordering.handle</code>, boolean, default <code>true</code>) a six-dot grip handle shows at the start of every reorderable row, and dragging lifts a full-row floating ghost that follows the cursor. Both interaction modes are supported: <strong>handle mode</strong> (only the grip starts a drag, so the rest of the row stays free for selection and editing) and <strong>whole-row mode</strong> (set <code>handle: false</code> to drag from anywhere on the row, excluding interactive sub-parts like inputs and buttons). Or use the keyboard: focus a row, <strong>Space</strong> to grab, <strong>Arrow</strong> keys to move, <strong>Space / Enter</strong> to drop, <strong>Esc</strong> to cancel. The grid holds a manual order that is mutually exclusive with sorting (applying a sort clears it). By default the app persists the order via the <code>rowMoved</code> event; set <code>applyToData: true</code> to splice <code>grid.data</code> directly. Events: <code>rowMoving</code> (cancellable), <code>rowMoved { from, to, data }</code>.</p>
166
267
  <h3 id="row-expansion-master-detail" class="tsd-anchor-link">Row expansion (master-detail)<a href="#row-expansion-master-detail" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
167
268
  <pre><code class="ts"><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">expansion</span><span class="hl-1"> = {</span><br/><span class="hl-1"> </span><span class="hl-2">enabled:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">detailTemplate</span><span class="hl-2">:</span><span class="hl-1"> ({ </span><span class="hl-2">data</span><span class="hl-1"> }) </span><span class="hl-5">=&gt;</span><span class="hl-1"> </span><span class="hl-4">html</span><span class="hl-3">`&lt;order-summary .order=</span><span class="hl-5">${</span><span class="hl-2">data</span><span class="hl-5">}</span><span class="hl-3">&gt;&lt;/order-summary&gt;`</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">isExpandable</span><span class="hl-2">:</span><span class="hl-1"> (</span><span class="hl-2">row</span><span class="hl-1">) </span><span class="hl-5">=&gt;</span><span class="hl-1"> </span><span class="hl-2">row</span><span class="hl-1">.</span><span class="hl-2">hasDetails</span><span class="hl-1">,</span><br/><span class="hl-1">};</span><br/><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">expandRow</span><span class="hl-1">(</span><span class="hl-2">data</span><span class="hl-1">[</span><span class="hl-8">0</span><span class="hl-1">]);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">toggleRowExpansion</span><span class="hl-1">(</span><span class="hl-2">data</span><span class="hl-1">[</span><span class="hl-8">0</span><span class="hl-1">]);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">expandAllRows</span><span class="hl-1">();</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">collapseAllRows</span><span class="hl-1">();</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">expandedRows</span><span class="hl-1">; </span><span class="hl-15">// snapshot</span>
168
269
  </code><button type="button">Copy</button></pre>
169
270
 
170
271
  <p>Events: <code>rowExpanding</code> (cancellable), <code>rowExpanded</code>.</p>
171
272
  <h3 id="tree-data-nested-rows" class="tsd-anchor-link">Tree data (nested rows)<a href="#tree-data-nested-rows" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
172
- <p>The data array stays <strong>flat</strong>. The grid derives the hierarchy from a <code>getDataPath(row)</code> callback that returns the path from root to that row — AG Grid's &quot;tree data&quot; pattern.</p>
173
- <pre><code class="ts"><span class="hl-5">type</span><span class="hl-1"> </span><span class="hl-6">Person</span><span class="hl-1"> = { </span><span class="hl-2">id</span><span class="hl-1">: </span><span class="hl-6">number</span><span class="hl-1">; </span><span class="hl-2">name</span><span class="hl-1">: </span><span class="hl-6">string</span><span class="hl-1">; </span><span class="hl-2">title</span><span class="hl-1">: </span><span class="hl-6">string</span><span class="hl-1">; </span><span class="hl-2">path</span><span class="hl-1">: </span><span class="hl-6">string</span><span class="hl-1">[] };</span><br/><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">data</span><span class="hl-1">: </span><span class="hl-6">Person</span><span class="hl-1">[] = [</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-8">1</span><span class="hl-1">, </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">&#39;Adrian&#39;</span><span class="hl-1">, </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&#39;CEO&#39;</span><span class="hl-1">, </span><span class="hl-2">path:</span><span class="hl-1"> [</span><span class="hl-3">&#39;Adrian&#39;</span><span class="hl-1">] },</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-8">2</span><span class="hl-1">, </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">&#39;Bryan&#39;</span><span class="hl-1">, </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&#39;VP Eng&#39;</span><span class="hl-1">, </span><span class="hl-2">path:</span><span class="hl-1"> [</span><span class="hl-3">&#39;Adrian&#39;</span><span class="hl-1">, </span><span class="hl-3">&#39;Bryan&#39;</span><span class="hl-1">] },</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-8">3</span><span class="hl-1">, </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">&#39;Cara&#39;</span><span class="hl-1">, </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&#39;Manager&#39;</span><span class="hl-1">, </span><span class="hl-2">path:</span><span class="hl-1"> [</span><span class="hl-3">&#39;Adrian&#39;</span><span class="hl-1">, </span><span class="hl-3">&#39;Bryan&#39;</span><span class="hl-1">, </span><span class="hl-3">&#39;Cara&#39;</span><span class="hl-1">] },</span><br/><span class="hl-1">];</span><br/><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">tree</span><span class="hl-1"> = {</span><br/><span class="hl-1"> </span><span class="hl-2">enabled:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">getDataPath</span><span class="hl-2">:</span><span class="hl-1"> (</span><span class="hl-2">row</span><span class="hl-1">) </span><span class="hl-5">=&gt;</span><span class="hl-1"> </span><span class="hl-2">row</span><span class="hl-1">.</span><span class="hl-2">path</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">defaultExpanded:</span><span class="hl-1"> </span><span class="hl-8">1</span><span class="hl-1">, </span><span class="hl-15">// boolean | number — depth to expand</span><br/><span class="hl-1"> </span><span class="hl-2">groupColumnKey:</span><span class="hl-1"> </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1">, </span><span class="hl-15">// which column shows the chevron + indent</span><br/><span class="hl-1"> </span><span class="hl-2">childIndent:</span><span class="hl-1"> </span><span class="hl-8">20</span><span class="hl-1">, </span><span class="hl-15">// px per depth level</span><br/><span class="hl-1">};</span><br/><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">toggleTreeRow</span><span class="hl-1">(</span><span class="hl-2">data</span><span class="hl-1">[</span><span class="hl-8">0</span><span class="hl-1">]);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">expandAllTreeRows</span><span class="hl-1">();</span>
273
+ <p>The data array stays <strong>flat</strong>. The grid derives the hierarchy from a <code>getDataPath(row)</code> callback that returns the path from root to that row, the flat-array &quot;tree data&quot; pattern.</p>
274
+ <pre><code class="ts"><span class="hl-5">type</span><span class="hl-1"> </span><span class="hl-6">Person</span><span class="hl-1"> = { </span><span class="hl-2">id</span><span class="hl-1">: </span><span class="hl-6">number</span><span class="hl-1">; </span><span class="hl-2">name</span><span class="hl-1">: </span><span class="hl-6">string</span><span class="hl-1">; </span><span class="hl-2">title</span><span class="hl-1">: </span><span class="hl-6">string</span><span class="hl-1">; </span><span class="hl-2">path</span><span class="hl-1">: </span><span class="hl-6">string</span><span class="hl-1">[] };</span><br/><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">data</span><span class="hl-1">: </span><span class="hl-6">Person</span><span class="hl-1">[] = [</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-8">1</span><span class="hl-1">, </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">&#39;Adrian&#39;</span><span class="hl-1">, </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&#39;CEO&#39;</span><span class="hl-1">, </span><span class="hl-2">path:</span><span class="hl-1"> [</span><span class="hl-3">&#39;Adrian&#39;</span><span class="hl-1">] },</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-8">2</span><span class="hl-1">, </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">&#39;Bryan&#39;</span><span class="hl-1">, </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&#39;VP Eng&#39;</span><span class="hl-1">, </span><span class="hl-2">path:</span><span class="hl-1"> [</span><span class="hl-3">&#39;Adrian&#39;</span><span class="hl-1">, </span><span class="hl-3">&#39;Bryan&#39;</span><span class="hl-1">] },</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-8">3</span><span class="hl-1">, </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">&#39;Cara&#39;</span><span class="hl-1">, </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&#39;Manager&#39;</span><span class="hl-1">, </span><span class="hl-2">path:</span><span class="hl-1"> [</span><span class="hl-3">&#39;Adrian&#39;</span><span class="hl-1">, </span><span class="hl-3">&#39;Bryan&#39;</span><span class="hl-1">, </span><span class="hl-3">&#39;Cara&#39;</span><span class="hl-1">] },</span><br/><span class="hl-1">];</span><br/><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">tree</span><span class="hl-1"> = {</span><br/><span class="hl-1"> </span><span class="hl-2">enabled:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">getDataPath</span><span class="hl-2">:</span><span class="hl-1"> (</span><span class="hl-2">row</span><span class="hl-1">) </span><span class="hl-5">=&gt;</span><span class="hl-1"> </span><span class="hl-2">row</span><span class="hl-1">.</span><span class="hl-2">path</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">defaultExpanded:</span><span class="hl-1"> </span><span class="hl-8">1</span><span class="hl-1">, </span><span class="hl-15">// boolean | number, depth to expand</span><br/><span class="hl-1"> </span><span class="hl-2">groupColumnKey:</span><span class="hl-1"> </span><span class="hl-3">&#39;name&#39;</span><span class="hl-1">, </span><span class="hl-15">// which column shows the chevron + indent</span><br/><span class="hl-1"> </span><span class="hl-2">childIndent:</span><span class="hl-1"> </span><span class="hl-8">20</span><span class="hl-1">, </span><span class="hl-15">// px per depth level</span><br/><span class="hl-1">};</span><br/><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">toggleTreeRow</span><span class="hl-1">(</span><span class="hl-2">data</span><span class="hl-1">[</span><span class="hl-8">0</span><span class="hl-1">]);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">expandAllTreeRows</span><span class="hl-1">();</span>
174
275
  </code><button type="button">Copy</button></pre>
175
276
 
176
277
  <p>Methods: <code>toggleTreeRow</code>, <code>expandTreeRow</code>, <code>collapseTreeRow</code>, <code>expandAllTreeRows</code>, <code>collapseAllTreeRows</code>, <code>isTreeRowExpanded</code>. Events: <code>treeRowExpanding</code> (cancellable), <code>treeRowExpanded</code>. When tree mode is active, the host element advertises <code>role=&quot;treegrid&quot;</code>.</p>
@@ -179,7 +280,7 @@
179
280
  <pre><code class="ts"><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">exportToCSV</span><span class="hl-1">(); </span><span class="hl-15">// downloads data.csv</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">exportToCSV</span><span class="hl-1">({ </span><span class="hl-2">filename:</span><span class="hl-1"> </span><span class="hl-3">&#39;users&#39;</span><span class="hl-1">, </span><span class="hl-2">source:</span><span class="hl-1"> </span><span class="hl-3">&#39;selected&#39;</span><span class="hl-1"> });</span><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">text</span><span class="hl-1"> = </span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">exportToCSV</span><span class="hl-1">({ </span><span class="hl-2">filename:</span><span class="hl-1"> </span><span class="hl-3">&#39;&#39;</span><span class="hl-1"> }); </span><span class="hl-15">// no download, returns the string</span>
180
281
  </code><button type="button">Copy</button></pre>
181
282
 
182
- <p><code>source</code> can be <code>'view'</code> (default — post-filter/post-sort), <code>'page'</code>, <code>'selected'</code>, or <code>'all'</code>. Per-column opt-out: <code>{ key: 'secret', exportable: false }</code>.</p>
283
+ <p><code>source</code> can be <code>'view'</code> (default, post-filter/post-sort), <code>'page'</code>, <code>'selected'</code>, or <code>'all'</code>. Per-column opt-out: <code>{ key: 'secret', exportable: false }</code>.</p>
183
284
  <blockquote>
184
285
  <p><strong>XLSX (Excel) export</strong> moved to <a href="https://www.npmjs.com/package/apex-grid-enterprise"><code>apex-grid-enterprise</code></a> in v3. <code>&lt;apex-grid-enterprise&gt;</code> adds <code>grid.exportToXLSX(...)</code> and an &quot;Export XLSX&quot; entry to this same toolbar menu. CSV stays free.</p>
185
286
  </blockquote>
@@ -234,11 +335,28 @@
234
335
  </table>
235
336
  <p>Search input has a <code>debounce</code> attribute (default <code>200</code>ms).</p>
236
337
  <h3 id="theming" class="tsd-anchor-link">Theming<a href="#theming" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
237
- <p>The grid styles itself through <code>--ag-*</code> CSS custom properties — override them on <code>apex-grid</code> (or any ancestor) to rebrand; see <a href="media/_tokens.scss"><code>src/styles/_tokens.scss</code></a> for the full list. When <code>igniteui-webcomponents</code> is present, the brand tokens auto-tint from its palette.</p>
338
+ <p>The grid styles itself through <code>--ag-*</code> CSS custom properties; override them on <code>apex-grid</code> (or any ancestor) to rebrand; see <a href="media/_tokens.scss"><code>src/styles/_tokens.scss</code></a> for the full list. When <code>igniteui-webcomponents</code> is present, the brand tokens auto-tint from its palette.</p>
238
339
  <p>Style with CSS parts on the grid, paginator, and toolbar:</p>
239
340
  <pre><code class="css"><span class="hl-10">apex-grid</span><span class="hl-1">::part(paginator) { </span><span class="hl-12">background</span><span class="hl-1">: </span><span class="hl-4">var</span><span class="hl-1">(</span><span class="hl-12">--surface-2</span><span class="hl-1">); }</span><br/><span class="hl-10">apex-grid-toolbar</span><span class="hl-1">::part(</span><span class="hl-10">search-input</span><span class="hl-1">) { </span><span class="hl-12">font-family</span><span class="hl-1">: </span><span class="hl-4">var</span><span class="hl-1">(</span><span class="hl-12">--font-mono</span><span class="hl-1">); }</span>
240
341
  </code><button type="button">Copy</button></pre>
241
342
 
343
+ <h3 id="spreadsheet-coordinates" class="tsd-anchor-link">Spreadsheet coordinates<a href="#spreadsheet-coordinates" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
344
+ <pre><code class="ts"><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-2">coordinateHints</span><span class="hl-1"> = </span><span class="hl-5">true</span><span class="hl-1">;</span>
345
+ </code><button type="button">Copy</button></pre>
346
+
347
+ <pre><code class="html"><span class="hl-9">&lt;</span><span class="hl-10">apex-grid</span><span class="hl-1"> </span><span class="hl-12">coordinate-hints</span><span class="hl-9">&gt;&lt;/</span><span class="hl-10">apex-grid</span><span class="hl-9">&gt;</span>
348
+ </code><button type="button">Copy</button></pre>
349
+
350
+ <p>When <code>coordinateHints</code> is on, the grid shows a leading row-number gutter (1, 2, 3, and so on) and A / B / C column-letter chips in the headers, so cell references are discoverable (a spreadsheet-style look). Set it directly for a persistent spreadsheet look. <code>apex-grid-enterprise</code> turns it on by default for any grid that has an <code>allowFormula</code> column, so the gutter is reserved up front and entering a formula never shifts the layout. Reflected to the <code>coordinate-hints</code> attribute (default <code>false</code>).</p>
351
+ <h3 id="state-persistence" class="tsd-anchor-link">State &amp; persistence<a href="#state-persistence" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
352
+ <p><code>getState()</code> returns a JSON-safe snapshot of the grid's restorable view and <code>setState()</code> applies one back. The snapshot covers column layout (order, width, pinning, visibility), sort, filter, quick filter, pagination, selection, expansion, tree expansion, pinned rows, the manual drag-reorder order, and any feature-module state (enterprise grouping / pivot / aggregation / ranges). Functions and templates are never serialized: sort comparers, filter condition functions, and cell/header/editor templates re-bind from the live <code>columns</code> config on restore (filter conditions are captured by operand name).</p>
353
+ <pre><code class="js"><span class="hl-15">// Save and restore a view.</span><br/><span class="hl-2">localStorage</span><span class="hl-1">.</span><span class="hl-4">setItem</span><span class="hl-1">(</span><span class="hl-3">&#39;view&#39;</span><span class="hl-1">, </span><span class="hl-7">JSON</span><span class="hl-1">.</span><span class="hl-4">stringify</span><span class="hl-1">(</span><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">getState</span><span class="hl-1">()));</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">setState</span><span class="hl-1">(</span><span class="hl-7">JSON</span><span class="hl-1">.</span><span class="hl-4">parse</span><span class="hl-1">(</span><span class="hl-2">localStorage</span><span class="hl-1">.</span><span class="hl-4">getItem</span><span class="hl-1">(</span><span class="hl-3">&#39;view&#39;</span><span class="hl-1">)));</span><br/><br/><span class="hl-15">// Persist automatically: stateChanged fires (debounced) after every settled</span><br/><span class="hl-15">// change, and only while something is listening.</span><br/><span class="hl-2">grid</span><span class="hl-1">.</span><span class="hl-4">addEventListener</span><span class="hl-1">(</span><span class="hl-3">&#39;stateChanged&#39;</span><span class="hl-1">, (</span><span class="hl-2">e</span><span class="hl-1">) </span><span class="hl-5">=&gt;</span><br/><span class="hl-1"> </span><span class="hl-2">localStorage</span><span class="hl-1">.</span><span class="hl-4">setItem</span><span class="hl-1">(</span><span class="hl-3">&#39;view&#39;</span><span class="hl-1">, </span><span class="hl-7">JSON</span><span class="hl-1">.</span><span class="hl-4">stringify</span><span class="hl-1">(</span><span class="hl-2">e</span><span class="hl-1">.</span><span class="hl-2">detail</span><span class="hl-1">.</span><span class="hl-2">state</span><span class="hl-1">))</span><br/><span class="hl-1">);</span>
354
+ </code><button type="button">Copy</button></pre>
355
+
356
+ <p><strong>Row identity.</strong> Selection, expansion, pinned rows, and the manual order are captured as row references. Set <code>grid.rowId = (row) =&gt; row.id</code> for durable references that survive a data reload; without it, rows are referenced by position (index), which round-trips within a session but not across a reload.</p>
357
+ <p><strong><code>setState</code> is defensive.</strong> It is meant to accept persisted-and-possibly-stale blobs and AI output, so it never throws on bad input (unless you pass <code>{ strict: true }</code>): unknown columns / operands are dropped, out-of-range pages clamped, unresolvable rows skipped, and a wrong snapshot <code>version</code> applied best-effort. It returns a <code>SetStateResult</code> (<code>{ applied, skipped, warnings }</code>) so you can see exactly what happened. <code>setState</code> is partial: pass only the slices you want to change.</p>
358
+ <p><strong><code>getSchema()</code></strong> returns a machine-readable description of the grid (columns + data types, available sort directions and filter operands per column, grid-level capabilities) with the current state embedded. It is the contract an AI layer feeds an LLM and validates a patch against, but it equally drives a view-editor UI or documentation.</p>
359
+ <p>See <a href="media/state-persistence.html"><code>demo/state-persistence.html</code></a> for a save / restore / live-snapshot example.</p>
242
360
  <hr>
243
361
  <h2 id="api-reference" class="tsd-anchor-link">API Reference<a href="#api-reference" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
244
362
  <h3 id="properties" class="tsd-anchor-link">Properties<a href="#properties" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
@@ -279,13 +397,13 @@
279
397
  <tr>
280
398
  <td><code>dataPipelineConfiguration</code></td>
281
399
  <td><code>DataPipelineConfiguration&lt;T&gt;</code></td>
282
- <td>—</td>
400
+ <td></td>
283
401
  <td>Custom sort/filter/pagination hooks</td>
284
402
  </tr>
285
403
  <tr>
286
404
  <td><code>pagination</code></td>
287
405
  <td><code>PaginationConfiguration</code></td>
288
- <td>—</td>
406
+ <td></td>
289
407
  <td></td>
290
408
  </tr>
291
409
  <tr>
@@ -313,93 +431,141 @@
313
431
  <td>Attr <code>column-reordering</code></td>
314
432
  </tr>
315
433
  <tr>
434
+ <td><code>columnGroups</code></td>
435
+ <td><code>ColumnGroupConfiguration[]</code></td>
436
+ <td></td>
437
+ <td>Spanning header groups (<code>column.group</code> references an <code>id</code>)</td>
438
+ </tr>
439
+ <tr>
316
440
  <td><code>editing</code></td>
317
441
  <td><code>GridEditingConfiguration</code></td>
318
- <td>—</td>
319
442
  <td></td>
443
+ <td>Includes <code>history</code> for undo/redo; per-column <code>validators</code></td>
320
444
  </tr>
321
445
  <tr>
322
446
  <td><code>selection</code></td>
323
447
  <td><code>GridSelectionConfiguration</code></td>
324
- <td>—</td>
448
+ <td></td>
325
449
  <td></td>
326
450
  </tr>
327
451
  <tr>
328
452
  <td><code>expansion</code></td>
329
453
  <td><code>GridExpansionConfiguration&lt;T&gt;</code></td>
330
- <td>—</td>
454
+ <td></td>
331
455
  <td></td>
332
456
  </tr>
333
457
  <tr>
334
458
  <td><code>tree</code></td>
335
459
  <td><code>GridTreeConfiguration&lt;T&gt;</code></td>
336
- <td>—</td>
337
460
  <td></td>
461
+ <td></td>
462
+ </tr>
463
+ <tr>
464
+ <td><code>rowPinning</code></td>
465
+ <td><code>GridRowPinningConfiguration</code></td>
466
+ <td></td>
467
+ <td><code>{ enabled }</code></td>
468
+ </tr>
469
+ <tr>
470
+ <td><code>rowReordering</code></td>
471
+ <td><code>GridRowReorderingConfiguration</code></td>
472
+ <td></td>
473
+ <td><code>{ enabled, applyToData?, handle? }</code> (<code>handle</code> default <code>true</code>: grip-only drag)</td>
474
+ </tr>
475
+ <tr>
476
+ <td><code>coordinateHints</code></td>
477
+ <td><code>boolean</code></td>
478
+ <td><code>false</code></td>
479
+ <td>Show a row-number gutter + A / B / C header chips (spreadsheet look). Attr <code>coordinate-hints</code></td>
480
+ </tr>
481
+ <tr>
482
+ <td><code>columnMenu</code></td>
483
+ <td><code>boolean</code></td>
484
+ <td><code>true</code></td>
485
+ <td>Show the always-visible column-menu (kebab) button on headers; <code>false</code> hides it</td>
486
+ </tr>
487
+ <tr>
488
+ <td><code>rowId</code></td>
489
+ <td><code>(row: T) =&gt; string | number</code></td>
490
+ <td></td>
491
+ <td>Durable row identity for <code>getState</code> / <code>setState</code></td>
492
+ </tr>
493
+ <tr>
494
+ <td><code>localeText</code></td>
495
+ <td><code>GridLocaleText</code></td>
496
+ <td></td>
497
+ <td>Override map for built-in strings (e.g. <code>esLocale</code>)</td>
498
+ </tr>
499
+ <tr>
500
+ <td><code>canUndo</code>, <code>canRedo</code></td>
501
+ <td><code>boolean</code></td>
502
+ <td></td>
503
+ <td>Get (history)</td>
338
504
  </tr>
339
505
  <tr>
340
506
  <td><code>sortExpressions</code></td>
341
507
  <td><code>SortExpression&lt;T&gt;[]</code></td>
342
- <td>—</td>
508
+ <td></td>
343
509
  <td>Get/set</td>
344
510
  </tr>
345
511
  <tr>
346
512
  <td><code>filterExpressions</code></td>
347
513
  <td><code>FilterExpression&lt;T&gt;[]</code></td>
348
- <td>—</td>
514
+ <td></td>
349
515
  <td>Get/set</td>
350
516
  </tr>
351
517
  <tr>
352
518
  <td><code>selectedRows</code></td>
353
519
  <td><code>T[]</code></td>
354
- <td>—</td>
520
+ <td></td>
355
521
  <td>Get/set</td>
356
522
  </tr>
357
523
  <tr>
358
524
  <td><code>expandedRows</code></td>
359
525
  <td><code>T[]</code></td>
360
- <td>—</td>
526
+ <td></td>
361
527
  <td>Get/set</td>
362
528
  </tr>
363
529
  <tr>
364
530
  <td><code>page</code>, <code>pageSize</code>, <code>pageCount</code>, <code>totalItems</code></td>
365
531
  <td><code>number</code></td>
366
- <td>—</td>
532
+ <td></td>
367
533
  <td></td>
368
534
  </tr>
369
535
  <tr>
370
536
  <td><code>pageItems</code></td>
371
537
  <td><code>readonly T[]</code></td>
372
- <td>—</td>
538
+ <td></td>
373
539
  <td>Currently rendered slice</td>
374
540
  </tr>
375
541
  <tr>
376
542
  <td><code>dataView</code></td>
377
543
  <td><code>readonly T[]</code></td>
378
- <td>—</td>
544
+ <td></td>
379
545
  <td>Post-filter, post-sort</td>
380
546
  </tr>
381
547
  <tr>
382
548
  <td><code>displayColumns</code></td>
383
549
  <td><code>readonly ColumnConfiguration&lt;T&gt;[]</code></td>
384
- <td>—</td>
550
+ <td></td>
385
551
  <td>Render order (pinned start → unpinned → pinned end)</td>
386
552
  </tr>
387
553
  <tr>
388
554
  <td><code>editingCell</code></td>
389
555
  <td><code>{ rowIndex, columnKey } | null</code></td>
390
- <td>—</td>
556
+ <td></td>
391
557
  <td></td>
392
558
  </tr>
393
559
  <tr>
394
560
  <td><code>editingRow</code></td>
395
561
  <td><code>number | null</code></td>
396
- <td>—</td>
562
+ <td></td>
397
563
  <td>Row-mode only</td>
398
564
  </tr>
399
565
  </tbody>
400
566
  </table>
401
567
  <h3 id="methods" class="tsd-anchor-link">Methods<a href="#methods" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
402
- <pre><code class="ts"><span class="hl-4">sort</span><span class="hl-1">(</span><span class="hl-2">expr</span><span class="hl-1">): </span><span class="hl-5">void</span><br/><span class="hl-4">filter</span><span class="hl-1">(</span><span class="hl-2">expr</span><span class="hl-1">): </span><span class="hl-5">void</span><br/><span class="hl-4">clearSort</span><span class="hl-1">(</span><span class="hl-2">key</span><span class="hl-1">?): </span><span class="hl-5">void</span><br/><span class="hl-4">clearFilter</span><span class="hl-1">(</span><span class="hl-2">key</span><span class="hl-1">?): </span><span class="hl-5">void</span><br/><span class="hl-4">setQuickFilter</span><span class="hl-1">(</span><span class="hl-2">value</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><br/><span class="hl-4">getColumn</span><span class="hl-1">(</span><span class="hl-2">keyOrIndex</span><span class="hl-1">): </span><span class="hl-2">ColumnConfiguration</span><span class="hl-1">&lt;</span><span class="hl-7">T</span><span class="hl-1">&gt; | </span><span class="hl-5">undefined</span><br/><span class="hl-4">updateColumns</span><span class="hl-1">(</span><span class="hl-2">columns</span><span class="hl-1">): </span><span class="hl-5">void</span><br/><span class="hl-4">pinColumn</span><span class="hl-1">(</span><span class="hl-2">key</span><span class="hl-1">, </span><span class="hl-3">&#39;start&#39;</span><span class="hl-1"> | </span><span class="hl-3">&#39;end&#39;</span><span class="hl-1"> | </span><span class="hl-5">null</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">unpinColumn</span><span class="hl-1">(</span><span class="hl-2">key</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">moveColumn</span><span class="hl-1">(</span><span class="hl-2">fromKey</span><span class="hl-1">, </span><span class="hl-2">toKey</span><span class="hl-1">, </span><span class="hl-3">&#39;before&#39;</span><span class="hl-1"> | </span><span class="hl-3">&#39;after&#39;</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><br/><span class="hl-4">gotoPage</span><span class="hl-1">(</span><span class="hl-2">page</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">setPageSize</span><span class="hl-1">(</span><span class="hl-2">size</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">nextPage</span><span class="hl-1">(); </span><span class="hl-4">previousPage</span><span class="hl-1">(); </span><span class="hl-4">firstPage</span><span class="hl-1">(); </span><span class="hl-4">lastPage</span><span class="hl-1">()</span><br/><br/><span class="hl-4">editCell</span><span class="hl-1">(</span><span class="hl-2">rowIndex</span><span class="hl-1">, </span><span class="hl-2">columnKey</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">editRow</span><span class="hl-1">(</span><span class="hl-2">rowIndex</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">commitEdit</span><span class="hl-1">(): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">cancelEdit</span><span class="hl-1">(): </span><span class="hl-5">void</span><br/><br/><span class="hl-4">selectRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">); </span><span class="hl-4">deselectRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">); </span><span class="hl-4">toggleRowSelection</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">)</span><br/><span class="hl-4">selectAllRows</span><span class="hl-1">(); </span><span class="hl-4">clearSelection</span><span class="hl-1">(); </span><span class="hl-4">isRowSelected</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">)</span><br/><br/><span class="hl-4">expandRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">); </span><span class="hl-4">collapseRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">); </span><span class="hl-4">toggleRowExpansion</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">)</span><br/><span class="hl-4">expandAllRows</span><span class="hl-1">(); </span><span class="hl-4">collapseAllRows</span><span class="hl-1">(); </span><span class="hl-4">isRowExpanded</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">)</span><br/><br/><span class="hl-4">toggleTreeRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">); </span><span class="hl-4">expandTreeRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">); </span><span class="hl-4">collapseTreeRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">)</span><br/><span class="hl-4">expandAllTreeRows</span><span class="hl-1">(); </span><span class="hl-4">collapseAllTreeRows</span><span class="hl-1">(); </span><span class="hl-4">isTreeRowExpanded</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">)</span><br/><br/><span class="hl-4">exportToCSV</span><span class="hl-1">(</span><span class="hl-2">options</span><span class="hl-1">?): </span><span class="hl-2">string</span><br/><span class="hl-4">exportAs</span><span class="hl-1">(</span><span class="hl-2">formatId</span><span class="hl-1">, </span><span class="hl-2">options</span><span class="hl-1">?): </span><span class="hl-5">void</span><span class="hl-1"> </span><span class="hl-15">// toolbar dispatch; &#39;csv&#39; (community), &#39;xlsx&#39; (enterprise)</span>
568
+ <pre><code class="ts"><span class="hl-4">sort</span><span class="hl-1">(</span><span class="hl-2">expr</span><span class="hl-1">): </span><span class="hl-5">void</span><br/><span class="hl-4">filter</span><span class="hl-1">(</span><span class="hl-2">expr</span><span class="hl-1">): </span><span class="hl-5">void</span><br/><span class="hl-4">clearSort</span><span class="hl-1">(</span><span class="hl-2">key</span><span class="hl-1">?): </span><span class="hl-5">void</span><br/><span class="hl-4">clearFilter</span><span class="hl-1">(</span><span class="hl-2">key</span><span class="hl-1">?): </span><span class="hl-5">void</span><br/><span class="hl-4">setQuickFilter</span><span class="hl-1">(</span><span class="hl-2">value</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><br/><span class="hl-4">getColumn</span><span class="hl-1">(</span><span class="hl-2">keyOrIndex</span><span class="hl-1">): </span><span class="hl-2">ColumnConfiguration</span><span class="hl-1">&lt;</span><span class="hl-7">T</span><span class="hl-1">&gt; | </span><span class="hl-5">undefined</span><br/><span class="hl-4">updateColumns</span><span class="hl-1">(</span><span class="hl-2">columns</span><span class="hl-1">): </span><span class="hl-5">void</span><br/><span class="hl-4">pinColumn</span><span class="hl-1">(</span><span class="hl-2">key</span><span class="hl-1">, </span><span class="hl-3">&#39;start&#39;</span><span class="hl-1"> | </span><span class="hl-3">&#39;end&#39;</span><span class="hl-1"> | </span><span class="hl-5">null</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">unpinColumn</span><span class="hl-1">(</span><span class="hl-2">key</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">moveColumn</span><span class="hl-1">(</span><span class="hl-2">fromKey</span><span class="hl-1">, </span><span class="hl-2">toKey</span><span class="hl-1">, </span><span class="hl-3">&#39;before&#39;</span><span class="hl-1"> | </span><span class="hl-3">&#39;after&#39;</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><br/><span class="hl-4">gotoPage</span><span class="hl-1">(</span><span class="hl-2">page</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">setPageSize</span><span class="hl-1">(</span><span class="hl-2">size</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">nextPage</span><span class="hl-1">(); </span><span class="hl-4">previousPage</span><span class="hl-1">(); </span><span class="hl-4">firstPage</span><span class="hl-1">(); </span><span class="hl-4">lastPage</span><span class="hl-1">()</span><br/><br/><span class="hl-4">editCell</span><span class="hl-1">(</span><span class="hl-2">rowIndex</span><span class="hl-1">, </span><span class="hl-2">columnKey</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">editRow</span><span class="hl-1">(</span><span class="hl-2">rowIndex</span><span class="hl-1">): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">commitEdit</span><span class="hl-1">(): </span><span class="hl-6">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">boolean</span><span class="hl-1">&gt;</span><br/><span class="hl-4">cancelEdit</span><span class="hl-1">(): </span><span class="hl-5">void</span><br/><br/><span class="hl-4">selectRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">); </span><span class="hl-4">deselectRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">); </span><span class="hl-4">toggleRowSelection</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">)</span><br/><span class="hl-4">selectAllRows</span><span class="hl-1">(); </span><span class="hl-4">clearSelection</span><span class="hl-1">(); </span><span class="hl-4">isRowSelected</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">)</span><br/><br/><span class="hl-4">expandRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">); </span><span class="hl-4">collapseRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">); </span><span class="hl-4">toggleRowExpansion</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">)</span><br/><span class="hl-4">expandAllRows</span><span class="hl-1">(); </span><span class="hl-4">collapseAllRows</span><span class="hl-1">(); </span><span class="hl-4">isRowExpanded</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">)</span><br/><br/><span class="hl-4">toggleTreeRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">); </span><span class="hl-4">expandTreeRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">); </span><span class="hl-4">collapseTreeRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">)</span><br/><span class="hl-4">expandAllTreeRows</span><span class="hl-1">(); </span><span class="hl-4">collapseAllTreeRows</span><span class="hl-1">(); </span><span class="hl-4">isTreeRowExpanded</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">)</span><br/><br/><span class="hl-4">pinRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">, </span><span class="hl-3">&#39;top&#39;</span><span class="hl-1"> | </span><span class="hl-3">&#39;bottom&#39;</span><span class="hl-1">); </span><span class="hl-4">unpinRow</span><span class="hl-1">(</span><span class="hl-2">row</span><span class="hl-1">) </span><span class="hl-15">// pinnedRows getter</span><br/><span class="hl-4">moveRow</span><span class="hl-1">(</span><span class="hl-2">from</span><span class="hl-1">, </span><span class="hl-2">to</span><span class="hl-1">, </span><span class="hl-3">&#39;before&#39;</span><span class="hl-1"> | </span><span class="hl-3">&#39;after&#39;</span><span class="hl-1">)</span><br/><br/><span class="hl-4">undo</span><span class="hl-1">(); </span><span class="hl-4">redo</span><span class="hl-1">(); </span><span class="hl-4">clearHistory</span><span class="hl-1">() </span><span class="hl-15">// canUndo / canRedo getters</span><br/><br/><span class="hl-4">localize</span><span class="hl-1">(</span><span class="hl-2">key</span><span class="hl-1">, </span><span class="hl-2">params</span><span class="hl-1">?, </span><span class="hl-2">fallback</span><span class="hl-1">?): </span><span class="hl-2">string</span><span class="hl-1"> </span><span class="hl-15">// resolve a locale string</span><br/><br/><span class="hl-4">exportToCSV</span><span class="hl-1">(</span><span class="hl-2">options</span><span class="hl-1">?): </span><span class="hl-2">string</span><br/><span class="hl-4">exportAs</span><span class="hl-1">(</span><span class="hl-2">formatId</span><span class="hl-1">, </span><span class="hl-2">options</span><span class="hl-1">?): </span><span class="hl-5">void</span><span class="hl-1"> </span><span class="hl-15">// toolbar dispatch; &#39;csv&#39; (community), &#39;xlsx&#39; (enterprise)</span><br/><br/><span class="hl-4">getState</span><span class="hl-1">(</span><span class="hl-2">options</span><span class="hl-1">?): </span><span class="hl-2">GridState</span><br/><span class="hl-4">setState</span><span class="hl-1">(</span><span class="hl-2">state</span><span class="hl-1">, </span><span class="hl-2">options</span><span class="hl-1">?): </span><span class="hl-2">SetStateResult</span><span class="hl-1"> </span><span class="hl-15">// partial + defensive; never throws unless { strict: true }</span><br/><span class="hl-4">getSchema</span><span class="hl-1">(): </span><span class="hl-2">GridSchema</span><span class="hl-1"> </span><span class="hl-15">// machine-readable capability descriptor</span>
403
569
  </code><button type="button">Copy</button></pre>
404
570
 
405
571
  <h3 id="events" class="tsd-anchor-link">Events<a href="#events" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
@@ -449,16 +615,36 @@
449
615
  <td><code>{ row, column, value, newValue }</code></td>
450
616
  </tr>
451
617
  <tr>
618
+ <td><code>cellValidationFailed</code></td>
619
+ <td>no</td>
620
+ <td><code>{ key, rowIndex, data, value, errors }</code></td>
621
+ </tr>
622
+ <tr>
452
623
  <td><code>rowEditStarted</code> / <code>rowEditEnded</code></td>
453
624
  <td>no / no</td>
454
625
  <td>row context</td>
455
626
  </tr>
456
627
  <tr>
628
+ <td><code>historyChanged</code></td>
629
+ <td>no</td>
630
+ <td><code>{ canUndo, canRedo }</code></td>
631
+ </tr>
632
+ <tr>
457
633
  <td><code>rowSelecting</code> / <code>rowSelected</code></td>
458
634
  <td>yes / no</td>
459
635
  <td><code>{ added, removed }</code></td>
460
636
  </tr>
461
637
  <tr>
638
+ <td><code>rowPinning</code> / <code>rowPinned</code></td>
639
+ <td>yes / no</td>
640
+ <td><code>{ row, position }</code></td>
641
+ </tr>
642
+ <tr>
643
+ <td><code>rowMoving</code> / <code>rowMoved</code></td>
644
+ <td>yes / no</td>
645
+ <td><code>{ from, to, data }</code></td>
646
+ </tr>
647
+ <tr>
462
648
  <td><code>rowExpanding</code> / <code>rowExpanded</code></td>
463
649
  <td>yes / no</td>
464
650
  <td>row context</td>
@@ -468,11 +654,16 @@
468
654
  <td>yes / no</td>
469
655
  <td>row context</td>
470
656
  </tr>
657
+ <tr>
658
+ <td><code>stateChanged</code></td>
659
+ <td>no</td>
660
+ <td><code>{ state }</code> (debounced; only while listened)</td>
661
+ </tr>
471
662
  </tbody>
472
663
  </table>
473
- <p>Programmatic <code>sort()</code> / <code>filter()</code> calls are silent — only UI-initiated changes emit <code>sorting</code> / <code>filtering</code>.</p>
664
+ <p>Programmatic <code>sort()</code> / <code>filter()</code> calls are silent; only UI-initiated changes emit <code>sorting</code> / <code>filtering</code>.</p>
474
665
  <h3 id="attributes" class="tsd-anchor-link">Attributes<a href="#attributes" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
475
- <p><code>auto-generate</code>, <code>quick-filter</code>, <code>show-quick-filter</code>, <code>show-export</code>, <code>column-reordering</code>.</p>
666
+ <p><code>auto-generate</code>, <code>quick-filter</code>, <code>show-quick-filter</code>, <code>show-export</code>, <code>column-reordering</code>, <code>coordinate-hints</code>.</p>
476
667
  <h3 id="css-parts" class="tsd-anchor-link">CSS parts<a href="#css-parts" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
477
668
  <table>
478
669
  <thead>
@@ -537,12 +728,12 @@
537
728
  <h2 id="releasing" class="tsd-anchor-link">Releasing<a href="#releasing" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
538
729
  <p>Releases are automated by <a href=".github/workflows/publish.yml">.github/workflows/publish.yml</a>:</p>
539
730
  <ol>
540
- <li>Bump <code>&quot;version&quot;</code> in <a href="media/package.json">package.json</a> — the single source of truth. The build injects it into <code>dist/package.json</code>.</li>
731
+ <li>Bump <code>&quot;version&quot;</code> in <a href="media/package.json">package.json</a>, the single source of truth. The build injects it into <code>dist/package.json</code>.</li>
541
732
  <li>Commit with a message starting with <code>release:</code> and the same version, e.g. <code>release: 2.0.0</code> or <code>release: 2.0.0-rc.1</code>.</li>
542
733
  <li>Push to <code>main</code>.</li>
543
734
  </ol>
544
- <p>The workflow then verifies the version triple-match, runs lint + tests + build, publishes <code>dist/</code> to npm with <code>--provenance</code> (OIDC trusted publishing — no token in secrets), and creates a <code>vX.Y.Z</code> git tag and GitHub Release with auto-generated notes. Pre-release versions (containing <code>-</code>) publish under the <code>next</code> dist-tag; stable versions under <code>latest</code>.</p>
735
+ <p>The workflow then verifies the version triple-match, runs lint + tests + build, publishes <code>dist/</code> to npm with <code>--provenance</code> (OIDC trusted publishing, no token in secrets), and creates a <code>vX.Y.Z</code> git tag and GitHub Release with auto-generated notes. Pre-release versions (containing <code>-</code>) publish under the <code>next</code> dist-tag; stable versions under <code>latest</code>.</p>
545
736
  <p>Any push whose head commit does not start with <code>release:</code> is a no-op for the workflow.</p>
546
737
  <h2 id="license" class="tsd-anchor-link">License<a href="#license" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
547
738
  <p>See <a href="media/LICENSE">LICENSE</a>.</p>
548
- </div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#apex-grid"><span>Apex <wbr/>Grid</span></a><ul><li><a href="#features"><span>Features</span></a></li><li><a href="#quick-start"><span>Quick <wbr/>Start</span></a></li><li><ul><li><a href="#one-call-setup"><span>One-<wbr/>call setup</span></a></li><li><a href="#render-the-grid"><span>Render the grid</span></a></li></ul></li><li><a href="#manual-setup-four-steps"><span>Manual setup (four steps)</span></a></li><li><ul><li><a href="#1-install"><span>1. <wbr/>Install</span></a></li><li><a href="#2-register-the-custom-element"><span>2. <wbr/>Register the custom element</span></a></li><li><a href="#3-optional-customize-the-look"><span>3. (<wbr/>Optional) <wbr/>Customize the look</span></a></li><li><a href="#4-size-the-host"><span>4. <wbr/>Size the host</span></a></li><li><a href="#what-success-looks-like"><span>What success looks like</span></a></li><li><a href="#troubleshooting"><span>Troubleshooting</span></a></li></ul></li><li><a href="#features-in-depth"><span>Features in depth</span></a></li><li><ul><li><a href="#sorting"><span>Sorting</span></a></li><li><a href="#filtering"><span>Filtering</span></a></li><li><a href="#quick-filter-global-search"><span>Quick filter (global search)</span></a></li><li><a href="#pagination"><span>Pagination</span></a></li><li><a href="#column-pinning"><span>Column pinning</span></a></li><li><a href="#column-reordering"><span>Column reordering</span></a></li><li><a href="#inline-editing"><span>Inline editing</span></a></li><li><a href="#row-selection"><span>Row selection</span></a></li><li><a href="#row-expansion-master-detail"><span>Row expansion (master-<wbr/>detail)</span></a></li><li><a href="#tree-data-nested-rows"><span>Tree data (nested rows)</span></a></li><li><a href="#csv-export"><span>CSV export</span></a></li><li><a href="#toolbar"><span>Toolbar</span></a></li><li><a href="#theming"><span>Theming</span></a></li></ul></li><li><a href="#api-reference"><span>API <wbr/>Reference</span></a></li><li><ul><li><a href="#properties"><span>Properties</span></a></li><li><a href="#methods"><span>Methods</span></a></li><li><a href="#events"><span>Events</span></a></li><li><a href="#attributes"><span>Attributes</span></a></li><li><a href="#css-parts"><span>CSS parts</span></a></li></ul></li><li><a href="#framework-integration"><span>Framework integration</span></a></li><li><a href="#local-development"><span>Local development</span></a></li><li><a href="#releasing"><span>Releasing</span></a></li><li><a href="#license"><span>License</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">apex-grid</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
739
+ </div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#apex-grid"><span>Apex <wbr/>Grid</span></a><ul><li><a href="#features"><span>Features</span></a></li><li><a href="#quick-start"><span>Quick <wbr/>Start</span></a></li><li><ul><li><a href="#one-call-setup"><span>One-<wbr/>call setup</span></a></li><li><a href="#render-the-grid"><span>Render the grid</span></a></li></ul></li><li><a href="#manual-setup-four-steps"><span>Manual setup (four steps)</span></a></li><li><ul><li><a href="#1-install"><span>1. <wbr/>Install</span></a></li><li><a href="#2-register-the-custom-element"><span>2. <wbr/>Register the custom element</span></a></li><li><a href="#3-optional-customize-the-look"><span>3. (<wbr/>Optional) <wbr/>Customize the look</span></a></li><li><a href="#4-size-the-host"><span>4. <wbr/>Size the host</span></a></li><li><a href="#what-success-looks-like"><span>What success looks like</span></a></li><li><a href="#troubleshooting"><span>Troubleshooting</span></a></li></ul></li><li><a href="#features-in-depth"><span>Features in depth</span></a></li><li><ul><li><a href="#sorting"><span>Sorting</span></a></li><li><a href="#filtering"><span>Filtering</span></a></li><li><a href="#quick-filter-global-search"><span>Quick filter (global search)</span></a></li><li><a href="#pagination"><span>Pagination</span></a></li><li><a href="#column-pinning"><span>Column pinning</span></a></li><li><a href="#column-reordering"><span>Column reordering</span></a></li><li><a href="#column-separators"><span>Column separators</span></a></li><li><a href="#column-groups-spanning-headers"><span>Column groups (spanning headers)</span></a></li><li><a href="#inline-editing"><span>Inline editing</span></a></li><li><a href="#keyboard-navigation-and-accessibility"><span>Keyboard navigation and accessibility</span></a></li><li><a href="#cell-validation"><span>Cell validation</span></a></li><li><a href="#undo-redo"><span>Undo / redo</span></a></li><li><a href="#row-selection"><span>Row selection</span></a></li><li><a href="#row-pinning-top-bottom"><span>Row pinning (top / bottom)</span></a></li><li><a href="#row-drag-reorder"><span>Row drag-<wbr/>reorder</span></a></li><li><a href="#row-expansion-master-detail"><span>Row expansion (master-<wbr/>detail)</span></a></li><li><a href="#tree-data-nested-rows"><span>Tree data (nested rows)</span></a></li><li><a href="#csv-export"><span>CSV export</span></a></li><li><a href="#toolbar"><span>Toolbar</span></a></li><li><a href="#theming"><span>Theming</span></a></li><li><a href="#spreadsheet-coordinates"><span>Spreadsheet coordinates</span></a></li><li><a href="#state-persistence"><span>State &amp; persistence</span></a></li></ul></li><li><a href="#api-reference"><span>API <wbr/>Reference</span></a></li><li><ul><li><a href="#properties"><span>Properties</span></a></li><li><a href="#methods"><span>Methods</span></a></li><li><a href="#events"><span>Events</span></a></li><li><a href="#attributes"><span>Attributes</span></a></li><li><a href="#css-parts"><span>CSS parts</span></a></li></ul></li><li><a href="#framework-integration"><span>Framework integration</span></a></li><li><a href="#local-development"><span>Local development</span></a></li><li><a href="#releasing"><span>Releasing</span></a></li><li><a href="#license"><span>License</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">apex-grid</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>