apex-grid 3.3.0 → 3.5.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 (132) hide show
  1. package/CHANGELOG.md +143 -0
  2. package/README.md +74 -6
  3. package/components/cell.d.ts +2 -2
  4. package/components/cell.js +30 -2
  5. package/components/cell.js.map +1 -1
  6. package/components/filter-row.js +65 -6
  7. package/components/filter-row.js.map +1 -1
  8. package/components/grid.d.ts +132 -0
  9. package/components/grid.js +59 -2
  10. package/components/grid.js.map +1 -1
  11. package/components/header-row.js +8 -0
  12. package/components/header-row.js.map +1 -1
  13. package/components/header.js +85 -12
  14. package/components/header.js.map +1 -1
  15. package/components/row.js +32 -4
  16. package/components/row.js.map +1 -1
  17. package/components/virtualizer.d.ts +5 -1
  18. package/components/virtualizer.js +72 -2
  19. package/components/virtualizer.js.map +1 -1
  20. package/controllers/expansion.js +4 -4
  21. package/controllers/expansion.js.map +1 -1
  22. package/controllers/filter.js +11 -0
  23. package/controllers/filter.js.map +1 -1
  24. package/controllers/history.js +11 -4
  25. package/controllers/history.js.map +1 -1
  26. package/controllers/navigation.d.ts +35 -2
  27. package/controllers/navigation.js +102 -8
  28. package/controllers/navigation.js.map +1 -1
  29. package/controllers/pagination.js +1 -1
  30. package/controllers/pagination.js.map +1 -1
  31. package/controllers/reorder.js +4 -2
  32. package/controllers/reorder.js.map +1 -1
  33. package/controllers/row-pin.js +2 -2
  34. package/controllers/row-pin.js.map +1 -1
  35. package/controllers/row-reorder.js +6 -6
  36. package/controllers/row-reorder.js.map +1 -1
  37. package/controllers/selection.js +3 -3
  38. package/controllers/selection.js.map +1 -1
  39. package/controllers/sort.js +4 -2
  40. package/controllers/sort.js.map +1 -1
  41. package/controllers/state.d.ts +9 -3
  42. package/controllers/state.js +11 -1
  43. package/controllers/state.js.map +1 -1
  44. package/custom-elements.json +664 -190
  45. package/docs/assets/hierarchy.js +1 -1
  46. package/docs/assets/navigation.js +1 -1
  47. package/docs/assets/search.js +1 -1
  48. package/docs/classes/ApexGrid.html +586 -0
  49. package/docs/classes/ApexGridPaginator.html +36 -0
  50. package/docs/classes/ApexGridToolbar.html +67 -0
  51. package/docs/functions/localize.html +2 -2
  52. package/docs/functions/setup.html +1 -2
  53. package/docs/hierarchy.html +1 -1
  54. package/docs/index.html +94 -6
  55. package/docs/interfaces/ApexCellValidationFailedEvent.html +1 -1
  56. package/docs/interfaces/ApexCellValueChangedEvent.html +1 -1
  57. package/docs/interfaces/ApexCellValueChangingEvent.html +2 -2
  58. package/docs/interfaces/ApexColumnMovedEvent.html +2 -2
  59. package/docs/interfaces/ApexColumnMovingEvent.html +1 -1
  60. package/docs/interfaces/ApexDetailContext.html +2 -2
  61. package/docs/interfaces/ApexGridEventMap.html +5 -5
  62. package/docs/interfaces/ApexRowMovingEvent.html +1 -1
  63. package/docs/interfaces/ApexRowPinningEvent.html +1 -1
  64. package/docs/interfaces/BaseApexCellContext.html +1 -1
  65. package/docs/interfaces/BaseApexEditorContext.html +1 -1
  66. package/docs/interfaces/BaseColumnConfiguration.html +3 -3
  67. package/docs/interfaces/CSVExportOptions.html +2 -2
  68. package/docs/interfaces/DataPipelineConfiguration.html +2 -2
  69. package/docs/interfaces/EditingHistoryConfiguration.html +1 -1
  70. package/docs/interfaces/ExportFormat.html +2 -2
  71. package/docs/interfaces/ExportOptions.html +1 -1
  72. package/docs/interfaces/GridRowPinningConfiguration.html +1 -1
  73. package/docs/interfaces/GridRowReorderingConfiguration.html +2 -2
  74. package/docs/interfaces/PaginationConfiguration.html +1 -1
  75. package/docs/interfaces/PaginationState.html +1 -1
  76. package/docs/media/_tokens.scss +29 -8
  77. package/docs/media/package.json +4 -5
  78. package/docs/media/state-persistence.html +0 -10
  79. package/docs/modules.html +1 -1
  80. package/docs/types/DataPipelineParams.html +2 -2
  81. package/docs/types/EditMode.html +2 -2
  82. package/docs/types/GridLocaleText.html +1 -1
  83. package/docs/types/PaginationMode.html +1 -1
  84. package/docs/variables/EN_LOCALE.html +3 -3
  85. package/docs/variables/esLocale.html +1 -1
  86. package/i18n/en.d.ts +109 -1
  87. package/i18n/en.js +109 -1
  88. package/i18n/en.js.map +1 -1
  89. package/i18n/es.js +109 -1
  90. package/i18n/es.js.map +1 -1
  91. package/index.d.ts +2 -0
  92. package/index.js +2 -0
  93. package/index.js.map +1 -1
  94. package/internal/column-types.js +1 -1
  95. package/internal/column-types.js.map +1 -1
  96. package/internal/feature-module.d.ts +22 -0
  97. package/internal/feature-module.js +5 -0
  98. package/internal/feature-module.js.map +1 -1
  99. package/internal/index.d.ts +2 -2
  100. package/internal/index.js +1 -1
  101. package/internal/index.js.map +1 -1
  102. package/internal/utils.d.ts +14 -0
  103. package/internal/utils.js +5 -0
  104. package/internal/utils.js.map +1 -1
  105. package/package.json +1 -2
  106. package/setup.d.ts +12 -11
  107. package/setup.js +12 -4
  108. package/setup.js.map +1 -1
  109. package/styles/_common.css.js +1 -1
  110. package/styles/_common.css.js.map +1 -1
  111. package/styles/_tokens.css.js +1 -1
  112. package/styles/_tokens.css.js.map +1 -1
  113. package/styles/body-cell/body-cell.css.js +1 -1
  114. package/styles/body-cell/body-cell.css.js.map +1 -1
  115. package/styles/body-row/body-row.css.js +1 -1
  116. package/styles/body-row/body-row.css.js.map +1 -1
  117. package/styles/filter-row/filter-row.css.js +1 -1
  118. package/styles/filter-row/filter-row.css.js.map +1 -1
  119. package/styles/grid/_grid.base.css.js +1 -1
  120. package/styles/grid/_grid.base.css.js.map +1 -1
  121. package/styles/grid/grid.css.js +1 -1
  122. package/styles/grid/grid.css.js.map +1 -1
  123. package/styles/group-header-row/group-header-row.css.js +1 -1
  124. package/styles/group-header-row/group-header-row.css.js.map +1 -1
  125. package/styles/header-cell/header-cell.css.js +1 -1
  126. package/styles/header-cell/header-cell.css.js.map +1 -1
  127. package/styles/header-row/header-row.base.css.js +1 -1
  128. package/styles/header-row/header-row.base.css.js.map +1 -1
  129. package/styles/paginator/paginator.css.js +1 -1
  130. package/styles/paginator/paginator.css.js.map +1 -1
  131. package/styles/toolbar/toolbar.css.js +1 -1
  132. package/styles/toolbar/toolbar.css.js.map +1 -1
@@ -24,13 +24,51 @@ export default class ApexFilterRow extends LitElement {
24
24
  this.column = DEFAULT_COLUMN_CONFIG;
25
25
  this.#handleDropdownItemClick = (event) => {
26
26
  event.stopPropagation();
27
- const target = event.target.closest('[data-value]');
28
- if (!target)
27
+ this.#selectOption(event.target.closest('[data-value]'));
28
+ };
29
+ this.#handleTriggerKeydown = (event) => {
30
+ if (event.key !== 'ArrowDown' && event.key !== 'Down')
29
31
  return;
30
- const value = target.dataset.value;
31
- this.#applyCondition(value);
32
- this.dropdownOpen = false;
33
- this.input?.focus();
32
+ event.preventDefault();
33
+ event.stopPropagation();
34
+ this.dropdownOpen = true;
35
+ this.#focusDropdownOption();
36
+ };
37
+ this.#handleDropdownKeydown = (event) => {
38
+ const options = this.#dropdownOptions();
39
+ const current = options.findIndex((option) => option.matches(':focus'));
40
+ switch (event.key) {
41
+ case 'ArrowDown':
42
+ case 'Down':
43
+ event.preventDefault();
44
+ event.stopPropagation();
45
+ options[Math.min(current + 1, options.length - 1)]?.focus();
46
+ return;
47
+ case 'ArrowUp':
48
+ case 'Up':
49
+ event.preventDefault();
50
+ event.stopPropagation();
51
+ options[Math.max(current - 1, 0)]?.focus();
52
+ return;
53
+ case 'Home':
54
+ event.preventDefault();
55
+ event.stopPropagation();
56
+ options[0]?.focus();
57
+ return;
58
+ case 'End':
59
+ event.preventDefault();
60
+ event.stopPropagation();
61
+ options[options.length - 1]?.focus();
62
+ return;
63
+ case 'Enter':
64
+ case ' ':
65
+ event.preventDefault();
66
+ event.stopPropagation();
67
+ this.#selectOption(options[current] ?? null);
68
+ return;
69
+ default:
70
+ return;
71
+ }
34
72
  };
35
73
  this.#handleOutsidePointer = (event) => {
36
74
  const path = event.composedPath();
@@ -91,7 +129,26 @@ export default class ApexFilterRow extends LitElement {
91
129
  }
92
130
  this.requestUpdate();
93
131
  }
132
+ #selectOption(target) {
133
+ if (!target)
134
+ return;
135
+ const value = target.dataset.value;
136
+ this.#applyCondition(value);
137
+ this.dropdownOpen = false;
138
+ this.input?.focus();
139
+ }
94
140
  #handleDropdownItemClick;
141
+ #dropdownOptions() {
142
+ return Array.from(this.dropdown?.querySelectorAll('[role="option"]') ?? []);
143
+ }
144
+ #focusDropdownOption() {
145
+ requestAnimationFrame(() => {
146
+ const options = this.#dropdownOptions();
147
+ (options.find((option) => option.matches('[aria-selected="true"]')) ?? options[0])?.focus();
148
+ });
149
+ }
150
+ #handleTriggerKeydown;
151
+ #handleDropdownKeydown;
95
152
  #handleOutsidePointer;
96
153
  #handleDocumentKey;
97
154
  #handleInput(event) {
@@ -271,6 +328,7 @@ export default class ApexFilterRow extends LitElement {
271
328
  aria-label=${this.state.localize('filter.conditionList')}
272
329
  ?hidden=${!this.dropdownOpen}
273
330
  @click=${this.#handleDropdownItemClick}
331
+ @keydown=${this.#handleDropdownKeydown}
274
332
  >
275
333
  ${Object.entries(getFilterOperandsFor(this.column)).map(([key, operand]) => html `
276
334
  <li
@@ -298,6 +356,7 @@ export default class ApexFilterRow extends LitElement {
298
356
  aria-haspopup="listbox"
299
357
  aria-expanded=${this.dropdownOpen ? 'true' : 'false'}
300
358
  @click=${this.#openDropdownList}
359
+ @keydown=${this.#handleTriggerKeydown}
301
360
  >
302
361
  <span>${conditionLabel}</span>
303
362
  ${renderIcon('chevron-down')}
@@ -1 +1 @@
1
- {"version":3,"file":"filter-row.js","sourceRoot":"","sources":["../../src/components/filter-row.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 type { GridLocaleKey } from '../i18n/index.js';\nimport { DEFAULT_COLUMN_CONFIG } from '../internal/constants.js';\nimport { renderIcon } from '../internal/icons.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_FILTER_ROW_TAG } from '../internal/tags.js';\nimport type { ColumnConfiguration } from '../internal/types.js';\nimport { getFilterOperandsFor } from '../internal/utils.js';\nimport { watch } from '../internal/watch.js';\nimport type { FilterExpression, FilterOperation, OperandKeys } from '../operations/filter/types.js';\nimport { styles } from '../styles/filter-row/filter-row.css.js';\n\ntype ExpressionChipProps<T> = {\n expression: FilterExpression<T>;\n selected: boolean;\n onRemove: (e: Event) => Promise<void>;\n onSelect: (e: Event) => Promise<void>;\n};\n\nexport default class ApexFilterRow<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_FILTER_ROW_TAG;\n }\n\n public static override styles = styles;\n\n public static register() {\n registerComponent(ApexFilterRow);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n protected get isNumeric() {\n return this.column.type === 'number';\n }\n\n protected get filterController() {\n return this.state.filtering;\n }\n\n protected get condition() {\n return this.expression.condition as FilterOperation<T>;\n }\n\n @property({ attribute: false })\n public active = false;\n\n /** Bounding rect of the filter icon that opened this panel. Used for positioning. */\n @property({ attribute: false })\n public triggerRect: DOMRect | null = null;\n\n @query('input')\n public input!: HTMLInputElement;\n\n @query('#condition')\n public conditionElement!: HTMLElement;\n\n @query('[part~=\"dropdown\"]')\n public dropdown!: HTMLElement;\n\n @state()\n protected dropdownOpen = false;\n\n @property({ attribute: false })\n public column: ColumnConfiguration<T> = DEFAULT_COLUMN_CONFIG as ColumnConfiguration<T>;\n\n @property({ attribute: false })\n public expression!: FilterExpression<T>;\n\n #setDefaultExpression() {\n this.expression = this.filterController.getDefaultExpression(this.column);\n }\n\n #removeExpression(expression: FilterExpression<T>) {\n this.filterController.removeExpression(expression);\n }\n\n #applyCondition(key: OperandKeys<T[typeof this.column.key]>) {\n // XXX: Types\n this.expression.condition = (getFilterOperandsFor(this.column) as any)[key] as FilterOperation<\n T[keyof T]\n >;\n\n if (this.input?.value || this.expression.condition.unary) {\n this.filterController.filterWithEvent(this.expression, 'modify');\n }\n\n this.requestUpdate();\n }\n\n #handleDropdownItemClick = (event: Event) => {\n event.stopPropagation();\n const target = (event.target as HTMLElement).closest<HTMLElement>('[data-value]');\n if (!target) return;\n const value = target.dataset.value as OperandKeys<T[typeof this.column.key]>;\n this.#applyCondition(value);\n this.dropdownOpen = false;\n this.input?.focus();\n };\n\n #handleOutsidePointer = (event: PointerEvent) => {\n const path = event.composedPath();\n\n // Close the condition dropdown if clicking outside it.\n if (this.dropdownOpen) {\n if (!path.includes(this.dropdown) && !path.includes(this.conditionElement)) {\n this.dropdownOpen = false;\n }\n return;\n }\n\n // Close the whole panel if clicking outside it.\n if (this.active && !path.includes(this)) {\n this.active = false;\n }\n };\n\n #handleDocumentKey = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return;\n\n if (this.dropdownOpen) {\n event.stopPropagation();\n this.dropdownOpen = false;\n this.conditionElement?.focus();\n return;\n }\n\n if (this.active) {\n event.stopPropagation();\n this.active = false;\n }\n };\n\n #handleInput(event: Event) {\n event.stopPropagation();\n\n const raw = (event.target as HTMLInputElement).value ?? '';\n const value = this.isNumeric ? Number.parseFloat(raw) : raw;\n const shouldUpdate = this.isNumeric ? !Number.isNaN(value as number) : !!value;\n const type = this.filterController.get(this.expression.key)?.has(this.expression)\n ? 'modify'\n : 'add';\n\n if (shouldUpdate) {\n this.expression.searchTerm = value as any;\n this.filterController.filterWithEvent(this.expression, type);\n } else {\n this.#removeExpression(this.expression);\n }\n\n this.requestUpdate();\n }\n\n #handleKeydown(event: KeyboardEvent) {\n event.stopPropagation();\n\n switch (event.key) {\n case 'Enter':\n if (this.input) this.input.value = '';\n this.#setDefaultExpression();\n return;\n case 'Escape':\n this.active = false;\n return;\n default:\n return;\n }\n }\n\n #handleResetClick() {\n this.filterController.removeAllExpressions(this.column.key);\n this.#setDefaultExpression();\n this.requestUpdate();\n }\n\n #openDropdownList = () => {\n this.dropdownOpen = !this.dropdownOpen;\n };\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 super.disconnectedCallback();\n }\n\n @watch('active', { waitUntilFirstUpdate: true })\n protected async activeChanged() {\n if (this.active && this.triggerRect) {\n const panelWidth = 240;\n const viewportWidth = window.innerWidth;\n let left = this.triggerRect.left;\n // Clamp so the panel doesn't overflow the right edge of the viewport.\n if (left + panelWidth > viewportWidth - 8) {\n left = Math.max(8, viewportWidth - panelWidth - 8);\n }\n this.style.setProperty('--fp-top', `${this.triggerRect.bottom + 4}px`);\n this.style.setProperty('--fp-left', `${left}px`);\n this.setAttribute('data-active', '');\n await this.updateComplete;\n this.input?.select();\n } else {\n this.removeAttribute('data-active');\n this.style.removeProperty('--fp-top');\n this.style.removeProperty('--fp-left');\n this.column = DEFAULT_COLUMN_CONFIG as ColumnConfiguration<T>;\n }\n\n this.state.host.requestUpdate();\n }\n\n #chipCriteriaFor(expression: FilterExpression<T>) {\n return async (e: Event) => {\n e.stopPropagation();\n expression.criteria = expression.criteria === 'and' ? 'or' : 'and';\n this.filterController.filterWithEvent(expression, 'modify');\n this.requestUpdate();\n };\n }\n\n #chipSelectFor(expression: FilterExpression<T>) {\n return async (e: Event) => {\n e.stopPropagation();\n this.expression = expression;\n await this.updateComplete;\n this.input?.select();\n };\n }\n\n #chipRemoveFor(expression: FilterExpression<T>) {\n return async (e: Event) => {\n e.stopPropagation();\n this.#removeExpression(expression);\n\n if (this.active && this.expression === expression) {\n this.#setDefaultExpression();\n await this.updateComplete;\n this.input?.focus();\n }\n\n this.requestUpdate();\n };\n }\n\n protected renderCriteriaButton(expr: FilterExpression<T>, index: number) {\n return index\n ? html`<button\n type=\"button\"\n part=\"criteria\"\n @click=${this.#chipCriteriaFor(expr)}\n >\n ${expr.criteria}\n </button>`\n : nothing;\n }\n\n protected renderExpressionChip(props: ExpressionChipProps<T>) {\n const { name, unary } = props.expression.condition as FilterOperation<T>;\n const { searchTerm: term } = props.expression;\n\n return html`<div\n part=\"expression-chip\"\n ?selected=${props.selected}\n >\n <button\n part=\"chip-body\"\n type=\"button\"\n @click=${props.onSelect}\n >\n ${renderIcon(name)}\n <span>${unary ? name : term}</span>\n </button>\n <button\n part=\"chip-remove\"\n type=\"button\"\n aria-label=${this.state.localize('filter.removeFilter')}\n @click=${props.onRemove}\n >\n ${renderIcon('close')}\n </button>\n </div>`;\n }\n\n protected renderActiveChips() {\n const state = this.filterController.get(this.column.key);\n\n return !state\n ? nothing\n : Array.from(state).map((expression, idx) => {\n const props: ExpressionChipProps<T> = {\n expression,\n selected: this.expression === expression,\n onRemove: this.#chipRemoveFor(expression),\n onSelect: this.#chipSelectFor(expression),\n };\n\n return html`${this.renderCriteriaButton(expression, idx)}${this.renderExpressionChip(\n props\n )}`;\n });\n }\n\n protected renderFilterActions() {\n return html`\n <button\n id=\"reset\"\n type=\"button\"\n part=\"action\"\n @click=${this.#handleResetClick}\n >\n ${renderIcon('refresh')} ${this.state.localize('filter.reset')}\n </button>\n <button\n id=\"close\"\n type=\"button\"\n part=\"action\"\n @click=${() => {\n this.active = false;\n }}\n >\n ${renderIcon('close')} ${this.state.localize('filter.close')}\n </button>\n `;\n }\n\n protected renderDropdown() {\n return html`<ul\n part=\"dropdown\"\n role=\"listbox\"\n aria-label=${this.state.localize('filter.conditionList')}\n ?hidden=${!this.dropdownOpen}\n @click=${this.#handleDropdownItemClick}\n >\n ${Object.entries(getFilterOperandsFor(this.column)).map(\n ([key, operand]) => html`\n <li\n part=\"dropdown-item\"\n role=\"option\"\n tabindex=\"-1\"\n data-value=${key}\n aria-selected=${this.condition.name === key}\n ?selected=${this.condition.name === key}\n >\n ${renderIcon(key)}<span\n >${this.state.localize(\n `filter.operator.${key}` as GridLocaleKey,\n undefined,\n operand?.label ?? key\n )}</span\n >\n </li>\n `\n )}\n </ul>`;\n }\n\n protected renderDropdownTarget() {\n const conditionLabel = this.state.localize(\n `filter.operator.${this.condition.name}` as GridLocaleKey,\n undefined,\n (this.condition as FilterOperation<T>).label ?? this.condition.name\n );\n return html`<button\n id=\"condition\"\n type=\"button\"\n part=\"condition-trigger\"\n aria-label=${this.state.localize('filter.changeCondition')}\n aria-haspopup=\"listbox\"\n aria-expanded=${this.dropdownOpen ? 'true' : 'false'}\n @click=${this.#openDropdownList}\n >\n <span>${conditionLabel}</span>\n ${renderIcon('chevron-down')}\n </button>`;\n }\n\n protected renderActiveState() {\n const hasChips = Boolean(this.filterController.get(this.column.key)?.length);\n return html`\n <div part=\"panel\">\n <div part=\"condition-row\">\n ${this.renderDropdownTarget()}\n ${this.renderDropdown()}\n </div>\n ${\n !this.condition.unary\n ? html`<div part=\"panel-input-row\">\n <input\n part=\"filter-input\"\n type=\"text\"\n .value=${(this.expression?.searchTerm as string) ?? ''}\n placeholder=${this.state.localize('filter.inputPlaceholder')}\n @input=${this.#handleInput}\n @keydown=${this.#handleKeydown}\n />\n </div>`\n : nothing\n }\n ${hasChips ? html`<div part=\"chips-row\">${this.renderActiveChips()}</div>` : nothing}\n <div part=\"panel-footer\">${this.renderFilterActions()}</div>\n </div>\n `;\n }\n\n protected override render() {\n return html`${this.active ? this.renderActiveState() : nothing}`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexFilterRow.tagName]: ApexFilterRow<object>;\n }\n}\n"]}
1
+ {"version":3,"file":"filter-row.js","sourceRoot":"","sources":["../../src/components/filter-row.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 type { GridLocaleKey } from '../i18n/index.js';\nimport { DEFAULT_COLUMN_CONFIG } from '../internal/constants.js';\nimport { renderIcon } from '../internal/icons.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_FILTER_ROW_TAG } from '../internal/tags.js';\nimport type { ColumnConfiguration } from '../internal/types.js';\nimport { getFilterOperandsFor } from '../internal/utils.js';\nimport { watch } from '../internal/watch.js';\nimport type { FilterExpression, FilterOperation, OperandKeys } from '../operations/filter/types.js';\nimport { styles } from '../styles/filter-row/filter-row.css.js';\n\ntype ExpressionChipProps<T> = {\n expression: FilterExpression<T>;\n selected: boolean;\n onRemove: (e: Event) => Promise<void>;\n onSelect: (e: Event) => Promise<void>;\n};\n\nexport default class ApexFilterRow<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_FILTER_ROW_TAG;\n }\n\n public static override styles = styles;\n\n public static register() {\n registerComponent(ApexFilterRow);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n protected get isNumeric() {\n return this.column.type === 'number';\n }\n\n protected get filterController() {\n return this.state.filtering;\n }\n\n protected get condition() {\n return this.expression.condition as FilterOperation<T>;\n }\n\n @property({ attribute: false })\n public active = false;\n\n /** Bounding rect of the filter icon that opened this panel. Used for positioning. */\n @property({ attribute: false })\n public triggerRect: DOMRect | null = null;\n\n @query('input')\n public input!: HTMLInputElement;\n\n @query('#condition')\n public conditionElement!: HTMLElement;\n\n @query('[part~=\"dropdown\"]')\n public dropdown!: HTMLElement;\n\n @state()\n protected dropdownOpen = false;\n\n @property({ attribute: false })\n public column: ColumnConfiguration<T> = DEFAULT_COLUMN_CONFIG as ColumnConfiguration<T>;\n\n @property({ attribute: false })\n public expression!: FilterExpression<T>;\n\n #setDefaultExpression() {\n this.expression = this.filterController.getDefaultExpression(this.column);\n }\n\n #removeExpression(expression: FilterExpression<T>) {\n this.filterController.removeExpression(expression);\n }\n\n #applyCondition(key: OperandKeys<T[typeof this.column.key]>) {\n // XXX: Types\n this.expression.condition = (getFilterOperandsFor(this.column) as any)[key] as FilterOperation<\n T[keyof T]\n >;\n\n if (this.input?.value || this.expression.condition.unary) {\n this.filterController.filterWithEvent(this.expression, 'modify');\n }\n\n this.requestUpdate();\n }\n\n #selectOption(target: HTMLElement | null) {\n if (!target) return;\n const value = target.dataset.value as OperandKeys<T[typeof this.column.key]>;\n this.#applyCondition(value);\n this.dropdownOpen = false;\n this.input?.focus();\n }\n\n #handleDropdownItemClick = (event: Event) => {\n event.stopPropagation();\n this.#selectOption((event.target as HTMLElement).closest<HTMLElement>('[data-value]'));\n };\n\n #dropdownOptions(): HTMLElement[] {\n return Array.from(this.dropdown?.querySelectorAll<HTMLElement>('[role=\"option\"]') ?? []);\n }\n\n /** Moves focus into the dropdown, landing on the selected (or first) option. */\n #focusDropdownOption() {\n requestAnimationFrame(() => {\n const options = this.#dropdownOptions();\n (options.find((option) => option.matches('[aria-selected=\"true\"]')) ?? options[0])?.focus();\n });\n }\n\n /** ArrowDown on the condition trigger opens the listbox and focuses into it. */\n #handleTriggerKeydown = (event: KeyboardEvent) => {\n if (event.key !== 'ArrowDown' && event.key !== 'Down') return;\n event.preventDefault();\n event.stopPropagation();\n this.dropdownOpen = true;\n this.#focusDropdownOption();\n };\n\n /** Listbox keyboard pattern: arrows/Home/End rove, Enter/Space pick. */\n #handleDropdownKeydown = (event: KeyboardEvent) => {\n const options = this.#dropdownOptions();\n const current = options.findIndex((option) => option.matches(':focus'));\n switch (event.key) {\n case 'ArrowDown':\n case 'Down':\n event.preventDefault();\n event.stopPropagation();\n options[Math.min(current + 1, options.length - 1)]?.focus();\n return;\n case 'ArrowUp':\n case 'Up':\n event.preventDefault();\n event.stopPropagation();\n options[Math.max(current - 1, 0)]?.focus();\n return;\n case 'Home':\n event.preventDefault();\n event.stopPropagation();\n options[0]?.focus();\n return;\n case 'End':\n event.preventDefault();\n event.stopPropagation();\n options[options.length - 1]?.focus();\n return;\n case 'Enter':\n case ' ':\n event.preventDefault();\n event.stopPropagation();\n this.#selectOption(options[current] ?? null);\n return;\n default:\n return;\n }\n };\n\n #handleOutsidePointer = (event: PointerEvent) => {\n const path = event.composedPath();\n\n // Close the condition dropdown if clicking outside it.\n if (this.dropdownOpen) {\n if (!path.includes(this.dropdown) && !path.includes(this.conditionElement)) {\n this.dropdownOpen = false;\n }\n return;\n }\n\n // Close the whole panel if clicking outside it.\n if (this.active && !path.includes(this)) {\n this.active = false;\n }\n };\n\n #handleDocumentKey = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return;\n\n if (this.dropdownOpen) {\n event.stopPropagation();\n this.dropdownOpen = false;\n this.conditionElement?.focus();\n return;\n }\n\n if (this.active) {\n event.stopPropagation();\n this.active = false;\n }\n };\n\n #handleInput(event: Event) {\n event.stopPropagation();\n\n const raw = (event.target as HTMLInputElement).value ?? '';\n const value = this.isNumeric ? Number.parseFloat(raw) : raw;\n const shouldUpdate = this.isNumeric ? !Number.isNaN(value as number) : !!value;\n const type = this.filterController.get(this.expression.key)?.has(this.expression)\n ? 'modify'\n : 'add';\n\n if (shouldUpdate) {\n this.expression.searchTerm = value as any;\n this.filterController.filterWithEvent(this.expression, type);\n } else {\n this.#removeExpression(this.expression);\n }\n\n this.requestUpdate();\n }\n\n #handleKeydown(event: KeyboardEvent) {\n event.stopPropagation();\n\n switch (event.key) {\n case 'Enter':\n if (this.input) this.input.value = '';\n this.#setDefaultExpression();\n return;\n case 'Escape':\n this.active = false;\n return;\n default:\n return;\n }\n }\n\n #handleResetClick() {\n this.filterController.removeAllExpressions(this.column.key);\n this.#setDefaultExpression();\n this.requestUpdate();\n }\n\n #openDropdownList = () => {\n this.dropdownOpen = !this.dropdownOpen;\n };\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 super.disconnectedCallback();\n }\n\n @watch('active', { waitUntilFirstUpdate: true })\n protected async activeChanged() {\n if (this.active && this.triggerRect) {\n const panelWidth = 240;\n const viewportWidth = window.innerWidth;\n let left = this.triggerRect.left;\n // Clamp so the panel doesn't overflow the right edge of the viewport.\n if (left + panelWidth > viewportWidth - 8) {\n left = Math.max(8, viewportWidth - panelWidth - 8);\n }\n this.style.setProperty('--fp-top', `${this.triggerRect.bottom + 4}px`);\n this.style.setProperty('--fp-left', `${left}px`);\n this.setAttribute('data-active', '');\n await this.updateComplete;\n this.input?.select();\n } else {\n this.removeAttribute('data-active');\n this.style.removeProperty('--fp-top');\n this.style.removeProperty('--fp-left');\n this.column = DEFAULT_COLUMN_CONFIG as ColumnConfiguration<T>;\n }\n\n this.state.host.requestUpdate();\n }\n\n #chipCriteriaFor(expression: FilterExpression<T>) {\n return async (e: Event) => {\n e.stopPropagation();\n expression.criteria = expression.criteria === 'and' ? 'or' : 'and';\n this.filterController.filterWithEvent(expression, 'modify');\n this.requestUpdate();\n };\n }\n\n #chipSelectFor(expression: FilterExpression<T>) {\n return async (e: Event) => {\n e.stopPropagation();\n this.expression = expression;\n await this.updateComplete;\n this.input?.select();\n };\n }\n\n #chipRemoveFor(expression: FilterExpression<T>) {\n return async (e: Event) => {\n e.stopPropagation();\n this.#removeExpression(expression);\n\n if (this.active && this.expression === expression) {\n this.#setDefaultExpression();\n await this.updateComplete;\n this.input?.focus();\n }\n\n this.requestUpdate();\n };\n }\n\n protected renderCriteriaButton(expr: FilterExpression<T>, index: number) {\n return index\n ? html`<button\n type=\"button\"\n part=\"criteria\"\n @click=${this.#chipCriteriaFor(expr)}\n >\n ${expr.criteria}\n </button>`\n : nothing;\n }\n\n protected renderExpressionChip(props: ExpressionChipProps<T>) {\n const { name, unary } = props.expression.condition as FilterOperation<T>;\n const { searchTerm: term } = props.expression;\n\n return html`<div\n part=\"expression-chip\"\n ?selected=${props.selected}\n >\n <button\n part=\"chip-body\"\n type=\"button\"\n @click=${props.onSelect}\n >\n ${renderIcon(name)}\n <span>${unary ? name : term}</span>\n </button>\n <button\n part=\"chip-remove\"\n type=\"button\"\n aria-label=${this.state.localize('filter.removeFilter')}\n @click=${props.onRemove}\n >\n ${renderIcon('close')}\n </button>\n </div>`;\n }\n\n protected renderActiveChips() {\n const state = this.filterController.get(this.column.key);\n\n return !state\n ? nothing\n : Array.from(state).map((expression, idx) => {\n const props: ExpressionChipProps<T> = {\n expression,\n selected: this.expression === expression,\n onRemove: this.#chipRemoveFor(expression),\n onSelect: this.#chipSelectFor(expression),\n };\n\n return html`${this.renderCriteriaButton(expression, idx)}${this.renderExpressionChip(\n props\n )}`;\n });\n }\n\n protected renderFilterActions() {\n return html`\n <button\n id=\"reset\"\n type=\"button\"\n part=\"action\"\n @click=${this.#handleResetClick}\n >\n ${renderIcon('refresh')} ${this.state.localize('filter.reset')}\n </button>\n <button\n id=\"close\"\n type=\"button\"\n part=\"action\"\n @click=${() => {\n this.active = false;\n }}\n >\n ${renderIcon('close')} ${this.state.localize('filter.close')}\n </button>\n `;\n }\n\n protected renderDropdown() {\n return html`<ul\n part=\"dropdown\"\n role=\"listbox\"\n aria-label=${this.state.localize('filter.conditionList')}\n ?hidden=${!this.dropdownOpen}\n @click=${this.#handleDropdownItemClick}\n @keydown=${this.#handleDropdownKeydown}\n >\n ${Object.entries(getFilterOperandsFor(this.column)).map(\n ([key, operand]) => html`\n <li\n part=\"dropdown-item\"\n role=\"option\"\n tabindex=\"-1\"\n data-value=${key}\n aria-selected=${this.condition.name === key}\n ?selected=${this.condition.name === key}\n >\n ${renderIcon(key)}<span\n >${this.state.localize(\n `filter.operator.${key}` as GridLocaleKey,\n undefined,\n operand?.label ?? key\n )}</span\n >\n </li>\n `\n )}\n </ul>`;\n }\n\n protected renderDropdownTarget() {\n const conditionLabel = this.state.localize(\n `filter.operator.${this.condition.name}` as GridLocaleKey,\n undefined,\n (this.condition as FilterOperation<T>).label ?? this.condition.name\n );\n return html`<button\n id=\"condition\"\n type=\"button\"\n part=\"condition-trigger\"\n aria-label=${this.state.localize('filter.changeCondition')}\n aria-haspopup=\"listbox\"\n aria-expanded=${this.dropdownOpen ? 'true' : 'false'}\n @click=${this.#openDropdownList}\n @keydown=${this.#handleTriggerKeydown}\n >\n <span>${conditionLabel}</span>\n ${renderIcon('chevron-down')}\n </button>`;\n }\n\n protected renderActiveState() {\n const hasChips = Boolean(this.filterController.get(this.column.key)?.length);\n return html`\n <div part=\"panel\">\n <div part=\"condition-row\">\n ${this.renderDropdownTarget()}\n ${this.renderDropdown()}\n </div>\n ${\n !this.condition.unary\n ? html`<div part=\"panel-input-row\">\n <input\n part=\"filter-input\"\n type=\"text\"\n .value=${(this.expression?.searchTerm as string) ?? ''}\n placeholder=${this.state.localize('filter.inputPlaceholder')}\n @input=${this.#handleInput}\n @keydown=${this.#handleKeydown}\n />\n </div>`\n : nothing\n }\n ${hasChips ? html`<div part=\"chips-row\">${this.renderActiveChips()}</div>` : nothing}\n <div part=\"panel-footer\">${this.renderFilterActions()}</div>\n </div>\n `;\n }\n\n protected override render() {\n return html`${this.active ? this.renderActiveState() : nothing}`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexFilterRow.tagName]: ApexFilterRow<object>;\n }\n}\n"]}
@@ -649,6 +649,88 @@ export interface ApexGridEventMap<T extends object> {
649
649
  */
650
650
  rowSelected: CustomEvent<ApexRowSelectedEvent<T>>;
651
651
  }
652
+ /**
653
+ * Apex grid is a web component for displaying data in a tabular format quick and easy.
654
+ *
655
+ * Out of the box it provides row virtualization, sort and filter operations (client and server side),
656
+ * the ability to template cells and headers and column hiding.
657
+ *
658
+ * @remarks
659
+ * A working, styled grid requires three things:
660
+ * 1. Register the element: `import 'apex-grid/define'` (or `ApexGrid.register()`).
661
+ * 2. Give the host element a bounded height, e.g. `apex-grid { height: 480px }` —
662
+ * the virtualizer collapses without one.
663
+ * 3. Do NOT set `display` on the host — the component declares `:host { display: grid }`
664
+ * internally and any override breaks the track layout.
665
+ *
666
+ * The grid is styled out of the box through `--ag-*` CSS custom properties —
667
+ * there is no theme to import and no `configureTheme()` call. Override `--ag-*`
668
+ * tokens on the host (or any ancestor) to rebrand; where an Ignite UI palette is
669
+ * present, the brand tokens auto-tint from it. For dark mode, set
670
+ * the `theme="dark"` attribute on the host for the built-in slate dark palette
671
+ * (further `--ag-*` overrides still compose on top). Add `tinted` (e.g.
672
+ * `theme="tinted"` or `theme="dark tinted"`) to mix the brand into the chrome
673
+ * so the grid wears its brand even at rest. See the README "Getting Started"
674
+ * and "Theming" sections for the full example and token list.
675
+ *
676
+ * @element apex-grid
677
+ *
678
+ * @attr {string} theme - Space-separated theme flags. `dark` opts into the built-in dark palette; `tinted` mixes `--ag-brand` into the chrome surfaces. Combine as `theme="dark tinted"`.
679
+ *
680
+ * @fires sorting - Emitted when sorting is initiated through the UI.
681
+ * @fires sorted - Emitted when a sort operation initiated through the UI has completed.
682
+ * @fires filtering - Emitted when filtering is initiated through the UI.
683
+ * @fires filtered - Emitted when a filter operation initiated through the UI has completed.
684
+ * @fires pageChanging - Cancellable. Emitted before page/page-size changes are applied.
685
+ * @fires pageChanged - Emitted after a page/page-size change has been applied.
686
+ * @fires quickFilterChanging - Cancellable. Emitted before a quick-filter value is applied.
687
+ * @fires quickFilterChanged - Emitted after a quick-filter change has been applied.
688
+ * @fires columnPinning - Cancellable. Emitted before a column's pin position changes.
689
+ * @fires columnPinned - Emitted after a column's pin position has changed.
690
+ * @fires columnMoving - Cancellable. Emitted before a column is moved.
691
+ * @fires columnMoved - Emitted after a column has been moved.
692
+ * @fires cellValueChanging - Cancellable. Emitted before a cell value is committed.
693
+ * @fires cellValueChanged - Emitted after a cell value has been committed.
694
+ * @fires rowEditStarted - Emitted when a row enters edit mode (row mode only).
695
+ * @fires rowEditEnded - Emitted when a row leaves edit mode (row mode only).
696
+ * @fires rowSelecting - Cancellable. Emitted before a selection-set change is applied.
697
+ * @fires rowSelected - Emitted after a selection-set change has been applied.
698
+ * @fires rowExpanding - Cancellable. Emitted before the row-expansion set changes (master-detail).
699
+ * @fires rowExpanded - Emitted after a row-expansion change has been applied.
700
+ * @fires treeRowExpanding - Cancellable. Emitted before a tree-row expansion change (tree mode).
701
+ * @fires treeRowExpanded - Emitted after a tree-row expansion change has been applied.
702
+ *
703
+ * @csspart live-region - Visually-hidden ARIA live region used for screen-reader announcements.
704
+ *
705
+ * @cssprop [--ag-brand] - Brand color for selection, focus rings, and accents. Auto-tints from `--ig-primary-500` where an Ignite UI palette is present.
706
+ * @cssprop [--ag-brand-strong] - Brand color for hover / pressed states.
707
+ * @cssprop [--ag-grid-shadow] - Grid edge/shadow override. Default is a flat 1px hairline edge; set to `var(--ag-shadow-card)` for the elevated card look, or `none` to remove it.
708
+ * @cssprop [--ag-grid-bg] - Host card background. Defaults to a subtle light gradient; override with a flat color (or use `theme="dark"`) for dark themes.
709
+ * @cssprop [--ag-surface] - Grid card background (must be opaque).
710
+ * @cssprop [--ag-surface-alt] - Alternating row tint.
711
+ * @cssprop [--ag-surface-elevated] - Header background.
712
+ * @cssprop [--ag-hairline] - Header / structural gridline color.
713
+ * @cssprop [--ag-border] - Row separator color.
714
+ * @cssprop [--ag-text] - Primary text color.
715
+ * @cssprop [--ag-text-body] - Row text color.
716
+ * @cssprop [--ag-text-muted] - Muted text (roles, labels).
717
+ * @cssprop [--ag-row-hover] - Row hover wash.
718
+ * @cssprop [--ag-row-h] - Row height.
719
+ * @cssprop [--ag-header-h] - Header height.
720
+ * @cssprop [--ag-radius] - Outer card corner radius.
721
+ * @cssprop [--ag-font] - Grid font family.
722
+ * @cssprop [--ag-fs-cell] - Cell font size.
723
+ *
724
+ * @see {@link https://github.com/apexcharts/apex-grid/blob/main/packages/core/src/styles/_tokens.scss | _tokens.scss} for the complete `--ag-*` token list.
725
+ *
726
+ * @fires cellValidationFailed - Emitted when a candidate cell value is rejected by a column validator; the value is not written.
727
+ * @fires historyChanged - Emitted after the undo / redo stacks change; carries the current `canUndo` / `canRedo`.
728
+ * @fires stateChanged - Emitted (debounced) whenever the grid's restorable state changes; carries the new `getState` snapshot.
729
+ * @fires rowPinning - Cancellable. Emitted before a row is pinned, moved between bands, or unpinned.
730
+ * @fires rowPinned - Emitted after a row's pin state has changed.
731
+ * @fires rowMoving - Cancellable. Emitted before a row is moved via drag, keyboard, or `moveRow`.
732
+ * @fires rowMoved - Emitted after a row has been moved.
733
+ */
652
734
  export declare class ApexGrid<T extends object> extends EventEmitterBase<ApexGridEventMap<T>> {
653
735
  #private;
654
736
  static get tagName(): string;
@@ -1365,6 +1447,51 @@ export declare class ApexGrid<T extends object> extends EventEmitterBase<ApexGri
1365
1447
  * `rowEditEnded` in row mode.
1366
1448
  */
1367
1449
  commitEdit(): Promise<boolean>;
1450
+ /**
1451
+ * Applies many cell edits as a **single** operation.
1452
+ *
1453
+ * Every write goes through the same choke point interactive editing uses, so
1454
+ * each one emits the cancellable `cellValueChanging` and then
1455
+ * `cellValueChanged`, and runs the column's validators. What differs from
1456
+ * calling {@link editCell} + {@link commitEdit} in a loop is that the whole
1457
+ * set lands as one undo step and triggers one pipeline run, which is the
1458
+ * point: a thousand `editCell` round-trips would be a thousand entries in the
1459
+ * undo stack and a thousand re-renders.
1460
+ *
1461
+ * `rowIndex` is view-relative and matches {@link ApexGrid.pageItems}, the same
1462
+ * as {@link editCell}. Edits naming an unknown column, a row index out of
1463
+ * range, or a column the user could not edit either (editing off, not
1464
+ * `editable`, or hidden — the same gate interactive editing uses) are skipped
1465
+ * rather than throwing, so a partially-stale batch still applies what it can.
1466
+ *
1467
+ * @param edits Cells to write. Order is preserved, so later edits to the same
1468
+ * cell win.
1469
+ * @returns A per-outcome tally. `applied` counts cells whose value actually
1470
+ * changed; `unchanged`, `invalid` and `cancelled` explain the rest, so a caller
1471
+ * can tell a rejected batch from a no-op one.
1472
+ *
1473
+ * @example Bulk-clear a column for the rows the user selected
1474
+ * ```ts
1475
+ * grid.applyEdits(
1476
+ * grid.selectedRows.map((row) => ({
1477
+ * rowIndex: grid.pageItems.indexOf(row),
1478
+ * column: 'discount',
1479
+ * value: 0,
1480
+ * }))
1481
+ * );
1482
+ * ```
1483
+ */
1484
+ applyEdits(edits: ReadonlyArray<{
1485
+ rowIndex: number;
1486
+ column: Keys<T>;
1487
+ value: unknown;
1488
+ }>): {
1489
+ applied: number;
1490
+ unchanged: number;
1491
+ invalid: number;
1492
+ cancelled: number;
1493
+ skipped: number;
1494
+ };
1368
1495
  /**
1369
1496
  * Discards the current edit without writing back to {@link ApexGrid.data}.
1370
1497
  */
@@ -1506,6 +1633,11 @@ export declare class ApexGrid<T extends object> extends EventEmitterBase<ApexGri
1506
1633
  moveColumn(fromKey: Keys<T>, toKey: Keys<T>, position?: ColumnDropPosition): Promise<boolean>;
1507
1634
  protected bodyClickHandler(event: MouseEvent): void;
1508
1635
  protected bodyKeydownHandler(event: KeyboardEvent): void;
1636
+ /**
1637
+ * Tabbing into the grid body lands on the scroll container; forward focus to
1638
+ * the active cell (when one exists) so the roving tab stop is honored.
1639
+ */
1640
+ protected bodyFocusHandler(event: FocusEvent): void;
1509
1641
  /**
1510
1642
  * Forwards body-cell pointer interactions (press / drag-over / release) to
1511
1643
  * feature modules via {@link StateController.handleCellInteraction}. Gated on
@@ -12,7 +12,7 @@ import { DataOperationsController } from '../controllers/data-operation.js';
12
12
  import { GridDOMController } from '../controllers/dom.js';
13
13
  import { gridStateContext, StateController } from '../controllers/state.js';
14
14
  import { localize as resolveLocaleText, } from '../i18n/index.js';
15
- import { DEFAULT_COLUMN_CONFIG, PIPELINE } from '../internal/constants.js';
15
+ import { DEFAULT_COLUMN_CONFIG, PIPELINE, SENTINEL_NODE } from '../internal/constants.js';
16
16
  import { buildCSV, downloadBlob, } from '../internal/export.js';
17
17
  import { EventEmitterBase } from '../internal/mixins/event-emitter.js';
18
18
  import { registerComponent } from '../internal/register.js';
@@ -68,6 +68,7 @@ export class ApexGrid extends EventEmitterBase {
68
68
  this.columnSeparator = true;
69
69
  this.coordinateHints = false;
70
70
  this.columnMenu = true;
71
+ this.#autoAriaLabel = null;
71
72
  this.#stateChangedListeners = 0;
72
73
  this.#lastStateJson = null;
73
74
  }
@@ -271,8 +272,28 @@ export class ApexGrid extends EventEmitterBase {
271
272
  const extras = (this.stateController.selection.showCheckboxColumn ? 1 : 0) +
272
273
  (this.stateController.expansion.showToggleColumn ? 1 : 0);
273
274
  this.setAttribute('aria-colcount', String(visibleColumns + extras));
275
+ const selection = this.stateController.selection;
276
+ if (selection.enabled && selection.mode === 'multiple') {
277
+ this.setAttribute('aria-multiselectable', 'true');
278
+ }
279
+ else {
280
+ this.removeAttribute('aria-multiselectable');
281
+ }
282
+ if (this.scrollContainer) {
283
+ this.scrollContainer.tabIndex = this.stateController.active === SENTINEL_NODE ? 0 : -1;
284
+ }
285
+ const currentLabel = this.getAttribute('aria-label');
286
+ const authorLabeled = this.hasAttribute('aria-labelledby') ||
287
+ (currentLabel !== null && currentLabel !== this.#autoAriaLabel);
288
+ if (!authorLabeled) {
289
+ const label = this.localize('grid.label');
290
+ if (currentLabel !== label)
291
+ this.setAttribute('aria-label', label);
292
+ this.#autoAriaLabel = label;
293
+ }
274
294
  this.#emitStateChangedIfNeeded();
275
295
  }
296
+ #autoAriaLabel;
276
297
  #stateChangedListeners;
277
298
  #lastStateJson;
278
299
  addEventListener(type, listener, options) {
@@ -616,6 +637,31 @@ export class ApexGrid extends EventEmitterBase {
616
637
  const editing = this.stateController.editing;
617
638
  return editing.mode === 'row' ? editing.commitRow() : editing.commitCell();
618
639
  }
640
+ applyEdits(edits) {
641
+ const tally = { applied: 0, unchanged: 0, invalid: 0, cancelled: 0, skipped: 0 };
642
+ if (!edits.length)
643
+ return tally;
644
+ const editing = this.stateController.editing;
645
+ const items = this.pageItems;
646
+ this.stateController.history.beginBatch();
647
+ try {
648
+ for (const { rowIndex, column, value } of edits) {
649
+ const record = items.at(rowIndex);
650
+ const config = this.getColumn(column);
651
+ if (!record || rowIndex < 0 || !config || !editing.isEditable(config)) {
652
+ tally.skipped += 1;
653
+ continue;
654
+ }
655
+ tally[editing.applyCellEdit(rowIndex, column, record, value)] += 1;
656
+ }
657
+ }
658
+ finally {
659
+ this.stateController.history.endBatch();
660
+ }
661
+ if (tally.applied > 0)
662
+ this.requestUpdate(PIPELINE);
663
+ return tally;
664
+ }
619
665
  cancelEdit() {
620
666
  const editing = this.stateController.editing;
621
667
  if (editing.mode === 'row') {
@@ -716,13 +762,23 @@ export class ApexGrid extends EventEmitterBase {
716
762
  column: target.column.key,
717
763
  row: target.row.index,
718
764
  };
765
+ if (!target.editing)
766
+ target.focus({ preventScroll: true });
719
767
  }
720
768
  }
721
769
  bodyKeydownHandler(event) {
722
- if (this.scrollContainer.isSameNode(event.target)) {
770
+ const origin = event.composedPath()[0];
771
+ const fromBody = this.scrollContainer.isSameNode(event.target);
772
+ const fromCell = origin instanceof ApexGridCell && !origin.editing;
773
+ if (fromBody || fromCell) {
723
774
  this.stateController.navigation.navigate(event);
724
775
  }
725
776
  }
777
+ bodyFocusHandler(event) {
778
+ if (this.scrollContainer.isSameNode(event.target)) {
779
+ this.stateController.navigation.focusActiveCell();
780
+ }
781
+ }
726
782
  bodyPointerHandler(event) {
727
783
  if (this.stateController.modules.size === 0)
728
784
  return;
@@ -772,6 +828,7 @@ export class ApexGrid extends EventEmitterBase {
772
828
  .renderItem=${this.DOM.rowRenderer}
773
829
  @click=${this.bodyClickHandler}
774
830
  @keydown=${this.bodyKeydownHandler}
831
+ @focusin=${this.bodyFocusHandler}
775
832
  @pointerdown=${this.bodyPointerHandler}
776
833
  @pointermove=${this.bodyPointerHandler}
777
834
  @pointerup=${this.bodyPointerHandler}