apex-grid 3.4.0 → 3.6.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 (217) hide show
  1. package/CHANGELOG.md +439 -0
  2. package/LICENSE.md +125 -0
  3. package/README.md +107 -14
  4. package/components/cell.d.ts +30 -4
  5. package/components/cell.js +199 -53
  6. package/components/cell.js.map +1 -1
  7. package/components/filter-row.d.ts +2 -0
  8. package/components/filter-row.js +82 -28
  9. package/components/filter-row.js.map +1 -1
  10. package/components/grid.d.ts +257 -20
  11. package/components/grid.js +463 -99
  12. package/components/grid.js.map +1 -1
  13. package/components/group-header-row.js +28 -25
  14. package/components/group-header-row.js.map +1 -1
  15. package/components/header-row.d.ts +7 -5
  16. package/components/header-row.js +19 -9
  17. package/components/header-row.js.map +1 -1
  18. package/components/header.js +36 -22
  19. package/components/header.js.map +1 -1
  20. package/components/row.d.ts +19 -3
  21. package/components/row.js +96 -22
  22. package/components/row.js.map +1 -1
  23. package/components/toolbar.js +2 -1
  24. package/components/toolbar.js.map +1 -1
  25. package/components/virtualizer.d.ts +45 -1
  26. package/components/virtualizer.js +184 -3
  27. package/components/virtualizer.js.map +1 -1
  28. package/controllers/dom.d.ts +4 -4
  29. package/controllers/dom.js +40 -22
  30. package/controllers/dom.js.map +1 -1
  31. package/controllers/editing.d.ts +104 -37
  32. package/controllers/editing.js +230 -78
  33. package/controllers/editing.js.map +1 -1
  34. package/controllers/expansion.d.ts +14 -5
  35. package/controllers/expansion.js +24 -1
  36. package/controllers/expansion.js.map +1 -1
  37. package/controllers/filter.d.ts +10 -2
  38. package/controllers/filter.js +62 -17
  39. package/controllers/filter.js.map +1 -1
  40. package/controllers/history.d.ts +45 -8
  41. package/controllers/history.js +58 -20
  42. package/controllers/history.js.map +1 -1
  43. package/controllers/navigation.d.ts +68 -13
  44. package/controllers/navigation.js +196 -51
  45. package/controllers/navigation.js.map +1 -1
  46. package/controllers/pagination.d.ts +6 -0
  47. package/controllers/pagination.js +10 -2
  48. package/controllers/pagination.js.map +1 -1
  49. package/controllers/reorder.js +42 -24
  50. package/controllers/reorder.js.map +1 -1
  51. package/controllers/resize.d.ts +17 -2
  52. package/controllers/resize.js +16 -6
  53. package/controllers/resize.js.map +1 -1
  54. package/controllers/row-pin.d.ts +20 -2
  55. package/controllers/row-pin.js +16 -9
  56. package/controllers/row-pin.js.map +1 -1
  57. package/controllers/row-reorder.d.ts +31 -11
  58. package/controllers/row-reorder.js +117 -37
  59. package/controllers/row-reorder.js.map +1 -1
  60. package/controllers/selection.d.ts +11 -4
  61. package/controllers/selection.js +26 -11
  62. package/controllers/selection.js.map +1 -1
  63. package/controllers/sort.d.ts +22 -2
  64. package/controllers/sort.js +29 -23
  65. package/controllers/sort.js.map +1 -1
  66. package/controllers/state.d.ts +65 -10
  67. package/controllers/state.js +86 -6
  68. package/controllers/state.js.map +1 -1
  69. package/controllers/tree.d.ts +15 -10
  70. package/controllers/tree.js +0 -0
  71. package/controllers/tree.js.map +1 -1
  72. package/custom-elements.json +3589 -452
  73. package/docs/assets/hierarchy.js +1 -1
  74. package/docs/assets/highlight.css +15 -8
  75. package/docs/assets/navigation.js +1 -1
  76. package/docs/assets/search.js +1 -1
  77. package/docs/classes/ApexGrid.html +660 -0
  78. package/docs/classes/ApexGridPaginator.html +36 -0
  79. package/docs/classes/ApexGridToolbar.html +67 -0
  80. package/docs/functions/localize.html +2 -2
  81. package/docs/functions/setup.html +1 -2
  82. package/docs/hierarchy.html +1 -1
  83. package/docs/index.html +105 -15
  84. package/docs/interfaces/ApexCellValidationFailedEvent.html +3 -2
  85. package/docs/interfaces/ApexCellValueChangedEvent.html +4 -2
  86. package/docs/interfaces/ApexCellValueChangingEvent.html +3 -2
  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 +9 -6
  91. package/docs/interfaces/ApexRowEditEndedEvent.html +2 -1
  92. package/docs/interfaces/ApexRowEditStartedEvent.html +2 -1
  93. package/docs/interfaces/ApexRowMovingEvent.html +9 -3
  94. package/docs/interfaces/ApexRowPinningEvent.html +1 -1
  95. package/docs/interfaces/ApexTreeRowExpandedEvent.html +4 -1
  96. package/docs/interfaces/ApexTreeRowExpandingEvent.html +4 -1
  97. package/docs/interfaces/BaseApexCellContext.html +1 -1
  98. package/docs/interfaces/BaseApexEditorContext.html +1 -1
  99. package/docs/interfaces/BaseColumnConfiguration.html +3 -3
  100. package/docs/interfaces/BaseFilterExpression.html +2 -2
  101. package/docs/interfaces/CSVExportOptions.html +13 -5
  102. package/docs/interfaces/DataPipelineConfiguration.html +2 -2
  103. package/docs/interfaces/EditingHistoryConfiguration.html +1 -1
  104. package/docs/interfaces/ExportFormat.html +2 -2
  105. package/docs/interfaces/ExportOptions.html +5 -3
  106. package/docs/interfaces/GridExpansionConfiguration.html +6 -2
  107. package/docs/interfaces/GridRowPinningConfiguration.html +1 -1
  108. package/docs/interfaces/GridRowReorderingConfiguration.html +2 -2
  109. package/docs/interfaces/PaginationConfiguration.html +1 -1
  110. package/docs/interfaces/PaginationState.html +1 -1
  111. package/docs/interfaces/SetStateResult.html +3 -2
  112. package/docs/interfaces/ValidatorContext.html +7 -2
  113. package/docs/media/_token-values.scss +118 -0
  114. package/docs/media/package.json +5 -5
  115. package/docs/media/state-persistence.html +0 -10
  116. package/docs/modules.html +1 -1
  117. package/docs/types/DataPipelineParams.html +2 -2
  118. package/docs/types/EditMode.html +2 -2
  119. package/docs/types/ExportSource.html +6 -4
  120. package/docs/types/GridLocaleText.html +1 -1
  121. package/docs/types/OperandKeys.html +9 -0
  122. package/docs/types/PaginationMode.html +1 -1
  123. package/docs/variables/EN_LOCALE.html +3 -3
  124. package/docs/variables/esLocale.html +1 -1
  125. package/i18n/en.d.ts +19 -0
  126. package/i18n/en.js +19 -0
  127. package/i18n/en.js.map +1 -1
  128. package/i18n/es.js +19 -0
  129. package/i18n/es.js.map +1 -1
  130. package/index.d.ts +2 -0
  131. package/index.js +2 -0
  132. package/index.js.map +1 -1
  133. package/internal/column-types.d.ts +27 -1
  134. package/internal/column-types.js +75 -49
  135. package/internal/column-types.js.map +1 -1
  136. package/internal/constants.d.ts +1 -2
  137. package/internal/constants.js +0 -4
  138. package/internal/constants.js.map +1 -1
  139. package/internal/document-styles.d.ts +30 -0
  140. package/internal/document-styles.js +48 -0
  141. package/internal/document-styles.js.map +1 -0
  142. package/internal/export.d.ts +39 -7
  143. package/internal/export.js +35 -34
  144. package/internal/export.js.map +1 -1
  145. package/internal/feature-module.d.ts +82 -3
  146. package/internal/feature-module.js +11 -0
  147. package/internal/feature-module.js.map +1 -1
  148. package/internal/index.d.ts +6 -4
  149. package/internal/index.js +5 -3
  150. package/internal/index.js.map +1 -1
  151. package/internal/normalize-case.d.ts +8 -1
  152. package/internal/normalize-case.js +3 -2
  153. package/internal/normalize-case.js.map +1 -1
  154. package/internal/state-snapshot.d.ts +60 -8
  155. package/internal/state-snapshot.js +87 -19
  156. package/internal/state-snapshot.js.map +1 -1
  157. package/internal/types.d.ts +17 -2
  158. package/internal/types.js.map +1 -1
  159. package/internal/utils.d.ts +48 -6
  160. package/internal/utils.js +35 -21
  161. package/internal/utils.js.map +1 -1
  162. package/internal/validators.js +1 -0
  163. package/internal/validators.js.map +1 -1
  164. package/operations/filter/operands/number.js +9 -6
  165. package/operations/filter/operands/number.js.map +1 -1
  166. package/operations/filter/operands/string.js +2 -3
  167. package/operations/filter/operands/string.js.map +1 -1
  168. package/operations/filter/types.d.ts +13 -1
  169. package/operations/filter/types.js.map +1 -1
  170. package/operations/filter.d.ts +6 -0
  171. package/operations/filter.js +23 -7
  172. package/operations/filter.js.map +1 -1
  173. package/operations/quick-filter.js +2 -5
  174. package/operations/quick-filter.js.map +1 -1
  175. package/operations/sort.d.ts +21 -2
  176. package/operations/sort.js +41 -14
  177. package/operations/sort.js.map +1 -1
  178. package/package.json +8 -4
  179. package/setup.d.ts +23 -11
  180. package/setup.js +19 -21
  181. package/setup.js.map +1 -1
  182. package/styles/_common.css.js +1 -1
  183. package/styles/_common.css.js.map +1 -1
  184. package/styles/_token-values.css.d.ts +1 -0
  185. package/styles/_token-values.css.js +3 -0
  186. package/styles/_token-values.css.js.map +1 -0
  187. package/styles/_tokens.css.js +1 -1
  188. package/styles/_tokens.css.js.map +1 -1
  189. package/styles/body-cell/body-cell.css.js +1 -1
  190. package/styles/body-cell/body-cell.css.js.map +1 -1
  191. package/styles/body-cell/cell-renderers.css.js +1 -1
  192. package/styles/body-cell/cell-renderers.css.js.map +1 -1
  193. package/styles/body-row/body-row.css.js +1 -1
  194. package/styles/body-row/body-row.css.js.map +1 -1
  195. package/styles/document-tokens.css.d.ts +1 -0
  196. package/styles/document-tokens.css.js +3 -0
  197. package/styles/document-tokens.css.js.map +1 -0
  198. package/styles/filter-row/filter-row.css.js +1 -1
  199. package/styles/filter-row/filter-row.css.js.map +1 -1
  200. package/styles/grid/_grid.base.css.js +1 -1
  201. package/styles/grid/_grid.base.css.js.map +1 -1
  202. package/styles/grid/grid.css.js +1 -1
  203. package/styles/grid/grid.css.js.map +1 -1
  204. package/styles/group-header-row/group-header-row.css.js +1 -1
  205. package/styles/group-header-row/group-header-row.css.js.map +1 -1
  206. package/styles/header-cell/header-cell.css.js +1 -1
  207. package/styles/header-cell/header-cell.css.js.map +1 -1
  208. package/styles/header-row/header-row.base.css.js +1 -1
  209. package/styles/header-row/header-row.base.css.js.map +1 -1
  210. package/styles/paginator/paginator.css.js +1 -1
  211. package/styles/paginator/paginator.css.js.map +1 -1
  212. package/styles/toolbar/toolbar.css.js +1 -1
  213. package/styles/toolbar/toolbar.css.js.map +1 -1
  214. package/tokens.css +78 -0
  215. package/LICENSE +0 -80
  216. package/docs/media/LICENSE +0 -80
  217. package/docs/media/_tokens.scss +0 -193
@@ -1 +1 @@
1
- {"version":3,"file":"row-pin.js","sourceRoot":"","sources":["../../src/controllers/row-pin.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport type { GridHost } from '../internal/types.js';\n\n/** Where a row is pinned, or `null` when it scrolls with the body. */\nexport type RowPinPosition = 'top' | 'bottom';\n\n/**\n * Reactive controller backing row pinning.\n *\n * @remarks\n * Pinned rows are lifted out of the scrollable body and rendered in sticky\n * bands above (`'top'`) or below (`'bottom'`) the virtualized rows. State is\n * reference-based: the controller holds a `Set` of row data references per band,\n * so pins survive sort / filter / pagination as long as those preserve row\n * identity (the default in-place pipeline does). Replacing {@link ApexGrid.data}\n * wholesale should be followed by re-pinning or {@link clear}.\n *\n * Mutations go through the cancellable `rowPinning` event and emit a follow-up\n * `rowPinned` event, mirroring selection / expansion.\n */\nexport class RowPinController<T extends object> implements ReactiveController {\n #top: Set<T> = new Set();\n #bottom: Set<T> = new Set();\n\n constructor(protected host: GridHost<T>) {\n this.host.addController(this);\n }\n\n public hostConnected() {}\n\n /** Whether row pinning is enabled at the grid level. */\n public get enabled(): boolean {\n return Boolean(this.host.rowPinning?.enabled);\n }\n\n /** Whether any row is currently pinned. */\n public get hasPinnedRows(): boolean {\n return this.#top.size > 0 || this.#bottom.size > 0;\n }\n\n /** The band `row` is pinned to, or `null` when it is not pinned. */\n public pinnedPosition(row: T): RowPinPosition | null {\n if (this.#top.has(row)) return 'top';\n if (this.#bottom.has(row)) return 'bottom';\n return null;\n }\n\n /** Whether `row` is pinned to either band. */\n public isPinned(row: T): boolean {\n return this.#top.has(row) || this.#bottom.has(row);\n }\n\n /** Pinned rows per band, in the order they were pinned. */\n public get pinnedRows(): { top: T[]; bottom: T[] } {\n return { top: [...this.#top], bottom: [...this.#bottom] };\n }\n\n /**\n * Pins `row` to the given band. Moves it between bands when already pinned\n * elsewhere. No-op (returns `true`) when it is already pinned there.\n *\n * @returns `true` when applied, `false` when disabled or cancelled.\n */\n public pinRow(row: T, position: RowPinPosition): boolean {\n if (!this.enabled) return false;\n if (this.pinnedPosition(row) === position) return true;\n if (!this.#emitPinning(row, position)) return false;\n\n this.#top.delete(row);\n this.#bottom.delete(row);\n (position === 'top' ? this.#top : this.#bottom).add(row);\n this.#commit(\n row,\n position,\n this.host.localize(position === 'top' ? 'announce.rowPinnedTop' : 'announce.rowPinnedBottom')\n );\n return true;\n }\n\n /**\n * Unpins `row` from whichever band holds it. No-op (returns `true`) when it is\n * not pinned.\n *\n * @returns `true` when applied, `false` when cancelled.\n */\n public unpinRow(row: T): boolean {\n if (!this.isPinned(row)) return true;\n if (!this.#emitPinning(row, null)) return false;\n\n this.#top.delete(row);\n this.#bottom.delete(row);\n this.#commit(row, null, this.host.localize('announce.rowUnpinned'));\n return true;\n }\n\n /** Clears every pin in both bands. */\n public clear(): void {\n if (!this.hasPinnedRows) return;\n this.#top.clear();\n this.#bottom.clear();\n this.host.requestUpdate();\n }\n\n /**\n * Restores pinned rows from explicit per-band reference lists (state restore),\n * replacing any current pins. Silent: emits no `rowPinning` / `rowPinned` and\n * preserves the given order within each band.\n */\n public restore(top: ReadonlyArray<T>, bottom: ReadonlyArray<T>): void {\n this.#top = new Set(top);\n this.#bottom = new Set(bottom);\n this.host.requestUpdate();\n }\n\n #emitPinning(row: T, position: RowPinPosition | null): boolean {\n return this.host.emitEvent('rowPinning', {\n detail: { row, position },\n cancelable: true,\n });\n }\n\n #commit(row: T, position: RowPinPosition | null, message: string): void {\n this.host.requestUpdate();\n this.host.announce(message);\n this.host.emitEvent('rowPinned', { detail: { row, position } });\n }\n}\n"]}
1
+ {"version":3,"file":"row-pin.js","sourceRoot":"","sources":["../../src/controllers/row-pin.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport type { GridHost } from '../internal/types.js';\n\n/** Where a row is pinned, or `null` when it scrolls with the body. */\nexport type RowPinPosition = 'top' | 'bottom';\n\n/**\n * Reactive controller backing row pinning.\n *\n * @remarks\n * Pinned rows are lifted out of the scrollable body and rendered in sticky\n * bands above (`'top'`) or below (`'bottom'`) the virtualized rows. State is\n * reference-based: the controller holds a `Set` of row data references per band,\n * so pins survive sort / filter / pagination as long as those preserve row\n * identity (the default in-place pipeline does). Replacing {@link ApexGrid.data}\n * carries the pins onto the new array: by `rowId` when set, else a pin whose\n * row left the data is dropped.\n *\n * While `rowPinning.enabled` is false every query reports no pins and the\n * rows stay in the body; the pins are kept (and `getState` still saves them),\n * and re-enabling brings them back.\n *\n * Mutations go through the cancellable `rowPinning` event and emit a follow-up\n * `rowPinned` event, mirroring selection / expansion.\n */\nexport class RowPinController<T extends object> implements ReactiveController {\n #top: Set<T> = new Set();\n #bottom: Set<T> = new Set();\n\n constructor(protected host: GridHost<T>) {\n this.host.addController(this);\n }\n\n public hostConnected() {}\n\n /** Whether row pinning is enabled at the grid level. */\n public get enabled(): boolean {\n return Boolean(this.host.rowPinning?.enabled);\n }\n\n /** Whether any row is currently pinned (none while pinning is disabled). */\n public get hasPinnedRows(): boolean {\n return this.enabled && (this.#top.size > 0 || this.#bottom.size > 0);\n }\n\n /** The band `row` is pinned to, or `null` when it is not pinned. */\n public pinnedPosition(row: T): RowPinPosition | null {\n return this.enabled ? this.#band(row) : null;\n }\n\n /** Whether `row` is pinned to either band. */\n public isPinned(row: T): boolean {\n return this.pinnedPosition(row) !== null;\n }\n\n /** Pinned rows per band, in the order they were pinned. */\n public get pinnedRows(): { top: T[]; bottom: T[] } {\n return this.enabled ? this.pins : { top: [], bottom: [] };\n }\n\n /**\n * Every pin per band, kept while pinning is disabled too, so a `getState`\n * snapshot taken then still carries them.\n */\n public get pins(): { top: T[]; bottom: T[] } {\n return { top: [...this.#top], bottom: [...this.#bottom] };\n }\n\n /** The band holding `row`, whether or not pinning is enabled. */\n #band(row: T): RowPinPosition | null {\n return this.#top.has(row) ? 'top' : this.#bottom.has(row) ? 'bottom' : null;\n }\n\n /**\n * Pins `row` to the given band. Moves it between bands when already pinned\n * elsewhere. No-op (returns `true`) when it is already pinned there.\n *\n * @returns `true` when applied, `false` when disabled or cancelled.\n */\n public pinRow(row: T, position: RowPinPosition): boolean {\n if (!this.enabled) return false;\n if (this.pinnedPosition(row) === position) return true;\n if (!this.#emitPinning(row, position)) return false;\n\n this.#top.delete(row);\n this.#bottom.delete(row);\n (position === 'top' ? this.#top : this.#bottom).add(row);\n this.#commit(\n row,\n position,\n this.host.localize(position === 'top' ? 'announce.rowPinnedTop' : 'announce.rowPinnedBottom')\n );\n return true;\n }\n\n /**\n * Unpins `row` from whichever band holds it. No-op (returns `true`) when it is\n * not pinned.\n *\n * @returns `true` when applied, `false` when cancelled.\n */\n public unpinRow(row: T): boolean {\n if (!this.#band(row)) return true;\n if (!this.#emitPinning(row, null)) return false;\n\n this.#top.delete(row);\n this.#bottom.delete(row);\n this.#commit(row, null, this.host.localize('announce.rowUnpinned'));\n return true;\n }\n\n /** Clears every pin in both bands. */\n public clear(): void {\n if (!this.#top.size && !this.#bottom.size) return;\n this.#top.clear();\n this.#bottom.clear();\n this.host.requestUpdate();\n }\n\n /**\n * Restores pinned rows from explicit per-band reference lists (state restore),\n * replacing any current pins. Silent: emits no `rowPinning` / `rowPinned` and\n * preserves the given order within each band.\n */\n public restore(top: ReadonlyArray<T>, bottom: ReadonlyArray<T>): void {\n this.#top = new Set(top);\n this.#bottom = new Set(bottom);\n this.host.requestUpdate();\n }\n\n /**\n * Carries the pins onto a new `data` array through `carry` (by `rowId` when\n * set, else the rows still present), so the bands never show a stale object.\n */\n public resetForDataChange(carry: (rows: T[]) => T[]): void {\n if (this.#top.size || this.#bottom.size) {\n this.restore(carry([...this.#top]), carry([...this.#bottom]));\n }\n }\n\n #emitPinning(row: T, position: RowPinPosition | null): boolean {\n return this.host.emitEvent('rowPinning', {\n detail: { row, position },\n cancelable: true,\n });\n }\n\n #commit(row: T, position: RowPinPosition | null, message: string): void {\n this.host.requestUpdate();\n this.host.announce(message);\n this.host.emitEvent('rowPinned', { detail: { row, position } });\n }\n}\n"]}
@@ -45,9 +45,12 @@ export interface RowGhostState {
45
45
  * @remarks
46
46
  * Row order is normally derived (filter → sort). This controller adds a
47
47
  * **manual order**: an explicit sequence of row references applied as a
48
- * pipeline step after sort. While a manual order is active, sorting is mutually
49
- * exclusive (applying a sort clears the manual order). State is reference-based,
50
- * so it survives the in-place pipeline.
48
+ * pipeline step after sort. A manual order and a sort are mutually exclusive:
49
+ * applying a sort clears the manual order, and a move clears the sort. The
50
+ * order spans every row, hidden by a filter or not, so a move made under a
51
+ * filter leaves the hidden rows in place. State is reference-based, so it
52
+ * survives the in-place pipeline, and it is carried onto a new `data` array
53
+ * (by `rowId` when set, else by identity).
51
54
  *
52
55
  * Reordering happens through {@link moveRow} (pointer live-swap during a drag,
53
56
  * the keyboard grab/move flow, or the public API). Each move goes through the
@@ -75,6 +78,8 @@ export declare class RowReorderController<T extends object> implements ReactiveC
75
78
  grabbed: T | null;
76
79
  constructor(host: GridHost<T>);
77
80
  hostConnected(): void;
81
+ /** A grid detached mid-drag ends the gesture, so no frozen ghost stays behind. */
82
+ hostDisconnected(): void;
78
83
  /** Whether row reordering is enabled at the grid level. */
79
84
  get enabled(): boolean;
80
85
  /**
@@ -115,12 +120,20 @@ export declare class RowReorderController<T extends object> implements ReactiveC
115
120
  * Clears the manual order (e.g. when a sort is applied). Re-runs the pipeline.
116
121
  */
117
122
  clearManualOrder(announce?: boolean): void;
123
+ /**
124
+ * Carries the manual order onto a new `data` array through `carry` (by
125
+ * `rowId` when set, else the rows still present), clearing it when no row
126
+ * survives. A grab or drag follows its row onto the new data, so an app
127
+ * that re-sets `data` on `rowMoved` keeps the gesture; it ends only when
128
+ * the row is gone.
129
+ */
130
+ resetForDataChange(carry: (rows: T[]) => T[]): void;
118
131
  /**
119
132
  * Moves the row at view index `from` relative to the row at view index `to`.
120
133
  * Indices are into {@link ApexGrid.pageItems}.
121
134
  *
122
- * @returns `true` when applied, `false` when disabled, out of range, or
123
- * cancelled via `rowMoving`.
135
+ * @returns `true` when applied, `false` when disabled, out of range, a
136
+ * no-op (the row would land where it is), or cancelled via `rowMoving`.
124
137
  */
125
138
  moveRow(from: number, to: number, position?: RowDropPosition): boolean;
126
139
  /**
@@ -140,11 +153,13 @@ export declare class RowReorderController<T extends object> implements ReactiveC
140
153
  endDrag(): void;
141
154
  /**
142
155
  * Arms a pointer drag from a row press. Called by the row on `pointerdown`
143
- * (from the grip in handle mode, or anywhere in whole-row mode). The move /
144
- * up / cancel listeners are bound to the **grid host**, so the gesture is
145
- * immune to the source row's DOM being recycled by a live-swap. `getGhost` is
146
- * a thunk the controller invokes once, the instant the drag engages, to
147
- * snapshot the row's cells (the row is still in place then).
156
+ * (from the grip in handle mode, or anywhere in whole-row mode). The move
157
+ * listener is bound to the **grid host**, so the gesture is immune to the
158
+ * source row's DOM being recycled by a live-swap; the up / cancel listeners
159
+ * are bound to the document, so a release outside the grid ends it too, as
160
+ * does a move with the primary button no longer held. `getGhost` is a thunk
161
+ * the controller invokes once, the instant the drag engages, to snapshot the
162
+ * row's cells (the row is still in place then).
148
163
  */
149
164
  armPointerDrag(data: T, getGhost: () => RowGhostInit, event: PointerEvent): void;
150
165
  /** Grabs the row at view index `rowIndex` for keyboard reorder. */
@@ -156,6 +171,11 @@ export declare class RowReorderController<T extends object> implements ReactiveC
156
171
  moveGrabbed(direction: -1 | 1): number;
157
172
  /** Drops the grabbed row, keeping its moves. */
158
173
  drop(): void;
159
- /** Cancels the grab, reverting to the order captured when it was grabbed. */
174
+ /**
175
+ * Cancels the grab, reverting the order, the data order (with
176
+ * `applyToData`) and the sort to what they were when the row was grabbed.
177
+ * Emits `rowMoved` for the way back when the row had moved, so an app
178
+ * persisting each step sees the revert too.
179
+ */
160
180
  cancelGrab(): void;
161
181
  }
@@ -1,5 +1,6 @@
1
1
  import { PIPELINE } from '../internal/constants.js';
2
2
  import { awaitChildUpdates, playKeyedFlip } from '../internal/flip.js';
3
+ import SortDataOperation from '../operations/sort.js';
3
4
  const DRAG_THRESHOLD_PX = 4;
4
5
  export class RowReorderController {
5
6
  #order;
@@ -19,6 +20,10 @@ export class RowReorderController {
19
20
  const pending = this.#pending;
20
21
  if (!pending || event.pointerId !== pending.pointerId)
21
22
  return;
23
+ if (!(event.buttons & 1)) {
24
+ this.#endPointer();
25
+ return;
26
+ }
22
27
  if (!this.dragging) {
23
28
  const dx = event.clientX - pending.startX;
24
29
  const dy = event.clientY - pending.startY;
@@ -34,22 +39,9 @@ export class RowReorderController {
34
39
  this.moveGhost(event.clientX, event.clientY);
35
40
  this.dragOver(event.clientY);
36
41
  };
37
- this.#onHostPointerUp = (event) => {
38
- const pending = this.#pending;
39
- if (!pending || event.pointerId !== pending.pointerId)
40
- return;
41
- const host = this.#hostElement;
42
- host.removeEventListener('pointermove', this.#onHostPointerMove);
43
- host.removeEventListener('pointerup', this.#onHostPointerUp);
44
- host.removeEventListener('pointercancel', this.#onHostPointerUp);
45
- try {
46
- if (host.hasPointerCapture(pending.pointerId))
47
- host.releasePointerCapture(pending.pointerId);
48
- }
49
- catch {
50
- }
51
- this.#pending = null;
52
- this.endDrag();
42
+ this.#onPointerUp = (event) => {
43
+ if (event.pointerId === this.#pending?.pointerId)
44
+ this.#endPointer();
53
45
  };
54
46
  this.host.addController(this);
55
47
  }
@@ -57,6 +49,9 @@ export class RowReorderController {
57
49
  return this.host;
58
50
  }
59
51
  hostConnected() { }
52
+ hostDisconnected() {
53
+ this.#endPointer();
54
+ }
60
55
  get enabled() {
61
56
  return Boolean(this.host.rowReordering?.enabled);
62
57
  }
@@ -103,6 +98,33 @@ export class RowReorderController {
103
98
  if (announce)
104
99
  this.host.announce(this.host.localize('announce.manualOrderCleared'));
105
100
  }
101
+ resetForDataChange(carry) {
102
+ const pre = this.#preGrab;
103
+ if (this.grabbed) {
104
+ this.grabbed = carry([this.grabbed])[0] ?? null;
105
+ if (!this.grabbed)
106
+ this.#preGrab = null;
107
+ else if (pre) {
108
+ pre.order = pre.order && carry(pre.order);
109
+ pre.data = pre.data && carry(pre.data);
110
+ }
111
+ }
112
+ const pending = this.#pending;
113
+ const held = pending?.data ?? this.dragging;
114
+ if (held) {
115
+ const row = carry([held])[0];
116
+ if (!row)
117
+ this.#endPointer();
118
+ else {
119
+ if (pending)
120
+ pending.data = row;
121
+ if (this.dragging)
122
+ this.dragging = row;
123
+ }
124
+ }
125
+ if (this.#order)
126
+ this.restoreManualOrder(carry(this.#order));
127
+ }
106
128
  moveRow(from, to, position = 'before') {
107
129
  const view = this.host.pageItems;
108
130
  const before = this.#captureRowRects();
@@ -184,11 +206,29 @@ export class RowReorderController {
184
206
  };
185
207
  const host = this.#hostElement;
186
208
  host.addEventListener('pointermove', this.#onHostPointerMove);
187
- host.addEventListener('pointerup', this.#onHostPointerUp);
188
- host.addEventListener('pointercancel', this.#onHostPointerUp);
209
+ host.ownerDocument.addEventListener('pointerup', this.#onPointerUp, true);
210
+ host.ownerDocument.addEventListener('pointercancel', this.#onPointerUp, true);
189
211
  }
190
212
  #onHostPointerMove;
191
- #onHostPointerUp;
213
+ #onPointerUp;
214
+ #endPointer() {
215
+ const pending = this.#pending;
216
+ if (pending) {
217
+ const host = this.#hostElement;
218
+ host.removeEventListener('pointermove', this.#onHostPointerMove);
219
+ host.ownerDocument.removeEventListener('pointerup', this.#onPointerUp, true);
220
+ host.ownerDocument.removeEventListener('pointercancel', this.#onPointerUp, true);
221
+ try {
222
+ if (host.hasPointerCapture(pending.pointerId)) {
223
+ host.releasePointerCapture(pending.pointerId);
224
+ }
225
+ }
226
+ catch {
227
+ }
228
+ this.#pending = null;
229
+ }
230
+ this.endDrag();
231
+ }
192
232
  async #dragSwap(target, position) {
193
233
  if (this.#swapping)
194
234
  return;
@@ -212,7 +252,12 @@ export class RowReorderController {
212
252
  if (!row)
213
253
  return false;
214
254
  this.grabbed = row;
215
- this.#preGrab = this.#order ? [...this.#order] : null;
255
+ this.#preGrab = {
256
+ order: this.#order,
257
+ data: this.applyToData ? [...this.host.data] : null,
258
+ sort: this.host.sortExpressions,
259
+ index: rowIndex,
260
+ };
216
261
  this.host.requestUpdate();
217
262
  this.host.announce(this.host.localize('announce.rowGrabbed'));
218
263
  return true;
@@ -244,13 +289,46 @@ export class RowReorderController {
244
289
  this.host.announce(this.host.localize('announce.rowDropped'));
245
290
  }
246
291
  cancelGrab() {
247
- if (!this.grabbed)
292
+ const row = this.grabbed;
293
+ const pre = this.#preGrab;
294
+ if (!row || !pre)
248
295
  return;
249
- this.grabbed = null;
250
- this.#order = this.#preGrab;
251
- this.#preGrab = null;
296
+ const from = this.host.pageItems.indexOf(row);
297
+ this.grabbed = this.#preGrab = null;
298
+ this.#order = pre.order;
299
+ if (pre.data)
300
+ this.#spliceData(pre.data);
301
+ if (pre.sort.length)
302
+ this.host.sortExpressions = pre.sort;
252
303
  this.host.requestUpdate(PIPELINE);
253
304
  this.host.announce(this.host.localize('announce.reorderCancelled'));
305
+ const to = pre.index;
306
+ if (from !== to) {
307
+ const position = from > to ? 'before' : 'after';
308
+ this.host.emitEvent('rowMoved', { detail: { from, to, position, toIndex: to, data: row } });
309
+ }
310
+ }
311
+ #fullOrder() {
312
+ const data = this.host.data;
313
+ const sort = this.host.sortExpressions;
314
+ let base;
315
+ if (this.#order) {
316
+ const rest = new Set(data);
317
+ base = this.#order.filter((row) => rest.delete(row));
318
+ base.push(...rest);
319
+ }
320
+ else if (sort.length && !this.host.dataPipelineConfiguration?.sort) {
321
+ const state = new Map(sort.map((expr) => [expr.key, expr]));
322
+ base = new SortDataOperation().apply([...data], state);
323
+ }
324
+ else {
325
+ base = [...data];
326
+ }
327
+ const listed = new Set(base);
328
+ const shown = this.host.dataView.filter((row) => listed.has(row));
329
+ const inView = new Set(shown);
330
+ let k = 0;
331
+ return base.map((row) => (inView.has(row) ? shown[k++] : row));
254
332
  }
255
333
  #commit(source, target, position, options = {}) {
256
334
  if (!this.enabled || !source || !target || source === target)
@@ -258,20 +336,22 @@ export class RowReorderController {
258
336
  const view = this.host.pageItems;
259
337
  const from = view.indexOf(source);
260
338
  const to = view.indexOf(target);
261
- const proceed = this.host.emitEvent('rowMoving', {
262
- detail: { from, to, data: source },
263
- cancelable: true,
264
- });
265
- if (!proceed)
339
+ const toIndex = position === 'after' ? (from < to ? to : to + 1) : from < to ? to - 1 : to;
340
+ if (from === -1 || to === -1 || toIndex === from)
341
+ return false;
342
+ const next = this.#fullOrder();
343
+ const at = next.indexOf(source);
344
+ if (at === -1 || !next.includes(target))
345
+ return false;
346
+ next.splice(at, 1);
347
+ next.splice(next.indexOf(target) + (position === 'after' ? 1 : 0), 0, source);
348
+ if (next.indexOf(source) === at)
266
349
  return false;
267
- const baseline = this.#order ?? [...this.host.dataView];
268
- const next = baseline.filter((row) => row !== source);
269
- let index = next.indexOf(target);
270
- if (index === -1)
350
+ const detail = { from, to, position, toIndex, data: source };
351
+ if (!this.host.emitEvent('rowMoving', { detail, cancelable: true }))
271
352
  return false;
272
- if (position === 'after')
273
- index += 1;
274
- next.splice(index, 0, source);
353
+ if (this.host.sortExpressions.length)
354
+ this.host.sortExpressions = [];
275
355
  if (this.applyToData) {
276
356
  this.#spliceData(next);
277
357
  this.#order = null;
@@ -282,7 +362,7 @@ export class RowReorderController {
282
362
  this.host.requestUpdate(PIPELINE);
283
363
  if (!options.silent)
284
364
  this.host.announce(this.host.localize('announce.rowMoved'));
285
- this.host.emitEvent('rowMoved', { detail: { from, to, data: source } });
365
+ this.host.emitEvent('rowMoved', { detail });
286
366
  return true;
287
367
  }
288
368
  #spliceData(order) {
@@ -1 +1 @@
1
- {"version":3,"file":"row-reorder.js","sourceRoot":"","sources":["../../src/controllers/row-reorder.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport { PIPELINE } from '../internal/constants.js';\nimport { awaitChildUpdates, type KeyedFlipEntry, playKeyedFlip } from '../internal/flip.js';\nimport type { GridHost } from '../internal/types.js';\n\n/** Where a moved row lands relative to its target. */\nexport type RowDropPosition = 'before' | 'after';\n\n/** Pixels the pointer must travel before a row drag engages. */\nconst DRAG_THRESHOLD_PX = 4;\n\n/** A single cell snapshot used to paint the floating row ghost. */\nexport interface RowGhostCell {\n /** The cell's rendered text at grab time. */\n text: string;\n /** The cell's rendered width (px), so the ghost matches the column layout. */\n width: number;\n /** The cell's computed `text-align`, so numbers stay right-aligned in the ghost. */\n align: string;\n}\n\n/** Everything the row hands the controller to seed the floating ghost. */\nexport interface RowGhostInit {\n /** The source row's bounding rect at grab time. */\n rect: DOMRect;\n /** Pointer position at grab time (to keep the grab point under the cursor). */\n clientX: number;\n clientY: number;\n /** Per-cell snapshot of the row's visible content. */\n cells: RowGhostCell[];\n}\n\n/**\n * Live state for the floating \"ghost\" row that trails the cursor during a\n * pointer drag. Mirrors {@link ReorderController}'s column ghost: the source\n * row stays in the grid (and live-swaps), the ghost is a purely visual proxy.\n */\nexport interface RowGhostState {\n /** Ghost position (viewport-relative top-left, in CSS pixels). */\n x: number;\n y: number;\n /** Ghost size, fixed at the source row's initial bounding rect. */\n width: number;\n height: number;\n /** Cursor offset within the ghost so the grab point stays under the cursor. */\n pointerOffsetX: number;\n pointerOffsetY: number;\n /** Snapshot of the row's visible cells. */\n cells: ReadonlyArray<RowGhostCell>;\n}\n\n/**\n * Reactive controller backing row drag-reorder and a manual row order.\n *\n * @remarks\n * Row order is normally derived (filter → sort). This controller adds a\n * **manual order**: an explicit sequence of row references applied as a\n * pipeline step after sort. While a manual order is active, sorting is mutually\n * exclusive (applying a sort clears the manual order). State is reference-based,\n * so it survives the in-place pipeline.\n *\n * Reordering happens through {@link moveRow} (pointer live-swap during a drag,\n * the keyboard grab/move flow, or the public API). Each move goes through the\n * cancellable `rowMoving` event and emits a follow-up `rowMoved`, then animates\n * with a Y-axis FLIP. Pinned rows (F4) are never the drag source and reorder\n * only within the unpinned body set.\n *\n * Persistence: by default the order lives in this controller and the app\n * persists via `rowMoved`. With `rowReordering.applyToData` the move also\n * splices {@link ApexGrid.data} in place (and clears the manual order, since the\n * data array then carries the order).\n */\nexport class RowReorderController<T extends object> implements ReactiveController {\n /** Manual order of row references, or `null` for the natural (sorted) order. */\n #order: T[] | null = null;\n\n /** Order snapshot captured at keyboard-grab time, for Escape-to-cancel. */\n #preGrab: T[] | null = null;\n\n /** The row currently being pointer-dragged, or `null`. */\n public dragging: T | null = null;\n\n /**\n * Live floating-ghost state during a pointer drag, or `null`. Surfaced to the\n * grid, which renders the ghost at the top of its shadow tree (outside the\n * virtualizer) so `position: fixed` tracks the viewport cleanly.\n */\n public ghost: RowGhostState | null = null;\n\n /** The row currently grabbed for keyboard reorder, or `null`. */\n public grabbed: T | null = null;\n\n /** Re-entrancy guard so a slow swap can't trigger a second mid-drag. */\n #swapping = false;\n\n /**\n * In-flight pointer-drag gesture. The move/up listeners live on the **grid\n * host** (a stable element), not the row, so a live-swap that recycles the\n * source row's DOM can't tear the drag down mid-gesture.\n */\n #pending: {\n data: T;\n getGhost: () => RowGhostInit;\n startX: number;\n startY: number;\n pointerId: number;\n } | null = null;\n\n constructor(protected host: GridHost<T>) {\n this.host.addController(this);\n }\n\n /** The grid host as a DOM event target (it is always an `HTMLElement`). */\n get #hostElement(): HTMLElement {\n return this.host as unknown as HTMLElement;\n }\n\n public hostConnected() {}\n\n /** Whether row reordering is enabled at the grid level. */\n public get enabled(): boolean {\n return Boolean(this.host.rowReordering?.enabled);\n }\n\n /**\n * Whether a pointer drag must start from the dedicated grip handle (the\n * default), rather than from anywhere on the row. Driven by\n * `rowReordering.handle` (defaults to `true`).\n */\n public get handleMode(): boolean {\n return this.enabled && this.host.rowReordering?.handle !== false;\n }\n\n /**\n * Whether the leading grip-handle column is rendered. Only in handle mode, and\n * only while reordering is enabled.\n */\n public get showHandleColumn(): boolean {\n return this.handleMode;\n }\n\n /** Whether moves also splice {@link ApexGrid.data} in place. */\n public get applyToData(): boolean {\n return Boolean(this.host.rowReordering?.applyToData);\n }\n\n /** Whether a manual order is currently active. */\n public get hasManualOrder(): boolean {\n return this.#order !== null;\n }\n\n /** Whether a row is currently grabbed for keyboard reorder. */\n public get isGrabbing(): boolean {\n return this.grabbed !== null;\n }\n\n /**\n * Pipeline step: reorders the (post-filter, post-sort) rows by the manual\n * order. Rows absent from the manual order (e.g. newly added) keep their\n * incoming relative order at the end. Identity pass-through when inactive.\n */\n public apply(rows: T[]): T[] {\n if (!this.#order) return rows;\n const rank = new Map<T, number>();\n this.#order.forEach((row, i) => {\n rank.set(row, i);\n });\n return [...rows].sort((a, b) => {\n const ra = rank.has(a) ? (rank.get(a) as number) : Number.POSITIVE_INFINITY;\n const rb = rank.has(b) ? (rank.get(b) as number) : Number.POSITIVE_INFINITY;\n return ra - rb;\n });\n }\n\n /**\n * The current manual order as a copy of its row references, or `null` for the\n * derived order. Consumed by `ApexGrid.getState`.\n */\n public getManualOrder(): T[] | null {\n return this.#order ? [...this.#order] : null;\n }\n\n /**\n * Restores a manual order from a list of row references (state restore). Pass\n * `null` (or an empty list) to clear it. Silent: emits no `rowMoving` /\n * `rowMoved` and does not animate; re-runs the pipeline.\n */\n public restoreManualOrder(order: T[] | null): void {\n this.#order = order?.length ? [...order] : null;\n this.host.requestUpdate(PIPELINE);\n }\n\n /**\n * Clears the manual order (e.g. when a sort is applied). Re-runs the pipeline.\n */\n public clearManualOrder(announce = false): void {\n if (!this.#order) return;\n this.#order = null;\n this.host.requestUpdate(PIPELINE);\n if (announce) this.host.announce(this.host.localize('announce.manualOrderCleared'));\n }\n\n /**\n * Moves the row at view index `from` relative to the row at view index `to`.\n * Indices are into {@link ApexGrid.pageItems}.\n *\n * @returns `true` when applied, `false` when disabled, out of range, or\n * cancelled via `rowMoving`.\n */\n public moveRow(from: number, to: number, position: RowDropPosition = 'before'): boolean {\n const view = this.host.pageItems;\n const before = this.#captureRowRects();\n const ok = this.#commit(view[from] as T, view[to] as T, position);\n if (ok) void this.#flipAfterUpdate(before);\n return ok;\n }\n\n // --- pointer drag -------------------------------------------------------\n\n /**\n * Begins a pointer drag from `source`. When `ghost` is supplied (the pointer\n * path always does), seeds the floating ghost from the source row's rect and\n * the grab point so it stays anchored under the cursor.\n */\n public startDrag(source: T, ghost?: RowGhostInit): void {\n if (!this.enabled) return;\n this.dragging = source;\n this.ghost = ghost\n ? {\n x: ghost.rect.left,\n y: ghost.rect.top,\n width: ghost.rect.width,\n height: ghost.rect.height,\n pointerOffsetX: ghost.clientX - ghost.rect.left,\n pointerOffsetY: ghost.clientY - ghost.rect.top,\n cells: ghost.cells,\n }\n : null;\n this.host.requestUpdate();\n }\n\n /** Moves the floating ghost to track the cursor. No-op without an active ghost. */\n public moveGhost(clientX: number, clientY: number): void {\n if (!this.ghost) return;\n this.ghost = {\n ...this.ghost,\n x: clientX - this.ghost.pointerOffsetX,\n y: clientY - this.ghost.pointerOffsetY,\n };\n this.host.requestUpdate();\n }\n\n /**\n * Called on pointer-move during a drag: live-swaps the dragged row past the\n * body row currently under `clientY` once the cursor crosses its midpoint.\n */\n public dragOver(clientY: number): void {\n if (!this.dragging || this.#swapping) return;\n const target = this.#bodyRowAt(clientY);\n if (!target || target.data === this.dragging) return;\n\n const view = this.host.pageItems;\n const sourceIdx = view.indexOf(this.dragging);\n const targetIdx = view.indexOf(target.data);\n if (sourceIdx === -1 || targetIdx === -1) return;\n\n const rect = target.element.getBoundingClientRect();\n const midpoint = rect.top + rect.height / 2;\n let position: RowDropPosition;\n if (sourceIdx < targetIdx) {\n if (clientY < midpoint) return; // dragging down — wait for the midpoint\n position = 'after';\n } else {\n if (clientY > midpoint) return; // dragging up\n position = 'before';\n }\n void this.#dragSwap(target.data, position);\n }\n\n /** Ends the pointer drag. The order is already final (live-swapped). */\n public endDrag(): void {\n if (!this.dragging) return;\n this.dragging = null;\n this.ghost = null;\n this.host.requestUpdate();\n }\n\n /**\n * Arms a pointer drag from a row press. Called by the row on `pointerdown`\n * (from the grip in handle mode, or anywhere in whole-row mode). The move /\n * up / cancel listeners are bound to the **grid host**, so the gesture is\n * immune to the source row's DOM being recycled by a live-swap. `getGhost` is\n * a thunk the controller invokes once, the instant the drag engages, to\n * snapshot the row's cells (the row is still in place then).\n */\n public armPointerDrag(data: T, getGhost: () => RowGhostInit, event: PointerEvent): void {\n const pinned = this.host.pinnedRows;\n if (!this.enabled || pinned.top.includes(data) || pinned.bottom.includes(data)) return;\n this.#pending = {\n data,\n getGhost,\n startX: event.clientX,\n startY: event.clientY,\n pointerId: event.pointerId,\n };\n const host = this.#hostElement;\n host.addEventListener('pointermove', this.#onHostPointerMove);\n host.addEventListener('pointerup', this.#onHostPointerUp);\n host.addEventListener('pointercancel', this.#onHostPointerUp);\n }\n\n #onHostPointerMove = (event: PointerEvent): void => {\n const pending = this.#pending;\n if (!pending || event.pointerId !== pending.pointerId) return;\n if (!this.dragging) {\n const dx = event.clientX - pending.startX;\n const dy = event.clientY - pending.startY;\n if (Math.hypot(dx, dy) < DRAG_THRESHOLD_PX) return;\n // Capture on the stable host so moves keep arriving even when the cursor\n // leaves the grid, and so the source row reflowing can't drop the pointer.\n try {\n this.#hostElement.setPointerCapture(pending.pointerId);\n } catch {\n /* a synthetic pointer id may not be capturable; hit-testing still works */\n }\n this.startDrag(pending.data, pending.getGhost());\n }\n this.moveGhost(event.clientX, event.clientY);\n this.dragOver(event.clientY);\n };\n\n #onHostPointerUp = (event: PointerEvent): void => {\n const pending = this.#pending;\n if (!pending || event.pointerId !== pending.pointerId) return;\n const host = this.#hostElement;\n host.removeEventListener('pointermove', this.#onHostPointerMove);\n host.removeEventListener('pointerup', this.#onHostPointerUp);\n host.removeEventListener('pointercancel', this.#onHostPointerUp);\n try {\n if (host.hasPointerCapture(pending.pointerId)) host.releasePointerCapture(pending.pointerId);\n } catch {\n /* capture was never taken or already released */\n }\n this.#pending = null;\n this.endDrag();\n };\n\n async #dragSwap(target: T, position: RowDropPosition): Promise<void> {\n if (this.#swapping) return;\n this.#swapping = true;\n try {\n const before = this.#captureRowRects();\n if (this.#commit(this.dragging as T, target, position)) {\n await this.host.updateComplete;\n await awaitChildUpdates(this.host.rows);\n this.#playRowFlip(before);\n }\n } finally {\n this.#swapping = false;\n }\n }\n\n // --- keyboard grab ------------------------------------------------------\n\n /** Grabs the row at view index `rowIndex` for keyboard reorder. */\n public grab(rowIndex: number): boolean {\n if (!this.enabled) return false;\n const row = this.host.pageItems[rowIndex] as T | undefined;\n if (!row) return false;\n this.grabbed = row;\n this.#preGrab = this.#order ? [...this.#order] : null;\n this.host.requestUpdate();\n this.host.announce(this.host.localize('announce.rowGrabbed'));\n return true;\n }\n\n /**\n * Moves the grabbed row one position in `direction`. Returns the grabbed\n * row's new view index, or `-1` when it can't move (no grab / at the edge).\n */\n public moveGrabbed(direction: -1 | 1): number {\n if (!this.grabbed) return -1;\n const view = this.host.pageItems;\n const current = view.indexOf(this.grabbed);\n const target = current + direction;\n if (current === -1 || target < 0 || target >= view.length) return -1;\n const before = this.#captureRowRects();\n const ok = this.#commit(this.grabbed, view[target] as T, direction > 0 ? 'after' : 'before', {\n silent: true,\n });\n if (!ok) return -1;\n void this.#flipAfterUpdate(before);\n this.host.announce(this.host.localize('announce.rowMovedTo', { position: target + 1 }));\n return target;\n }\n\n /** Drops the grabbed row, keeping its moves. */\n public drop(): void {\n if (!this.grabbed) return;\n this.grabbed = null;\n this.#preGrab = null;\n this.host.requestUpdate();\n this.host.announce(this.host.localize('announce.rowDropped'));\n }\n\n /** Cancels the grab, reverting to the order captured when it was grabbed. */\n public cancelGrab(): void {\n if (!this.grabbed) return;\n this.grabbed = null;\n this.#order = this.#preGrab;\n this.#preGrab = null;\n this.host.requestUpdate(PIPELINE);\n this.host.announce(this.host.localize('announce.reorderCancelled'));\n }\n\n // --- internals ----------------------------------------------------------\n\n /**\n * The core order mutation: validates, emits `rowMoving` (cancellable),\n * updates the manual order (or splices data when `applyToData`), re-runs the\n * pipeline, and emits `rowMoved`. Does not animate.\n */\n #commit(\n source: T | undefined,\n target: T | undefined,\n position: RowDropPosition,\n options: { silent?: boolean } = {}\n ): boolean {\n if (!this.enabled || !source || !target || source === target) return false;\n const view = this.host.pageItems;\n const from = view.indexOf(source);\n const to = view.indexOf(target);\n\n const proceed = this.host.emitEvent('rowMoving', {\n detail: { from, to, data: source },\n cancelable: true,\n });\n if (!proceed) return false;\n\n const baseline = this.#order ?? [...(this.host.dataView as ReadonlyArray<T>)];\n const next = baseline.filter((row) => row !== source);\n let index = next.indexOf(target);\n if (index === -1) return false;\n if (position === 'after') index += 1;\n next.splice(index, 0, source);\n\n if (this.applyToData) {\n this.#spliceData(next);\n this.#order = null; // the data array now carries the order\n } else {\n this.#order = next;\n }\n\n this.host.requestUpdate(PIPELINE);\n if (!options.silent) this.host.announce(this.host.localize('announce.rowMoved'));\n this.host.emitEvent('rowMoved', { detail: { from, to, data: source } });\n return true;\n }\n\n /** Reorders {@link ApexGrid.data} in place to match `order`. */\n #spliceData(order: ReadonlyArray<T>): void {\n const rank = new Map<T, number>();\n order.forEach((row, i) => {\n rank.set(row, i);\n });\n (this.host.data as T[]).sort((a, b) => {\n const ra = rank.has(a) ? (rank.get(a) as number) : Number.POSITIVE_INFINITY;\n const rb = rank.has(b) ? (rank.get(b) as number) : Number.POSITIVE_INFINITY;\n return ra - rb;\n });\n }\n\n /** The rendered body row (non-pinned) whose box contains `clientY`. */\n #bodyRowAt(clientY: number): { data: T; element: HTMLElement } | null {\n const pinned = this.host.pinnedRows;\n for (const row of this.host.rows) {\n if (pinned.top.includes(row.data) || pinned.bottom.includes(row.data)) continue;\n const element = row as unknown as HTMLElement;\n const rect = element.getBoundingClientRect();\n if (clientY >= rect.top && clientY < rect.bottom) return { data: row.data, element };\n }\n return null;\n }\n\n #captureRowRects(): KeyedFlipEntry<T>[] {\n const entries: KeyedFlipEntry<T>[] = [];\n for (const row of this.host.rows) {\n const el = row as unknown as HTMLElement;\n entries.push({ key: row.data, rect: el.getBoundingClientRect() });\n }\n return entries;\n }\n\n async #flipAfterUpdate(before: ReadonlyArray<KeyedFlipEntry<T>>): Promise<void> {\n await this.host.updateComplete;\n await awaitChildUpdates(this.host.rows);\n this.#playRowFlip(before);\n }\n\n #playRowFlip(before: ReadonlyArray<KeyedFlipEntry<T>>): void {\n const byData = new Map<T, HTMLElement>();\n for (const row of this.host.rows) {\n byData.set(row.data, row as unknown as HTMLElement);\n }\n playKeyedFlip(before, (data) => byData.get(data) ?? null, 'y');\n }\n}\n"]}
1
+ {"version":3,"file":"row-reorder.js","sourceRoot":"","sources":["../../src/controllers/row-reorder.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport { PIPELINE } from '../internal/constants.js';\nimport { awaitChildUpdates, type KeyedFlipEntry, playKeyedFlip } from '../internal/flip.js';\nimport type { GridHost } from '../internal/types.js';\nimport type { SortExpression } from '../operations/sort/types.js';\nimport SortDataOperation from '../operations/sort.js';\n\n/** Where a moved row lands relative to its target. */\nexport type RowDropPosition = 'before' | 'after';\n\n/** Pixels the pointer must travel before a row drag engages. */\nconst DRAG_THRESHOLD_PX = 4;\n\n/** A single cell snapshot used to paint the floating row ghost. */\nexport interface RowGhostCell {\n /** The cell's rendered text at grab time. */\n text: string;\n /** The cell's rendered width (px), so the ghost matches the column layout. */\n width: number;\n /** The cell's computed `text-align`, so numbers stay right-aligned in the ghost. */\n align: string;\n}\n\n/** Everything the row hands the controller to seed the floating ghost. */\nexport interface RowGhostInit {\n /** The source row's bounding rect at grab time. */\n rect: DOMRect;\n /** Pointer position at grab time (to keep the grab point under the cursor). */\n clientX: number;\n clientY: number;\n /** Per-cell snapshot of the row's visible content. */\n cells: RowGhostCell[];\n}\n\n/**\n * Live state for the floating \"ghost\" row that trails the cursor during a\n * pointer drag. Mirrors {@link ReorderController}'s column ghost: the source\n * row stays in the grid (and live-swaps), the ghost is a purely visual proxy.\n */\nexport interface RowGhostState {\n /** Ghost position (viewport-relative top-left, in CSS pixels). */\n x: number;\n y: number;\n /** Ghost size, fixed at the source row's initial bounding rect. */\n width: number;\n height: number;\n /** Cursor offset within the ghost so the grab point stays under the cursor. */\n pointerOffsetX: number;\n pointerOffsetY: number;\n /** Snapshot of the row's visible cells. */\n cells: ReadonlyArray<RowGhostCell>;\n}\n\n/**\n * Reactive controller backing row drag-reorder and a manual row order.\n *\n * @remarks\n * Row order is normally derived (filter → sort). This controller adds a\n * **manual order**: an explicit sequence of row references applied as a\n * pipeline step after sort. A manual order and a sort are mutually exclusive:\n * applying a sort clears the manual order, and a move clears the sort. The\n * order spans every row, hidden by a filter or not, so a move made under a\n * filter leaves the hidden rows in place. State is reference-based, so it\n * survives the in-place pipeline, and it is carried onto a new `data` array\n * (by `rowId` when set, else by identity).\n *\n * Reordering happens through {@link moveRow} (pointer live-swap during a drag,\n * the keyboard grab/move flow, or the public API). Each move goes through the\n * cancellable `rowMoving` event and emits a follow-up `rowMoved`, then animates\n * with a Y-axis FLIP. Pinned rows (F4) are never the drag source and reorder\n * only within the unpinned body set.\n *\n * Persistence: by default the order lives in this controller and the app\n * persists via `rowMoved`. With `rowReordering.applyToData` the move also\n * splices {@link ApexGrid.data} in place (and clears the manual order, since the\n * data array then carries the order).\n */\nexport class RowReorderController<T extends object> implements ReactiveController {\n /** Manual order of row references, or `null` for the natural (sorted) order. */\n #order: T[] | null = null;\n\n /**\n * What a keyboard grab may change, captured when it starts, for\n * Escape-to-cancel: the manual order, the data order (with `applyToData`),\n * the sort and the grabbed row's view index.\n */\n #preGrab: {\n order: T[] | null;\n data: T[] | null;\n sort: SortExpression<T>[];\n index: number;\n } | null = null;\n\n /** The row currently being pointer-dragged, or `null`. */\n public dragging: T | null = null;\n\n /**\n * Live floating-ghost state during a pointer drag, or `null`. Surfaced to the\n * grid, which renders the ghost at the top of its shadow tree (outside the\n * virtualizer) so `position: fixed` tracks the viewport cleanly.\n */\n public ghost: RowGhostState | null = null;\n\n /** The row currently grabbed for keyboard reorder, or `null`. */\n public grabbed: T | null = null;\n\n /** Re-entrancy guard so a slow swap can't trigger a second mid-drag. */\n #swapping = false;\n\n /**\n * In-flight pointer-drag gesture. The move/up listeners live on the **grid\n * host** (a stable element), not the row, so a live-swap that recycles the\n * source row's DOM can't tear the drag down mid-gesture.\n */\n #pending: {\n data: T;\n getGhost: () => RowGhostInit;\n startX: number;\n startY: number;\n pointerId: number;\n } | null = null;\n\n constructor(protected host: GridHost<T>) {\n this.host.addController(this);\n }\n\n /** The grid host as a DOM event target (it is always an `HTMLElement`). */\n get #hostElement(): HTMLElement {\n return this.host as unknown as HTMLElement;\n }\n\n public hostConnected() {}\n\n /** A grid detached mid-drag ends the gesture, so no frozen ghost stays behind. */\n public hostDisconnected() {\n this.#endPointer();\n }\n\n /** Whether row reordering is enabled at the grid level. */\n public get enabled(): boolean {\n return Boolean(this.host.rowReordering?.enabled);\n }\n\n /**\n * Whether a pointer drag must start from the dedicated grip handle (the\n * default), rather than from anywhere on the row. Driven by\n * `rowReordering.handle` (defaults to `true`).\n */\n public get handleMode(): boolean {\n return this.enabled && this.host.rowReordering?.handle !== false;\n }\n\n /**\n * Whether the leading grip-handle column is rendered. Only in handle mode, and\n * only while reordering is enabled.\n */\n public get showHandleColumn(): boolean {\n return this.handleMode;\n }\n\n /** Whether moves also splice {@link ApexGrid.data} in place. */\n public get applyToData(): boolean {\n return Boolean(this.host.rowReordering?.applyToData);\n }\n\n /** Whether a manual order is currently active. */\n public get hasManualOrder(): boolean {\n return this.#order !== null;\n }\n\n /** Whether a row is currently grabbed for keyboard reorder. */\n public get isGrabbing(): boolean {\n return this.grabbed !== null;\n }\n\n /**\n * Pipeline step: reorders the (post-filter, post-sort) rows by the manual\n * order. Rows absent from the manual order (e.g. newly added) keep their\n * incoming relative order at the end. Identity pass-through when inactive.\n */\n public apply(rows: T[]): T[] {\n if (!this.#order) return rows;\n const rank = new Map<T, number>();\n this.#order.forEach((row, i) => {\n rank.set(row, i);\n });\n return [...rows].sort((a, b) => {\n const ra = rank.has(a) ? (rank.get(a) as number) : Number.POSITIVE_INFINITY;\n const rb = rank.has(b) ? (rank.get(b) as number) : Number.POSITIVE_INFINITY;\n return ra - rb;\n });\n }\n\n /**\n * The current manual order as a copy of its row references, or `null` for the\n * derived order. Consumed by `ApexGrid.getState`.\n */\n public getManualOrder(): T[] | null {\n return this.#order ? [...this.#order] : null;\n }\n\n /**\n * Restores a manual order from a list of row references (state restore). Pass\n * `null` (or an empty list) to clear it. Silent: emits no `rowMoving` /\n * `rowMoved` and does not animate; re-runs the pipeline.\n */\n public restoreManualOrder(order: T[] | null): void {\n this.#order = order?.length ? [...order] : null;\n this.host.requestUpdate(PIPELINE);\n }\n\n /**\n * Clears the manual order (e.g. when a sort is applied). Re-runs the pipeline.\n */\n public clearManualOrder(announce = false): void {\n if (!this.#order) return;\n this.#order = null;\n this.host.requestUpdate(PIPELINE);\n if (announce) this.host.announce(this.host.localize('announce.manualOrderCleared'));\n }\n\n /**\n * Carries the manual order onto a new `data` array through `carry` (by\n * `rowId` when set, else the rows still present), clearing it when no row\n * survives. A grab or drag follows its row onto the new data, so an app\n * that re-sets `data` on `rowMoved` keeps the gesture; it ends only when\n * the row is gone.\n */\n public resetForDataChange(carry: (rows: T[]) => T[]): void {\n const pre = this.#preGrab;\n if (this.grabbed) {\n this.grabbed = carry([this.grabbed])[0] ?? null;\n if (!this.grabbed) this.#preGrab = null;\n else if (pre) {\n pre.order = pre.order && carry(pre.order);\n pre.data = pre.data && carry(pre.data);\n }\n }\n const pending = this.#pending;\n const held = pending?.data ?? this.dragging;\n if (held) {\n const row = carry([held])[0];\n if (!row) this.#endPointer();\n else {\n if (pending) pending.data = row;\n if (this.dragging) this.dragging = row;\n }\n }\n if (this.#order) this.restoreManualOrder(carry(this.#order));\n }\n\n /**\n * Moves the row at view index `from` relative to the row at view index `to`.\n * Indices are into {@link ApexGrid.pageItems}.\n *\n * @returns `true` when applied, `false` when disabled, out of range, a\n * no-op (the row would land where it is), or cancelled via `rowMoving`.\n */\n public moveRow(from: number, to: number, position: RowDropPosition = 'before'): boolean {\n const view = this.host.pageItems;\n const before = this.#captureRowRects();\n const ok = this.#commit(view[from] as T, view[to] as T, position);\n if (ok) void this.#flipAfterUpdate(before);\n return ok;\n }\n\n // --- pointer drag -------------------------------------------------------\n\n /**\n * Begins a pointer drag from `source`. When `ghost` is supplied (the pointer\n * path always does), seeds the floating ghost from the source row's rect and\n * the grab point so it stays anchored under the cursor.\n */\n public startDrag(source: T, ghost?: RowGhostInit): void {\n if (!this.enabled) return;\n this.dragging = source;\n this.ghost = ghost\n ? {\n x: ghost.rect.left,\n y: ghost.rect.top,\n width: ghost.rect.width,\n height: ghost.rect.height,\n pointerOffsetX: ghost.clientX - ghost.rect.left,\n pointerOffsetY: ghost.clientY - ghost.rect.top,\n cells: ghost.cells,\n }\n : null;\n this.host.requestUpdate();\n }\n\n /** Moves the floating ghost to track the cursor. No-op without an active ghost. */\n public moveGhost(clientX: number, clientY: number): void {\n if (!this.ghost) return;\n this.ghost = {\n ...this.ghost,\n x: clientX - this.ghost.pointerOffsetX,\n y: clientY - this.ghost.pointerOffsetY,\n };\n this.host.requestUpdate();\n }\n\n /**\n * Called on pointer-move during a drag: live-swaps the dragged row past the\n * body row currently under `clientY` once the cursor crosses its midpoint.\n */\n public dragOver(clientY: number): void {\n if (!this.dragging || this.#swapping) return;\n const target = this.#bodyRowAt(clientY);\n if (!target || target.data === this.dragging) return;\n\n const view = this.host.pageItems;\n const sourceIdx = view.indexOf(this.dragging);\n const targetIdx = view.indexOf(target.data);\n if (sourceIdx === -1 || targetIdx === -1) return;\n\n const rect = target.element.getBoundingClientRect();\n const midpoint = rect.top + rect.height / 2;\n let position: RowDropPosition;\n if (sourceIdx < targetIdx) {\n if (clientY < midpoint) return; // dragging down — wait for the midpoint\n position = 'after';\n } else {\n if (clientY > midpoint) return; // dragging up\n position = 'before';\n }\n void this.#dragSwap(target.data, position);\n }\n\n /** Ends the pointer drag. The order is already final (live-swapped). */\n public endDrag(): void {\n if (!this.dragging) return;\n this.dragging = null;\n this.ghost = null;\n this.host.requestUpdate();\n }\n\n /**\n * Arms a pointer drag from a row press. Called by the row on `pointerdown`\n * (from the grip in handle mode, or anywhere in whole-row mode). The move\n * listener is bound to the **grid host**, so the gesture is immune to the\n * source row's DOM being recycled by a live-swap; the up / cancel listeners\n * are bound to the document, so a release outside the grid ends it too, as\n * does a move with the primary button no longer held. `getGhost` is a thunk\n * the controller invokes once, the instant the drag engages, to snapshot the\n * row's cells (the row is still in place then).\n */\n public armPointerDrag(data: T, getGhost: () => RowGhostInit, event: PointerEvent): void {\n const pinned = this.host.pinnedRows;\n if (!this.enabled || pinned.top.includes(data) || pinned.bottom.includes(data)) return;\n this.#pending = {\n data,\n getGhost,\n startX: event.clientX,\n startY: event.clientY,\n pointerId: event.pointerId,\n };\n const host = this.#hostElement;\n host.addEventListener('pointermove', this.#onHostPointerMove);\n host.ownerDocument.addEventListener('pointerup', this.#onPointerUp, true);\n host.ownerDocument.addEventListener('pointercancel', this.#onPointerUp, true);\n }\n\n #onHostPointerMove = (event: PointerEvent): void => {\n const pending = this.#pending;\n if (!pending || event.pointerId !== pending.pointerId) return;\n // The release was missed (e.g. outside the window): a hover is not a drag.\n if (!(event.buttons & 1)) {\n this.#endPointer();\n return;\n }\n if (!this.dragging) {\n const dx = event.clientX - pending.startX;\n const dy = event.clientY - pending.startY;\n if (Math.hypot(dx, dy) < DRAG_THRESHOLD_PX) return;\n // Capture on the stable host so moves keep arriving even when the cursor\n // leaves the grid, and so the source row reflowing can't drop the pointer.\n try {\n this.#hostElement.setPointerCapture(pending.pointerId);\n } catch {\n /* a synthetic pointer id may not be capturable; hit-testing still works */\n }\n this.startDrag(pending.data, pending.getGhost());\n }\n this.moveGhost(event.clientX, event.clientY);\n this.dragOver(event.clientY);\n };\n\n #onPointerUp = (event: PointerEvent): void => {\n if (event.pointerId === this.#pending?.pointerId) this.#endPointer();\n };\n\n /** Tears down an armed or engaged pointer gesture. */\n #endPointer(): void {\n const pending = this.#pending;\n if (pending) {\n const host = this.#hostElement;\n host.removeEventListener('pointermove', this.#onHostPointerMove);\n host.ownerDocument.removeEventListener('pointerup', this.#onPointerUp, true);\n host.ownerDocument.removeEventListener('pointercancel', this.#onPointerUp, true);\n try {\n if (host.hasPointerCapture(pending.pointerId)) {\n host.releasePointerCapture(pending.pointerId);\n }\n } catch {\n /* capture was never taken or already released */\n }\n this.#pending = null;\n }\n this.endDrag();\n }\n\n async #dragSwap(target: T, position: RowDropPosition): Promise<void> {\n if (this.#swapping) return;\n this.#swapping = true;\n try {\n const before = this.#captureRowRects();\n if (this.#commit(this.dragging as T, target, position)) {\n await this.host.updateComplete;\n await awaitChildUpdates(this.host.rows);\n this.#playRowFlip(before);\n }\n } finally {\n this.#swapping = false;\n }\n }\n\n // --- keyboard grab ------------------------------------------------------\n\n /** Grabs the row at view index `rowIndex` for keyboard reorder. */\n public grab(rowIndex: number): boolean {\n if (!this.enabled) return false;\n const row = this.host.pageItems[rowIndex] as T | undefined;\n if (!row) return false;\n this.grabbed = row;\n this.#preGrab = {\n order: this.#order,\n data: this.applyToData ? [...this.host.data] : null,\n sort: this.host.sortExpressions,\n index: rowIndex,\n };\n this.host.requestUpdate();\n this.host.announce(this.host.localize('announce.rowGrabbed'));\n return true;\n }\n\n /**\n * Moves the grabbed row one position in `direction`. Returns the grabbed\n * row's new view index, or `-1` when it can't move (no grab / at the edge).\n */\n public moveGrabbed(direction: -1 | 1): number {\n if (!this.grabbed) return -1;\n const view = this.host.pageItems;\n const current = view.indexOf(this.grabbed);\n const target = current + direction;\n if (current === -1 || target < 0 || target >= view.length) return -1;\n const before = this.#captureRowRects();\n const ok = this.#commit(this.grabbed, view[target] as T, direction > 0 ? 'after' : 'before', {\n silent: true,\n });\n if (!ok) return -1;\n void this.#flipAfterUpdate(before);\n this.host.announce(this.host.localize('announce.rowMovedTo', { position: target + 1 }));\n return target;\n }\n\n /** Drops the grabbed row, keeping its moves. */\n public drop(): void {\n if (!this.grabbed) return;\n this.grabbed = null;\n this.#preGrab = null;\n this.host.requestUpdate();\n this.host.announce(this.host.localize('announce.rowDropped'));\n }\n\n /**\n * Cancels the grab, reverting the order, the data order (with\n * `applyToData`) and the sort to what they were when the row was grabbed.\n * Emits `rowMoved` for the way back when the row had moved, so an app\n * persisting each step sees the revert too.\n */\n public cancelGrab(): void {\n const row = this.grabbed;\n const pre = this.#preGrab;\n if (!row || !pre) return;\n const from = this.host.pageItems.indexOf(row);\n this.grabbed = this.#preGrab = null;\n this.#order = pre.order;\n if (pre.data) this.#spliceData(pre.data);\n if (pre.sort.length) this.host.sortExpressions = pre.sort;\n this.host.requestUpdate(PIPELINE);\n this.host.announce(this.host.localize('announce.reorderCancelled'));\n const to = pre.index;\n if (from !== to) {\n const position: RowDropPosition = from > to ? 'before' : 'after';\n this.host.emitEvent('rowMoved', { detail: { from, to, position, toIndex: to, data: row } });\n }\n }\n\n // --- internals ----------------------------------------------------------\n\n /**\n * The order every row is in, hidden by a filter or not: the manual order,\n * else `data` under the active sort, with rows it lacks following in data\n * order. The rows the view shows are laid into their own slots in view order,\n * so the move applies to exactly what the user sees and hidden rows stay put.\n */\n #fullOrder(): T[] {\n const data = this.host.data;\n const sort = this.host.sortExpressions;\n let base: T[];\n if (this.#order) {\n const rest = new Set(data);\n base = this.#order.filter((row) => rest.delete(row));\n base.push(...rest);\n } else if (sort.length && !this.host.dataPipelineConfiguration?.sort) {\n const state = new Map(sort.map((expr) => [expr.key, expr] as const));\n base = new SortDataOperation<T>().apply([...data], state);\n } else {\n base = [...data];\n }\n const listed = new Set(base);\n const shown = this.host.dataView.filter((row) => listed.has(row));\n const inView = new Set(shown);\n let k = 0;\n return base.map((row) => (inView.has(row) ? shown[k++] : row));\n }\n\n /**\n * The core order mutation: validates, emits `rowMoving` (cancellable),\n * updates the manual order (or splices data when `applyToData`), clears any\n * sort (a move establishes a manual order, which a sort would undo), re-runs\n * the pipeline, and emits `rowMoved`. Does not animate.\n */\n #commit(\n source: T | undefined,\n target: T | undefined,\n position: RowDropPosition,\n options: { silent?: boolean } = {}\n ): boolean {\n if (!this.enabled || !source || !target || source === target) return false;\n const view = this.host.pageItems;\n const from = view.indexOf(source);\n const to = view.indexOf(target);\n // Where the row lands in the view; a move that leaves it in place is no move.\n const toIndex = position === 'after' ? (from < to ? to : to + 1) : from < to ? to - 1 : to;\n if (from === -1 || to === -1 || toIndex === from) return false;\n\n // A row outside the order (a tree child, a module's row) cannot move.\n const next = this.#fullOrder();\n const at = next.indexOf(source);\n if (at === -1 || !next.includes(target)) return false;\n next.splice(at, 1);\n next.splice(next.indexOf(target) + (position === 'after' ? 1 : 0), 0, source);\n // Rows outside the order (group rows) can make a view move a no-op too.\n if (next.indexOf(source) === at) return false;\n\n const detail = { from, to, position, toIndex, data: source };\n if (!this.host.emitEvent('rowMoving', { detail, cancelable: true })) return false;\n\n if (this.host.sortExpressions.length) this.host.sortExpressions = [];\n\n if (this.applyToData) {\n this.#spliceData(next);\n this.#order = null; // the data array now carries the order\n } else {\n this.#order = next;\n }\n\n this.host.requestUpdate(PIPELINE);\n if (!options.silent) this.host.announce(this.host.localize('announce.rowMoved'));\n this.host.emitEvent('rowMoved', { detail });\n return true;\n }\n\n /** Reorders {@link ApexGrid.data} in place to match `order`. */\n #spliceData(order: ReadonlyArray<T>): void {\n const rank = new Map<T, number>();\n order.forEach((row, i) => {\n rank.set(row, i);\n });\n (this.host.data as T[]).sort((a, b) => {\n const ra = rank.has(a) ? (rank.get(a) as number) : Number.POSITIVE_INFINITY;\n const rb = rank.has(b) ? (rank.get(b) as number) : Number.POSITIVE_INFINITY;\n return ra - rb;\n });\n }\n\n /** The rendered body row (non-pinned) whose box contains `clientY`. */\n #bodyRowAt(clientY: number): { data: T; element: HTMLElement } | null {\n const pinned = this.host.pinnedRows;\n for (const row of this.host.rows) {\n if (pinned.top.includes(row.data) || pinned.bottom.includes(row.data)) continue;\n const element = row as unknown as HTMLElement;\n const rect = element.getBoundingClientRect();\n if (clientY >= rect.top && clientY < rect.bottom) return { data: row.data, element };\n }\n return null;\n }\n\n #captureRowRects(): KeyedFlipEntry<T>[] {\n const entries: KeyedFlipEntry<T>[] = [];\n for (const row of this.host.rows) {\n const el = row as unknown as HTMLElement;\n entries.push({ key: row.data, rect: el.getBoundingClientRect() });\n }\n return entries;\n }\n\n async #flipAfterUpdate(before: ReadonlyArray<KeyedFlipEntry<T>>): Promise<void> {\n await this.host.updateComplete;\n await awaitChildUpdates(this.host.rows);\n this.#playRowFlip(before);\n }\n\n #playRowFlip(before: ReadonlyArray<KeyedFlipEntry<T>>): void {\n const byData = new Map<T, HTMLElement>();\n for (const row of this.host.rows) {\n byData.set(row.data, row as unknown as HTMLElement);\n }\n playKeyedFlip(before, (data) => byData.get(data) ?? null, 'y');\n }\n}\n"]}
@@ -19,6 +19,10 @@ export declare const DEFAULT_SELECTION_CONFIG: Readonly<{
19
19
  * any selected rows that are no longer present in the new array; consumers
20
20
  * should call {@link clear} or re-apply selection after such a change.
21
21
  *
22
+ * Only data records are selectable: rows a feature module synthesizes into the
23
+ * view (group headers, a grand-total row; see {@link StateController.isDataRow})
24
+ * are skipped by every mutation and ignored by {@link allSelected}.
25
+ *
22
26
  * Mutations go through the cancellable `rowSelecting` event and emit a
23
27
  * follow-up `rowSelected` event, mirroring the pattern used by editing.
24
28
  */
@@ -55,8 +59,10 @@ export declare class SelectionController<T extends object> implements ReactiveCo
55
59
  */
56
60
  selectedRows(): T[];
57
61
  /**
58
- * Whether every row in the current view ({@link ApexGrid.dataView}) is
59
- * selected. Used by the header checkbox to render its "all" state.
62
+ * Whether every data record the current view covers is selected, including
63
+ * the leaves of collapsed groups (see {@link StateController.viewRecords}).
64
+ * `false` when the view covers none. Used by the header checkbox to render
65
+ * its "all" state.
60
66
  */
61
67
  allSelected(): boolean;
62
68
  /**
@@ -92,8 +98,9 @@ export declare class SelectionController<T extends object> implements ReactiveCo
92
98
  */
93
99
  rangeToggle(row: T): Promise<boolean>;
94
100
  /**
95
- * Selects every row currently in view ({@link ApexGrid.dataView}). No-op
96
- * in `'single'` mode.
101
+ * Selects every data record the current view ({@link ApexGrid.dataView})
102
+ * covers, including the leaves of collapsed groups. No-op in `'single'`
103
+ * mode.
97
104
  */
98
105
  selectAll(): Promise<boolean>;
99
106
  /**