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/components/row.js CHANGED
@@ -14,6 +14,20 @@ import { GRID_ROW_TAG } from '../internal/tags.js';
14
14
  import { getPinEdge } from '../internal/utils.js';
15
15
  import { styles } from '../styles/body-row/body-row.css.js';
16
16
  import ApexGridCell from './cell.js';
17
+ const GRIP_ICON = html `<svg
18
+ part="reorder-grip"
19
+ viewBox="0 0 16 16"
20
+ width="16"
21
+ height="16"
22
+ aria-hidden="true"
23
+ >
24
+ <circle cx="6" cy="3.5" r="1.25" />
25
+ <circle cx="10" cy="3.5" r="1.25" />
26
+ <circle cx="6" cy="8" r="1.25" />
27
+ <circle cx="10" cy="8" r="1.25" />
28
+ <circle cx="6" cy="12.5" r="1.25" />
29
+ <circle cx="10" cy="12.5" r="1.25" />
30
+ </svg>`;
17
31
  export default class ApexGridRow extends LitElement {
18
32
  constructor() {
19
33
  super(...arguments);
@@ -22,9 +36,40 @@ export default class ApexGridRow extends LitElement {
22
36
  this.index = -1;
23
37
  this.selected = false;
24
38
  this.expanded = false;
39
+ this.dragging = false;
40
+ this.grabbed = false;
41
+ this.coordinateHints = false;
25
42
  this.editingKey = null;
26
43
  this.decorationVersion = 0;
44
+ this.validationVersion = 0;
27
45
  this.#presented = null;
46
+ this.#dragStartX = 0;
47
+ this.#dragStartY = 0;
48
+ this.#handleReorderPointerDown = (event) => {
49
+ const reorder = this.state?.rowReorder;
50
+ if (!reorder?.enabled || event.button !== 0 || !this.data)
51
+ return;
52
+ if (this.state.rowPin.isPinned(this.data))
53
+ return;
54
+ const path = event.composedPath();
55
+ const onHandle = path.some((node) => node instanceof Element && (node.getAttribute?.('part') ?? '').includes('reorder-handle'));
56
+ if (reorder.handleMode) {
57
+ if (!onHandle)
58
+ return;
59
+ event.preventDefault();
60
+ event.stopPropagation();
61
+ }
62
+ else {
63
+ const target = path[0];
64
+ if (target instanceof Element &&
65
+ target.closest?.('input, button, a, select, textarea, [data-apex-editor]')) {
66
+ return;
67
+ }
68
+ }
69
+ this.#dragStartX = event.clientX;
70
+ this.#dragStartY = event.clientY;
71
+ reorder.armPointerDrag(this.data, () => this.#captureGhost(this.#dragStartX, this.#dragStartY), event);
72
+ };
28
73
  this.ariaRowOffset = 1;
29
74
  }
30
75
  static get tagName() {
@@ -38,10 +83,30 @@ export default class ApexGridRow extends LitElement {
38
83
  return Array.from(this._cells);
39
84
  }
40
85
  #presented;
86
+ #dragStartX;
87
+ #dragStartY;
88
+ #handleReorderPointerDown;
89
+ #captureGhost(clientX, clientY) {
90
+ const rect = this.getBoundingClientRect();
91
+ const cells = this.cells.map((cell) => {
92
+ const el = cell;
93
+ return {
94
+ text: (el.textContent ?? '').replace(/\s+/g, ' ').trim(),
95
+ width: el.getBoundingClientRect().width,
96
+ align: getComputedStyle(el).textAlign,
97
+ };
98
+ });
99
+ return { rect, clientX, clientY, cells };
100
+ }
41
101
  connectedCallback() {
42
102
  super.connectedCallback();
43
103
  this.setAttribute('exportparts', 'cell');
44
104
  this.setAttribute('role', 'row');
105
+ this.addEventListener('pointerdown', this.#handleReorderPointerDown);
106
+ }
107
+ disconnectedCallback() {
108
+ this.removeEventListener('pointerdown', this.#handleReorderPointerDown);
109
+ super.disconnectedCallback();
45
110
  }
46
111
  willUpdate() {
47
112
  this.setAttribute('aria-rowindex', String(this.index + this.ariaRowOffset + 1));
@@ -94,6 +159,23 @@ export default class ApexGridRow extends LitElement {
94
159
  }
95
160
  }
96
161
  }
162
+ renderRowNumber() {
163
+ if (!this.coordinateHints)
164
+ return nothing;
165
+ const pinned = Boolean(this.state?.rowPin?.isPinned(this.data));
166
+ return html `<div part="row-number-cell" data-pinned="start" aria-hidden="true">
167
+ ${pinned ? nothing : html `<span part="row-number">${this.index + 1}</span>`}
168
+ </div>`;
169
+ }
170
+ renderReorderHandle() {
171
+ const reorder = this.state?.rowReorder;
172
+ if (!reorder?.showHandleColumn)
173
+ return nothing;
174
+ const draggable = !this.state?.rowPin?.isPinned(this.data);
175
+ return html `<div part="reorder-handle-cell" data-pinned="start" aria-hidden="true">
176
+ ${draggable ? html `<span part="reorder-handle">${GRIP_ICON}</span>` : nothing}
177
+ </div>`;
178
+ }
97
179
  renderExpansionToggle(colindex) {
98
180
  const expansion = this.state?.expansion;
99
181
  if (!expansion?.showToggleColumn)
@@ -115,7 +197,7 @@ export default class ApexGridRow extends LitElement {
115
197
  <button
116
198
  type="button"
117
199
  part="expansion-toggle"
118
- aria-label=${expanded ? 'Collapse row' : 'Expand row'}
200
+ aria-label=${expanded ? this.state.localize('row.collapse') : this.state.localize('row.expand')}
119
201
  aria-expanded=${expanded ? 'true' : 'false'}
120
202
  ?disabled=${!canExpand}
121
203
  @click=${handleClick}
@@ -151,7 +233,7 @@ export default class ApexGridRow extends LitElement {
151
233
  rowIndex: this.index,
152
234
  parent: this.state.host,
153
235
  });
154
- return html `<div part="detail-panel" role="region" aria-label="Row detail">${content}</div>`;
236
+ return html `<div part="detail-panel" role="region" aria-label=${this.state.localize('row.detail')}>${content}</div>`;
155
237
  }
156
238
  renderSelectionCell(colindex) {
157
239
  if (!this.state?.selection.showCheckboxColumn)
@@ -184,7 +266,7 @@ export default class ApexGridRow extends LitElement {
184
266
  <input
185
267
  type="checkbox"
186
268
  part="selection-checkbox"
187
- aria-label="Select row"
269
+ aria-label=${this.state.localize('row.select')}
188
270
  .checked=${selected}
189
271
  @click=${handleClick}
190
272
  @change=${handleChange}
@@ -204,6 +286,8 @@ export default class ApexGridRow extends LitElement {
204
286
  const selectionCol = this.state?.selection.showCheckboxColumn ? ++colCursor : 0;
205
287
  const expansionCol = this.state?.expansion.showToggleColumn ? ++colCursor : 0;
206
288
  return html `
289
+ ${this.renderRowNumber()}
290
+ ${this.renderReorderHandle()}
207
291
  ${this.renderSelectionCell(selectionCol)}
208
292
  ${this.renderExpansionToggle(expansionCol)}
209
293
  ${repeat(this.columns, (column) => String(column.key), (column, colIndex) => {
@@ -227,6 +311,7 @@ export default class ApexGridRow extends LitElement {
227
311
  .value=${this.data[column.key]}
228
312
  .colindex=${ariaColindex}
229
313
  .decorationVersion=${this.decorationVersion}
314
+ .validationVersion=${this.validationVersion}
230
315
  ></apex-grid-cell>`;
231
316
  })}
232
317
  ${this.renderDetailPanel()}
@@ -261,12 +346,24 @@ __decorate([
261
346
  __decorate([
262
347
  property({ type: Boolean, reflect: true })
263
348
  ], ApexGridRow.prototype, "expanded", void 0);
349
+ __decorate([
350
+ property({ type: Boolean, reflect: true })
351
+ ], ApexGridRow.prototype, "dragging", void 0);
352
+ __decorate([
353
+ property({ type: Boolean, reflect: true })
354
+ ], ApexGridRow.prototype, "grabbed", void 0);
355
+ __decorate([
356
+ property({ type: Boolean })
357
+ ], ApexGridRow.prototype, "coordinateHints", void 0);
264
358
  __decorate([
265
359
  property({ attribute: false })
266
360
  ], ApexGridRow.prototype, "editingKey", void 0);
267
361
  __decorate([
268
362
  property({ attribute: false, type: Number })
269
363
  ], ApexGridRow.prototype, "decorationVersion", void 0);
364
+ __decorate([
365
+ property({ attribute: false, type: Number })
366
+ ], ApexGridRow.prototype, "validationVersion", void 0);
270
367
  __decorate([
271
368
  property({ attribute: false, type: Number })
272
369
  ], ApexGridRow.prototype, "ariaRowOffset", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"row.js","sourceRoot":"","sources":["../../src/components/row.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property, queryAll } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport type { PresentedRow } from '../internal/feature-module.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_ROW_TAG } from '../internal/tags.js';\nimport type { ActiveNode, ColumnConfiguration, Keys } from '../internal/types.js';\nimport { getPinEdge } from '../internal/utils.js';\nimport { styles } from '../styles/body-row/body-row.css.js';\nimport ApexGridCell from './cell.js';\n\n/**\n * Component representing the DOM row in the Apex grid.\n */\nexport default class ApexGridRow<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_ROW_TAG;\n }\n public static override styles = styles;\n\n public static register(): void {\n registerComponent(ApexGridRow, ApexGridCell);\n }\n\n @queryAll(ApexGridCell.tagName)\n protected _cells!: NodeListOf<ApexGridCell<T>>;\n\n @property({ attribute: false })\n public data!: T;\n\n @property({ attribute: false })\n public columns: Array<ColumnConfiguration<T>> = [];\n\n /** Cumulative pin offsets (px) keyed by column key. */\n @property({ attribute: false })\n public pinOffsets: Map<unknown, number> = new Map();\n\n public get cells() {\n return Array.from(this._cells);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n @property({ attribute: false })\n public activeNode!: ActiveNode<T>;\n\n @property({ attribute: false, type: Number })\n public index = -1;\n\n /** Reflects current selection state so SCSS can highlight the row. */\n @property({ type: Boolean, reflect: true })\n public selected = false;\n\n /** Reflects current expansion state so SCSS can rotate the chevron. */\n @property({ type: Boolean, reflect: true })\n public expanded = false;\n\n /** The column key currently being edited in this row, or `null`. */\n @property({ attribute: false })\n public editingKey: Keys<T> | null = null;\n\n /**\n * Reactive token from {@link StateController.decorationVersion}, forwarded to\n * each cell so a decoration-only change re-renders the row's cells. Stays `0`\n * for the community grid.\n */\n @property({ attribute: false, type: Number })\n public decorationVersion = 0;\n\n /**\n * Result of the feature-module row presenter for the current update, or\n * `null` when no module renders this row full-width (the normal case).\n * Computed in {@link willUpdate} and consumed in {@link render}.\n */\n #presented: PresentedRow | null = null;\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('exportparts', 'cell');\n this.setAttribute('role', 'row');\n }\n\n /**\n * The number of \"chrome\" rows (header + filter) above the body. Used to\n * derive `aria-rowindex` from {@link index}. Set by the parent grid.\n */\n @property({ attribute: false, type: Number })\n public ariaRowOffset = 1;\n\n protected override willUpdate() {\n this.setAttribute('aria-rowindex', String(this.index + this.ariaRowOffset + 1));\n\n // Ask feature modules whether this row is rendered full-width (e.g. an\n // enterprise group header). When one owns it, the row is not a selectable\n // data row — it carries its own level/expanded semantics and skips the\n // selection/tree aria below.\n this.#presented = this.state\n ? this.state.presentRow(this.data, { columns: this.columns, rowIndex: this.index })\n : null;\n if (this.#presented) {\n this.selected = false;\n this.removeAttribute('aria-selected');\n if (typeof this.#presented.level === 'number') {\n this.setAttribute('aria-level', String(this.#presented.level));\n } else {\n this.removeAttribute('aria-level');\n }\n if (typeof this.#presented.expanded === 'boolean') {\n this.setAttribute('aria-expanded', this.#presented.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n return;\n }\n\n this.selected = Boolean(this.state?.selection.isSelected(this.data));\n this.expanded = Boolean(this.state?.expansion.isExpanded(this.data));\n if (this.state?.selection.enabled) {\n this.setAttribute('aria-selected', this.selected ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-selected');\n }\n\n // Tree mode reports aria-level (1-based depth) and aria-expanded for\n // parent rows; expansion mode shares the same attribute on detail-panel\n // rows. Tree wins when both are enabled since it's the more structural\n // semantic (the row represents a tree node).\n const tree = this.state?.tree;\n const treeMeta = tree?.enabled ? tree.getMeta(this.data) : undefined;\n if (treeMeta) {\n this.setAttribute('aria-level', String(treeMeta.depth + 1));\n if (treeMeta.hasChildren) {\n this.setAttribute('aria-expanded', tree!.isExpanded(this.data) ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n } else {\n this.removeAttribute('aria-level');\n if (this.state?.expansion.enabled) {\n this.setAttribute('aria-expanded', this.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n }\n }\n\n protected renderExpansionToggle(colindex: number) {\n const expansion = this.state?.expansion;\n if (!expansion?.showToggleColumn) return nothing;\n const canExpand = expansion.canExpand(this.data) || expansion.isExpanded(this.data);\n const expanded = this.expanded;\n const handleClick = (event: MouseEvent) => {\n event.stopPropagation();\n if (!canExpand) return;\n void expansion.toggleRow(this.data);\n };\n return html`<div\n part=\"expansion-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <button\n type=\"button\"\n part=\"expansion-toggle\"\n aria-label=${expanded ? 'Collapse row' : 'Expand row'}\n aria-expanded=${expanded ? 'true' : 'false'}\n ?disabled=${!canExpand}\n @click=${handleClick}\n >\n <svg\n part=\"expansion-chevron\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n width=\"14\"\n height=\"14\"\n >\n <path\n d=\"M9 6l6 6-6 6\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>`;\n }\n\n protected renderDetailPanel() {\n const expansion = this.state?.expansion;\n if (!expansion?.isExpanded(this.data)) return nothing;\n const template = this.state.host.expansion?.detailTemplate;\n if (typeof template !== 'function') return nothing;\n const content = template({\n data: this.data,\n rowIndex: this.index,\n parent: this.state.host,\n });\n return html`<div part=\"detail-panel\" role=\"region\" aria-label=\"Row detail\">${content}</div>`;\n }\n\n protected renderSelectionCell(colindex: number) {\n if (!this.state?.selection.showCheckboxColumn) return nothing;\n const selected = this.selected;\n const handleChange = (event: Event) => {\n const mouseEvent = event as Event & {\n shiftKey?: boolean;\n ctrlKey?: boolean;\n metaKey?: boolean;\n };\n // The native `change` event on a checkbox doesn't expose modifier keys\n // — they're carried on the preceding `click`. We handle Shift/Ctrl in\n // the click listener below; the change handler covers keyboard toggles\n // (Space on a focused checkbox) which always behave as plain toggles.\n void mouseEvent;\n this.state.selection.toggleRow(this.data);\n };\n const handleClick = (event: MouseEvent) => {\n // Prevent the click from bubbling to the grid's body click handler\n // (which would otherwise re-target the active cell to a non-existent\n // selection column).\n event.stopPropagation();\n if (event.shiftKey && this.state.selection.mode === 'multiple') {\n event.preventDefault();\n void this.state.selection.rangeToggle(this.data);\n return;\n }\n if ((event.ctrlKey || event.metaKey) && this.state.selection.mode === 'multiple') {\n event.preventDefault();\n void this.state.selection.additiveToggle(this.data);\n return;\n }\n // Plain click: let the default checkbox toggle proceed; `change` will\n // commit the new state via `toggleRow`.\n };\n return html`<div\n part=\"selection-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <input\n type=\"checkbox\"\n part=\"selection-checkbox\"\n aria-label=\"Select row\"\n .checked=${selected}\n @click=${handleClick}\n @change=${handleChange}\n />\n </div>`;\n }\n\n protected override render() {\n // Full-width module-rendered row (e.g. a group header): render the module's\n // content spanning all columns, like the master-detail panel, and skip the\n // normal selection/expansion/cell grid.\n if (this.#presented) {\n return html`<div part=${this.#presented.part ?? 'group-row'} style=\"grid-column: 1 / -1\">\n ${this.#presented.content}\n </div>`;\n }\n\n // A row index can transiently fall beyond the current data — e.g. while a\n // server-side / infinite row model resizes `data` on a filter or sort\n // change, the virtualizer may render a stale index for a frame. Render\n // nothing until the real item arrives, rather than dereferencing undefined.\n if (this.data == null) return nothing;\n\n const { column: key, row: index } = this.activeNode;\n\n // Track aria-colindex (1-based) across the auto chrome columns and the\n // data columns. Selection comes first, then expansion, then data.\n let colCursor = 0;\n const selectionCol = this.state?.selection.showCheckboxColumn ? ++colCursor : 0;\n const expansionCol = this.state?.expansion.showToggleColumn ? ++colCursor : 0;\n\n // Keyed by column.key so the same `<apex-grid-cell>` follows its\n // column through a reorder swap — required for the column-reorder FLIP\n // animation in ReorderController to track motion per cell.\n return html`\n ${this.renderSelectionCell(selectionCol)}\n ${this.renderExpansionToggle(expansionCol)}\n ${repeat(\n this.columns,\n (column) => String(column.key),\n (column, colIndex) => {\n if (column.hidden) return nothing;\n const offset = this.pinOffsets.get(column.key);\n const pinStyle =\n column.pinned && typeof offset === 'number' ? `--apex-pin-offset:${offset}px` : '';\n const edge = getPinEdge(this.columns, colIndex);\n const editing = this.editingKey === column.key;\n const ariaColindex = ++colCursor;\n return html`<apex-grid-cell\n part=\"cell\"\n data-pinned=${column.pinned ?? 'none'}\n data-pin-edge=${edge ?? 'none'}\n data-cell-type=${column.type ?? 'string'}\n style=${pinStyle}\n .active=${key === column.key && index === this.index}\n .editing=${editing}\n .column=${column}\n .row=${this as ApexGridRow<T>}\n .value=${this.data[column.key]}\n .colindex=${ariaColindex}\n .decorationVersion=${this.decorationVersion}\n ></apex-grid-cell>`;\n }\n )}\n ${this.renderDetailPanel()}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridRow.tagName]: ApexGridRow<object>;\n }\n}\n"]}
1
+ {"version":3,"file":"row.js","sourceRoot":"","sources":["../../src/components/row.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,OAAO,EAAE,gBAAgB,EAAwB,MAAM,yBAAyB,CAAC;AAEjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAC5D,OAAO,YAAY,MAAM,WAAW,CAAC;AAGrC,MAAM,SAAS,GAAG,IAAI,CAAA;;;;;;;;;;;;;OAaf,CAAC;AAKR,MAAM,CAAC,OAAO,OAAO,WAA8B,SAAQ,UAAU;IAArE;;QAiBS,YAAO,GAAkC,EAAE,CAAC;QAI5C,eAAU,GAAyB,IAAI,GAAG,EAAE,CAAC;QAc7C,UAAK,GAAG,CAAC,CAAC,CAAC;QAIX,aAAQ,GAAG,KAAK,CAAC;QAIjB,aAAQ,GAAG,KAAK,CAAC;QAIjB,aAAQ,GAAG,KAAK,CAAC;QAIjB,YAAO,GAAG,KAAK,CAAC;QAIhB,oBAAe,GAAG,KAAK,CAAC;QAIxB,eAAU,GAAmB,IAAI,CAAC;QAQlC,sBAAiB,GAAG,CAAC,CAAC;QAStB,sBAAiB,GAAG,CAAC,CAAC;QAO7B,eAAU,GAAwB,IAAI,CAAC;QAEvC,gBAAW,GAAG,CAAC,CAAC;QAChB,gBAAW,GAAG,CAAC,CAAC;QAQhB,8BAAyB,GAAG,CAAC,KAAmB,EAAE,EAAE;YAClD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC;YACvC,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;gBAAE,OAAO;YAElE,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO;YAElD,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;YAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CACxB,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,YAAY,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAC5F,CAAC;YAEF,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;gBAGvB,IAAI,CAAC,QAAQ;oBAAE,OAAO;gBAGtB,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,eAAe,EAAE,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBAGN,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBACvB,IACE,MAAM,YAAY,OAAO;oBACzB,MAAM,CAAC,OAAO,EAAE,CAAC,wDAAwD,CAAC,EAC1E,CAAC;oBACD,OAAO;gBACT,CAAC;YACH,CAAC;YAED,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC;YACjC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC;YAGjC,OAAO,CAAC,cAAc,CACpB,IAAI,CAAC,IAAI,EACT,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,EAC5D,KAAK,CACN,CAAC;QACJ,CAAC,CAAC;QAqCK,kBAAa,GAAG,CAAC,CAAC;IAqQ3B,CAAC;IAhbQ,MAAM,KAAK,OAAO;QACvB,OAAO,YAAY,CAAC;IACtB,CAAC;aACsB,WAAM,GAAG,MAAM,AAAT,CAAU;IAEhC,MAAM,CAAC,QAAQ;QACpB,iBAAiB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAC/C,CAAC;IAeD,IAAW,KAAK;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IA0DD,UAAU,CAA6B;IAEvC,WAAW,CAAK;IAChB,WAAW,CAAK;IAQhB,yBAAyB,CAyCvB;IAOF,aAAa,CAAC,OAAe,EAAE,OAAe;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACpC,MAAM,EAAE,GAAG,IAA8B,CAAC;YAC1C,OAAO;gBACL,IAAI,EAAE,CAAC,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE;gBACxD,KAAK,EAAE,EAAE,CAAC,qBAAqB,EAAE,CAAC,KAAK;gBACvC,KAAK,EAAE,gBAAgB,CAAC,EAAE,CAAC,CAAC,SAAS;aACtC,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC3C,CAAC;IAEe,iBAAiB;QAC/B,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACvE,CAAC;IAEe,oBAAoB;QAClC,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACxE,KAAK,CAAC,oBAAoB,EAAE,CAAC;IAC/B,CAAC;IASkB,UAAU;QAC3B,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC;QAMhF,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK;YAC1B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YACnF,CAAC,CAAC,IAAI,CAAC;QACT,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;YACtC,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9C,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;YACjE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;YACrC,CAAC;YACD,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAClD,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAClF,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;YACxC,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACrE,IAAI,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;QACxC,CAAC;QAMD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrE,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;YAC5D,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACzB,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,IAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YACrF,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;YACnC,IAAI,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC;gBAClC,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YACvE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAQS,eAAe;QACvB,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO,OAAO,CAAC;QAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAChE,OAAO,IAAI,CAAA;QACP,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA,2BAA2B,IAAI,CAAC,KAAK,GAAG,CAAC,SAAS;WACtE,CAAC;IACV,CAAC;IAQS,mBAAmB;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC;QACvC,IAAI,CAAC,OAAO,EAAE,gBAAgB;YAAE,OAAO,OAAO,CAAC;QAC/C,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAA;QACP,SAAS,CAAC,CAAC,CAAC,IAAI,CAAA,+BAA+B,SAAS,SAAS,CAAC,CAAC,CAAC,OAAO;WACxE,CAAC;IACV,CAAC;IAES,qBAAqB,CAAC,QAAgB;QAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC;QACxC,IAAI,CAAC,SAAS,EAAE,gBAAgB;YAAE,OAAO,OAAO,CAAC;QACjD,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpF,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,MAAM,WAAW,GAAG,CAAC,KAAiB,EAAE,EAAE;YACxC,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,CAAC,SAAS;gBAAE,OAAO;YACvB,KAAK,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC;QACF,OAAO,IAAI,CAAA;;;sBAGO,QAAQ;;;;;;qBAOpB,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CACnF;wBACgB,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;oBAC/B,CAAC,SAAS;iBACb,WAAW;;;;;;;;;;;;;;;;;;;WAmBjB,CAAC;IACV,CAAC;IAES,iBAAiB;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC;QACxC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,OAAO,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC;QAC3D,IAAI,OAAO,QAAQ,KAAK,UAAU;YAAE,OAAO,OAAO,CAAC;QACnD,MAAM,OAAO,GAAG,QAAQ,CAAC;YACvB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,KAAK;YACpB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;SACxB,CAAC,CAAC;QACH,OAAO,IAAI,CAAA,qDAAqD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,OAAO,QAAQ,CAAC;IACvH,CAAC;IAES,mBAAmB,CAAC,QAAgB;QAC5C,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,kBAAkB;YAAE,OAAO,OAAO,CAAC;QAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE;YACpC,MAAM,UAAU,GAAG,KAIlB,CAAC;YAKF,KAAK,UAAU,CAAC;YAChB,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC,CAAC;QACF,MAAM,WAAW,GAAG,CAAC,KAAiB,EAAE,EAAE;YAIxC,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC/D,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjD,OAAO;YACT,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACjF,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpD,OAAO;YACT,CAAC;QAGH,CAAC,CAAC;QACF,OAAO,IAAI,CAAA;;;sBAGO,QAAQ;;;;;;qBAMT,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC;mBACnC,QAAQ;iBACV,WAAW;kBACV,YAAY;;WAEnB,CAAC;IACV,CAAC;IAEkB,MAAM;QAIvB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,OAAO,IAAI,CAAA,aAAa,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,WAAW;UACvD,IAAI,CAAC,UAAU,CAAC,OAAO;aACpB,CAAC;QACV,CAAC;QAMD,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI;YAAE,OAAO,OAAO,CAAC;QAEtC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC;QAIpD,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAChF,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAK9E,OAAO,IAAI,CAAA;QACP,IAAI,CAAC,eAAe,EAAE;QACtB,IAAI,CAAC,mBAAmB,EAAE;QAC1B,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC;QACtC,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC;QACxC,MAAM,CACN,IAAI,CAAC,OAAO,EACZ,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAC9B,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;YACnB,IAAI,MAAM,CAAC,MAAM;gBAAE,OAAO,OAAO,CAAC;YAClC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,QAAQ,GACZ,MAAM,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,qBAAqB,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACrF,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAChD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,KAAK,MAAM,CAAC,GAAG,CAAC;YAC/C,MAAM,YAAY,GAAG,EAAE,SAAS,CAAC;YACjC,OAAO,IAAI,CAAA;;0BAEK,MAAM,CAAC,MAAM,IAAI,MAAM;4BACrB,IAAI,IAAI,MAAM;6BACb,MAAM,CAAC,IAAI,IAAI,QAAQ;oBAChC,QAAQ;sBACN,GAAG,KAAK,MAAM,CAAC,GAAG,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK;uBACzC,OAAO;sBACR,MAAM;mBACT,IAAsB;qBACpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;wBAClB,YAAY;iCACH,IAAI,CAAC,iBAAiB;iCACtB,IAAI,CAAC,iBAAiB;6BAC1B,CAAC;QACtB,CAAC,CACF;QACC,IAAI,CAAC,iBAAiB,EAAE;KAC3B,CAAC;IACJ,CAAC;;AAraS;IADT,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC;2CACgB;AAGxC;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;yCACf;AAGT;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;4CACoB;AAI5C;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;+CACqB;AAQ7C;IAFN,OAAO,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACvD,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;0CACG;AAG3B;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;+CACG;AAG3B;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CAC3B;AAIX;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;6CACnB;AAIjB;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;6CACnB;AAIjB;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;6CACnB;AAIjB;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;4CACpB;AAIhB;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;oDACG;AAIxB;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;+CACU;AAQlC;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sDAChB;AAStB;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sDAChB;AAgGtB;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;kDACpB","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property, queryAll } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport type { RowGhostInit } from '../controllers/row-reorder.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport type { PresentedRow } from '../internal/feature-module.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_ROW_TAG } from '../internal/tags.js';\nimport type { ActiveNode, ColumnConfiguration, Keys } from '../internal/types.js';\nimport { getPinEdge } from '../internal/utils.js';\nimport { styles } from '../styles/body-row/body-row.css.js';\nimport ApexGridCell from './cell.js';\n\n/** The six-dot grip drawn inside the row-reorder drag handle. */\nconst GRIP_ICON = html`<svg\n part=\"reorder-grip\"\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n>\n <circle cx=\"6\" cy=\"3.5\" r=\"1.25\" />\n <circle cx=\"10\" cy=\"3.5\" r=\"1.25\" />\n <circle cx=\"6\" cy=\"8\" r=\"1.25\" />\n <circle cx=\"10\" cy=\"8\" r=\"1.25\" />\n <circle cx=\"6\" cy=\"12.5\" r=\"1.25\" />\n <circle cx=\"10\" cy=\"12.5\" r=\"1.25\" />\n</svg>`;\n\n/**\n * Component representing the DOM row in the Apex grid.\n */\nexport default class ApexGridRow<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_ROW_TAG;\n }\n public static override styles = styles;\n\n public static register(): void {\n registerComponent(ApexGridRow, ApexGridCell);\n }\n\n @queryAll(ApexGridCell.tagName)\n protected _cells!: NodeListOf<ApexGridCell<T>>;\n\n @property({ attribute: false })\n public data!: T;\n\n @property({ attribute: false })\n public columns: Array<ColumnConfiguration<T>> = [];\n\n /** Cumulative pin offsets (px) keyed by column key. */\n @property({ attribute: false })\n public pinOffsets: Map<unknown, number> = new Map();\n\n public get cells() {\n return Array.from(this._cells);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n @property({ attribute: false })\n public activeNode!: ActiveNode<T>;\n\n @property({ attribute: false, type: Number })\n public index = -1;\n\n /** Reflects current selection state so SCSS can highlight the row. */\n @property({ type: Boolean, reflect: true })\n public selected = false;\n\n /** Reflects current expansion state so SCSS can rotate the chevron. */\n @property({ type: Boolean, reflect: true })\n public expanded = false;\n\n /** Reflects pointer-drag state (row reorder) so SCSS can dim the source. */\n @property({ type: Boolean, reflect: true })\n public dragging = false;\n\n /** Reflects keyboard-grab state (row reorder) so SCSS can outline the row. */\n @property({ type: Boolean, reflect: true })\n public grabbed = false;\n\n /** Reveal the spreadsheet row-number gutter cell (transient formula coordinate hint). */\n @property({ type: Boolean })\n public coordinateHints = false;\n\n /** The column key currently being edited in this row, or `null`. */\n @property({ attribute: false })\n public editingKey: Keys<T> | null = null;\n\n /**\n * Reactive token from {@link StateController.decorationVersion}, forwarded to\n * each cell so a decoration-only change re-renders the row's cells. Stays `0`\n * for the community grid.\n */\n @property({ attribute: false, type: Number })\n public decorationVersion = 0;\n\n /**\n * Reactive token from {@link EditingController.validationVersion}, forwarded to\n * each cell so a validation-only change re-renders the row's cells (toggling\n * `aria-invalid` and the inline error node). Stays `0` until the first\n * validation failure.\n */\n @property({ attribute: false, type: Number })\n public validationVersion = 0;\n\n /**\n * Result of the feature-module row presenter for the current update, or\n * `null` when no module renders this row full-width (the normal case).\n * Computed in {@link willUpdate} and consumed in {@link render}.\n */\n #presented: PresentedRow | null = null;\n\n #dragStartX = 0;\n #dragStartY = 0;\n\n /**\n * Arms a row drag. In handle mode only the grip starts one; in whole-row mode\n * a press anywhere except an interactive sub-part does. The move / up plumbing\n * lives on the grid host (see {@link RowReorderController.armPointerDrag}), so\n * a live-swap that recycles this row's DOM can't break the gesture.\n */\n #handleReorderPointerDown = (event: PointerEvent) => {\n const reorder = this.state?.rowReorder;\n if (!reorder?.enabled || event.button !== 0 || !this.data) return;\n // Pinned rows are not reorder sources (F4 scope).\n if (this.state.rowPin.isPinned(this.data)) return;\n\n const path = event.composedPath();\n const onHandle = path.some(\n (node) =>\n node instanceof Element && (node.getAttribute?.('part') ?? '').includes('reorder-handle')\n );\n\n if (reorder.handleMode) {\n // Handle mode: only the grip starts a drag. The rest of the row stays free\n // for selection / editing / text selection.\n if (!onHandle) return;\n // Own the gesture: keep the grid's body handler from treating the press as\n // a cell interaction, and suppress native text/element drag-selection.\n event.preventDefault();\n event.stopPropagation();\n } else {\n // Whole-row mode: a drag begins anywhere except an interactive sub-part\n // (editor, checkbox, button).\n const target = path[0];\n if (\n target instanceof Element &&\n target.closest?.('input, button, a, select, textarea, [data-apex-editor]')\n ) {\n return;\n }\n }\n\n this.#dragStartX = event.clientX;\n this.#dragStartY = event.clientY;\n // The controller snapshots the ghost the instant the drag engages (the row\n // is still in place then), seeded from the original press point.\n reorder.armPointerDrag(\n this.data,\n () => this.#captureGhost(this.#dragStartX, this.#dragStartY),\n event\n );\n };\n\n /**\n * Snapshots the row's visible cells (text, width, alignment) and bounding rect\n * so the controller can paint a faithful floating ghost. Invoked once, at the\n * moment the drag engages.\n */\n #captureGhost(clientX: number, clientY: number): RowGhostInit {\n const rect = this.getBoundingClientRect();\n const cells = this.cells.map((cell) => {\n const el = cell as unknown as HTMLElement;\n return {\n text: (el.textContent ?? '').replace(/\\s+/g, ' ').trim(),\n width: el.getBoundingClientRect().width,\n align: getComputedStyle(el).textAlign,\n };\n });\n return { rect, clientX, clientY, cells };\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('exportparts', 'cell');\n this.setAttribute('role', 'row');\n this.addEventListener('pointerdown', this.#handleReorderPointerDown);\n }\n\n public override disconnectedCallback(): void {\n this.removeEventListener('pointerdown', this.#handleReorderPointerDown);\n super.disconnectedCallback();\n }\n\n /**\n * The number of \"chrome\" rows (header + filter) above the body. Used to\n * derive `aria-rowindex` from {@link index}. Set by the parent grid.\n */\n @property({ attribute: false, type: Number })\n public ariaRowOffset = 1;\n\n protected override willUpdate() {\n this.setAttribute('aria-rowindex', String(this.index + this.ariaRowOffset + 1));\n\n // Ask feature modules whether this row is rendered full-width (e.g. an\n // enterprise group header). When one owns it, the row is not a selectable\n // data row — it carries its own level/expanded semantics and skips the\n // selection/tree aria below.\n this.#presented = this.state\n ? this.state.presentRow(this.data, { columns: this.columns, rowIndex: this.index })\n : null;\n if (this.#presented) {\n this.selected = false;\n this.removeAttribute('aria-selected');\n if (typeof this.#presented.level === 'number') {\n this.setAttribute('aria-level', String(this.#presented.level));\n } else {\n this.removeAttribute('aria-level');\n }\n if (typeof this.#presented.expanded === 'boolean') {\n this.setAttribute('aria-expanded', this.#presented.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n return;\n }\n\n this.selected = Boolean(this.state?.selection.isSelected(this.data));\n this.expanded = Boolean(this.state?.expansion.isExpanded(this.data));\n if (this.state?.selection.enabled) {\n this.setAttribute('aria-selected', this.selected ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-selected');\n }\n\n // Tree mode reports aria-level (1-based depth) and aria-expanded for\n // parent rows; expansion mode shares the same attribute on detail-panel\n // rows. Tree wins when both are enabled since it's the more structural\n // semantic (the row represents a tree node).\n const tree = this.state?.tree;\n const treeMeta = tree?.enabled ? tree.getMeta(this.data) : undefined;\n if (treeMeta) {\n this.setAttribute('aria-level', String(treeMeta.depth + 1));\n if (treeMeta.hasChildren) {\n this.setAttribute('aria-expanded', tree!.isExpanded(this.data) ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n } else {\n this.removeAttribute('aria-level');\n if (this.state?.expansion.enabled) {\n this.setAttribute('aria-expanded', this.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n }\n }\n\n /**\n * Leading row-number gutter cell (transient spreadsheet coordinate hint). Shown\n * only while `coordinateHints` is on; pinned rows render an empty spacer (their\n * band-local index is not a meaningful A1 row number) so the track stays\n * aligned. Presentational: the accessible row index is `aria-rowindex`.\n */\n protected renderRowNumber() {\n if (!this.coordinateHints) return nothing;\n const pinned = Boolean(this.state?.rowPin?.isPinned(this.data));\n return html`<div part=\"row-number-cell\" data-pinned=\"start\" aria-hidden=\"true\">\n ${pinned ? nothing : html`<span part=\"row-number\">${this.index + 1}</span>`}\n </div>`;\n }\n\n /**\n * Leading drag-handle (grip) cell. Rendered only in handle mode; pinned rows\n * get an empty spacer so the grid track stays aligned. The cell is\n * presentational (`aria-hidden`) — the accessible reorder path is the keyboard\n * grab flow, not this pointer affordance.\n */\n protected renderReorderHandle() {\n const reorder = this.state?.rowReorder;\n if (!reorder?.showHandleColumn) return nothing;\n const draggable = !this.state?.rowPin?.isPinned(this.data);\n return html`<div part=\"reorder-handle-cell\" data-pinned=\"start\" aria-hidden=\"true\">\n ${draggable ? html`<span part=\"reorder-handle\">${GRIP_ICON}</span>` : nothing}\n </div>`;\n }\n\n protected renderExpansionToggle(colindex: number) {\n const expansion = this.state?.expansion;\n if (!expansion?.showToggleColumn) return nothing;\n const canExpand = expansion.canExpand(this.data) || expansion.isExpanded(this.data);\n const expanded = this.expanded;\n const handleClick = (event: MouseEvent) => {\n event.stopPropagation();\n if (!canExpand) return;\n void expansion.toggleRow(this.data);\n };\n return html`<div\n part=\"expansion-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <button\n type=\"button\"\n part=\"expansion-toggle\"\n aria-label=${\n expanded ? this.state.localize('row.collapse') : this.state.localize('row.expand')\n }\n aria-expanded=${expanded ? 'true' : 'false'}\n ?disabled=${!canExpand}\n @click=${handleClick}\n >\n <svg\n part=\"expansion-chevron\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n width=\"14\"\n height=\"14\"\n >\n <path\n d=\"M9 6l6 6-6 6\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>`;\n }\n\n protected renderDetailPanel() {\n const expansion = this.state?.expansion;\n if (!expansion?.isExpanded(this.data)) return nothing;\n const template = this.state.host.expansion?.detailTemplate;\n if (typeof template !== 'function') return nothing;\n const content = template({\n data: this.data,\n rowIndex: this.index,\n parent: this.state.host,\n });\n return html`<div part=\"detail-panel\" role=\"region\" aria-label=${this.state.localize('row.detail')}>${content}</div>`;\n }\n\n protected renderSelectionCell(colindex: number) {\n if (!this.state?.selection.showCheckboxColumn) return nothing;\n const selected = this.selected;\n const handleChange = (event: Event) => {\n const mouseEvent = event as Event & {\n shiftKey?: boolean;\n ctrlKey?: boolean;\n metaKey?: boolean;\n };\n // The native `change` event on a checkbox doesn't expose modifier keys\n // — they're carried on the preceding `click`. We handle Shift/Ctrl in\n // the click listener below; the change handler covers keyboard toggles\n // (Space on a focused checkbox) which always behave as plain toggles.\n void mouseEvent;\n this.state.selection.toggleRow(this.data);\n };\n const handleClick = (event: MouseEvent) => {\n // Prevent the click from bubbling to the grid's body click handler\n // (which would otherwise re-target the active cell to a non-existent\n // selection column).\n event.stopPropagation();\n if (event.shiftKey && this.state.selection.mode === 'multiple') {\n event.preventDefault();\n void this.state.selection.rangeToggle(this.data);\n return;\n }\n if ((event.ctrlKey || event.metaKey) && this.state.selection.mode === 'multiple') {\n event.preventDefault();\n void this.state.selection.additiveToggle(this.data);\n return;\n }\n // Plain click: let the default checkbox toggle proceed; `change` will\n // commit the new state via `toggleRow`.\n };\n return html`<div\n part=\"selection-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <input\n type=\"checkbox\"\n part=\"selection-checkbox\"\n aria-label=${this.state.localize('row.select')}\n .checked=${selected}\n @click=${handleClick}\n @change=${handleChange}\n />\n </div>`;\n }\n\n protected override render() {\n // Full-width module-rendered row (e.g. a group header): render the module's\n // content spanning all columns, like the master-detail panel, and skip the\n // normal selection/expansion/cell grid.\n if (this.#presented) {\n return html`<div part=${this.#presented.part ?? 'group-row'} style=\"grid-column: 1 / -1\">\n ${this.#presented.content}\n </div>`;\n }\n\n // A row index can transiently fall beyond the current data — e.g. while a\n // server-side / infinite row model resizes `data` on a filter or sort\n // change, the virtualizer may render a stale index for a frame. Render\n // nothing until the real item arrives, rather than dereferencing undefined.\n if (this.data == null) return nothing;\n\n const { column: key, row: index } = this.activeNode;\n\n // Track aria-colindex (1-based) across the auto chrome columns and the\n // data columns. Selection comes first, then expansion, then data.\n let colCursor = 0;\n const selectionCol = this.state?.selection.showCheckboxColumn ? ++colCursor : 0;\n const expansionCol = this.state?.expansion.showToggleColumn ? ++colCursor : 0;\n\n // Keyed by column.key so the same `<apex-grid-cell>` follows its\n // column through a reorder swap — required for the column-reorder FLIP\n // animation in ReorderController to track motion per cell.\n return html`\n ${this.renderRowNumber()}\n ${this.renderReorderHandle()}\n ${this.renderSelectionCell(selectionCol)}\n ${this.renderExpansionToggle(expansionCol)}\n ${repeat(\n this.columns,\n (column) => String(column.key),\n (column, colIndex) => {\n if (column.hidden) return nothing;\n const offset = this.pinOffsets.get(column.key);\n const pinStyle =\n column.pinned && typeof offset === 'number' ? `--apex-pin-offset:${offset}px` : '';\n const edge = getPinEdge(this.columns, colIndex);\n const editing = this.editingKey === column.key;\n const ariaColindex = ++colCursor;\n return html`<apex-grid-cell\n part=\"cell\"\n data-pinned=${column.pinned ?? 'none'}\n data-pin-edge=${edge ?? 'none'}\n data-cell-type=${column.type ?? 'string'}\n style=${pinStyle}\n .active=${key === column.key && index === this.index}\n .editing=${editing}\n .column=${column}\n .row=${this as ApexGridRow<T>}\n .value=${this.data[column.key]}\n .colindex=${ariaColindex}\n .decorationVersion=${this.decorationVersion}\n .validationVersion=${this.validationVersion}\n ></apex-grid-cell>`;\n }\n )}\n ${this.renderDetailPanel()}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridRow.tagName]: ApexGridRow<object>;\n }\n}\n"]}
@@ -12,6 +12,7 @@ import { type StateController } from '../controllers/state.js';
12
12
  * @csspart search-icon - The leading search icon.
13
13
  * @csspart search-input - The text input itself.
14
14
  * @csspart toolbar-actions - The trailing actions area (right side).
15
+ * @csspart toolbar-action - A custom host-contributed action button (e.g. "Create chart").
15
16
  * @csspart export-trigger - The export menu trigger button.
16
17
  * @csspart export-menu - The dropdown menu containing export options.
17
18
  * @csspart export-menu-item - A single menu item inside the export dropdown.
@@ -31,8 +32,13 @@ export default class ApexGridToolbar<T extends object> extends LitElement {
31
32
  value: string;
32
33
  /**
33
34
  * The placeholder rendered in the search input.
35
+ *
36
+ * @remarks
37
+ * When unset, falls back to the grid's localized `toolbar.searchPlaceholder`
38
+ * text (see {@link ApexGrid.localeText}).
34
39
  */
35
40
  placeholder: string;
41
+ protected get searchPlaceholder(): string;
36
42
  /**
37
43
  * Debounce window (ms) before {@link ApexGrid.quickFilter} updates.
38
44
  */
@@ -51,7 +57,8 @@ export default class ApexGridToolbar<T extends object> extends LitElement {
51
57
  disconnectedCallback(): void;
52
58
  protected renderQuickFilter(): import("lit-html").TemplateResult<1> | typeof nothing;
53
59
  protected renderExportMenu(): import("lit-html").TemplateResult<1> | typeof nothing;
54
- protected render(): import("lit-html").TemplateResult<1>;
60
+ protected renderToolbarActions(): import("lit-html").TemplateResult<1> | typeof nothing;
61
+ protected render(): import("lit-html").TemplateResult<1> | typeof nothing;
55
62
  }
56
63
  declare global {
57
64
  interface HTMLElementTagNameMap {
@@ -16,7 +16,7 @@ export default class ApexGridToolbar extends LitElement {
16
16
  constructor() {
17
17
  super(...arguments);
18
18
  this.value = '';
19
- this.placeholder = 'Search…';
19
+ this.placeholder = '';
20
20
  this.debounce = 200;
21
21
  this.showQuickFilter = true;
22
22
  this.showExport = false;
@@ -118,6 +118,9 @@ export default class ApexGridToolbar extends LitElement {
118
118
  static register() {
119
119
  registerComponent(ApexGridToolbar);
120
120
  }
121
+ get searchPlaceholder() {
122
+ return this.placeholder || this.state?.localize('toolbar.searchPlaceholder') || 'Search…';
123
+ }
121
124
  #debounceHandle;
122
125
  connectedCallback() {
123
126
  super.connectedCallback();
@@ -166,8 +169,8 @@ export default class ApexGridToolbar extends LitElement {
166
169
  part="search-input"
167
170
  type="search"
168
171
  role="searchbox"
169
- aria-label=${this.placeholder}
170
- placeholder=${this.placeholder}
172
+ aria-label=${this.searchPlaceholder}
173
+ placeholder=${this.searchPlaceholder}
171
174
  .value=${this.value}
172
175
  @input=${this.#handleInput}
173
176
  @keydown=${this.#handleKeydown}
@@ -183,7 +186,7 @@ export default class ApexGridToolbar extends LitElement {
183
186
  <button
184
187
  type="button"
185
188
  part="export-trigger"
186
- aria-label="Export"
189
+ aria-label=${this.state.localize('toolbar.export')}
187
190
  aria-haspopup="menu"
188
191
  aria-expanded=${open ? 'true' : 'false'}
189
192
  @click=${this.#toggleExportMenu}
@@ -195,7 +198,7 @@ export default class ApexGridToolbar extends LitElement {
195
198
  <ul
196
199
  part="export-menu"
197
200
  role="menu"
198
- aria-label="Export options"
201
+ aria-label=${this.state.localize('toolbar.exportOptions')}
199
202
  ?hidden=${!open}
200
203
  @keydown=${this.#handleMenuKeydown}
201
204
  >
@@ -213,11 +216,26 @@ export default class ApexGridToolbar extends LitElement {
213
216
  </ul>
214
217
  </div>`;
215
218
  }
219
+ renderToolbarActions() {
220
+ const actions = this.state?.host?.toolbarActions ?? [];
221
+ if (!actions.length)
222
+ return nothing;
223
+ return html `${actions.map((action) => html `<button
224
+ type="button"
225
+ part="toolbar-action"
226
+ data-action-id=${action.id ?? ''}
227
+ @click=${() => action.run()}
228
+ >
229
+ ${action.label}
230
+ </button>`)}`;
231
+ }
216
232
  render() {
233
+ if (!this.state)
234
+ return nothing;
217
235
  return html `
218
- <div part="toolbar" role="toolbar" aria-label="Grid toolbar">
236
+ <div part="toolbar" role="toolbar" aria-label=${this.state.localize('toolbar.label')}>
219
237
  ${this.renderQuickFilter()}
220
- <div part="toolbar-actions">${this.renderExportMenu()}</div>
238
+ <div part="toolbar-actions">${this.renderToolbarActions()}${this.renderExportMenu()}</div>
221
239
  </div>
222
240
  `;
223
241
  }
@@ -1 +1 @@
1
- {"version":3,"file":"toolbar.js","sourceRoot":"","sources":["../../src/components/toolbar.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { renderIcon } from '../internal/icons.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_TOOLBAR_TAG } from '../internal/tags.js';\nimport { styles } from '../styles/toolbar/toolbar.css.js';\n\n/**\n * Toolbar shown above the grid's header row. Hosts opt-in toolbar features\n * such as the quick-filter (global search) input and the export menu.\n *\n * @element apex-grid-toolbar\n *\n * @csspart toolbar - The toolbar's container element.\n * @csspart toolbar-search - The quick-filter input wrapper.\n * @csspart search-field - The bordered field containing the icon + input.\n * @csspart search-icon - The leading search icon.\n * @csspart search-input - The text input itself.\n * @csspart toolbar-actions - The trailing actions area (right side).\n * @csspart export-trigger - The export menu trigger button.\n * @csspart export-menu - The dropdown menu containing export options.\n * @csspart export-menu-item - A single menu item inside the export dropdown.\n */\nexport default class ApexGridToolbar<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_TOOLBAR_TAG;\n }\n\n public static override styles = styles;\n\n /**\n * Registers the `<apex-grid-toolbar>` element. Idempotent.\n */\n public static register() {\n registerComponent(ApexGridToolbar);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n /**\n * The current quick-filter value, mirrored from {@link ApexGrid.quickFilter}.\n */\n @property({ type: String })\n public value = '';\n\n /**\n * The placeholder rendered in the search input.\n */\n @property({ type: String })\n public placeholder = 'Search…';\n\n /**\n * Debounce window (ms) before {@link ApexGrid.quickFilter} updates.\n */\n @property({ type: Number, attribute: 'debounce' })\n public debounce = 200;\n\n /** Whether to render the quick-filter input. Driven by the parent grid. */\n @property({ attribute: false, type: Boolean })\n public showQuickFilter = true;\n\n /** Whether to render the export menu trigger. Driven by the parent grid. */\n @property({ attribute: false, type: Boolean })\n public showExport = false;\n\n /** Optional override filename (without extension) for exports. */\n @property({ attribute: false, type: String })\n public exportFilename = 'data';\n\n @query('input')\n protected input!: HTMLInputElement;\n\n @query('[part=\"export-trigger\"]')\n protected exportTrigger!: HTMLButtonElement;\n\n @query('[part=\"export-menu\"]')\n protected exportMenuEl!: HTMLElement;\n\n @state()\n protected exportMenuOpen = false;\n\n #debounceHandle: ReturnType<typeof setTimeout> | null = null;\n\n public override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('pointerdown', this.#handleOutsidePointer, true);\n document.addEventListener('keydown', this.#handleDocumentKey, true);\n }\n\n public override disconnectedCallback(): void {\n document.removeEventListener('pointerdown', this.#handleOutsidePointer, true);\n document.removeEventListener('keydown', this.#handleDocumentKey, true);\n if (this.#debounceHandle) {\n clearTimeout(this.#debounceHandle);\n this.#debounceHandle = null;\n }\n super.disconnectedCallback();\n }\n\n #emit(value: string) {\n this.dispatchEvent(\n new CustomEvent<string>('apex-quick-filter', {\n detail: value,\n bubbles: true,\n composed: true,\n })\n );\n }\n\n #handleInput = (event: Event) => {\n event.stopPropagation();\n const next = (event.target as HTMLInputElement).value ?? '';\n if (this.#debounceHandle) clearTimeout(this.#debounceHandle);\n\n if (this.debounce <= 0) {\n this.#emit(next);\n return;\n }\n\n this.#debounceHandle = setTimeout(() => {\n this.#debounceHandle = null;\n this.#emit(next);\n }, this.debounce);\n };\n\n #handleKeydown = (event: KeyboardEvent) => {\n // Don't let arrow keys bubble into the grid navigation controller.\n event.stopPropagation();\n if (event.key === 'Escape' && this.input.value) {\n event.preventDefault();\n this.input.value = '';\n if (this.#debounceHandle) {\n clearTimeout(this.#debounceHandle);\n this.#debounceHandle = null;\n }\n this.#emit('');\n }\n };\n\n #toggleExportMenu = (event?: Event) => {\n event?.stopPropagation();\n this.exportMenuOpen = !this.exportMenuOpen;\n };\n\n #closeExportMenu(returnFocus = false) {\n if (!this.exportMenuOpen) return;\n this.exportMenuOpen = false;\n if (returnFocus) {\n // Return focus to the trigger so keyboard users don't lose their place.\n requestAnimationFrame(() => this.exportTrigger?.focus());\n }\n }\n\n #handleOutsidePointer = (event: PointerEvent) => {\n if (!this.exportMenuOpen) return;\n const path = event.composedPath();\n if (path.includes(this.exportTrigger) || path.includes(this.exportMenuEl)) return;\n this.#closeExportMenu();\n };\n\n #handleDocumentKey = (event: KeyboardEvent) => {\n if (!this.exportMenuOpen) return;\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.#closeExportMenu(true);\n }\n };\n\n #handleExport = (formatId: string) => {\n this.#closeExportMenu();\n const grid = this.state?.host;\n if (!grid) return;\n grid.exportAs(formatId, { filename: this.exportFilename });\n };\n\n /** Lets keyboard users land in the menu when it opens via arrow-down. */\n #handleTriggerKeydown = (event: KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault();\n if (!this.exportMenuOpen) this.exportMenuOpen = true;\n requestAnimationFrame(() => {\n const first = this.exportMenuEl?.querySelector<HTMLElement>('[role=\"menuitem\"]');\n first?.focus();\n });\n }\n };\n\n #handleMenuKeydown = (event: KeyboardEvent) => {\n const items = Array.from(\n this.exportMenuEl?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]') ?? []\n );\n const current = items.indexOf(document.activeElement as HTMLElement);\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault();\n items[(current + 1) % items.length]?.focus();\n } else if (event.key === 'ArrowUp' || event.key === 'Up') {\n event.preventDefault();\n items[(current - 1 + items.length) % items.length]?.focus();\n } else if (event.key === 'Home') {\n event.preventDefault();\n items[0]?.focus();\n } else if (event.key === 'End') {\n event.preventDefault();\n items[items.length - 1]?.focus();\n } else if (event.key === 'Tab') {\n // Tab closes the menu so focus moves naturally to the next focusable.\n this.#closeExportMenu();\n }\n };\n\n protected renderQuickFilter() {\n if (!this.showQuickFilter) return nothing;\n return html`<div part=\"toolbar-search\">\n <label part=\"search-field\">\n ${renderIcon('search', { part: 'search-icon' })}\n <input\n part=\"search-input\"\n type=\"search\"\n role=\"searchbox\"\n aria-label=${this.placeholder}\n placeholder=${this.placeholder}\n .value=${this.value}\n @input=${this.#handleInput}\n @keydown=${this.#handleKeydown}\n />\n </label>\n </div>`;\n }\n\n protected renderExportMenu() {\n if (!this.showExport) return nothing;\n const open = this.exportMenuOpen;\n return html`<div part=\"export\">\n <button\n type=\"button\"\n part=\"export-trigger\"\n aria-label=\"Export\"\n aria-haspopup=\"menu\"\n aria-expanded=${open ? 'true' : 'false'}\n @click=${this.#toggleExportMenu}\n @keydown=${this.#handleTriggerKeydown}\n >\n ${renderIcon('download', { part: 'export-icon' })}\n ${renderIcon('chevron-down', { part: 'export-caret' })}\n </button>\n <ul\n part=\"export-menu\"\n role=\"menu\"\n aria-label=\"Export options\"\n ?hidden=${!open}\n @keydown=${this.#handleMenuKeydown}\n >\n ${(this.state?.host?.exportFormats ?? []).map(\n (format) => html`<li role=\"none\">\n <button\n type=\"button\"\n role=\"menuitem\"\n part=\"export-menu-item\"\n tabindex=\"-1\"\n @click=${() => this.#handleExport(format.id)}\n >\n ${format.label}\n </button>\n </li>`\n )}\n </ul>\n </div>`;\n }\n\n protected override render() {\n return html`\n <div part=\"toolbar\" role=\"toolbar\" aria-label=\"Grid toolbar\">\n ${this.renderQuickFilter()}\n <div part=\"toolbar-actions\">${this.renderExportMenu()}</div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridToolbar.tagName]: ApexGridToolbar<object>;\n }\n}\n"]}
1
+ {"version":3,"file":"toolbar.js","sourceRoot":"","sources":["../../src/components/toolbar.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { renderIcon } from '../internal/icons.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_TOOLBAR_TAG } from '../internal/tags.js';\nimport { styles } from '../styles/toolbar/toolbar.css.js';\n\n/**\n * Toolbar shown above the grid's header row. Hosts opt-in toolbar features\n * such as the quick-filter (global search) input and the export menu.\n *\n * @element apex-grid-toolbar\n *\n * @csspart toolbar - The toolbar's container element.\n * @csspart toolbar-search - The quick-filter input wrapper.\n * @csspart search-field - The bordered field containing the icon + input.\n * @csspart search-icon - The leading search icon.\n * @csspart search-input - The text input itself.\n * @csspart toolbar-actions - The trailing actions area (right side).\n * @csspart toolbar-action - A custom host-contributed action button (e.g. \"Create chart\").\n * @csspart export-trigger - The export menu trigger button.\n * @csspart export-menu - The dropdown menu containing export options.\n * @csspart export-menu-item - A single menu item inside the export dropdown.\n */\nexport default class ApexGridToolbar<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_TOOLBAR_TAG;\n }\n\n public static override styles = styles;\n\n /**\n * Registers the `<apex-grid-toolbar>` element. Idempotent.\n */\n public static register() {\n registerComponent(ApexGridToolbar);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n /**\n * The current quick-filter value, mirrored from {@link ApexGrid.quickFilter}.\n */\n @property({ type: String })\n public value = '';\n\n /**\n * The placeholder rendered in the search input.\n *\n * @remarks\n * When unset, falls back to the grid's localized `toolbar.searchPlaceholder`\n * text (see {@link ApexGrid.localeText}).\n */\n @property({ type: String })\n public placeholder = '';\n\n protected get searchPlaceholder() {\n return this.placeholder || this.state?.localize('toolbar.searchPlaceholder') || 'Search…';\n }\n\n /**\n * Debounce window (ms) before {@link ApexGrid.quickFilter} updates.\n */\n @property({ type: Number, attribute: 'debounce' })\n public debounce = 200;\n\n /** Whether to render the quick-filter input. Driven by the parent grid. */\n @property({ attribute: false, type: Boolean })\n public showQuickFilter = true;\n\n /** Whether to render the export menu trigger. Driven by the parent grid. */\n @property({ attribute: false, type: Boolean })\n public showExport = false;\n\n /** Optional override filename (without extension) for exports. */\n @property({ attribute: false, type: String })\n public exportFilename = 'data';\n\n @query('input')\n protected input!: HTMLInputElement;\n\n @query('[part=\"export-trigger\"]')\n protected exportTrigger!: HTMLButtonElement;\n\n @query('[part=\"export-menu\"]')\n protected exportMenuEl!: HTMLElement;\n\n @state()\n protected exportMenuOpen = false;\n\n #debounceHandle: ReturnType<typeof setTimeout> | null = null;\n\n public override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('pointerdown', this.#handleOutsidePointer, true);\n document.addEventListener('keydown', this.#handleDocumentKey, true);\n }\n\n public override disconnectedCallback(): void {\n document.removeEventListener('pointerdown', this.#handleOutsidePointer, true);\n document.removeEventListener('keydown', this.#handleDocumentKey, true);\n if (this.#debounceHandle) {\n clearTimeout(this.#debounceHandle);\n this.#debounceHandle = null;\n }\n super.disconnectedCallback();\n }\n\n #emit(value: string) {\n this.dispatchEvent(\n new CustomEvent<string>('apex-quick-filter', {\n detail: value,\n bubbles: true,\n composed: true,\n })\n );\n }\n\n #handleInput = (event: Event) => {\n event.stopPropagation();\n const next = (event.target as HTMLInputElement).value ?? '';\n if (this.#debounceHandle) clearTimeout(this.#debounceHandle);\n\n if (this.debounce <= 0) {\n this.#emit(next);\n return;\n }\n\n this.#debounceHandle = setTimeout(() => {\n this.#debounceHandle = null;\n this.#emit(next);\n }, this.debounce);\n };\n\n #handleKeydown = (event: KeyboardEvent) => {\n // Don't let arrow keys bubble into the grid navigation controller.\n event.stopPropagation();\n if (event.key === 'Escape' && this.input.value) {\n event.preventDefault();\n this.input.value = '';\n if (this.#debounceHandle) {\n clearTimeout(this.#debounceHandle);\n this.#debounceHandle = null;\n }\n this.#emit('');\n }\n };\n\n #toggleExportMenu = (event?: Event) => {\n event?.stopPropagation();\n this.exportMenuOpen = !this.exportMenuOpen;\n };\n\n #closeExportMenu(returnFocus = false) {\n if (!this.exportMenuOpen) return;\n this.exportMenuOpen = false;\n if (returnFocus) {\n // Return focus to the trigger so keyboard users don't lose their place.\n requestAnimationFrame(() => this.exportTrigger?.focus());\n }\n }\n\n #handleOutsidePointer = (event: PointerEvent) => {\n if (!this.exportMenuOpen) return;\n const path = event.composedPath();\n if (path.includes(this.exportTrigger) || path.includes(this.exportMenuEl)) return;\n this.#closeExportMenu();\n };\n\n #handleDocumentKey = (event: KeyboardEvent) => {\n if (!this.exportMenuOpen) return;\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.#closeExportMenu(true);\n }\n };\n\n #handleExport = (formatId: string) => {\n this.#closeExportMenu();\n const grid = this.state?.host;\n if (!grid) return;\n grid.exportAs(formatId, { filename: this.exportFilename });\n };\n\n /** Lets keyboard users land in the menu when it opens via arrow-down. */\n #handleTriggerKeydown = (event: KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault();\n if (!this.exportMenuOpen) this.exportMenuOpen = true;\n requestAnimationFrame(() => {\n const first = this.exportMenuEl?.querySelector<HTMLElement>('[role=\"menuitem\"]');\n first?.focus();\n });\n }\n };\n\n #handleMenuKeydown = (event: KeyboardEvent) => {\n const items = Array.from(\n this.exportMenuEl?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]') ?? []\n );\n const current = items.indexOf(document.activeElement as HTMLElement);\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault();\n items[(current + 1) % items.length]?.focus();\n } else if (event.key === 'ArrowUp' || event.key === 'Up') {\n event.preventDefault();\n items[(current - 1 + items.length) % items.length]?.focus();\n } else if (event.key === 'Home') {\n event.preventDefault();\n items[0]?.focus();\n } else if (event.key === 'End') {\n event.preventDefault();\n items[items.length - 1]?.focus();\n } else if (event.key === 'Tab') {\n // Tab closes the menu so focus moves naturally to the next focusable.\n this.#closeExportMenu();\n }\n };\n\n protected renderQuickFilter() {\n if (!this.showQuickFilter) return nothing;\n return html`<div part=\"toolbar-search\">\n <label part=\"search-field\">\n ${renderIcon('search', { part: 'search-icon' })}\n <input\n part=\"search-input\"\n type=\"search\"\n role=\"searchbox\"\n aria-label=${this.searchPlaceholder}\n placeholder=${this.searchPlaceholder}\n .value=${this.value}\n @input=${this.#handleInput}\n @keydown=${this.#handleKeydown}\n />\n </label>\n </div>`;\n }\n\n protected renderExportMenu() {\n if (!this.showExport) return nothing;\n const open = this.exportMenuOpen;\n return html`<div part=\"export\">\n <button\n type=\"button\"\n part=\"export-trigger\"\n aria-label=${this.state.localize('toolbar.export')}\n aria-haspopup=\"menu\"\n aria-expanded=${open ? 'true' : 'false'}\n @click=${this.#toggleExportMenu}\n @keydown=${this.#handleTriggerKeydown}\n >\n ${renderIcon('download', { part: 'export-icon' })}\n ${renderIcon('chevron-down', { part: 'export-caret' })}\n </button>\n <ul\n part=\"export-menu\"\n role=\"menu\"\n aria-label=${this.state.localize('toolbar.exportOptions')}\n ?hidden=${!open}\n @keydown=${this.#handleMenuKeydown}\n >\n ${(this.state?.host?.exportFormats ?? []).map(\n (format) => html`<li role=\"none\">\n <button\n type=\"button\"\n role=\"menuitem\"\n part=\"export-menu-item\"\n tabindex=\"-1\"\n @click=${() => this.#handleExport(format.id)}\n >\n ${format.label}\n </button>\n </li>`\n )}\n </ul>\n </div>`;\n }\n\n protected renderToolbarActions() {\n const actions = this.state?.host?.toolbarActions ?? [];\n if (!actions.length) return nothing;\n return html`${actions.map(\n (action) => html`<button\n type=\"button\"\n part=\"toolbar-action\"\n data-action-id=${action.id ?? ''}\n @click=${() => action.run()}\n >\n ${action.label}\n </button>`\n )}`;\n }\n\n protected override render() {\n if (!this.state) return nothing;\n return html`\n <div part=\"toolbar\" role=\"toolbar\" aria-label=${this.state.localize('toolbar.label')}>\n ${this.renderQuickFilter()}\n <div part=\"toolbar-actions\">${this.renderToolbarActions()}${this.renderExportMenu()}</div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridToolbar.tagName]: ApexGridToolbar<object>;\n }\n}\n"]}
@@ -44,6 +44,7 @@ export class DataOperationsController {
44
44
  transformed = this.hasCustomSort
45
45
  ? await this.customSort({ data: transformed, grid: this.host, type: 'sort' })
46
46
  : this.sorting.apply(transformed, sorting.state);
47
+ transformed = state.rowReorder.apply(transformed);
47
48
  if (state.tree.enabled) {
48
49
  transformed = state.tree.process(transformed);
49
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"data-operation.js","sourceRoot":"","sources":["../../src/controllers/data-operation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport { isDefined } from '../internal/is-defined.js';\nimport type { GridHost } from '../internal/types.js';\nimport FilterDataOperation from '../operations/filter.js';\nimport QuickFilterDataOperation from '../operations/quick-filter.js';\nimport SortDataOperation from '../operations/sort.js';\nimport type { StateController } from './state.js';\n\nexport class DataOperationsController<T extends object> implements ReactiveController {\n protected sorting = new SortDataOperation<T>();\n protected filtering = new FilterDataOperation<T>();\n protected quickFiltering = new QuickFilterDataOperation<T>();\n\n constructor(protected host: GridHost<T>) {\n this.host.addController(this);\n }\n\n public hostConnected() {}\n\n protected get hasCustomSort() {\n return isDefined(this.host.dataPipelineConfiguration?.sort);\n }\n\n protected get hasCustomFilter() {\n return isDefined(this.host.dataPipelineConfiguration?.filter);\n }\n\n protected get hasCustomQuickFilter() {\n return isDefined(this.host.dataPipelineConfiguration?.quickFilter);\n }\n\n protected get customFilter() {\n return this.host.dataPipelineConfiguration!.filter!;\n }\n\n protected get customSort() {\n return this.host.dataPipelineConfiguration!.sort!;\n }\n\n protected get customQuickFilter() {\n return this.host.dataPipelineConfiguration!.quickFilter!;\n }\n\n /**\n * Applies the quick-filter (global search), column-filter, and sort steps of the\n * data pipeline.\n *\n * @remarks\n * The returned dataset is the full post-filter, post-sort view. Pagination is\n * intentionally not applied here so callers can derive `totalItems` and the\n * paginator's `pageCount` from a stable value. The grid slices the page for\n * the virtualizer at render time.\n */\n public async apply(data: T[], state: StateController<T>) {\n const { filtering, sorting } = state;\n let transformed: T[];\n\n const quickFilterTerm = (this.host.quickFilter ?? '').trim();\n transformed = this.hasCustomQuickFilter\n ? await this.customQuickFilter({ data, grid: this.host, type: 'quickFilter' })\n : quickFilterTerm\n ? this.quickFiltering.apply(data, quickFilterTerm, this.host.columns)\n : data;\n\n transformed = this.hasCustomFilter\n ? await this.customFilter({ data: transformed, grid: this.host, type: 'filter' })\n : this.filtering.apply(transformed, filtering.state);\n\n transformed = this.hasCustomSort\n ? await this.customSort({ data: transformed, grid: this.host, type: 'sort' })\n : this.sorting.apply(transformed, sorting.state);\n\n // Tree mode flattens the post-sort rows according to the current\n // expansion set. Disabled is a no-op pass-through, so flat tables keep\n // their existing behaviour untouched.\n if (state.tree.enabled) {\n transformed = state.tree.process(transformed);\n }\n\n // Feature modules (e.g. enterprise row grouping) may inject or reorder rows\n // after the built-in pipeline, before pagination slices the page. With no\n // modules registered this is an identity pass-through, so the community\n // `<apex-grid>` behaviour is unchanged.\n transformed = state.applyModuleTransforms(transformed);\n\n return transformed;\n }\n}\n"]}
1
+ {"version":3,"file":"data-operation.js","sourceRoot":"","sources":["../../src/controllers/data-operation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport { isDefined } from '../internal/is-defined.js';\nimport type { GridHost } from '../internal/types.js';\nimport FilterDataOperation from '../operations/filter.js';\nimport QuickFilterDataOperation from '../operations/quick-filter.js';\nimport SortDataOperation from '../operations/sort.js';\nimport type { StateController } from './state.js';\n\nexport class DataOperationsController<T extends object> implements ReactiveController {\n protected sorting = new SortDataOperation<T>();\n protected filtering = new FilterDataOperation<T>();\n protected quickFiltering = new QuickFilterDataOperation<T>();\n\n constructor(protected host: GridHost<T>) {\n this.host.addController(this);\n }\n\n public hostConnected() {}\n\n protected get hasCustomSort() {\n return isDefined(this.host.dataPipelineConfiguration?.sort);\n }\n\n protected get hasCustomFilter() {\n return isDefined(this.host.dataPipelineConfiguration?.filter);\n }\n\n protected get hasCustomQuickFilter() {\n return isDefined(this.host.dataPipelineConfiguration?.quickFilter);\n }\n\n protected get customFilter() {\n return this.host.dataPipelineConfiguration!.filter!;\n }\n\n protected get customSort() {\n return this.host.dataPipelineConfiguration!.sort!;\n }\n\n protected get customQuickFilter() {\n return this.host.dataPipelineConfiguration!.quickFilter!;\n }\n\n /**\n * Applies the quick-filter (global search), column-filter, and sort steps of the\n * data pipeline.\n *\n * @remarks\n * The returned dataset is the full post-filter, post-sort view. Pagination is\n * intentionally not applied here so callers can derive `totalItems` and the\n * paginator's `pageCount` from a stable value. The grid slices the page for\n * the virtualizer at render time.\n */\n public async apply(data: T[], state: StateController<T>) {\n const { filtering, sorting } = state;\n let transformed: T[];\n\n const quickFilterTerm = (this.host.quickFilter ?? '').trim();\n transformed = this.hasCustomQuickFilter\n ? await this.customQuickFilter({ data, grid: this.host, type: 'quickFilter' })\n : quickFilterTerm\n ? this.quickFiltering.apply(data, quickFilterTerm, this.host.columns)\n : data;\n\n transformed = this.hasCustomFilter\n ? await this.customFilter({ data: transformed, grid: this.host, type: 'filter' })\n : this.filtering.apply(transformed, filtering.state);\n\n transformed = this.hasCustomSort\n ? await this.customSort({ data: transformed, grid: this.host, type: 'sort' })\n : this.sorting.apply(transformed, sorting.state);\n\n // Manual row order (drag-reorder) is applied after sort. Identity\n // pass-through when no manual order is active, so the natural order is\n // untouched.\n transformed = state.rowReorder.apply(transformed);\n\n // Tree mode flattens the post-sort rows according to the current\n // expansion set. Disabled is a no-op pass-through, so flat tables keep\n // their existing behaviour untouched.\n if (state.tree.enabled) {\n transformed = state.tree.process(transformed);\n }\n\n // Feature modules (e.g. enterprise row grouping) may inject or reorder rows\n // after the built-in pipeline, before pagination slices the page. With no\n // modules registered this is an identity pass-through, so the community\n // `<apex-grid>` behaviour is unchanged.\n transformed = state.applyModuleTransforms(transformed);\n\n return transformed;\n }\n}\n"]}
@@ -21,7 +21,23 @@ export declare class GridDOMController<T extends object> implements ReactiveCont
21
21
  * {@link recomputePinOffsets}.
22
22
  */
23
23
  pinOffsets: Map<keyof T, number>;
24
+ /**
25
+ * Number of chrome rows above the body for `aria-rowindex`: an optional group
26
+ * header row and the column header (always present). The filter panel is a
27
+ * floating overlay rather than a table row, so it is not counted here.
28
+ */
29
+ protected get headerRowCount(): number;
24
30
  rowRenderer: RenderItemFunction<T>;
31
+ /**
32
+ * Renders a single pinned row for a sticky band. Reuses {@link ApexGridRow}
33
+ * so selection / expansion / decoration all work by data reference, but pins a
34
+ * sentinel {@link ActiveNode} (pinned rows are presentation + selection
35
+ * surfaces in v1, never the active/edited cell) and renders no editor.
36
+ *
37
+ * @param localIndex - position within the band (drives the active sentinel id).
38
+ * @param ariaRowOffset - so `aria-rowindex` continues the unified sequence.
39
+ */
40
+ pinnedRowRenderer(data: T, localIndex: number, ariaRowOffset: number): import("lit-html").TemplateResult<1>;
25
41
  hostConnected(): Promise<void>;
26
42
  hostUpdate(): void;
27
43
  hostUpdated(): void;
@@ -43,12 +59,14 @@ export declare class GridDOMController<T extends object> implements ReactiveCont
43
59
  recomputePinOffsets(): void;
44
60
  protected observeHeaderCells(): void;
45
61
  /**
46
- * Writes the cumulative height of the sticky top rows into CSS custom
47
- * properties used by the header/filter rows for their `inset-block-start`
48
- * offsets. The toolbar is always at `top: 0`; the header sits below it
49
- * (`--apex-row-top-header`) and the filter sits below the header
50
- * (`--apex-row-top-filter`). Writes are skipped when the values haven't
51
- * changed so the ResizeObserver feedback loop terminates.
62
+ * Writes the cumulative heights of the sticky chrome rows into CSS custom
63
+ * properties used for their `inset-block-start` / `inset-block-end` offsets.
64
+ * The toolbar is at `top: 0`; the header sits below it
65
+ * (`--apex-row-top-header`), the filter below the header
66
+ * (`--apex-row-top-filter`), and the pinned-top band below the filter
67
+ * (`--apex-row-top-pinned`). The pinned-bottom band sticks above the
68
+ * paginator (`--apex-row-bottom-pinned`). Writes are skipped when values are
69
+ * unchanged so the ResizeObserver feedback loop terminates.
52
70
  */
53
71
  recomputeStickyRowOffsets(): void;
54
72
  protected observeStickyRows(): void;