apex-grid 3.0.1 → 3.1.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 (41) hide show
  1. package/CHANGELOG.md +40 -1
  2. package/components/cell.d.ts +7 -0
  3. package/components/cell.js +33 -0
  4. package/components/cell.js.map +1 -1
  5. package/components/filter-row.d.ts +1 -1
  6. package/components/grid.d.ts +11 -3
  7. package/components/grid.js +22 -1
  8. package/components/grid.js.map +1 -1
  9. package/components/header-row.d.ts +3 -3
  10. package/components/header.d.ts +2 -2
  11. package/components/paginator.d.ts +1 -1
  12. package/components/row.d.ts +11 -4
  13. package/components/row.js +35 -1
  14. package/components/row.js.map +1 -1
  15. package/components/toolbar.d.ts +2 -2
  16. package/controllers/data-operation.js +1 -0
  17. package/controllers/data-operation.js.map +1 -1
  18. package/controllers/dom.js +1 -0
  19. package/controllers/dom.js.map +1 -1
  20. package/controllers/resize.d.ts +1 -1
  21. package/controllers/state.d.ts +34 -1
  22. package/controllers/state.js +50 -1
  23. package/controllers/state.js.map +1 -1
  24. package/custom-elements.json +421 -2
  25. package/docs/assets/hierarchy.js +1 -1
  26. package/docs/hierarchy.html +1 -1
  27. package/docs/interfaces/BaseApexCellContext.html +1 -1
  28. package/docs/interfaces/BaseApexEditorContext.html +1 -1
  29. package/docs/interfaces/CSVExportOptions.html +1 -1
  30. package/docs/interfaces/ExportOptions.html +1 -1
  31. package/docs/interfaces/PaginationState.html +1 -1
  32. package/docs/media/package.json +1 -1
  33. package/internal/feature-module.d.ts +135 -3
  34. package/internal/feature-module.js +20 -1
  35. package/internal/feature-module.js.map +1 -1
  36. package/internal/index.d.ts +4 -2
  37. package/internal/index.js +2 -0
  38. package/internal/index.js.map +1 -1
  39. package/package.json +1 -1
  40. package/styles/body-cell/body-cell.css.js +1 -1
  41. package/styles/body-cell/body-cell.css.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"row.js","sourceRoot":"","sources":["../../src/components/row.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property, queryAll } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_ROW_TAG } from '../internal/tags.js';\nimport type { ActiveNode, ColumnConfiguration, Keys } from '../internal/types.js';\nimport { getPinEdge } from '../internal/utils.js';\nimport { styles } from '../styles/body-row/body-row.css.js';\nimport ApexGridCell from './cell.js';\n\n/**\n * Component representing the DOM row in the Apex grid.\n */\nexport default class ApexGridRow<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_ROW_TAG;\n }\n public static override styles = styles;\n\n public static register(): void {\n registerComponent(ApexGridRow, ApexGridCell);\n }\n\n @queryAll(ApexGridCell.tagName)\n protected _cells!: NodeListOf<ApexGridCell<T>>;\n\n @property({ attribute: false })\n public data!: T;\n\n @property({ attribute: false })\n public columns: Array<ColumnConfiguration<T>> = [];\n\n /** Cumulative pin offsets (px) keyed by column key. */\n @property({ attribute: false })\n public pinOffsets: Map<unknown, number> = new Map();\n\n public get cells() {\n return Array.from(this._cells);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n @property({ attribute: false })\n public activeNode!: ActiveNode<T>;\n\n @property({ attribute: false, type: Number })\n public index = -1;\n\n /** Reflects current selection state so SCSS can highlight the row. */\n @property({ type: Boolean, reflect: true })\n public selected = false;\n\n /** Reflects current expansion state so SCSS can rotate the chevron. */\n @property({ type: Boolean, reflect: true })\n public expanded = false;\n\n /** The column key currently being edited in this row, or `null`. */\n @property({ attribute: false })\n public editingKey: Keys<T> | null = null;\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('exportparts', 'cell');\n this.setAttribute('role', 'row');\n }\n\n /**\n * The number of \"chrome\" rows (header + filter) above the body. Used to\n * derive `aria-rowindex` from {@link index}. Set by the parent grid.\n */\n @property({ attribute: false, type: Number })\n public ariaRowOffset = 1;\n\n protected override willUpdate() {\n this.selected = Boolean(this.state?.selection.isSelected(this.data));\n this.expanded = Boolean(this.state?.expansion.isExpanded(this.data));\n this.setAttribute('aria-rowindex', String(this.index + this.ariaRowOffset + 1));\n if (this.state?.selection.enabled) {\n this.setAttribute('aria-selected', this.selected ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-selected');\n }\n\n // Tree mode reports aria-level (1-based depth) and aria-expanded for\n // parent rows; expansion mode shares the same attribute on detail-panel\n // rows. Tree wins when both are enabled since it's the more structural\n // semantic (the row represents a tree node).\n const tree = this.state?.tree;\n const treeMeta = tree?.enabled ? tree.getMeta(this.data) : undefined;\n if (treeMeta) {\n this.setAttribute('aria-level', String(treeMeta.depth + 1));\n if (treeMeta.hasChildren) {\n this.setAttribute('aria-expanded', tree!.isExpanded(this.data) ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n } else {\n this.removeAttribute('aria-level');\n if (this.state?.expansion.enabled) {\n this.setAttribute('aria-expanded', this.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n }\n }\n\n protected renderExpansionToggle(colindex: number) {\n const expansion = this.state?.expansion;\n if (!expansion?.showToggleColumn) return nothing;\n const canExpand = expansion.canExpand(this.data) || expansion.isExpanded(this.data);\n const expanded = this.expanded;\n const handleClick = (event: MouseEvent) => {\n event.stopPropagation();\n if (!canExpand) return;\n void expansion.toggleRow(this.data);\n };\n return html`<div\n part=\"expansion-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <button\n type=\"button\"\n part=\"expansion-toggle\"\n aria-label=${expanded ? 'Collapse row' : 'Expand row'}\n aria-expanded=${expanded ? 'true' : 'false'}\n ?disabled=${!canExpand}\n @click=${handleClick}\n >\n <svg\n part=\"expansion-chevron\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n width=\"14\"\n height=\"14\"\n >\n <path\n d=\"M9 6l6 6-6 6\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>`;\n }\n\n protected renderDetailPanel() {\n const expansion = this.state?.expansion;\n if (!expansion?.isExpanded(this.data)) return nothing;\n const template = this.state.host.expansion?.detailTemplate;\n if (typeof template !== 'function') return nothing;\n const content = template({\n data: this.data,\n rowIndex: this.index,\n parent: this.state.host,\n });\n return html`<div part=\"detail-panel\" role=\"region\" aria-label=\"Row detail\">${content}</div>`;\n }\n\n protected renderSelectionCell(colindex: number) {\n if (!this.state?.selection.showCheckboxColumn) return nothing;\n const selected = this.selected;\n const handleChange = (event: Event) => {\n const mouseEvent = event as Event & {\n shiftKey?: boolean;\n ctrlKey?: boolean;\n metaKey?: boolean;\n };\n // The native `change` event on a checkbox doesn't expose modifier keys\n // — they're carried on the preceding `click`. We handle Shift/Ctrl in\n // the click listener below; the change handler covers keyboard toggles\n // (Space on a focused checkbox) which always behave as plain toggles.\n void mouseEvent;\n this.state.selection.toggleRow(this.data);\n };\n const handleClick = (event: MouseEvent) => {\n // Prevent the click from bubbling to the grid's body click handler\n // (which would otherwise re-target the active cell to a non-existent\n // selection column).\n event.stopPropagation();\n if (event.shiftKey && this.state.selection.mode === 'multiple') {\n event.preventDefault();\n void this.state.selection.rangeToggle(this.data);\n return;\n }\n if ((event.ctrlKey || event.metaKey) && this.state.selection.mode === 'multiple') {\n event.preventDefault();\n void this.state.selection.additiveToggle(this.data);\n return;\n }\n // Plain click: let the default checkbox toggle proceed; `change` will\n // commit the new state via `toggleRow`.\n };\n return html`<div\n part=\"selection-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <input\n type=\"checkbox\"\n part=\"selection-checkbox\"\n aria-label=\"Select row\"\n .checked=${selected}\n @click=${handleClick}\n @change=${handleChange}\n />\n </div>`;\n }\n\n protected override render() {\n const { column: key, row: index } = this.activeNode;\n\n // Track aria-colindex (1-based) across the auto chrome columns and the\n // data columns. Selection comes first, then expansion, then data.\n let colCursor = 0;\n const selectionCol = this.state?.selection.showCheckboxColumn ? ++colCursor : 0;\n const expansionCol = this.state?.expansion.showToggleColumn ? ++colCursor : 0;\n\n // Keyed by column.key so the same `<apex-grid-cell>` follows its\n // column through a reorder swap — required for the column-reorder FLIP\n // animation in ReorderController to track motion per cell.\n return html`\n ${this.renderSelectionCell(selectionCol)}\n ${this.renderExpansionToggle(expansionCol)}\n ${repeat(\n this.columns,\n (column) => String(column.key),\n (column, colIndex) => {\n if (column.hidden) return nothing;\n const offset = this.pinOffsets.get(column.key);\n const pinStyle =\n column.pinned && typeof offset === 'number' ? `--apex-pin-offset:${offset}px` : '';\n const edge = getPinEdge(this.columns, colIndex);\n const editing = this.editingKey === column.key;\n const ariaColindex = ++colCursor;\n return html`<apex-grid-cell\n part=\"cell\"\n data-pinned=${column.pinned ?? 'none'}\n data-pin-edge=${edge ?? 'none'}\n data-cell-type=${column.type ?? 'string'}\n style=${pinStyle}\n .active=${key === column.key && index === this.index}\n .editing=${editing}\n .column=${column}\n .row=${this as ApexGridRow<T>}\n .value=${this.data[column.key]}\n .colindex=${ariaColindex}\n ></apex-grid-cell>`;\n }\n )}\n ${this.renderDetailPanel()}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridRow.tagName]: ApexGridRow<object>;\n }\n}\n"]}
1
+ {"version":3,"file":"row.js","sourceRoot":"","sources":["../../src/components/row.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property, queryAll } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport type { PresentedRow } from '../internal/feature-module.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_ROW_TAG } from '../internal/tags.js';\nimport type { ActiveNode, ColumnConfiguration, Keys } from '../internal/types.js';\nimport { getPinEdge } from '../internal/utils.js';\nimport { styles } from '../styles/body-row/body-row.css.js';\nimport ApexGridCell from './cell.js';\n\n/**\n * Component representing the DOM row in the Apex grid.\n */\nexport default class ApexGridRow<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_ROW_TAG;\n }\n public static override styles = styles;\n\n public static register(): void {\n registerComponent(ApexGridRow, ApexGridCell);\n }\n\n @queryAll(ApexGridCell.tagName)\n protected _cells!: NodeListOf<ApexGridCell<T>>;\n\n @property({ attribute: false })\n public data!: T;\n\n @property({ attribute: false })\n public columns: Array<ColumnConfiguration<T>> = [];\n\n /** Cumulative pin offsets (px) keyed by column key. */\n @property({ attribute: false })\n public pinOffsets: Map<unknown, number> = new Map();\n\n public get cells() {\n return Array.from(this._cells);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n @property({ attribute: false })\n public activeNode!: ActiveNode<T>;\n\n @property({ attribute: false, type: Number })\n public index = -1;\n\n /** Reflects current selection state so SCSS can highlight the row. */\n @property({ type: Boolean, reflect: true })\n public selected = false;\n\n /** Reflects current expansion state so SCSS can rotate the chevron. */\n @property({ type: Boolean, reflect: true })\n public expanded = false;\n\n /** The column key currently being edited in this row, or `null`. */\n @property({ attribute: false })\n public editingKey: Keys<T> | null = null;\n\n /**\n * Reactive token from {@link StateController.decorationVersion}, forwarded to\n * each cell so a decoration-only change re-renders the row's cells. Stays `0`\n * for the community grid.\n */\n @property({ attribute: false, type: Number })\n public decorationVersion = 0;\n\n /**\n * Result of the feature-module row presenter for the current update, or\n * `null` when no module renders this row full-width (the normal case).\n * Computed in {@link willUpdate} and consumed in {@link render}.\n */\n #presented: PresentedRow | null = null;\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('exportparts', 'cell');\n this.setAttribute('role', 'row');\n }\n\n /**\n * The number of \"chrome\" rows (header + filter) above the body. Used to\n * derive `aria-rowindex` from {@link index}. Set by the parent grid.\n */\n @property({ attribute: false, type: Number })\n public ariaRowOffset = 1;\n\n protected override willUpdate() {\n this.setAttribute('aria-rowindex', String(this.index + this.ariaRowOffset + 1));\n\n // Ask feature modules whether this row is rendered full-width (e.g. an\n // enterprise group header). When one owns it, the row is not a selectable\n // data row — it carries its own level/expanded semantics and skips the\n // selection/tree aria below.\n this.#presented = this.state\n ? this.state.presentRow(this.data, { columns: this.columns, rowIndex: this.index })\n : null;\n if (this.#presented) {\n this.selected = false;\n this.removeAttribute('aria-selected');\n if (typeof this.#presented.level === 'number') {\n this.setAttribute('aria-level', String(this.#presented.level));\n } else {\n this.removeAttribute('aria-level');\n }\n if (typeof this.#presented.expanded === 'boolean') {\n this.setAttribute('aria-expanded', this.#presented.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n return;\n }\n\n this.selected = Boolean(this.state?.selection.isSelected(this.data));\n this.expanded = Boolean(this.state?.expansion.isExpanded(this.data));\n if (this.state?.selection.enabled) {\n this.setAttribute('aria-selected', this.selected ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-selected');\n }\n\n // Tree mode reports aria-level (1-based depth) and aria-expanded for\n // parent rows; expansion mode shares the same attribute on detail-panel\n // rows. Tree wins when both are enabled since it's the more structural\n // semantic (the row represents a tree node).\n const tree = this.state?.tree;\n const treeMeta = tree?.enabled ? tree.getMeta(this.data) : undefined;\n if (treeMeta) {\n this.setAttribute('aria-level', String(treeMeta.depth + 1));\n if (treeMeta.hasChildren) {\n this.setAttribute('aria-expanded', tree!.isExpanded(this.data) ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n } else {\n this.removeAttribute('aria-level');\n if (this.state?.expansion.enabled) {\n this.setAttribute('aria-expanded', this.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n }\n }\n\n protected renderExpansionToggle(colindex: number) {\n const expansion = this.state?.expansion;\n if (!expansion?.showToggleColumn) return nothing;\n const canExpand = expansion.canExpand(this.data) || expansion.isExpanded(this.data);\n const expanded = this.expanded;\n const handleClick = (event: MouseEvent) => {\n event.stopPropagation();\n if (!canExpand) return;\n void expansion.toggleRow(this.data);\n };\n return html`<div\n part=\"expansion-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <button\n type=\"button\"\n part=\"expansion-toggle\"\n aria-label=${expanded ? 'Collapse row' : 'Expand row'}\n aria-expanded=${expanded ? 'true' : 'false'}\n ?disabled=${!canExpand}\n @click=${handleClick}\n >\n <svg\n part=\"expansion-chevron\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n width=\"14\"\n height=\"14\"\n >\n <path\n d=\"M9 6l6 6-6 6\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>`;\n }\n\n protected renderDetailPanel() {\n const expansion = this.state?.expansion;\n if (!expansion?.isExpanded(this.data)) return nothing;\n const template = this.state.host.expansion?.detailTemplate;\n if (typeof template !== 'function') return nothing;\n const content = template({\n data: this.data,\n rowIndex: this.index,\n parent: this.state.host,\n });\n return html`<div part=\"detail-panel\" role=\"region\" aria-label=\"Row detail\">${content}</div>`;\n }\n\n protected renderSelectionCell(colindex: number) {\n if (!this.state?.selection.showCheckboxColumn) return nothing;\n const selected = this.selected;\n const handleChange = (event: Event) => {\n const mouseEvent = event as Event & {\n shiftKey?: boolean;\n ctrlKey?: boolean;\n metaKey?: boolean;\n };\n // The native `change` event on a checkbox doesn't expose modifier keys\n // — they're carried on the preceding `click`. We handle Shift/Ctrl in\n // the click listener below; the change handler covers keyboard toggles\n // (Space on a focused checkbox) which always behave as plain toggles.\n void mouseEvent;\n this.state.selection.toggleRow(this.data);\n };\n const handleClick = (event: MouseEvent) => {\n // Prevent the click from bubbling to the grid's body click handler\n // (which would otherwise re-target the active cell to a non-existent\n // selection column).\n event.stopPropagation();\n if (event.shiftKey && this.state.selection.mode === 'multiple') {\n event.preventDefault();\n void this.state.selection.rangeToggle(this.data);\n return;\n }\n if ((event.ctrlKey || event.metaKey) && this.state.selection.mode === 'multiple') {\n event.preventDefault();\n void this.state.selection.additiveToggle(this.data);\n return;\n }\n // Plain click: let the default checkbox toggle proceed; `change` will\n // commit the new state via `toggleRow`.\n };\n return html`<div\n part=\"selection-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <input\n type=\"checkbox\"\n part=\"selection-checkbox\"\n aria-label=\"Select row\"\n .checked=${selected}\n @click=${handleClick}\n @change=${handleChange}\n />\n </div>`;\n }\n\n protected override render() {\n // Full-width module-rendered row (e.g. a group header): render the module's\n // content spanning all columns, like the master-detail panel, and skip the\n // normal selection/expansion/cell grid.\n if (this.#presented) {\n return html`<div part=${this.#presented.part ?? 'group-row'} style=\"grid-column: 1 / -1\">\n ${this.#presented.content}\n </div>`;\n }\n\n // A row index can transiently fall beyond the current data — e.g. while a\n // server-side / infinite row model resizes `data` on a filter or sort\n // change, the virtualizer may render a stale index for a frame. Render\n // nothing until the real item arrives, rather than dereferencing undefined.\n if (this.data == null) return nothing;\n\n const { column: key, row: index } = this.activeNode;\n\n // Track aria-colindex (1-based) across the auto chrome columns and the\n // data columns. Selection comes first, then expansion, then data.\n let colCursor = 0;\n const selectionCol = this.state?.selection.showCheckboxColumn ? ++colCursor : 0;\n const expansionCol = this.state?.expansion.showToggleColumn ? ++colCursor : 0;\n\n // Keyed by column.key so the same `<apex-grid-cell>` follows its\n // column through a reorder swap — required for the column-reorder FLIP\n // animation in ReorderController to track motion per cell.\n return html`\n ${this.renderSelectionCell(selectionCol)}\n ${this.renderExpansionToggle(expansionCol)}\n ${repeat(\n this.columns,\n (column) => String(column.key),\n (column, colIndex) => {\n if (column.hidden) return nothing;\n const offset = this.pinOffsets.get(column.key);\n const pinStyle =\n column.pinned && typeof offset === 'number' ? `--apex-pin-offset:${offset}px` : '';\n const edge = getPinEdge(this.columns, colIndex);\n const editing = this.editingKey === column.key;\n const ariaColindex = ++colCursor;\n return html`<apex-grid-cell\n part=\"cell\"\n data-pinned=${column.pinned ?? 'none'}\n data-pin-edge=${edge ?? 'none'}\n data-cell-type=${column.type ?? 'string'}\n style=${pinStyle}\n .active=${key === column.key && index === this.index}\n .editing=${editing}\n .column=${column}\n .row=${this as ApexGridRow<T>}\n .value=${this.data[column.key]}\n .colindex=${ariaColindex}\n .decorationVersion=${this.decorationVersion}\n ></apex-grid-cell>`;\n }\n )}\n ${this.renderDetailPanel()}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridRow.tagName]: ApexGridRow<object>;\n }\n}\n"]}
@@ -49,8 +49,8 @@ export default class ApexGridToolbar<T extends object> extends LitElement {
49
49
  protected exportMenuOpen: boolean;
50
50
  connectedCallback(): void;
51
51
  disconnectedCallback(): void;
52
- protected renderQuickFilter(): typeof nothing | import("lit-html").TemplateResult<1>;
53
- protected renderExportMenu(): typeof nothing | import("lit-html").TemplateResult<1>;
52
+ protected renderQuickFilter(): import("lit-html").TemplateResult<1> | typeof nothing;
53
+ protected renderExportMenu(): import("lit-html").TemplateResult<1> | typeof nothing;
54
54
  protected render(): import("lit-html").TemplateResult<1>;
55
55
  }
56
56
  declare global {
@@ -47,6 +47,7 @@ export class DataOperationsController {
47
47
  if (state.tree.enabled) {
48
48
  transformed = state.tree.process(transformed);
49
49
  }
50
+ transformed = state.applyModuleTransforms(transformed);
50
51
  return transformed;
51
52
  }
52
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"data-operation.js","sourceRoot":"","sources":["../../src/controllers/data-operation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport { isDefined } from '../internal/is-defined.js';\nimport type { GridHost } from '../internal/types.js';\nimport FilterDataOperation from '../operations/filter.js';\nimport QuickFilterDataOperation from '../operations/quick-filter.js';\nimport SortDataOperation from '../operations/sort.js';\nimport type { StateController } from './state.js';\n\nexport class DataOperationsController<T extends object> implements ReactiveController {\n protected sorting = new SortDataOperation<T>();\n protected filtering = new FilterDataOperation<T>();\n protected quickFiltering = new QuickFilterDataOperation<T>();\n\n constructor(protected host: GridHost<T>) {\n this.host.addController(this);\n }\n\n public hostConnected() {}\n\n protected get hasCustomSort() {\n return isDefined(this.host.dataPipelineConfiguration?.sort);\n }\n\n protected get hasCustomFilter() {\n return isDefined(this.host.dataPipelineConfiguration?.filter);\n }\n\n protected get hasCustomQuickFilter() {\n return isDefined(this.host.dataPipelineConfiguration?.quickFilter);\n }\n\n protected get customFilter() {\n return this.host.dataPipelineConfiguration!.filter!;\n }\n\n protected get customSort() {\n return this.host.dataPipelineConfiguration!.sort!;\n }\n\n protected get customQuickFilter() {\n return this.host.dataPipelineConfiguration!.quickFilter!;\n }\n\n /**\n * Applies the quick-filter (global search), column-filter, and sort steps of the\n * data pipeline.\n *\n * @remarks\n * The returned dataset is the full post-filter, post-sort view. Pagination is\n * intentionally not applied here so callers can derive `totalItems` and the\n * paginator's `pageCount` from a stable value. The grid slices the page for\n * the virtualizer at render time.\n */\n public async apply(data: T[], state: StateController<T>) {\n const { filtering, sorting } = state;\n let transformed: T[];\n\n const quickFilterTerm = (this.host.quickFilter ?? '').trim();\n transformed = this.hasCustomQuickFilter\n ? await this.customQuickFilter({ data, grid: this.host, type: 'quickFilter' })\n : quickFilterTerm\n ? this.quickFiltering.apply(data, quickFilterTerm, this.host.columns)\n : data;\n\n transformed = this.hasCustomFilter\n ? await this.customFilter({ data: transformed, grid: this.host, type: 'filter' })\n : this.filtering.apply(transformed, filtering.state);\n\n transformed = this.hasCustomSort\n ? await this.customSort({ data: transformed, grid: this.host, type: 'sort' })\n : this.sorting.apply(transformed, sorting.state);\n\n // Tree mode flattens the post-sort rows according to the current\n // expansion set. Disabled is a no-op pass-through, so flat tables keep\n // their existing behaviour untouched.\n if (state.tree.enabled) {\n transformed = state.tree.process(transformed);\n }\n\n return transformed;\n }\n}\n"]}
1
+ {"version":3,"file":"data-operation.js","sourceRoot":"","sources":["../../src/controllers/data-operation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport { isDefined } from '../internal/is-defined.js';\nimport type { GridHost } from '../internal/types.js';\nimport FilterDataOperation from '../operations/filter.js';\nimport QuickFilterDataOperation from '../operations/quick-filter.js';\nimport SortDataOperation from '../operations/sort.js';\nimport type { StateController } from './state.js';\n\nexport class DataOperationsController<T extends object> implements ReactiveController {\n protected sorting = new SortDataOperation<T>();\n protected filtering = new FilterDataOperation<T>();\n protected quickFiltering = new QuickFilterDataOperation<T>();\n\n constructor(protected host: GridHost<T>) {\n this.host.addController(this);\n }\n\n public hostConnected() {}\n\n protected get hasCustomSort() {\n return isDefined(this.host.dataPipelineConfiguration?.sort);\n }\n\n protected get hasCustomFilter() {\n return isDefined(this.host.dataPipelineConfiguration?.filter);\n }\n\n protected get hasCustomQuickFilter() {\n return isDefined(this.host.dataPipelineConfiguration?.quickFilter);\n }\n\n protected get customFilter() {\n return this.host.dataPipelineConfiguration!.filter!;\n }\n\n protected get customSort() {\n return this.host.dataPipelineConfiguration!.sort!;\n }\n\n protected get customQuickFilter() {\n return this.host.dataPipelineConfiguration!.quickFilter!;\n }\n\n /**\n * Applies the quick-filter (global search), column-filter, and sort steps of the\n * data pipeline.\n *\n * @remarks\n * The returned dataset is the full post-filter, post-sort view. Pagination is\n * intentionally not applied here so callers can derive `totalItems` and the\n * paginator's `pageCount` from a stable value. The grid slices the page for\n * the virtualizer at render time.\n */\n public async apply(data: T[], state: StateController<T>) {\n const { filtering, sorting } = state;\n let transformed: T[];\n\n const quickFilterTerm = (this.host.quickFilter ?? '').trim();\n transformed = this.hasCustomQuickFilter\n ? await this.customQuickFilter({ data, grid: this.host, type: 'quickFilter' })\n : quickFilterTerm\n ? this.quickFiltering.apply(data, quickFilterTerm, this.host.columns)\n : data;\n\n transformed = this.hasCustomFilter\n ? await this.customFilter({ data: transformed, grid: this.host, type: 'filter' })\n : this.filtering.apply(transformed, filtering.state);\n\n transformed = this.hasCustomSort\n ? await this.customSort({ data: transformed, grid: this.host, type: 'sort' })\n : this.sorting.apply(transformed, sorting.state);\n\n // Tree mode flattens the post-sort rows according to the current\n // expansion set. Disabled is a no-op pass-through, so flat tables keep\n // their existing behaviour untouched.\n if (state.tree.enabled) {\n transformed = state.tree.process(transformed);\n }\n\n // Feature modules (e.g. enterprise row grouping) may inject or reorder rows\n // after the built-in pipeline, before pagination slices the page. With no\n // modules registered this is an identity pass-through, so the community\n // `<apex-grid>` behaviour is unchanged.\n transformed = state.applyModuleTransforms(transformed);\n\n return transformed;\n }\n}\n"]}
@@ -34,6 +34,7 @@ export class GridDOMController {
34
34
  .pinOffsets=${this.pinOffsets}
35
35
  .editingKey=${editingKey}
36
36
  .ariaRowOffset=${ariaRowOffset}
37
+ .decorationVersion=${this.state.decorationVersion}
37
38
  >
38
39
  </apex-grid-row>
39
40
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"dom.js","sourceRoot":"","sources":["../../src/controllers/dom.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RenderItemFunction } from '@lit-labs/virtualizer/virtualize.js';\nimport { html, type ReactiveController } from 'lit';\nimport { type StyleInfo, styleMap } from 'lit/directives/style-map.js';\nimport type { ColumnConfiguration, GridHost, Keys } from '../internal/types.js';\nimport { applyColumnWidths, getDisplayColumns } from '../internal/utils.js';\nimport type { StateController } from './state.js';\n\nexport class GridDOMController<T extends object> implements ReactiveController {\n constructor(\n protected host: GridHost<T>,\n protected state: StateController<T>\n ) {\n this.host.addController(this);\n }\n\n #initialSize = () => {\n setTimeout(() => {\n this.setScrollOffset();\n this.recomputePinOffsets();\n this.recomputeStickyRowOffsets();\n });\n };\n\n #resizeObserver: ResizeObserver | null = null;\n #observedHeaders = new Set<Element>();\n #stickyRowObserver: ResizeObserver | null = null;\n #observedStickyRows = new Set<Element>();\n\n public get container() {\n // @ts-expect-error: protected member access\n return this.host.scrollContainer;\n }\n\n /**\n * Visual render order: `'start'`-pinned columns first, then unpinned, then\n * `'end'`-pinned. The user-supplied `columns` array is never mutated.\n */\n public get displayColumns(): Array<ColumnConfiguration<T>> {\n return getDisplayColumns(this.host.columns);\n }\n\n public columnSizes: StyleInfo = {};\n\n /**\n * The resolved inline-start (for `'start'` pin) or inline-end (for `'end'` pin)\n * pixel offset per pinned column key. Populated after layout by\n * {@link recomputePinOffsets}.\n */\n public pinOffsets = new Map<Keys<T>, number>();\n\n public rowRenderer: RenderItemFunction<T> = (data: T, index: number) => {\n const editingCell = this.state.editing.activeCell;\n const editingKey = editingCell?.rowIndex === index ? editingCell.columnKey : null;\n // aria-rowindex offset: header row is always row 1; filter row (when\n // any column has a filter configured) sits at row 2; body rows start\n // immediately after.\n const hasFilter = this.host.columns.some((column) => column.filter);\n const ariaRowOffset = hasFilter ? 2 : 1;\n return html`\n <apex-grid-row\n part=\"row\"\n style=${styleMap({ ...this.columnSizes, ...this.getActiveRowStyles(index) })}\n .index=${index}\n .activeNode=${this.state.active}\n .data=${data}\n .columns=${this.displayColumns}\n .pinOffsets=${this.pinOffsets}\n .editingKey=${editingKey}\n .ariaRowOffset=${ariaRowOffset}\n >\n </apex-grid-row>\n `;\n };\n\n public async hostConnected() {\n this.setGridColumnSizes();\n // Wait for the initial paint of the virtualizer and recalculate the scrollbar offset\n // for the next one\n await this.host.updateComplete;\n this.#initialSize();\n if (typeof ResizeObserver !== 'undefined' && !this.#hostWidthObserver) {\n this.#hostWidthObserver = new ResizeObserver(() => {\n requestAnimationFrame(() => this.recomputeHostWidth());\n });\n this.#hostWidthObserver.observe(this.host as HTMLElement);\n }\n this.recomputeHostWidth();\n }\n\n public hostUpdate(): void {\n this.setScrollOffset();\n this.setGridColumnSizes();\n }\n\n public hostUpdated(): void {\n this.recomputePinOffsets();\n this.observeHeaderCells();\n this.recomputeStickyRowOffsets();\n this.observeStickyRows();\n }\n\n public hostDisconnected(): void {\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = null;\n this.#observedHeaders.clear();\n this.#stickyRowObserver?.disconnect();\n this.#stickyRowObserver = null;\n this.#observedStickyRows.clear();\n this.#hostWidthObserver?.disconnect();\n this.#hostWidthObserver = null;\n }\n\n /**\n * Writes the grid host's `clientWidth` into `--apex-host-width`. Used by the\n * toolbar and paginator to clamp their width to the visible viewport so\n * horizontal scrolling doesn't drag them off-screen.\n */\n public recomputeHostWidth(): void {\n const host = this.host as HTMLElement;\n const width = host.clientWidth;\n if (width === this.#lastHostWidth) return;\n host.style.setProperty('--apex-host-width', `${width}px`);\n this.#lastHostWidth = width;\n }\n\n public setScrollOffset() {\n // The grid host now owns vertical scrolling, so the historic per-row\n // padding-inline-end compensation is no longer needed. Keep the CSS var\n // set to `0` for forward compatibility with consumer themes that read it.\n this.host.style.setProperty('--scrollbar-offset', '0px');\n }\n\n protected setGridColumnSizes() {\n this.columnSizes = applyColumnWidths(this.displayColumns, {\n showSelectionColumn: this.state.selection.showCheckboxColumn,\n showExpansionColumn: this.state.expansion.showToggleColumn,\n });\n }\n\n public getActiveRowStyles(index: number): StyleInfo {\n const { row } = this.state.active;\n return row === index ? { 'z-index': '3' } : {};\n }\n\n /**\n * Measures the rendered widths of pinned header cells and writes cumulative\n * inline-start / inline-end pixel offsets into {@link pinOffsets}. Called after\n * each grid update and whenever a header cell is resized.\n */\n public recomputePinOffsets(): void {\n // @ts-expect-error - protected member access\n const headerRow = this.host.headerRow as\n | {\n headers?: Array<{\n column: ColumnConfiguration<T>;\n getBoundingClientRect: () => DOMRect;\n }>;\n }\n | undefined;\n if (!headerRow?.headers) return;\n\n const next = new Map<Keys<T>, number>();\n const headersByKey = new Map<Keys<T>, DOMRect>();\n for (const header of headerRow.headers) {\n headersByKey.set(header.column.key as Keys<T>, header.getBoundingClientRect());\n }\n\n let leftAccum = 0;\n for (const column of this.displayColumns) {\n if (column.hidden) continue;\n if (column.pinned !== 'start') break;\n next.set(column.key as Keys<T>, leftAccum);\n const rect = headersByKey.get(column.key as Keys<T>);\n leftAccum += rect?.width ?? 0;\n }\n\n let rightAccum = 0;\n for (let i = this.displayColumns.length - 1; i >= 0; i--) {\n const column = this.displayColumns[i];\n if (column.hidden) continue;\n if (column.pinned !== 'end') break;\n next.set(column.key as Keys<T>, rightAccum);\n const rect = headersByKey.get(column.key as Keys<T>);\n rightAccum += rect?.width ?? 0;\n }\n\n if (!offsetsEqual(this.pinOffsets, next)) {\n this.pinOffsets = next;\n this.host.requestUpdate();\n }\n }\n\n protected observeHeaderCells(): void {\n // @ts-expect-error - protected member access\n const headerRow = this.host.headerRow as { headers?: Array<Element> } | undefined;\n if (!headerRow?.headers) return;\n\n if (!this.#resizeObserver) {\n this.#resizeObserver = new ResizeObserver(() => {\n // Defer to a new frame so any layout writes can't synchronously feed back\n // into this observer (which makes the browser raise the benign\n // \"ResizeObserver loop completed\" warning).\n requestAnimationFrame(() => this.recomputePinOffsets());\n });\n }\n\n const next = new Set<Element>(headerRow.headers);\n for (const element of this.#observedHeaders) {\n if (!next.has(element)) this.#resizeObserver.unobserve(element);\n }\n for (const element of next) {\n if (!this.#observedHeaders.has(element)) this.#resizeObserver.observe(element);\n }\n this.#observedHeaders = next;\n }\n\n #lastHeaderTop = -1;\n #lastFilterTop = -1;\n #lastHostWidth = -1;\n #hostWidthObserver: ResizeObserver | null = null;\n\n /**\n * Writes the cumulative height of the sticky top rows into CSS custom\n * properties used by the header/filter rows for their `inset-block-start`\n * offsets. The toolbar is always at `top: 0`; the header sits below it\n * (`--apex-row-top-header`) and the filter sits below the header\n * (`--apex-row-top-filter`). Writes are skipped when the values haven't\n * changed so the ResizeObserver feedback loop terminates.\n */\n public recomputeStickyRowOffsets(): void {\n const root = (this.host as HTMLElement).shadowRoot;\n if (!root) return;\n const toolbar = root.querySelector('apex-grid-toolbar') as HTMLElement | null;\n const header = root.querySelector('apex-grid-header-row') as HTMLElement | null;\n\n const toolbarH = toolbar?.offsetHeight ?? 0;\n const headerH = header?.offsetHeight ?? 0;\n const headerTop = toolbarH;\n const filterTop = toolbarH + headerH;\n\n if (headerTop !== this.#lastHeaderTop) {\n this.host.style.setProperty('--apex-row-top-header', `${headerTop}px`);\n this.#lastHeaderTop = headerTop;\n }\n if (filterTop !== this.#lastFilterTop) {\n this.host.style.setProperty('--apex-row-top-filter', `${filterTop}px`);\n this.#lastFilterTop = filterTop;\n }\n }\n\n protected observeStickyRows(): void {\n const root = (this.host as HTMLElement).shadowRoot;\n if (!root) return;\n const toolbar = root.querySelector('apex-grid-toolbar') as HTMLElement | null;\n const header = root.querySelector('apex-grid-header-row') as HTMLElement | null;\n\n if (!this.#stickyRowObserver) {\n this.#stickyRowObserver = new ResizeObserver(() => {\n requestAnimationFrame(() => this.recomputeStickyRowOffsets());\n });\n }\n\n const next = new Set<Element>([toolbar, header].filter((el): el is HTMLElement => !!el));\n for (const element of this.#observedStickyRows) {\n if (!next.has(element)) this.#stickyRowObserver.unobserve(element);\n }\n for (const element of next) {\n if (!this.#observedStickyRows.has(element)) this.#stickyRowObserver.observe(element);\n }\n this.#observedStickyRows = next;\n }\n}\n\nfunction offsetsEqual<K>(a: Map<K, number>, b: Map<K, number>): boolean {\n if (a.size !== b.size) return false;\n for (const [key, value] of a) {\n if (b.get(key) !== value) return false;\n }\n return true;\n}\n"]}
1
+ {"version":3,"file":"dom.js","sourceRoot":"","sources":["../../src/controllers/dom.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RenderItemFunction } from '@lit-labs/virtualizer/virtualize.js';\nimport { html, type ReactiveController } from 'lit';\nimport { type StyleInfo, styleMap } from 'lit/directives/style-map.js';\nimport type { ColumnConfiguration, GridHost, Keys } from '../internal/types.js';\nimport { applyColumnWidths, getDisplayColumns } from '../internal/utils.js';\nimport type { StateController } from './state.js';\n\nexport class GridDOMController<T extends object> implements ReactiveController {\n constructor(\n protected host: GridHost<T>,\n protected state: StateController<T>\n ) {\n this.host.addController(this);\n }\n\n #initialSize = () => {\n setTimeout(() => {\n this.setScrollOffset();\n this.recomputePinOffsets();\n this.recomputeStickyRowOffsets();\n });\n };\n\n #resizeObserver: ResizeObserver | null = null;\n #observedHeaders = new Set<Element>();\n #stickyRowObserver: ResizeObserver | null = null;\n #observedStickyRows = new Set<Element>();\n\n public get container() {\n // @ts-expect-error: protected member access\n return this.host.scrollContainer;\n }\n\n /**\n * Visual render order: `'start'`-pinned columns first, then unpinned, then\n * `'end'`-pinned. The user-supplied `columns` array is never mutated.\n */\n public get displayColumns(): Array<ColumnConfiguration<T>> {\n return getDisplayColumns(this.host.columns);\n }\n\n public columnSizes: StyleInfo = {};\n\n /**\n * The resolved inline-start (for `'start'` pin) or inline-end (for `'end'` pin)\n * pixel offset per pinned column key. Populated after layout by\n * {@link recomputePinOffsets}.\n */\n public pinOffsets = new Map<Keys<T>, number>();\n\n public rowRenderer: RenderItemFunction<T> = (data: T, index: number) => {\n const editingCell = this.state.editing.activeCell;\n const editingKey = editingCell?.rowIndex === index ? editingCell.columnKey : null;\n // aria-rowindex offset: header row is always row 1; filter row (when\n // any column has a filter configured) sits at row 2; body rows start\n // immediately after.\n const hasFilter = this.host.columns.some((column) => column.filter);\n const ariaRowOffset = hasFilter ? 2 : 1;\n return html`\n <apex-grid-row\n part=\"row\"\n style=${styleMap({ ...this.columnSizes, ...this.getActiveRowStyles(index) })}\n .index=${index}\n .activeNode=${this.state.active}\n .data=${data}\n .columns=${this.displayColumns}\n .pinOffsets=${this.pinOffsets}\n .editingKey=${editingKey}\n .ariaRowOffset=${ariaRowOffset}\n .decorationVersion=${this.state.decorationVersion}\n >\n </apex-grid-row>\n `;\n };\n\n public async hostConnected() {\n this.setGridColumnSizes();\n // Wait for the initial paint of the virtualizer and recalculate the scrollbar offset\n // for the next one\n await this.host.updateComplete;\n this.#initialSize();\n if (typeof ResizeObserver !== 'undefined' && !this.#hostWidthObserver) {\n this.#hostWidthObserver = new ResizeObserver(() => {\n requestAnimationFrame(() => this.recomputeHostWidth());\n });\n this.#hostWidthObserver.observe(this.host as HTMLElement);\n }\n this.recomputeHostWidth();\n }\n\n public hostUpdate(): void {\n this.setScrollOffset();\n this.setGridColumnSizes();\n }\n\n public hostUpdated(): void {\n this.recomputePinOffsets();\n this.observeHeaderCells();\n this.recomputeStickyRowOffsets();\n this.observeStickyRows();\n }\n\n public hostDisconnected(): void {\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = null;\n this.#observedHeaders.clear();\n this.#stickyRowObserver?.disconnect();\n this.#stickyRowObserver = null;\n this.#observedStickyRows.clear();\n this.#hostWidthObserver?.disconnect();\n this.#hostWidthObserver = null;\n }\n\n /**\n * Writes the grid host's `clientWidth` into `--apex-host-width`. Used by the\n * toolbar and paginator to clamp their width to the visible viewport so\n * horizontal scrolling doesn't drag them off-screen.\n */\n public recomputeHostWidth(): void {\n const host = this.host as HTMLElement;\n const width = host.clientWidth;\n if (width === this.#lastHostWidth) return;\n host.style.setProperty('--apex-host-width', `${width}px`);\n this.#lastHostWidth = width;\n }\n\n public setScrollOffset() {\n // The grid host now owns vertical scrolling, so the historic per-row\n // padding-inline-end compensation is no longer needed. Keep the CSS var\n // set to `0` for forward compatibility with consumer themes that read it.\n this.host.style.setProperty('--scrollbar-offset', '0px');\n }\n\n protected setGridColumnSizes() {\n this.columnSizes = applyColumnWidths(this.displayColumns, {\n showSelectionColumn: this.state.selection.showCheckboxColumn,\n showExpansionColumn: this.state.expansion.showToggleColumn,\n });\n }\n\n public getActiveRowStyles(index: number): StyleInfo {\n const { row } = this.state.active;\n return row === index ? { 'z-index': '3' } : {};\n }\n\n /**\n * Measures the rendered widths of pinned header cells and writes cumulative\n * inline-start / inline-end pixel offsets into {@link pinOffsets}. Called after\n * each grid update and whenever a header cell is resized.\n */\n public recomputePinOffsets(): void {\n // @ts-expect-error - protected member access\n const headerRow = this.host.headerRow as\n | {\n headers?: Array<{\n column: ColumnConfiguration<T>;\n getBoundingClientRect: () => DOMRect;\n }>;\n }\n | undefined;\n if (!headerRow?.headers) return;\n\n const next = new Map<Keys<T>, number>();\n const headersByKey = new Map<Keys<T>, DOMRect>();\n for (const header of headerRow.headers) {\n headersByKey.set(header.column.key as Keys<T>, header.getBoundingClientRect());\n }\n\n let leftAccum = 0;\n for (const column of this.displayColumns) {\n if (column.hidden) continue;\n if (column.pinned !== 'start') break;\n next.set(column.key as Keys<T>, leftAccum);\n const rect = headersByKey.get(column.key as Keys<T>);\n leftAccum += rect?.width ?? 0;\n }\n\n let rightAccum = 0;\n for (let i = this.displayColumns.length - 1; i >= 0; i--) {\n const column = this.displayColumns[i];\n if (column.hidden) continue;\n if (column.pinned !== 'end') break;\n next.set(column.key as Keys<T>, rightAccum);\n const rect = headersByKey.get(column.key as Keys<T>);\n rightAccum += rect?.width ?? 0;\n }\n\n if (!offsetsEqual(this.pinOffsets, next)) {\n this.pinOffsets = next;\n this.host.requestUpdate();\n }\n }\n\n protected observeHeaderCells(): void {\n // @ts-expect-error - protected member access\n const headerRow = this.host.headerRow as { headers?: Array<Element> } | undefined;\n if (!headerRow?.headers) return;\n\n if (!this.#resizeObserver) {\n this.#resizeObserver = new ResizeObserver(() => {\n // Defer to a new frame so any layout writes can't synchronously feed back\n // into this observer (which makes the browser raise the benign\n // \"ResizeObserver loop completed\" warning).\n requestAnimationFrame(() => this.recomputePinOffsets());\n });\n }\n\n const next = new Set<Element>(headerRow.headers);\n for (const element of this.#observedHeaders) {\n if (!next.has(element)) this.#resizeObserver.unobserve(element);\n }\n for (const element of next) {\n if (!this.#observedHeaders.has(element)) this.#resizeObserver.observe(element);\n }\n this.#observedHeaders = next;\n }\n\n #lastHeaderTop = -1;\n #lastFilterTop = -1;\n #lastHostWidth = -1;\n #hostWidthObserver: ResizeObserver | null = null;\n\n /**\n * Writes the cumulative height of the sticky top rows into CSS custom\n * properties used by the header/filter rows for their `inset-block-start`\n * offsets. The toolbar is always at `top: 0`; the header sits below it\n * (`--apex-row-top-header`) and the filter sits below the header\n * (`--apex-row-top-filter`). Writes are skipped when the values haven't\n * changed so the ResizeObserver feedback loop terminates.\n */\n public recomputeStickyRowOffsets(): void {\n const root = (this.host as HTMLElement).shadowRoot;\n if (!root) return;\n const toolbar = root.querySelector('apex-grid-toolbar') as HTMLElement | null;\n const header = root.querySelector('apex-grid-header-row') as HTMLElement | null;\n\n const toolbarH = toolbar?.offsetHeight ?? 0;\n const headerH = header?.offsetHeight ?? 0;\n const headerTop = toolbarH;\n const filterTop = toolbarH + headerH;\n\n if (headerTop !== this.#lastHeaderTop) {\n this.host.style.setProperty('--apex-row-top-header', `${headerTop}px`);\n this.#lastHeaderTop = headerTop;\n }\n if (filterTop !== this.#lastFilterTop) {\n this.host.style.setProperty('--apex-row-top-filter', `${filterTop}px`);\n this.#lastFilterTop = filterTop;\n }\n }\n\n protected observeStickyRows(): void {\n const root = (this.host as HTMLElement).shadowRoot;\n if (!root) return;\n const toolbar = root.querySelector('apex-grid-toolbar') as HTMLElement | null;\n const header = root.querySelector('apex-grid-header-row') as HTMLElement | null;\n\n if (!this.#stickyRowObserver) {\n this.#stickyRowObserver = new ResizeObserver(() => {\n requestAnimationFrame(() => this.recomputeStickyRowOffsets());\n });\n }\n\n const next = new Set<Element>([toolbar, header].filter((el): el is HTMLElement => !!el));\n for (const element of this.#observedStickyRows) {\n if (!next.has(element)) this.#stickyRowObserver.unobserve(element);\n }\n for (const element of next) {\n if (!this.#observedStickyRows.has(element)) this.#stickyRowObserver.observe(element);\n }\n this.#observedStickyRows = next;\n }\n}\n\nfunction offsetsEqual<K>(a: Map<K, number>, b: Map<K, number>): boolean {\n if (a.size !== b.size) return false;\n for (const [key, value] of a) {\n if (b.get(key) !== value) return false;\n }\n return true;\n}\n"]}
@@ -23,5 +23,5 @@ export declare class ResizeController<T extends object> implements ReactiveContr
23
23
  /**
24
24
  * Renders the resize indicator in the grid.
25
25
  */
26
- renderIndicator(): typeof nothing | import("lit-html").TemplateResult<1>;
26
+ renderIndicator(): import("lit-html").TemplateResult<1> | typeof nothing;
27
27
  }
@@ -1,5 +1,5 @@
1
1
  import type { ReactiveController } from 'lit';
2
- import type { GridFeatureModule } from '../internal/feature-module.js';
2
+ import { type CellDecoration, type CellDecoratorContext, type CellInteraction, type GridFeatureModule, type PresentedRow, type RowPresenterContext } from '../internal/feature-module.js';
3
3
  import type { ActiveNode, GridHost } from '../internal/types.js';
4
4
  import { EditingController } from './editing.js';
5
5
  import { ExpansionController } from './expansion.js';
@@ -62,6 +62,39 @@ export declare class StateController<T extends object> implements ReactiveContro
62
62
  * by its module id. Returns `undefined` when no such module is registered.
63
63
  */
64
64
  module<C extends ReactiveController>(id: string): C | undefined;
65
+ /**
66
+ * Runs the post-pipeline row transforms contributed by feature modules
67
+ * implementing {@link RowTransformer}, in registration order. Returns the
68
+ * input unchanged when no such module is registered — the community grid path
69
+ * is a no-op pass-through.
70
+ */
71
+ applyModuleTransforms(rows: T[]): T[];
72
+ /**
73
+ * Asks feature modules implementing {@link RowPresenter} whether they render
74
+ * the given row as full-width custom content (e.g. a group header). Returns
75
+ * the first non-null result, or `null` when no module owns the row.
76
+ */
77
+ presentRow(row: T, ctx: RowPresenterContext<T>): PresentedRow | null;
78
+ get decorationVersion(): number;
79
+ /**
80
+ * Signals that {@link CellDecorator} output may have changed. Bumps the
81
+ * {@link decorationVersion} and requests a host update so cells re-run their
82
+ * decoration. Called by feature modules after mutating decoration state.
83
+ */
84
+ bumpDecoration(): void;
85
+ /**
86
+ * Collects per-cell decoration contributed by feature modules implementing
87
+ * {@link CellDecorator}, merging their attribute maps (later modules win on a
88
+ * key clash). Returns `null` when no module decorates the cell — the community
89
+ * grid path, where each cell applies nothing.
90
+ */
91
+ decorateCell(ctx: CellDecoratorContext<T>): CellDecoration | null;
92
+ /**
93
+ * Forwards a body-cell pointer interaction to every feature module that
94
+ * implements {@link CellInteractionHandler}. No-op for the community grid
95
+ * (no modules); the grid only calls this when modules are registered.
96
+ */
97
+ handleCellInteraction(interaction: CellInteraction<T>): void;
65
98
  hostConnected(): void;
66
99
  hostUpdate(): void;
67
100
  }
@@ -1,4 +1,5 @@
1
1
  import { createContext } from '@lit/context';
2
+ import { isCellDecorator, isCellInteractionHandler, isRowPresenter, isRowTransformer, } from '../internal/feature-module.js';
2
3
  import { EditingController } from './editing.js';
3
4
  import { ExpansionController } from './expansion.js';
4
5
  import { FilterController } from './filter.js';
@@ -49,6 +50,7 @@ export class StateController {
49
50
  this.modules = new Map();
50
51
  this.announcement = '';
51
52
  this.#announceToken = 0;
53
+ this.#decorationVersion = 0;
52
54
  this.host.addController(this);
53
55
  this.init();
54
56
  }
@@ -66,12 +68,59 @@ export class StateController {
66
68
  for (const module of this.extraModules) {
67
69
  if (this.modules.has(module.id))
68
70
  continue;
69
- this.modules.set(module.id, module.create(this.host));
71
+ this.modules.set(module.id, module.create(this.host, this));
70
72
  }
71
73
  }
72
74
  module(id) {
73
75
  return this.modules.get(id);
74
76
  }
77
+ applyModuleTransforms(rows) {
78
+ let result = rows;
79
+ for (const controller of this.modules.values()) {
80
+ if (isRowTransformer(controller)) {
81
+ result = controller.processRows(result);
82
+ }
83
+ }
84
+ return result;
85
+ }
86
+ presentRow(row, ctx) {
87
+ for (const controller of this.modules.values()) {
88
+ if (isRowPresenter(controller)) {
89
+ const presented = controller.presentRow(row, ctx);
90
+ if (presented)
91
+ return presented;
92
+ }
93
+ }
94
+ return null;
95
+ }
96
+ #decorationVersion;
97
+ get decorationVersion() {
98
+ return this.#decorationVersion;
99
+ }
100
+ bumpDecoration() {
101
+ this.#decorationVersion += 1;
102
+ this.host.requestUpdate();
103
+ }
104
+ decorateCell(ctx) {
105
+ let attributes = null;
106
+ for (const controller of this.modules.values()) {
107
+ if (isCellDecorator(controller)) {
108
+ const decoration = controller.decorateCell(ctx);
109
+ if (decoration) {
110
+ attributes ??= {};
111
+ Object.assign(attributes, decoration.attributes);
112
+ }
113
+ }
114
+ }
115
+ return attributes ? { attributes } : null;
116
+ }
117
+ handleCellInteraction(interaction) {
118
+ for (const controller of this.modules.values()) {
119
+ if (isCellInteractionHandler(controller)) {
120
+ controller.handleCellInteraction(interaction);
121
+ }
122
+ }
123
+ }
75
124
  hostConnected() { }
76
125
  hostUpdate() {
77
126
  this.headerRow?.requestUpdate();
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/controllers/state.ts"],"names":[],"mappings":"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","sourcesContent":["import { createContext } from '@lit/context';\nimport type { ReactiveController } from 'lit';\nimport type { GridFeatureModule } from '../internal/feature-module.js';\nimport type { ActiveNode, GridHost } from '../internal/types.js';\nimport { EditingController } from './editing.js';\nimport { ExpansionController } from './expansion.js';\nimport { FilterController } from './filter.js';\nimport { NavigationController } from './navigation.js';\nimport { PaginationController } from './pagination.js';\nimport { ReorderController } from './reorder.js';\nimport { ResizeController } from './resize.js';\nimport { SelectionController } from './selection.js';\nimport { SortController } from './sort.js';\nimport { TreeController } from './tree.js';\n\nexport class StateController<T extends object> implements ReactiveController {\n public sorting!: SortController<T>;\n public filtering!: FilterController<T>;\n public navigation!: NavigationController<T>;\n public resizing!: ResizeController<T>;\n public pagination!: PaginationController<T>;\n public reordering!: ReorderController<T>;\n public editing!: EditingController<T>;\n public selection!: SelectionController<T>;\n public expansion!: ExpansionController<T>;\n public tree!: TreeController<T>;\n\n /**\n * Optional feature controllers contributed by {@link GridFeatureModule}s,\n * keyed by module id. Empty for the community `<apex-grid>` element; populated\n * by derived grids (e.g. `@apexcharts/grid-enterprise`) that pass modules to\n * the constructor.\n */\n public readonly modules = new Map<string, ReactiveController>();\n\n /**\n * Current message in the grid's polite live region. Bound by the host's\n * `renderLiveRegion()` template; mutated through {@link setAnnouncement}\n * so screen readers re-announce on every change.\n */\n public announcement = '';\n #announceToken = 0;\n\n /**\n * Updates the polite live region's text. Repeats are forced to fire by\n * appending a zero-width space — screen readers ignore unchanged content,\n * so two identical sort announcements wouldn't otherwise be read aloud.\n */\n public setAnnouncement(message: string): void {\n if (!message) {\n this.announcement = '';\n this.host.requestUpdate();\n return;\n }\n this.#announceToken = (this.#announceToken + 1) % 2;\n this.announcement = this.#announceToken ? message : `${message} `;\n this.host.requestUpdate();\n }\n\n public get active() {\n return this.navigation.active;\n }\n\n public set active(node: ActiveNode<T>) {\n this.navigation.active = node;\n }\n\n public get headerRow() {\n // @ts-expect-error - Protected member access\n return this.host.headerRow;\n }\n\n public get scrollContainer() {\n // @ts-expect-error - Protected member access\n return this.host.scrollContainer;\n }\n\n public get paginator() {\n // @ts-expect-error - Protected member access\n return this.host.paginator;\n }\n\n public get toolbar() {\n // @ts-expect-error - Protected member access\n return this.host.toolbar;\n }\n\n /**\n * Cumulative pin offsets (in px) keyed by column key. Populated by the\n * {@link GridDOMController} after each layout.\n */\n public get pinOffsets(): Map<unknown, number> {\n // @ts-expect-error - Protected member access\n const dom = this.host.DOM as { pinOffsets?: Map<unknown, number> } | undefined;\n return dom?.pinOffsets ?? new Map();\n }\n\n constructor(\n public host: GridHost<T>,\n private extraModules: ReadonlyArray<GridFeatureModule<T>> = []\n ) {\n this.host.addController(this);\n this.init();\n }\n\n protected init() {\n this.sorting = new SortController(this.host);\n this.filtering = new FilterController(this.host);\n this.navigation = new NavigationController(this.host);\n this.resizing = new ResizeController(this.host);\n this.pagination = new PaginationController(this.host);\n this.reordering = new ReorderController(this.host);\n this.editing = new EditingController(this.host);\n this.selection = new SelectionController(this.host);\n this.expansion = new ExpansionController(this.host);\n this.tree = new TreeController(this.host);\n\n for (const module of this.extraModules) {\n if (this.modules.has(module.id)) continue;\n this.modules.set(module.id, module.create(this.host));\n }\n }\n\n /**\n * Look up a feature controller contributed by a {@link GridFeatureModule},\n * by its module id. Returns `undefined` when no such module is registered.\n */\n public module<C extends ReactiveController>(id: string): C | undefined {\n return this.modules.get(id) as C | undefined;\n }\n\n public hostConnected() {}\n\n public hostUpdate(): void {\n this.headerRow?.requestUpdate();\n this.scrollContainer?.requestUpdate();\n this.paginator?.requestUpdate();\n this.toolbar?.requestUpdate();\n }\n}\n\nexport const gridStateContext = createContext<StateController<any>>('gridStateController');\n"]}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/controllers/state.ts"],"names":[],"mappings":"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","sourcesContent":["import { createContext } from '@lit/context';\nimport type { ReactiveController } from 'lit';\nimport {\n type CellDecoration,\n type CellDecoratorContext,\n type CellInteraction,\n type GridFeatureModule,\n isCellDecorator,\n isCellInteractionHandler,\n isRowPresenter,\n isRowTransformer,\n type PresentedRow,\n type RowPresenterContext,\n} from '../internal/feature-module.js';\nimport type { ActiveNode, GridHost } from '../internal/types.js';\nimport { EditingController } from './editing.js';\nimport { ExpansionController } from './expansion.js';\nimport { FilterController } from './filter.js';\nimport { NavigationController } from './navigation.js';\nimport { PaginationController } from './pagination.js';\nimport { ReorderController } from './reorder.js';\nimport { ResizeController } from './resize.js';\nimport { SelectionController } from './selection.js';\nimport { SortController } from './sort.js';\nimport { TreeController } from './tree.js';\n\nexport class StateController<T extends object> implements ReactiveController {\n public sorting!: SortController<T>;\n public filtering!: FilterController<T>;\n public navigation!: NavigationController<T>;\n public resizing!: ResizeController<T>;\n public pagination!: PaginationController<T>;\n public reordering!: ReorderController<T>;\n public editing!: EditingController<T>;\n public selection!: SelectionController<T>;\n public expansion!: ExpansionController<T>;\n public tree!: TreeController<T>;\n\n /**\n * Optional feature controllers contributed by {@link GridFeatureModule}s,\n * keyed by module id. Empty for the community `<apex-grid>` element; populated\n * by derived grids (e.g. `@apexcharts/grid-enterprise`) that pass modules to\n * the constructor.\n */\n public readonly modules = new Map<string, ReactiveController>();\n\n /**\n * Current message in the grid's polite live region. Bound by the host's\n * `renderLiveRegion()` template; mutated through {@link setAnnouncement}\n * so screen readers re-announce on every change.\n */\n public announcement = '';\n #announceToken = 0;\n\n /**\n * Updates the polite live region's text. Repeats are forced to fire by\n * appending a zero-width space — screen readers ignore unchanged content,\n * so two identical sort announcements wouldn't otherwise be read aloud.\n */\n public setAnnouncement(message: string): void {\n if (!message) {\n this.announcement = '';\n this.host.requestUpdate();\n return;\n }\n this.#announceToken = (this.#announceToken + 1) % 2;\n this.announcement = this.#announceToken ? message : `${message} `;\n this.host.requestUpdate();\n }\n\n public get active() {\n return this.navigation.active;\n }\n\n public set active(node: ActiveNode<T>) {\n this.navigation.active = node;\n }\n\n public get headerRow() {\n // @ts-expect-error - Protected member access\n return this.host.headerRow;\n }\n\n public get scrollContainer() {\n // @ts-expect-error - Protected member access\n return this.host.scrollContainer;\n }\n\n public get paginator() {\n // @ts-expect-error - Protected member access\n return this.host.paginator;\n }\n\n public get toolbar() {\n // @ts-expect-error - Protected member access\n return this.host.toolbar;\n }\n\n /**\n * Cumulative pin offsets (in px) keyed by column key. Populated by the\n * {@link GridDOMController} after each layout.\n */\n public get pinOffsets(): Map<unknown, number> {\n // @ts-expect-error - Protected member access\n const dom = this.host.DOM as { pinOffsets?: Map<unknown, number> } | undefined;\n return dom?.pinOffsets ?? new Map();\n }\n\n constructor(\n public host: GridHost<T>,\n private extraModules: ReadonlyArray<GridFeatureModule<T>> = []\n ) {\n this.host.addController(this);\n this.init();\n }\n\n protected init() {\n this.sorting = new SortController(this.host);\n this.filtering = new FilterController(this.host);\n this.navigation = new NavigationController(this.host);\n this.resizing = new ResizeController(this.host);\n this.pagination = new PaginationController(this.host);\n this.reordering = new ReorderController(this.host);\n this.editing = new EditingController(this.host);\n this.selection = new SelectionController(this.host);\n this.expansion = new ExpansionController(this.host);\n this.tree = new TreeController(this.host);\n\n for (const module of this.extraModules) {\n if (this.modules.has(module.id)) continue;\n this.modules.set(module.id, module.create(this.host, this));\n }\n }\n\n /**\n * Look up a feature controller contributed by a {@link GridFeatureModule},\n * by its module id. Returns `undefined` when no such module is registered.\n */\n public module<C extends ReactiveController>(id: string): C | undefined {\n return this.modules.get(id) as C | undefined;\n }\n\n /**\n * Runs the post-pipeline row transforms contributed by feature modules\n * implementing {@link RowTransformer}, in registration order. Returns the\n * input unchanged when no such module is registered — the community grid path\n * is a no-op pass-through.\n */\n public applyModuleTransforms(rows: T[]): T[] {\n let result = rows;\n for (const controller of this.modules.values()) {\n if (isRowTransformer<T>(controller)) {\n result = controller.processRows(result);\n }\n }\n return result;\n }\n\n /**\n * Asks feature modules implementing {@link RowPresenter} whether they render\n * the given row as full-width custom content (e.g. a group header). Returns\n * the first non-null result, or `null` when no module owns the row.\n */\n public presentRow(row: T, ctx: RowPresenterContext<T>): PresentedRow | null {\n for (const controller of this.modules.values()) {\n if (isRowPresenter<T>(controller)) {\n const presented = controller.presentRow(row, ctx);\n if (presented) return presented;\n }\n }\n return null;\n }\n\n /**\n * Monotonic token bumped by {@link bumpDecoration} whenever module-driven cell\n * decoration changes. Forwarded down to each cell as a reactive property so a\n * decoration-only change (e.g. dragging a selection range) re-renders cells\n * without re-running the data pipeline. Always `0` for the community grid.\n */\n #decorationVersion = 0;\n\n public get decorationVersion(): number {\n return this.#decorationVersion;\n }\n\n /**\n * Signals that {@link CellDecorator} output may have changed. Bumps the\n * {@link decorationVersion} and requests a host update so cells re-run their\n * decoration. Called by feature modules after mutating decoration state.\n */\n public bumpDecoration(): void {\n this.#decorationVersion += 1;\n this.host.requestUpdate();\n }\n\n /**\n * Collects per-cell decoration contributed by feature modules implementing\n * {@link CellDecorator}, merging their attribute maps (later modules win on a\n * key clash). Returns `null` when no module decorates the cell — the community\n * grid path, where each cell applies nothing.\n */\n public decorateCell(ctx: CellDecoratorContext<T>): CellDecoration | null {\n let attributes: Record<string, string | null | undefined> | null = null;\n for (const controller of this.modules.values()) {\n if (isCellDecorator<T>(controller)) {\n const decoration = controller.decorateCell(ctx);\n if (decoration) {\n attributes ??= {};\n Object.assign(attributes, decoration.attributes);\n }\n }\n }\n return attributes ? { attributes } : null;\n }\n\n /**\n * Forwards a body-cell pointer interaction to every feature module that\n * implements {@link CellInteractionHandler}. No-op for the community grid\n * (no modules); the grid only calls this when modules are registered.\n */\n public handleCellInteraction(interaction: CellInteraction<T>): void {\n for (const controller of this.modules.values()) {\n if (isCellInteractionHandler<T>(controller)) {\n controller.handleCellInteraction(interaction);\n }\n }\n }\n\n public hostConnected() {}\n\n public hostUpdate(): void {\n this.headerRow?.requestUpdate();\n this.scrollContainer?.requestUpdate();\n this.paginator?.requestUpdate();\n this.toolbar?.requestUpdate();\n }\n}\n\nexport const gridStateContext = createContext<StateController<any>>('gridStateController');\n"]}