apex-grid 3.5.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 (197) hide show
  1. package/CHANGELOG.md +338 -0
  2. package/LICENSE.md +125 -0
  3. package/README.md +64 -10
  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 +146 -36
  11. package/components/grid.js +442 -103
  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 +11 -9
  17. package/components/header-row.js.map +1 -1
  18. package/components/header.js +32 -20
  19. package/components/header.js.map +1 -1
  20. package/components/row.d.ts +19 -3
  21. package/components/row.js +69 -23
  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 +40 -0
  26. package/components/virtualizer.js +116 -5
  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 +67 -13
  44. package/controllers/navigation.js +191 -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 +38 -22
  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 +56 -7
  67. package/controllers/state.js +76 -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 +3156 -277
  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 +155 -81
  78. package/docs/classes/ApexGridPaginator.html +1 -1
  79. package/docs/classes/ApexGridToolbar.html +3 -3
  80. package/docs/functions/localize.html +2 -2
  81. package/docs/hierarchy.html +1 -1
  82. package/docs/index.html +74 -11
  83. package/docs/interfaces/ApexCellValidationFailedEvent.html +3 -2
  84. package/docs/interfaces/ApexCellValueChangedEvent.html +4 -2
  85. package/docs/interfaces/ApexCellValueChangingEvent.html +3 -2
  86. package/docs/interfaces/ApexGridEventMap.html +5 -2
  87. package/docs/interfaces/ApexRowEditEndedEvent.html +2 -1
  88. package/docs/interfaces/ApexRowEditStartedEvent.html +2 -1
  89. package/docs/interfaces/ApexRowMovingEvent.html +9 -3
  90. package/docs/interfaces/ApexRowPinningEvent.html +1 -1
  91. package/docs/interfaces/ApexTreeRowExpandedEvent.html +4 -1
  92. package/docs/interfaces/ApexTreeRowExpandingEvent.html +4 -1
  93. package/docs/interfaces/BaseApexCellContext.html +1 -1
  94. package/docs/interfaces/BaseApexEditorContext.html +1 -1
  95. package/docs/interfaces/BaseFilterExpression.html +2 -2
  96. package/docs/interfaces/CSVExportOptions.html +12 -4
  97. package/docs/interfaces/DataPipelineConfiguration.html +1 -1
  98. package/docs/interfaces/ExportOptions.html +5 -3
  99. package/docs/interfaces/GridExpansionConfiguration.html +6 -2
  100. package/docs/interfaces/GridRowReorderingConfiguration.html +1 -1
  101. package/docs/interfaces/PaginationState.html +1 -1
  102. package/docs/interfaces/SetStateResult.html +3 -2
  103. package/docs/interfaces/ValidatorContext.html +7 -2
  104. package/docs/media/_token-values.scss +118 -0
  105. package/docs/media/package.json +3 -2
  106. package/docs/modules.html +1 -1
  107. package/docs/types/ExportSource.html +6 -4
  108. package/docs/types/OperandKeys.html +9 -0
  109. package/docs/variables/EN_LOCALE.html +2 -2
  110. package/i18n/en.d.ts +5 -0
  111. package/i18n/en.js +5 -0
  112. package/i18n/en.js.map +1 -1
  113. package/i18n/es.js +5 -0
  114. package/i18n/es.js.map +1 -1
  115. package/internal/column-types.d.ts +27 -1
  116. package/internal/column-types.js +75 -49
  117. package/internal/column-types.js.map +1 -1
  118. package/internal/constants.d.ts +1 -2
  119. package/internal/constants.js +0 -4
  120. package/internal/constants.js.map +1 -1
  121. package/internal/document-styles.d.ts +30 -0
  122. package/internal/document-styles.js +48 -0
  123. package/internal/document-styles.js.map +1 -0
  124. package/internal/export.d.ts +39 -7
  125. package/internal/export.js +35 -34
  126. package/internal/export.js.map +1 -1
  127. package/internal/feature-module.d.ts +60 -3
  128. package/internal/feature-module.js +6 -0
  129. package/internal/feature-module.js.map +1 -1
  130. package/internal/index.d.ts +6 -4
  131. package/internal/index.js +5 -3
  132. package/internal/index.js.map +1 -1
  133. package/internal/normalize-case.d.ts +8 -1
  134. package/internal/normalize-case.js +3 -2
  135. package/internal/normalize-case.js.map +1 -1
  136. package/internal/state-snapshot.d.ts +60 -8
  137. package/internal/state-snapshot.js +87 -19
  138. package/internal/state-snapshot.js.map +1 -1
  139. package/internal/types.d.ts +17 -2
  140. package/internal/types.js.map +1 -1
  141. package/internal/utils.d.ts +34 -6
  142. package/internal/utils.js +30 -21
  143. package/internal/utils.js.map +1 -1
  144. package/internal/validators.js +1 -0
  145. package/internal/validators.js.map +1 -1
  146. package/operations/filter/operands/number.js +9 -6
  147. package/operations/filter/operands/number.js.map +1 -1
  148. package/operations/filter/operands/string.js +2 -3
  149. package/operations/filter/operands/string.js.map +1 -1
  150. package/operations/filter/types.d.ts +13 -1
  151. package/operations/filter/types.js.map +1 -1
  152. package/operations/filter.d.ts +6 -0
  153. package/operations/filter.js +23 -7
  154. package/operations/filter.js.map +1 -1
  155. package/operations/quick-filter.js +2 -5
  156. package/operations/quick-filter.js.map +1 -1
  157. package/operations/sort.d.ts +21 -2
  158. package/operations/sort.js +41 -14
  159. package/operations/sort.js.map +1 -1
  160. package/package.json +8 -3
  161. package/setup.d.ts +11 -0
  162. package/setup.js +9 -19
  163. package/setup.js.map +1 -1
  164. package/styles/_token-values.css.d.ts +1 -0
  165. package/styles/_token-values.css.js +3 -0
  166. package/styles/_token-values.css.js.map +1 -0
  167. package/styles/_tokens.css.js +1 -1
  168. package/styles/_tokens.css.js.map +1 -1
  169. package/styles/body-cell/body-cell.css.js +1 -1
  170. package/styles/body-cell/body-cell.css.js.map +1 -1
  171. package/styles/body-cell/cell-renderers.css.js +1 -1
  172. package/styles/body-cell/cell-renderers.css.js.map +1 -1
  173. package/styles/body-row/body-row.css.js +1 -1
  174. package/styles/body-row/body-row.css.js.map +1 -1
  175. package/styles/document-tokens.css.d.ts +1 -0
  176. package/styles/document-tokens.css.js +3 -0
  177. package/styles/document-tokens.css.js.map +1 -0
  178. package/styles/filter-row/filter-row.css.js +1 -1
  179. package/styles/filter-row/filter-row.css.js.map +1 -1
  180. package/styles/grid/_grid.base.css.js +1 -1
  181. package/styles/grid/_grid.base.css.js.map +1 -1
  182. package/styles/grid/grid.css.js +1 -1
  183. package/styles/grid/grid.css.js.map +1 -1
  184. package/styles/group-header-row/group-header-row.css.js +1 -1
  185. package/styles/group-header-row/group-header-row.css.js.map +1 -1
  186. package/styles/header-cell/header-cell.css.js +1 -1
  187. package/styles/header-cell/header-cell.css.js.map +1 -1
  188. package/styles/header-row/header-row.base.css.js +1 -1
  189. package/styles/header-row/header-row.base.css.js.map +1 -1
  190. package/styles/paginator/paginator.css.js +1 -1
  191. package/styles/paginator/paginator.css.js.map +1 -1
  192. package/styles/toolbar/toolbar.css.js +1 -1
  193. package/styles/toolbar/toolbar.css.js.map +1 -1
  194. package/tokens.css +78 -0
  195. package/LICENSE +0 -80
  196. package/docs/media/LICENSE +0 -80
  197. package/docs/media/_tokens.scss +0 -214
@@ -11,6 +11,7 @@ import { styleMap } from 'lit/directives/style-map.js';
11
11
  import { gridStateContext } from '../controllers/state.js';
12
12
  import { registerComponent } from '../internal/register.js';
13
13
  import { GRID_GROUP_HEADER_ROW_TAG } from '../internal/tags.js';
14
+ import { leadingChromeTracks } from '../internal/utils.js';
14
15
  import { styles } from '../styles/group-header-row/group-header-row.css.js';
15
16
  export default class ApexGridGroupHeaderRow extends LitElement {
16
17
  constructor() {
@@ -33,23 +34,31 @@ export default class ApexGridGroupHeaderRow extends LitElement {
33
34
  this.setAttribute('role', 'row');
34
35
  this.setAttribute('aria-rowindex', '1');
35
36
  }
36
- #chromeCount() {
37
- return ((this.state?.selection.showCheckboxColumn ? 1 : 0) +
38
- (this.state?.expansion.showToggleColumn ? 1 : 0));
37
+ #pinStyle(column) {
38
+ const offset = column.pinned ? this.pinOffsets.get(column.key) : undefined;
39
+ return typeof offset === 'number' ? { '--apex-pin-offset': `${offset}px` } : {};
40
+ }
41
+ #spacer(line, column) {
42
+ return html `<div
43
+ part="group-spacer"
44
+ data-pinned=${column.pinned ?? 'none'}
45
+ style=${styleMap({ gridColumn: `${line} / span 1`, ...this.#pinStyle(column) })}
46
+ ></div>`;
39
47
  }
40
48
  render() {
41
49
  const groupsById = new Map(this.groups.map((group) => [group.id, group]));
42
50
  const visible = this.columns.filter((column) => !column.hidden);
43
- const chrome = this.#chromeCount();
51
+ const chrome = leadingChromeTracks(this.state).length;
52
+ const ariaChrome = (this.state?.selection.showCheckboxColumn ? 1 : 0) +
53
+ (this.state?.expansion.showToggleColumn ? 1 : 0);
44
54
  const seen = new Set();
45
55
  const cells = [];
46
56
  let i = 0;
47
57
  while (i < visible.length) {
48
58
  const column = visible[i];
49
59
  const group = column.group ? groupsById.get(column.group) : undefined;
50
- const startLine = chrome + i + 1;
51
60
  if (!group) {
52
- cells.push(html `<div part="group-spacer" style=${styleMap({ gridColumn: `${startLine} / span 1` })}></div>`);
61
+ cells.push(this.#spacer(chrome + i + 1, column));
53
62
  i += 1;
54
63
  continue;
55
64
  }
@@ -65,42 +74,36 @@ export default class ApexGridGroupHeaderRow extends LitElement {
65
74
  console.warn(`[apex-grid] Column group "${group.id}" is not contiguous within a single pin region; its spanning header was skipped for the out-of-place members.`);
66
75
  }
67
76
  for (let k = i; k <= end; k += 1) {
68
- const line = chrome + k + 1;
69
- cells.push(html `<div part="group-spacer" style=${styleMap({ gridColumn: `${line} / span 1` })}></div>`);
77
+ cells.push(this.#spacer(chrome + k + 1, visible[k]));
70
78
  }
71
79
  i = end + 1;
72
80
  continue;
73
81
  }
74
82
  seen.add(group.id);
75
- cells.push(this.#renderGroupCell(group, visible[i], visible[end], startLine, end, chrome));
83
+ cells.push(this.#renderGroupCell(group, visible[i], visible[end], end - i + 1, chrome + i + 1, ariaChrome + i + 1));
76
84
  i = end + 1;
77
85
  }
78
86
  return html `${chrome > 0
79
- ? html `<div part="group-spacer" style=${styleMap({ gridColumn: `1 / span ${chrome}` })}></div>`
87
+ ? html `<div
88
+ part="group-spacer"
89
+ data-pinned="start"
90
+ style=${styleMap({ gridColumn: `1 / span ${chrome}` })}
91
+ ></div>`
80
92
  : nothing}${cells}`;
81
93
  }
82
- #renderGroupCell(group, first, last, startLine, endIndex, chrome) {
83
- const span = endIndex - (startLine - chrome - 1) + 1;
84
- const endLine = startLine + span;
94
+ #renderGroupCell(group, first, last, span, startLine, colindex) {
85
95
  const pinned = first.pinned ?? null;
86
- const style = { gridColumn: `${startLine} / ${endLine}` };
87
- if (pinned === 'start') {
88
- const offset = this.pinOffsets.get(first.key);
89
- if (typeof offset === 'number')
90
- style['--apex-pin-offset'] = `${offset}px`;
91
- }
92
- else if (pinned === 'end') {
93
- const offset = this.pinOffsets.get(last.key);
94
- if (typeof offset === 'number')
95
- style['--apex-pin-offset'] = `${offset}px`;
96
- }
96
+ const style = {
97
+ gridColumn: `${startLine} / ${startLine + span}`,
98
+ ...this.#pinStyle(pinned === 'end' ? last : first),
99
+ };
97
100
  const content = group.headerTemplate
98
101
  ? group.headerTemplate({ group, span })
99
102
  : group.headerText;
100
103
  return html `<div
101
104
  part="group-header"
102
105
  role="columnheader"
103
- aria-colindex=${startLine}
106
+ aria-colindex=${colindex}
104
107
  aria-colspan=${span}
105
108
  data-pinned=${pinned ?? 'none'}
106
109
  style=${styleMap(style)}
@@ -1 +1 @@
1
- {"version":3,"file":"group-header-row.js","sourceRoot":"","sources":["../../src/components/group-header-row.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_GROUP_HEADER_ROW_TAG } from '../internal/tags.js';\nimport type {\n ApexColumnGroupContext,\n ColumnConfiguration,\n ColumnGroupConfiguration,\n} from '../internal/types.js';\nimport { styles } from '../styles/group-header-row/group-header-row.css.js';\n\n/**\n * Spanning header row rendered above the column header row. Group cells are\n * derived at render time from contiguous runs of same-`group` columns in the\n * display order, split at pin boundaries. Lays out over the same CSS grid tracks\n * as the body (the host applies `grid-template-columns`), spanning members via\n * `grid-column`.\n *\n * @csspart group-header - A spanning group header cell.\n * @csspart group-header-label - The label inside a group header cell.\n * @csspart group-spacer - A placeholder over chrome / ungrouped columns.\n */\nexport default class ApexGridGroupHeaderRow<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_GROUP_HEADER_ROW_TAG;\n }\n\n public static override styles = styles;\n\n public static register(): void {\n registerComponent(ApexGridGroupHeaderRow);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n /** Display-ordered, pin-grouped columns (matches the body track order). */\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 /** Configured column groups. */\n @property({ attribute: false })\n public groups: ColumnGroupConfiguration[] = [];\n\n /** Group ids already warned about (non-contiguous), so we warn once each. */\n #warned = new Set<string>();\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('role', 'row');\n this.setAttribute('aria-rowindex', '1');\n }\n\n /** Number of leading chrome columns (selection + expansion). */\n #chromeCount(): number {\n return (\n (this.state?.selection.showCheckboxColumn ? 1 : 0) +\n (this.state?.expansion.showToggleColumn ? 1 : 0)\n );\n }\n\n protected override render() {\n const groupsById = new Map(this.groups.map((group) => [group.id, group]));\n const visible = this.columns.filter((column) => !column.hidden);\n const chrome = this.#chromeCount();\n const seen = new Set<string>();\n const cells = [];\n\n let i = 0;\n while (i < visible.length) {\n const column = visible[i];\n const group = column.group ? groupsById.get(column.group) : undefined;\n const startLine = chrome + i + 1;\n\n if (!group) {\n cells.push(\n html`<div part=\"group-spacer\" style=${styleMap({ gridColumn: `${startLine} / span 1` })}></div>`\n );\n i += 1;\n continue;\n }\n\n // Extend the run while the next column shares the group id and pin region.\n let end = i;\n while (\n end + 1 < visible.length &&\n visible[end + 1].group === column.group &&\n (visible[end + 1].pinned ?? null) === (column.pinned ?? null)\n ) {\n end += 1;\n }\n\n // A group whose members aren't contiguous within one pin region shows up\n // as a second run for an id we've already rendered — warn and render the\n // run as a plain spacer rather than a misleading duplicate header.\n if (seen.has(group.id)) {\n if (!this.#warned.has(group.id)) {\n this.#warned.add(group.id);\n // biome-ignore lint/suspicious/noConsole: intentional one-shot misconfiguration diagnostic\n console.warn(\n `[apex-grid] Column group \"${group.id}\" is not contiguous within a single pin region; its spanning header was skipped for the out-of-place members.`\n );\n }\n for (let k = i; k <= end; k += 1) {\n const line = chrome + k + 1;\n cells.push(\n html`<div part=\"group-spacer\" style=${styleMap({ gridColumn: `${line} / span 1` })}></div>`\n );\n }\n i = end + 1;\n continue;\n }\n seen.add(group.id);\n\n cells.push(this.#renderGroupCell(group, visible[i], visible[end], startLine, end, chrome));\n i = end + 1;\n }\n\n return html`${\n chrome > 0\n ? html`<div part=\"group-spacer\" style=${styleMap({ gridColumn: `1 / span ${chrome}` })}></div>`\n : nothing\n }${cells}`;\n }\n\n #renderGroupCell(\n group: ColumnGroupConfiguration,\n first: ColumnConfiguration<T>,\n last: ColumnConfiguration<T>,\n startLine: number,\n endIndex: number,\n chrome: number\n ) {\n const span = endIndex - (startLine - chrome - 1) + 1;\n const endLine = startLine + span;\n const pinned = first.pinned ?? null;\n\n const style: Record<string, string> = { gridColumn: `${startLine} / ${endLine}` };\n // Pin the group cell to the edge of its anchoring member so it tracks the\n // frozen column(s) during horizontal scroll.\n if (pinned === 'start') {\n const offset = this.pinOffsets.get(first.key);\n if (typeof offset === 'number') style['--apex-pin-offset'] = `${offset}px`;\n } else if (pinned === 'end') {\n const offset = this.pinOffsets.get(last.key);\n if (typeof offset === 'number') style['--apex-pin-offset'] = `${offset}px`;\n }\n\n const content = group.headerTemplate\n ? group.headerTemplate({ group, span } as ApexColumnGroupContext)\n : group.headerText;\n\n return html`<div\n part=\"group-header\"\n role=\"columnheader\"\n aria-colindex=${startLine}\n aria-colspan=${span}\n data-pinned=${pinned ?? 'none'}\n style=${styleMap(style)}\n >\n <span part=\"group-header-label\">${content}</span>\n </div>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridGroupHeaderRow.tagName]: ApexGridGroupHeaderRow<object>;\n }\n}\n"]}
1
+ {"version":3,"file":"group-header-row.js","sourceRoot":"","sources":["../../src/components/group-header-row.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_GROUP_HEADER_ROW_TAG } from '../internal/tags.js';\nimport type {\n ApexColumnGroupContext,\n ColumnConfiguration,\n ColumnGroupConfiguration,\n} from '../internal/types.js';\nimport { leadingChromeTracks } from '../internal/utils.js';\nimport { styles } from '../styles/group-header-row/group-header-row.css.js';\n\n/**\n * Spanning header row rendered above the column header row. Group cells are\n * derived at render time from contiguous runs of same-`group` columns in the\n * display order, split at pin boundaries. Lays out over the same CSS grid tracks\n * as the body (the host applies `grid-template-columns`), spanning members via\n * `grid-column`.\n *\n * @csspart group-header - A spanning group header cell.\n * @csspart group-header-label - The label inside a group header cell.\n * @csspart group-spacer - A placeholder over chrome / ungrouped columns.\n */\nexport default class ApexGridGroupHeaderRow<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_GROUP_HEADER_ROW_TAG;\n }\n\n public static override styles = styles;\n\n public static register(): void {\n registerComponent(ApexGridGroupHeaderRow);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n /** Display-ordered, pin-grouped columns (matches the body track order). */\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 /** Configured column groups. */\n @property({ attribute: false })\n public groups: ColumnGroupConfiguration[] = [];\n\n /** Group ids already warned about (non-contiguous), so we warn once each. */\n #warned = new Set<string>();\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('role', 'row');\n this.setAttribute('aria-rowindex', '1');\n }\n\n /**\n * The inline pin offset style for a cell over `column`, so a cell over a\n * frozen column stays frozen with it during horizontal scroll.\n */\n #pinStyle(column: ColumnConfiguration<T>): Record<string, string> {\n const offset = column.pinned ? this.pinOffsets.get(column.key) : undefined;\n return typeof offset === 'number' ? { '--apex-pin-offset': `${offset}px` } : {};\n }\n\n #spacer(line: number, column: ColumnConfiguration<T>) {\n return html`<div\n part=\"group-spacer\"\n data-pinned=${column.pinned ?? 'none'}\n style=${styleMap({ gridColumn: `${line} / span 1`, ...this.#pinStyle(column) })}\n ></div>`;\n }\n\n protected override render() {\n const groupsById = new Map(this.groups.map((group) => [group.id, group]));\n const visible = this.columns.filter((column) => !column.hidden);\n // Grid lines count every leading chrome track (the same list the grid\n // template is built from); aria-colindex counts only the selection and\n // expansion cells, as the header row does (the gutter and grip are\n // aria-hidden).\n const chrome = leadingChromeTracks(this.state).length;\n const ariaChrome =\n (this.state?.selection.showCheckboxColumn ? 1 : 0) +\n (this.state?.expansion.showToggleColumn ? 1 : 0);\n const seen = new Set<string>();\n const cells = [];\n\n let i = 0;\n while (i < visible.length) {\n const column = visible[i];\n const group = column.group ? groupsById.get(column.group) : undefined;\n\n if (!group) {\n cells.push(this.#spacer(chrome + i + 1, column));\n i += 1;\n continue;\n }\n\n // Extend the run while the next column shares the group id and pin region.\n let end = i;\n while (\n end + 1 < visible.length &&\n visible[end + 1].group === column.group &&\n (visible[end + 1].pinned ?? null) === (column.pinned ?? null)\n ) {\n end += 1;\n }\n\n // A group whose members aren't contiguous within one pin region shows up\n // as a second run for an id we've already rendered — warn and render the\n // run as a plain spacer rather than a misleading duplicate header.\n if (seen.has(group.id)) {\n if (!this.#warned.has(group.id)) {\n this.#warned.add(group.id);\n // biome-ignore lint/suspicious/noConsole: intentional one-shot misconfiguration diagnostic\n console.warn(\n `[apex-grid] Column group \"${group.id}\" is not contiguous within a single pin region; its spanning header was skipped for the out-of-place members.`\n );\n }\n for (let k = i; k <= end; k += 1) {\n cells.push(this.#spacer(chrome + k + 1, visible[k]));\n }\n i = end + 1;\n continue;\n }\n seen.add(group.id);\n\n cells.push(\n this.#renderGroupCell(\n group,\n visible[i],\n visible[end],\n end - i + 1,\n chrome + i + 1,\n ariaChrome + i + 1\n )\n );\n i = end + 1;\n }\n\n // The spacer over the chrome tracks sticks at the inline start with the\n // chrome cells below it, so scrolling group labels pass under it.\n return html`${\n chrome > 0\n ? html`<div\n part=\"group-spacer\"\n data-pinned=\"start\"\n style=${styleMap({ gridColumn: `1 / span ${chrome}` })}\n ></div>`\n : nothing\n }${cells}`;\n }\n\n #renderGroupCell(\n group: ColumnGroupConfiguration,\n first: ColumnConfiguration<T>,\n last: ColumnConfiguration<T>,\n span: number,\n startLine: number,\n colindex: number\n ) {\n const pinned = first.pinned ?? null;\n // Pin the group cell to the edge of its anchoring member so it tracks the\n // frozen column(s) during horizontal scroll.\n const style: Record<string, string> = {\n gridColumn: `${startLine} / ${startLine + span}`,\n ...this.#pinStyle(pinned === 'end' ? last : first),\n };\n\n const content = group.headerTemplate\n ? group.headerTemplate({ group, span } as ApexColumnGroupContext)\n : group.headerText;\n\n return html`<div\n part=\"group-header\"\n role=\"columnheader\"\n aria-colindex=${colindex}\n aria-colspan=${span}\n data-pinned=${pinned ?? 'none'}\n style=${styleMap(style)}\n >\n <span part=\"group-header-label\">${content}</span>\n </div>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridGroupHeaderRow.tagName]: ApexGridGroupHeaderRow<object>;\n }\n}\n"]}
@@ -23,11 +23,6 @@ export default class ApexGridHeaderRow<T extends object> extends LitElement {
23
23
  * collapses every expanded row when at least one is open.
24
24
  */
25
25
  protected renderExpansionHeader(): import("lit-html").TemplateResult<1> | typeof nothing;
26
- /**
27
- * Header cell for the built-in selection (checkbox) column. Renders a
28
- * "select all on this page" checkbox in multi-select mode; nothing in
29
- * single-select mode (selecting all rows isn't meaningful there).
30
- */
31
26
  /**
32
27
  * Corner spacer aligning the header with the body's leading row-number gutter
33
28
  * (formula coordinate hints). Shows a small "#" glyph.
@@ -38,6 +33,13 @@ export default class ApexGridHeaderRow<T extends object> extends LitElement {
38
33
  * column. Rendered only in row-reorder handle mode.
39
34
  */
40
35
  protected renderReorderHandleHeader(): import("lit-html").TemplateResult<1> | typeof nothing;
36
+ /**
37
+ * Header cell for the built-in selection (checkbox) column. In multi-select
38
+ * mode it renders a "select all" checkbox that selects every row in the
39
+ * current filtered view (all pages, collapsed group leaves included), not
40
+ * just the visible page; in single-select mode only an empty spacer, since
41
+ * selecting all rows isn't meaningful there.
42
+ */
41
43
  protected renderSelectionHeader(): import("lit-html").TemplateResult<1> | typeof nothing;
42
44
  /**
43
45
  * Floating "ghost" element that follows the cursor while a header is
@@ -120,19 +120,15 @@ export default class ApexGridHeaderRow extends LitElement {
120
120
  }
121
121
  const allChecked = selection.allSelected();
122
122
  const indeterminate = selection.someSelected();
123
- const syncIndeterminate = (el) => {
123
+ const syncState = (el) => {
124
124
  if (el instanceof HTMLInputElement) {
125
+ el.checked = allChecked;
125
126
  el.indeterminate = indeterminate;
126
127
  }
127
128
  };
128
129
  const handleChange = (event) => {
129
130
  const checked = event.target.checked;
130
- if (checked) {
131
- void selection.selectAll();
132
- }
133
- else {
134
- void selection.clear();
135
- }
131
+ void (checked ? selection.selectAll() : selection.clear()).then(() => this.requestUpdate());
136
132
  };
137
133
  const forwardToCheckbox = (event) => {
138
134
  const target = event.target;
@@ -153,7 +149,7 @@ export default class ApexGridHeaderRow extends LitElement {
153
149
  part="selection-checkbox"
154
150
  aria-label=${this.state.localize('header.selectAll')}
155
151
  .checked=${allChecked}
156
- ${ref(syncIndeterminate)}
152
+ ${ref(syncState)}
157
153
  @change=${handleChange}
158
154
  />
159
155
  </div>`;
@@ -182,6 +178,10 @@ export default class ApexGridHeaderRow extends LitElement {
182
178
  if (this.state?.expansion.showToggleColumn)
183
179
  colCursor++;
184
180
  let coordCol = 0;
181
+ const letterFor = (key, position) => {
182
+ const label = this.state?.columnCoordinate(key);
183
+ return label === undefined ? columnLetter(position) : (label ?? '');
184
+ };
185
185
  return html `${this.renderRowNumberHeader()}${this.renderReorderHandleHeader()}${this.renderSelectionHeader()}${this.renderExpansionHeader()}${repeat(this.columns, (column) => String(column.key), (column, index) => {
186
186
  if (column.hidden)
187
187
  return nothing;
@@ -190,7 +190,9 @@ export default class ApexGridHeaderRow extends LitElement {
190
190
  const edge = getPinEdge(this.columns, index);
191
191
  const isDragSource = reorderState?.sourceKey === column.key;
192
192
  const ariaColindex = ++colCursor;
193
- const coordinateLetter = this.coordinateHints ? columnLetter(coordCol) : '';
193
+ const coordinateLetter = this.coordinateHints
194
+ ? letterFor(String(column.key), coordCol)
195
+ : '';
194
196
  coordCol += 1;
195
197
  return html `<apex-grid-header
196
198
  part=${partNameMap({
@@ -1 +1 @@
1
- {"version":3,"file":"header-row.js","sourceRoot":"","sources":["../../src/components/header-row.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing, type PropertyValueMap } from 'lit';\nimport { property, queryAll } from 'lit/decorators.js';\nimport { ref } from 'lit/directives/ref.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { partNameMap } from '../internal/part-map.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_HEADER_ROW_TAG } from '../internal/tags.js';\nimport type { ColumnConfiguration } from '../internal/types.js';\nimport { columnLetter, getPinEdge } from '../internal/utils.js';\nimport { styles } from '../styles/header-row/header-row.base.css.js';\nimport ApexGridHeader from './header.js';\n\nexport default class ApexGridHeaderRow<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_HEADER_ROW_TAG;\n }\n public static override styles = styles;\n\n public static register(): void {\n registerComponent(ApexGridHeaderRow, ApexGridHeader);\n }\n\n @queryAll(ApexGridHeader.tagName)\n protected _headers!: NodeListOf<ApexGridHeader<T>>;\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<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 /** Reveal the spreadsheet coordinates (row-number header spacer + column letters). */\n @property({ attribute: false })\n public coordinateHints = false;\n\n public get headers() {\n return Array.from(this._headers);\n }\n\n public override connectedCallback() {\n super.connectedCallback();\n this.setAttribute('tabindex', '0');\n this.setAttribute('role', 'row');\n this.setAttribute('aria-rowindex', '1');\n }\n\n protected override updated(): void {\n // The column header is row 1, or row 2 when a group header row precedes it.\n const depth = this.state?.host?.columnGroupDepth ?? 0;\n this.setAttribute('aria-rowindex', String(depth + 1));\n }\n\n protected override shouldUpdate(props: PropertyValueMap<this> | Map<PropertyKey, this>): boolean {\n for (const header of this.headers) {\n header.requestUpdate();\n }\n\n return super.shouldUpdate(props);\n }\n\n /**\n * Header cell for the built-in expansion (chevron) column. Renders an\n * \"expand all\" toggle that expands every row in the current view, or\n * collapses every expanded row when at least one is open.\n */\n protected renderExpansionHeader() {\n const expansion = this.state?.expansion;\n if (!expansion?.showToggleColumn) return nothing;\n const someExpanded = expansion.expanded.size > 0;\n const handleClick = (event: MouseEvent) => {\n event.stopPropagation();\n if (someExpanded) {\n void expansion.collapseAll();\n } else {\n void expansion.expandAll();\n }\n };\n const selection = this.state?.selection;\n const colindex = selection?.showCheckboxColumn ? 2 : 1;\n return html`<div\n part=\"expansion-header\"\n role=\"columnheader\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <button\n type=\"button\"\n part=\"expansion-toggle\"\n aria-label=${\n someExpanded\n ? this.state.localize('header.collapseAll')\n : this.state.localize('header.expandAll')\n }\n aria-expanded=${someExpanded ? 'true' : 'false'}\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 style=${someExpanded ? 'transform: rotate(90deg)' : ''}\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 /**\n * Header cell for the built-in selection (checkbox) column. Renders a\n * \"select all on this page\" checkbox in multi-select mode; nothing in\n * single-select mode (selecting all rows isn't meaningful there).\n */\n /**\n * Corner spacer aligning the header with the body's leading row-number gutter\n * (formula coordinate hints). Shows a small \"#\" glyph.\n */\n protected renderRowNumberHeader() {\n if (!this.coordinateHints) return nothing;\n return html`<div part=\"row-number-header\" data-pinned=\"start\" aria-hidden=\"true\">#</div>`;\n }\n\n /**\n * Empty corner spacer aligning the header with the body's leading grip-handle\n * column. Rendered only in row-reorder handle mode.\n */\n protected renderReorderHandleHeader() {\n if (!this.state?.rowReorder?.showHandleColumn) return nothing;\n return html`<div part=\"reorder-handle-header\" data-pinned=\"start\" aria-hidden=\"true\"></div>`;\n }\n\n protected renderSelectionHeader() {\n const selection = this.state?.selection;\n if (!selection?.showCheckboxColumn) return nothing;\n if (selection.mode === 'single') {\n // Reserve the track so cells below line up — but no select-all\n // affordance in single-row-selection mode.\n return html`<div part=\"selection-header\" data-pinned=\"start\"></div>`;\n }\n const allChecked = selection.allSelected();\n const indeterminate = selection.someSelected();\n const syncIndeterminate = (el: Element | undefined) => {\n if (el instanceof HTMLInputElement) {\n el.indeterminate = indeterminate;\n }\n };\n const handleChange = (event: Event) => {\n const checked = (event.target as HTMLInputElement).checked;\n if (checked) {\n void selection.selectAll();\n } else {\n void selection.clear();\n }\n };\n // As in the body's selection cell: the 14x14 checkbox is under the 24x24\n // WCAG 2.2 AA minimum (2.5.8), so the header cell forwards clicks to it\n // rather than the mark growing. Clicks on the checkbox pass through\n // untouched, or the forward would toggle twice.\n const forwardToCheckbox = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (target instanceof HTMLInputElement) return;\n event.currentTarget instanceof HTMLElement &&\n event.currentTarget.querySelector<HTMLInputElement>('input[type=\"checkbox\"]')?.click();\n };\n return html`<div\n part=\"selection-header\"\n role=\"columnheader\"\n aria-colindex=\"1\"\n data-pinned=\"start\"\n @click=${forwardToCheckbox}\n >\n <input\n type=\"checkbox\"\n part=\"selection-checkbox\"\n aria-label=${this.state.localize('header.selectAll')}\n .checked=${allChecked}\n ${ref(syncIndeterminate)}\n @change=${handleChange}\n />\n </div>`;\n }\n\n /**\n * Floating \"ghost\" element that follows the cursor while a header is\n * being dragged. Positioned via `position: fixed` so it escapes the\n * header row's sticky containing block and follows the viewport.\n */\n protected renderDragGhost() {\n const state = this.state.reordering.state;\n if (!state) return nothing;\n return html`<div\n part=\"drag-ghost\"\n style=${styleMap({\n left: `${state.ghostX}px`,\n top: `${state.ghostY}px`,\n width: `${state.ghostWidth}px`,\n height: `${state.ghostHeight}px`,\n })}\n >\n ${state.label}\n </div>`;\n }\n\n protected override render() {\n const reorderState = this.state.reordering.state;\n\n // Track aria-colindex across the auto chrome columns (selection + expansion)\n // and the data columns so the same numbering is consistent across rows.\n let colCursor = 0;\n if (this.state?.selection.showCheckboxColumn) colCursor++;\n if (this.state?.expansion.showToggleColumn) colCursor++;\n // Spreadsheet column letter index: counts only visible data columns (A = the\n // first one), independent of the aria/chrome numbering above.\n let coordCol = 0;\n\n // Keyed by column.key so the same `<apex-grid-header>` DOM element\n // follows its column across a live reorder swap — critical for pointer\n // capture to stay bound to the dragged column as it moves.\n return html`${this.renderRowNumberHeader()}${this.renderReorderHandleHeader()}${this.renderSelectionHeader()}${this.renderExpansionHeader()}${repeat(\n this.columns,\n (column) => String(column.key),\n (column, index) => {\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, index);\n const isDragSource = reorderState?.sourceKey === column.key;\n const ariaColindex = ++colCursor;\n const coordinateLetter = this.coordinateHints ? columnLetter(coordCol) : '';\n coordCol += 1;\n return html`<apex-grid-header\n part=${partNameMap({\n filtered: this.state.filtering.state.has(column.key),\n 'pinned-start': column.pinned === 'start',\n 'pinned-end': column.pinned === 'end',\n dragging: isDragSource,\n })}\n data-pinned=${column.pinned ?? 'none'}\n data-pin-edge=${edge ?? 'none'}\n style=${pinStyle}\n .column=${column}\n .colindex=${ariaColindex}\n .coordinateLetter=${coordinateLetter}\n ></apex-grid-header>`;\n }\n )}${this.renderDragGhost()}`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridHeaderRow.tagName]: ApexGridHeaderRow<object>;\n }\n}\n"]}
1
+ {"version":3,"file":"header-row.js","sourceRoot":"","sources":["../../src/components/header-row.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing, type PropertyValueMap } from 'lit';\nimport { property, queryAll } from 'lit/decorators.js';\nimport { ref } from 'lit/directives/ref.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { partNameMap } from '../internal/part-map.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_HEADER_ROW_TAG } from '../internal/tags.js';\nimport type { ColumnConfiguration } from '../internal/types.js';\nimport { columnLetter, getPinEdge } from '../internal/utils.js';\nimport { styles } from '../styles/header-row/header-row.base.css.js';\nimport ApexGridHeader from './header.js';\n\nexport default class ApexGridHeaderRow<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_HEADER_ROW_TAG;\n }\n public static override styles = styles;\n\n public static register(): void {\n registerComponent(ApexGridHeaderRow, ApexGridHeader);\n }\n\n @queryAll(ApexGridHeader.tagName)\n protected _headers!: NodeListOf<ApexGridHeader<T>>;\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<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 /** Reveal the spreadsheet coordinates (row-number header spacer + column letters). */\n @property({ attribute: false })\n public coordinateHints = false;\n\n public get headers() {\n return Array.from(this._headers);\n }\n\n public override connectedCallback() {\n super.connectedCallback();\n this.setAttribute('tabindex', '0');\n this.setAttribute('role', 'row');\n this.setAttribute('aria-rowindex', '1');\n }\n\n protected override updated(): void {\n // The column header is row 1, or row 2 when a group header row precedes it.\n const depth = this.state?.host?.columnGroupDepth ?? 0;\n this.setAttribute('aria-rowindex', String(depth + 1));\n }\n\n protected override shouldUpdate(props: PropertyValueMap<this> | Map<PropertyKey, this>): boolean {\n for (const header of this.headers) {\n header.requestUpdate();\n }\n\n return super.shouldUpdate(props);\n }\n\n /**\n * Header cell for the built-in expansion (chevron) column. Renders an\n * \"expand all\" toggle that expands every row in the current view, or\n * collapses every expanded row when at least one is open.\n */\n protected renderExpansionHeader() {\n const expansion = this.state?.expansion;\n if (!expansion?.showToggleColumn) return nothing;\n const someExpanded = expansion.expanded.size > 0;\n const handleClick = (event: MouseEvent) => {\n event.stopPropagation();\n if (someExpanded) {\n void expansion.collapseAll();\n } else {\n void expansion.expandAll();\n }\n };\n const selection = this.state?.selection;\n const colindex = selection?.showCheckboxColumn ? 2 : 1;\n return html`<div\n part=\"expansion-header\"\n role=\"columnheader\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <button\n type=\"button\"\n part=\"expansion-toggle\"\n aria-label=${\n someExpanded\n ? this.state.localize('header.collapseAll')\n : this.state.localize('header.expandAll')\n }\n aria-expanded=${someExpanded ? 'true' : 'false'}\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 style=${someExpanded ? 'transform: rotate(90deg)' : ''}\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 /**\n * Corner spacer aligning the header with the body's leading row-number gutter\n * (formula coordinate hints). Shows a small \"#\" glyph.\n */\n protected renderRowNumberHeader() {\n if (!this.coordinateHints) return nothing;\n return html`<div part=\"row-number-header\" data-pinned=\"start\" aria-hidden=\"true\">#</div>`;\n }\n\n /**\n * Empty corner spacer aligning the header with the body's leading grip-handle\n * column. Rendered only in row-reorder handle mode.\n */\n protected renderReorderHandleHeader() {\n if (!this.state?.rowReorder?.showHandleColumn) return nothing;\n return html`<div part=\"reorder-handle-header\" data-pinned=\"start\" aria-hidden=\"true\"></div>`;\n }\n\n /**\n * Header cell for the built-in selection (checkbox) column. In multi-select\n * mode it renders a \"select all\" checkbox that selects every row in the\n * current filtered view (all pages, collapsed group leaves included), not\n * just the visible page; in single-select mode only an empty spacer, since\n * selecting all rows isn't meaningful there.\n */\n protected renderSelectionHeader() {\n const selection = this.state?.selection;\n if (!selection?.showCheckboxColumn) return nothing;\n if (selection.mode === 'single') {\n // Reserve the track so cells below line up — but no select-all\n // affordance in single-row-selection mode.\n return html`<div part=\"selection-header\" data-pinned=\"start\"></div>`;\n }\n const allChecked = selection.allSelected();\n const indeterminate = selection.someSelected();\n // Writes the native state on every render: a click flips `checked` before\n // the selection decides, and when Select all changes nothing the bound\n // value does not move, so Lit alone would leave the box checked.\n const syncState = (el: Element | undefined) => {\n if (el instanceof HTMLInputElement) {\n el.checked = allChecked;\n el.indeterminate = indeterminate;\n }\n };\n const handleChange = (event: Event) => {\n const checked = (event.target as HTMLInputElement).checked;\n void (checked ? selection.selectAll() : selection.clear()).then(() => this.requestUpdate());\n };\n // As in the body's selection cell: the 14x14 checkbox is under the 24x24\n // WCAG 2.2 AA minimum (2.5.8), so the header cell forwards clicks to it\n // rather than the mark growing. Clicks on the checkbox pass through\n // untouched, or the forward would toggle twice.\n const forwardToCheckbox = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (target instanceof HTMLInputElement) return;\n event.currentTarget instanceof HTMLElement &&\n event.currentTarget.querySelector<HTMLInputElement>('input[type=\"checkbox\"]')?.click();\n };\n return html`<div\n part=\"selection-header\"\n role=\"columnheader\"\n aria-colindex=\"1\"\n data-pinned=\"start\"\n @click=${forwardToCheckbox}\n >\n <input\n type=\"checkbox\"\n part=\"selection-checkbox\"\n aria-label=${this.state.localize('header.selectAll')}\n .checked=${allChecked}\n ${ref(syncState)}\n @change=${handleChange}\n />\n </div>`;\n }\n\n /**\n * Floating \"ghost\" element that follows the cursor while a header is\n * being dragged. Positioned via `position: fixed` so it escapes the\n * header row's sticky containing block and follows the viewport.\n */\n protected renderDragGhost() {\n const state = this.state.reordering.state;\n if (!state) return nothing;\n return html`<div\n part=\"drag-ghost\"\n style=${styleMap({\n left: `${state.ghostX}px`,\n top: `${state.ghostY}px`,\n width: `${state.ghostWidth}px`,\n height: `${state.ghostHeight}px`,\n })}\n >\n ${state.label}\n </div>`;\n }\n\n protected override render() {\n const reorderState = this.state.reordering.state;\n\n // Track aria-colindex across the auto chrome columns (selection + expansion)\n // and the data columns so the same numbering is consistent across rows.\n let colCursor = 0;\n if (this.state?.selection.showCheckboxColumn) colCursor++;\n if (this.state?.expansion.showToggleColumn) colCursor++;\n // Spreadsheet column letter index: counts only visible data columns (A = the\n // first one), independent of the aria/chrome numbering above. A feature\n // module that addresses columns its own way (formulas) labels them instead.\n let coordCol = 0;\n const letterFor = (key: string, position: number): string => {\n const label = this.state?.columnCoordinate(key);\n return label === undefined ? columnLetter(position) : (label ?? '');\n };\n\n // Keyed by column.key so the same `<apex-grid-header>` DOM element\n // follows its column across a live reorder swap — critical for pointer\n // capture to stay bound to the dragged column as it moves.\n return html`${this.renderRowNumberHeader()}${this.renderReorderHandleHeader()}${this.renderSelectionHeader()}${this.renderExpansionHeader()}${repeat(\n this.columns,\n (column) => String(column.key),\n (column, index) => {\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, index);\n const isDragSource = reorderState?.sourceKey === column.key;\n const ariaColindex = ++colCursor;\n const coordinateLetter = this.coordinateHints\n ? letterFor(String(column.key), coordCol)\n : '';\n coordCol += 1;\n return html`<apex-grid-header\n part=${partNameMap({\n filtered: this.state.filtering.state.has(column.key),\n 'pinned-start': column.pinned === 'start',\n 'pinned-end': column.pinned === 'end',\n dragging: isDragSource,\n })}\n data-pinned=${column.pinned ?? 'none'}\n data-pin-edge=${edge ?? 'none'}\n style=${pinStyle}\n .column=${column}\n .colindex=${ariaColindex}\n .coordinateLetter=${coordinateLetter}\n ></apex-grid-header>`;\n }\n )}${this.renderDragGhost()}`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridHeaderRow.tagName]: ApexGridHeaderRow<object>;\n }\n}\n"]}
@@ -26,8 +26,7 @@ export default class ApexGridHeader extends LitElement {
26
26
  const rect = this.getBoundingClientRect();
27
27
  const rtl = isRTL(this);
28
28
  const width = Math.max(rtl ? rect.right - clientX : clientX - rect.left, MIN_COL_RESIZE_WIDTH);
29
- const x = rtl ? this.offsetLeft + this.offsetWidth - width : this.offsetLeft + width;
30
- this.resizeController.resize(this.column, width, x);
29
+ this.resizeController.resize(this.column, width, this.resizeController.edge(this, width, rtl));
31
30
  };
32
31
  this.#handlePointerLost = () => {
33
32
  this.resizeController.indicatorActive = false;
@@ -44,22 +43,21 @@ export default class ApexGridHeader extends LitElement {
44
43
  return;
45
44
  if (event.button !== 0)
46
45
  return;
47
- const path = event.composedPath();
48
- const target = path[0];
46
+ const target = event.composedPath()[0];
49
47
  if (target instanceof Element &&
50
- target.closest?.('[part~="resizable"], [part~="action"], [part~="col-menu"]')) {
48
+ target.closest('[part~="resizable"],[part~="action"],[part~="col-menu"],input,textarea,select,button,a[href],[contenteditable]:not([contenteditable="false"])')) {
51
49
  return;
52
50
  }
53
51
  this.#dragStartX = event.clientX;
54
52
  this.#dragStartY = event.clientY;
55
53
  this.#dragPointerId = event.pointerId;
56
- this.addEventListener('pointermove', this.#handleReorderPointerMove);
57
- this.addEventListener('pointerup', this.#handleReorderPointerUp);
58
- this.addEventListener('pointercancel', this.#handleReorderPointerUp);
54
+ this.#listenReorder(true);
59
55
  };
60
56
  this.#handleReorderPointerMove = (event) => {
61
57
  if (event.pointerId !== this.#dragPointerId)
62
58
  return;
59
+ if (event.pointerType === 'mouse' && !(event.buttons & 1))
60
+ return this.#endReorder();
63
61
  if (!this.#isDragging) {
64
62
  const dx = event.clientX - this.#dragStartX;
65
63
  const dy = event.clientY - this.#dragStartY;
@@ -77,9 +75,6 @@ export default class ApexGridHeader extends LitElement {
77
75
  this.#handleReorderPointerUp = (event) => {
78
76
  if (event.pointerId !== this.#dragPointerId)
79
77
  return;
80
- this.removeEventListener('pointermove', this.#handleReorderPointerMove);
81
- this.removeEventListener('pointerup', this.#handleReorderPointerUp);
82
- this.removeEventListener('pointercancel', this.#handleReorderPointerUp);
83
78
  try {
84
79
  if (this.hasPointerCapture(event.pointerId)) {
85
80
  this.releasePointerCapture(event.pointerId);
@@ -87,12 +82,7 @@ export default class ApexGridHeader extends LitElement {
87
82
  }
88
83
  catch {
89
84
  }
90
- if (this.#isDragging) {
91
- this.#isDragging = false;
92
- this.removeAttribute('data-dragging');
93
- this.reorderController.end();
94
- }
95
- this.#dragPointerId = -1;
85
+ this.#endReorder();
96
86
  };
97
87
  this.#handleFilterClick = (e) => {
98
88
  e.stopPropagation();
@@ -182,7 +172,7 @@ export default class ApexGridHeader extends LitElement {
182
172
  };
183
173
  }
184
174
  get isSortable() {
185
- return Boolean(this.column.sort) && !this.state?.rowReorder?.hasManualOrder;
175
+ return Boolean(this.state?.sorting?.isSortable(this.column));
186
176
  }
187
177
  get isFilterable() {
188
178
  return Boolean(this.column.filter);
@@ -228,8 +218,24 @@ export default class ApexGridHeader extends LitElement {
228
218
  #dragPointerId;
229
219
  #isDragging;
230
220
  #handleReorderPointerDown;
221
+ #listenReorder(on) {
222
+ const doc = this.ownerDocument;
223
+ const toggle = on ? doc.addEventListener.bind(doc) : doc.removeEventListener.bind(doc);
224
+ toggle('pointermove', this.#handleReorderPointerMove, true);
225
+ toggle('pointerup', this.#handleReorderPointerUp, true);
226
+ toggle('pointercancel', this.#handleReorderPointerUp, true);
227
+ }
231
228
  #handleReorderPointerMove;
232
229
  #handleReorderPointerUp;
230
+ #endReorder() {
231
+ this.#listenReorder(false);
232
+ if (this.#isDragging) {
233
+ this.#isDragging = false;
234
+ this.removeAttribute('data-dragging');
235
+ this.reorderController.end();
236
+ }
237
+ this.#dragPointerId = -1;
238
+ }
233
239
  #handleFilterClick;
234
240
  #handleMenuClick;
235
241
  #handleMenuOutside;
@@ -281,6 +287,12 @@ export default class ApexGridHeader extends LitElement {
281
287
  disconnectedCallback() {
282
288
  this.removeEventListener('pointerdown', this.#handleReorderPointerDown);
283
289
  document.removeEventListener('pointerdown', this.#handleMenuOutside, true);
290
+ if (this.#dragPointerId !== -1) {
291
+ queueMicrotask(() => {
292
+ if (!this.isConnected)
293
+ this.#endReorder();
294
+ });
295
+ }
284
296
  super.disconnectedCallback();
285
297
  }
286
298
  renderSortPart() {
@@ -363,7 +375,7 @@ export default class ApexGridHeader extends LitElement {
363
375
  role="menuitem"
364
376
  tabindex="-1"
365
377
  @click=${() => {
366
- this.state.sorting.sort({ key: this.column.key, direction: 'ascending' });
378
+ this.state.sorting.sortFromUI(this.column, { direction: 'ascending' });
367
379
  this.menuOpen = false;
368
380
  }}
369
381
  >
@@ -375,7 +387,7 @@ export default class ApexGridHeader extends LitElement {
375
387
  role="menuitem"
376
388
  tabindex="-1"
377
389
  @click=${() => {
378
- this.state.sorting.sort({ key: this.column.key, direction: 'descending' });
390
+ this.state.sorting.sortFromUI(this.column, { direction: 'descending' });
379
391
  this.menuOpen = false;
380
392
  }}
381
393
  >