apex-grid 3.6.0 → 4.0.0-beta.2

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 (151) hide show
  1. package/CHANGELOG.md +301 -0
  2. package/LICENSE.md +2 -1
  3. package/README.md +117 -18
  4. package/components/cell.d.ts +13 -1
  5. package/components/cell.js +28 -13
  6. package/components/cell.js.map +1 -1
  7. package/components/grid.d.ts +175 -28
  8. package/components/grid.js +183 -63
  9. package/components/grid.js.map +1 -1
  10. package/components/header-row.d.ts +0 -6
  11. package/components/header-row.js +1 -19
  12. package/components/header-row.js.map +1 -1
  13. package/components/header.js +39 -2
  14. package/components/header.js.map +1 -1
  15. package/components/paginator.d.ts +20 -5
  16. package/components/paginator.js +54 -17
  17. package/components/paginator.js.map +1 -1
  18. package/components/row.js +149 -40
  19. package/components/row.js.map +1 -1
  20. package/components/toolbar.d.ts +5 -1
  21. package/components/toolbar.js +4 -1
  22. package/components/toolbar.js.map +1 -1
  23. package/components/virtualize-rows.d.ts +38 -0
  24. package/components/virtualize-rows.js +286 -0
  25. package/components/virtualize-rows.js.map +1 -0
  26. package/components/virtualizer.d.ts +71 -1
  27. package/components/virtualizer.js +105 -29
  28. package/components/virtualizer.js.map +1 -1
  29. package/controllers/dom.d.ts +10 -3
  30. package/controllers/dom.js +5 -5
  31. package/controllers/dom.js.map +1 -1
  32. package/controllers/navigation.d.ts +63 -0
  33. package/controllers/navigation.js +295 -21
  34. package/controllers/navigation.js.map +1 -1
  35. package/controllers/pagination.d.ts +7 -6
  36. package/controllers/pagination.js +27 -28
  37. package/controllers/pagination.js.map +1 -1
  38. package/controllers/row-pin.d.ts +6 -0
  39. package/controllers/row-pin.js +8 -2
  40. package/controllers/row-pin.js.map +1 -1
  41. package/controllers/row-reorder.d.ts +12 -4
  42. package/controllers/row-reorder.js +20 -6
  43. package/controllers/row-reorder.js.map +1 -1
  44. package/controllers/selection.d.ts +32 -10
  45. package/controllers/selection.js +33 -10
  46. package/controllers/selection.js.map +1 -1
  47. package/controllers/sort.js +2 -3
  48. package/controllers/sort.js.map +1 -1
  49. package/controllers/state.d.ts +18 -5
  50. package/controllers/state.js +53 -46
  51. package/controllers/state.js.map +1 -1
  52. package/custom-elements.json +1762 -339
  53. package/docs/assets/hierarchy.js +1 -1
  54. package/docs/assets/search.js +1 -1
  55. package/docs/classes/ApexGrid.html +166 -66
  56. package/docs/classes/ApexGridPaginator.html +39 -8
  57. package/docs/classes/ApexGridToolbar.html +9 -5
  58. package/docs/functions/localize.html +2 -2
  59. package/docs/hierarchy.html +1 -1
  60. package/docs/index.html +123 -20
  61. package/docs/interfaces/ApexPageChangedEvent.html +3 -1
  62. package/docs/interfaces/BaseApexCellContext.html +18 -5
  63. package/docs/interfaces/BaseApexEditorContext.html +20 -5
  64. package/docs/interfaces/BaseFilterExpression.html +1 -1
  65. package/docs/interfaces/CSVExportOptions.html +1 -1
  66. package/docs/interfaces/DataPipelineConfiguration.html +4 -9
  67. package/docs/interfaces/ExportOptions.html +1 -1
  68. package/docs/interfaces/GridSelectionConfiguration.html +19 -4
  69. package/docs/interfaces/PaginationConfiguration.html +11 -4
  70. package/docs/interfaces/PaginationState.html +4 -2
  71. package/docs/media/_token-values.scss +42 -16
  72. package/docs/media/package.json +12 -4
  73. package/docs/types/DataPipelineParams.html +2 -2
  74. package/docs/types/PaginationMode.html +5 -4
  75. package/docs/variables/EN_LOCALE.html +2 -2
  76. package/i18n/en.d.ts +2 -0
  77. package/i18n/en.js +2 -0
  78. package/i18n/en.js.map +1 -1
  79. package/i18n/es.js +2 -0
  80. package/i18n/es.js.map +1 -1
  81. package/ignite-ui.d.ts +1 -0
  82. package/ignite-ui.js +4 -0
  83. package/ignite-ui.js.map +1 -0
  84. package/internal/column-types.d.ts +11 -1
  85. package/internal/column-types.js +8 -6
  86. package/internal/column-types.js.map +1 -1
  87. package/internal/design-system.d.ts +32 -0
  88. package/internal/design-system.js +66 -0
  89. package/internal/design-system.js.map +1 -0
  90. package/internal/export.d.ts +6 -0
  91. package/internal/export.js +4 -0
  92. package/internal/export.js.map +1 -1
  93. package/internal/feature-module.d.ts +7 -0
  94. package/internal/feature-module.js.map +1 -1
  95. package/internal/flip.d.ts +28 -16
  96. package/internal/flip.js +42 -10
  97. package/internal/flip.js.map +1 -1
  98. package/internal/icons.d.ts +2 -16
  99. package/internal/icons.js +0 -8
  100. package/internal/icons.js.map +1 -1
  101. package/internal/ignite-ui.d.ts +10 -0
  102. package/internal/ignite-ui.js +118 -0
  103. package/internal/ignite-ui.js.map +1 -0
  104. package/internal/index.d.ts +4 -2
  105. package/internal/index.js +3 -2
  106. package/internal/index.js.map +1 -1
  107. package/internal/types.d.ts +75 -19
  108. package/internal/types.js.map +1 -1
  109. package/operations/filter/types.d.ts +1 -1
  110. package/operations/filter/types.js.map +1 -1
  111. package/package.json +7 -2
  112. package/styles/_token-blocks.css.d.ts +1 -0
  113. package/styles/_token-blocks.css.js +3 -0
  114. package/styles/_token-blocks.css.js.map +1 -0
  115. package/styles/_tokens.css.js +1 -1
  116. package/styles/_tokens.css.js.map +1 -1
  117. package/styles/body-cell/body-cell.css.js +1 -1
  118. package/styles/body-cell/body-cell.css.js.map +1 -1
  119. package/styles/body-cell/cell-renderers.css.js +1 -1
  120. package/styles/body-cell/cell-renderers.css.js.map +1 -1
  121. package/styles/body-row/body-row.css.js +1 -1
  122. package/styles/body-row/body-row.css.js.map +1 -1
  123. package/styles/document-tokens.css.js +1 -1
  124. package/styles/document-tokens.css.js.map +1 -1
  125. package/styles/grid/_grid.base.css.js +1 -1
  126. package/styles/grid/_grid.base.css.js.map +1 -1
  127. package/styles/grid/grid.css.js +1 -1
  128. package/styles/grid/grid.css.js.map +1 -1
  129. package/styles/group-header-row/group-header-row.css.js +1 -1
  130. package/styles/group-header-row/group-header-row.css.js.map +1 -1
  131. package/styles/header-cell/header-cell.css.js +1 -1
  132. package/styles/header-cell/header-cell.css.js.map +1 -1
  133. package/styles/header-row/header-row.base.css.js +1 -1
  134. package/styles/header-row/header-row.base.css.js.map +1 -1
  135. package/styles/ignite-ui/ignite-ui-dark.css.d.ts +1 -0
  136. package/styles/ignite-ui/ignite-ui-dark.css.js +3 -0
  137. package/styles/ignite-ui/ignite-ui-dark.css.js.map +1 -0
  138. package/styles/ignite-ui/ignite-ui-document.css.d.ts +1 -0
  139. package/styles/ignite-ui/ignite-ui-document.css.js +3 -0
  140. package/styles/ignite-ui/ignite-ui-document.css.js.map +1 -0
  141. package/styles/ignite-ui/ignite-ui.css.d.ts +1 -0
  142. package/styles/ignite-ui/ignite-ui.css.js +3 -0
  143. package/styles/ignite-ui/ignite-ui.css.js.map +1 -0
  144. package/styles/paginator/paginator.css.js +1 -1
  145. package/styles/paginator/paginator.css.js.map +1 -1
  146. package/styles/toolbar/toolbar.css.js +1 -1
  147. package/styles/toolbar/toolbar.css.js.map +1 -1
  148. package/tokens.css +14 -15
  149. package/operations/pagination.d.ts +0 -19
  150. package/operations/pagination.js +0 -12
  151. package/operations/pagination.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"paginator.js","sourceRoot":"","sources":["../../src/components/paginator.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { renderIcon } from '../internal/icons.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_PAGINATOR_TAG } from '../internal/tags.js';\nimport { styles } from '../styles/paginator/paginator.css.js';\n\n/**\n * Pagination toolbar rendered beneath the grid body.\n *\n * @remarks\n * Drives {@link PaginationController} on the host grid. The component is purely\n * presentational — page transitions go through the controller so they emit the\n * cancellable `pageChanging` event and the post-update `pageChanged` event.\n *\n * @element apex-grid-paginator\n *\n * @csspart paginator - The root container.\n * @csspart paginator-size - The page-size selector wrapper.\n * @csspart paginator-info - The \"1–25 of 100\" status label.\n * @csspart paginator-controls - The first/prev/next/last button cluster.\n * @csspart paginator-page - The \"Page X of N\" status label.\n */\nexport default class ApexGridPaginator<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_PAGINATOR_TAG;\n }\n\n public static override styles = styles;\n\n /**\n * Registers the `<apex-grid-paginator>` element and its dependencies. Idempotent.\n */\n public static register() {\n registerComponent(ApexGridPaginator);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n /**\n * The page-size choices rendered in the rows-per-page selector.\n *\n * @remarks\n * Defaults to `[10, 25, 50, 100]`.\n */\n @property({ attribute: false })\n public pageSizeOptions: number[] = [10, 25, 50, 100];\n\n /**\n * Accessible label for the rows-per-page selector.\n *\n * @remarks\n * When unset, falls back to the grid's localized `pagination.rowsPerPage`\n * text (see {@link ApexGrid.localeText}).\n */\n @property({ type: String, attribute: 'page-size-label' })\n public pageSizeLabel?: string;\n\n protected get controller() {\n return this.state.pagination;\n }\n\n protected get sizeLabel() {\n return this.pageSizeLabel ?? this.state.localize('pagination.rowsPerPage');\n }\n\n #handleSizeChange = (event: Event) => {\n event.stopPropagation();\n const next = Number((event.target as HTMLSelectElement).value);\n if (Number.isFinite(next)) {\n this.controller.setPageSize(next);\n }\n };\n\n protected renderSizeSelect() {\n const current = this.controller.pageSize;\n return html`\n <label part=\"paginator-size\">\n <span class=\"visually-hidden\">${this.sizeLabel}</span>\n <select\n aria-label=${this.sizeLabel}\n .value=${String(current)}\n @change=${this.#handleSizeChange}\n >\n ${this.pageSizeOptions.map(\n (size) =>\n html`<option .value=${String(size)} ?selected=${size === current}>${size}</option>`\n )}\n </select>\n </label>\n `;\n }\n\n protected renderInfo() {\n const { page, pageSize, totalItems } = this.controller.state;\n if (totalItems === 0) {\n return html`<span part=\"paginator-info\" aria-live=\"polite\"\n >${this.state.localize('pagination.summaryEmpty')}</span\n >`;\n }\n const start = page * pageSize + 1;\n const end = Math.min(totalItems, (page + 1) * pageSize);\n return html`<span part=\"paginator-info\" aria-live=\"polite\"\n >${this.state.localize('pagination.summary', { start, end, total: totalItems })}</span\n >`;\n }\n\n protected renderButton(opts: {\n id: string;\n icon: string;\n label: string;\n disabled: boolean;\n onClick: () => void;\n }) {\n return html`<button\n part=\"paginator-button\"\n id=${opts.id}\n type=\"button\"\n aria-label=${opts.label}\n title=${opts.label}\n ?disabled=${opts.disabled}\n @click=${opts.onClick}\n >\n ${renderIcon(opts.icon)}\n </button>`;\n }\n\n #handleControlsKeydown = (event: KeyboardEvent) => {\n // Keep arrow-key navigation inside the paginator instead of bubbling into the grid.\n if (\n event.key === 'ArrowLeft' ||\n event.key === 'ArrowRight' ||\n event.key === 'ArrowUp' ||\n event.key === 'ArrowDown'\n ) {\n event.stopPropagation();\n }\n };\n\n protected renderControls() {\n const { page, pageCount, totalItems } = this.controller.state;\n const onFirst = page <= 0 || totalItems === 0;\n const onLast = page >= pageCount - 1 || totalItems === 0;\n\n return html`\n <div\n part=\"paginator-controls\"\n role=\"group\"\n aria-label=${this.state.localize('pagination.controls')}\n @keydown=${this.#handleControlsKeydown}\n >\n ${this.renderButton({\n id: 'first',\n icon: 'page-first',\n label: this.state.localize('pagination.firstPage'),\n disabled: onFirst,\n onClick: () => this.controller.firstPage(),\n })}\n ${this.renderButton({\n id: 'previous',\n icon: 'page-previous',\n label: this.state.localize('pagination.previousPage'),\n disabled: onFirst,\n onClick: () => this.controller.previousPage(),\n })}\n <span part=\"paginator-page\" aria-live=\"polite\">${page + 1} / ${pageCount}</span>\n ${this.renderButton({\n id: 'next',\n icon: 'page-next',\n label: this.state.localize('pagination.nextPage'),\n disabled: onLast,\n onClick: () => this.controller.nextPage(),\n })}\n ${this.renderButton({\n id: 'last',\n icon: 'page-last',\n label: this.state.localize('pagination.lastPage'),\n disabled: onLast,\n onClick: () => this.controller.lastPage(),\n })}\n </div>\n `;\n }\n\n protected override render() {\n if (!this.state) return nothing;\n return html`\n <div part=\"paginator\" role=\"navigation\" aria-label=${this.state.localize('pagination.label')}>\n ${this.renderSizeSelect()} ${this.renderInfo()} ${this.renderControls()}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridPaginator.tagName]: ApexGridPaginator<object>;\n }\n}\n"]}
1
+ {"version":3,"file":"paginator.js","sourceRoot":"","sources":["../../src/components/paginator.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { DEFAULT_PAGINATION } from '../controllers/pagination.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { renderIcon } from '../internal/icons.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_PAGINATOR_TAG } from '../internal/tags.js';\nimport { styles } from '../styles/paginator/paginator.css.js';\n\n/**\n * Pagination toolbar rendered beneath the grid body.\n *\n * @remarks\n * Drives {@link PaginationController} on the host grid. The component is purely\n * presentational: page transitions go through the controller so they emit the\n * cancellable `pageChanging` event and the post-update `pageChanged` event.\n *\n * It never clips its controls: when the bar is too narrow it drops the page\n * size selector first, then the first and last buttons, so previous and next\n * stay reachable. `pagination.paginator: 'compact'` always uses that narrow\n * layout. The grid re-exports every part, so `apex-grid::part(name)` styles it.\n *\n * @element apex-grid-paginator\n *\n * @csspart paginator - The root container.\n * @csspart paginator-size - The page-size selector wrapper.\n * @csspart paginator-info - The \"1-25 of 100\" status label.\n * @csspart paginator-controls - The first/prev/next/last button cluster.\n * @csspart paginator-page - The \"page / count\" status label.\n * @csspart paginator-button - Each of the first, previous, next and last buttons.\n * @csspart paginator-first - The first page button (also `paginator-button`).\n * @csspart paginator-prev - The previous page button (also `paginator-button`).\n * @csspart paginator-next - The next page button (also `paginator-button`).\n * @csspart paginator-last - The last page button (also `paginator-button`).\n */\nexport default class ApexGridPaginator<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_PAGINATOR_TAG;\n }\n\n public static override styles = styles;\n\n /**\n * Registers the `<apex-grid-paginator>` element and its dependencies. Idempotent.\n */\n public static register() {\n registerComponent(ApexGridPaginator);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n /**\n * The page-size choices rendered in the rows-per-page selector.\n *\n * @remarks\n * Defaults to `[10, 25, 50, 100]`, also when empty. A current page size missing\n * from the list is listed too, so the selector always shows the size in force.\n */\n @property({ attribute: false })\n public pageSizeOptions: readonly number[] = DEFAULT_PAGINATION.pageSizeOptions;\n\n /**\n * Accessible label for the rows-per-page selector.\n *\n * @remarks\n * When unset, falls back to the grid's localized `pagination.rowsPerPage`\n * text (see {@link ApexGrid.localeText}).\n */\n @property({ type: String, attribute: 'page-size-label' })\n public pageSizeLabel?: string;\n\n #resizeObserver?: ResizeObserver;\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.#resizeObserver ??= new ResizeObserver(() => this.#fit());\n this.#resizeObserver.observe(this);\n }\n\n public override disconnectedCallback(): void {\n this.#resizeObserver?.disconnect();\n super.disconnectedCallback();\n }\n\n protected override updated(): void {\n // Selected here, after the options rendered, so a size just added to the\n // list is found and a refused pick is undone.\n const select = this.renderRoot.querySelector('select');\n if (select) select.value = String(this.controller.pageSize);\n // The grid re-renders the paginator on each of its updates: measure only\n // when the text or the layout option changed (the observer covers resizes).\n const bar = this.renderRoot.querySelector('[part=paginator]');\n const key = `${this.state?.host.pagination?.paginator}|${bar?.textContent}`;\n if (key !== this.#fitKey) {\n this.#fitKey = key;\n this.#fit();\n }\n }\n\n #fitKey = '';\n\n /**\n * Drops what the bar has no room for, least needed first: the page size\n * selector (step 1), then the first and last buttons (step 2, the compact\n * layout, where the summary may also shorten), so previous and next always\n * stay reachable. The steps are CSS rules keyed on `data-fit`. Hiding them\n * does not change the bar's height, so the resize observer does not loop.\n */\n #fit(): void {\n const bar = this.renderRoot.querySelector<HTMLElement>('[part=paginator]');\n let step = this.state?.host.pagination?.paginator === 'compact' ? 2 : 0;\n while (bar) {\n // Written only on a change, so a render that keeps the layout restyles nothing.\n if (bar.dataset.fit !== `${step}`) bar.dataset.fit = `${step}`;\n if (step > 1 || bar.scrollWidth <= bar.clientWidth) break;\n step++;\n }\n }\n\n protected get controller() {\n return this.state.pagination;\n }\n\n protected get sizeLabel() {\n return this.pageSizeLabel ?? this.state.localize('pagination.rowsPerPage');\n }\n\n #handleSizeChange = (event: Event) => {\n event.stopPropagation();\n const next = Number((event.target as HTMLSelectElement).value);\n if (Number.isFinite(next)) {\n this.controller.setPageSize(next);\n }\n // A cancelled change leaves the page size as it was: render again so the\n // selector shows the size in force (see updated), not the refused one.\n this.requestUpdate();\n };\n\n protected renderSizeSelect() {\n const current = this.controller.pageSize;\n const listed = this.pageSizeOptions.length\n ? this.pageSizeOptions\n : DEFAULT_PAGINATION.pageSizeOptions;\n const options = [...listed];\n if (!listed.includes(current)) {\n // Before the first larger size: an ascending list stays ascending and a\n // custom order is kept.\n const at = listed.findIndex((size) => size > current);\n options.splice(at < 0 ? options.length : at, 0, current);\n }\n return html`\n <label part=\"paginator-size\">\n <span class=\"visually-hidden\">${this.sizeLabel}</span>\n <select aria-label=${this.sizeLabel} @change=${this.#handleSizeChange}>\n ${options.map((size) => html`<option .value=${String(size)}>${size}</option>`)}\n </select>\n </label>\n `;\n }\n\n protected renderInfo() {\n // The grid's live region announces a page change; this summary stays quiet\n // so a screen reader hears it once.\n const { page, pageSize, totalItems } = this.controller.state;\n const start = page * pageSize + 1;\n const end = Math.min(totalItems, (page + 1) * pageSize);\n return html`<span part=\"paginator-info\"\n >${\n totalItems\n ? this.state.localize('pagination.summary', { start, end, total: totalItems })\n : this.state.localize('pagination.summaryEmpty')\n }</span\n >`;\n }\n\n protected renderButton(opts: {\n /** `first`, `prev`, `next` or `last`; also names the button's own part (`paginator-first`). */\n id: string;\n icon: string;\n label: string;\n disabled: boolean;\n onClick: () => void;\n }) {\n return html`<button\n part=\"paginator-button paginator-${opts.id}\"\n id=${opts.id}\n type=\"button\"\n aria-label=${opts.label}\n title=${opts.label}\n ?disabled=${opts.disabled}\n @click=${opts.onClick}\n >\n ${renderIcon(opts.icon)}\n </button>`;\n }\n\n #handleControlsKeydown = (event: KeyboardEvent) => {\n // Keep arrow-key navigation inside the paginator instead of bubbling into the grid.\n if (\n event.key === 'ArrowLeft' ||\n event.key === 'ArrowRight' ||\n event.key === 'ArrowUp' ||\n event.key === 'ArrowDown'\n ) {\n event.stopPropagation();\n }\n };\n\n protected renderControls() {\n const { page, pageCount, totalItems } = this.controller.state;\n const onFirst = page <= 0 || totalItems === 0;\n const onLast = page >= pageCount - 1 || totalItems === 0;\n\n return html`\n <div\n part=\"paginator-controls\"\n role=\"group\"\n aria-label=${this.state.localize('pagination.controls')}\n @keydown=${this.#handleControlsKeydown}\n >\n ${this.renderButton({\n id: 'first',\n icon: 'page-first',\n label: this.state.localize('pagination.firstPage'),\n disabled: onFirst,\n onClick: () => this.controller.firstPage(),\n })}\n ${this.renderButton({\n id: 'prev',\n icon: 'page-previous',\n label: this.state.localize('pagination.previousPage'),\n disabled: onFirst,\n onClick: () => this.controller.previousPage(),\n })}\n <span part=\"paginator-page\">${page + 1} / ${pageCount}</span>\n ${this.renderButton({\n id: 'next',\n icon: 'page-next',\n label: this.state.localize('pagination.nextPage'),\n disabled: onLast,\n onClick: () => this.controller.nextPage(),\n })}\n ${this.renderButton({\n id: 'last',\n icon: 'page-last',\n label: this.state.localize('pagination.lastPage'),\n disabled: onLast,\n onClick: () => this.controller.lastPage(),\n })}\n </div>\n `;\n }\n\n protected override render() {\n if (!this.state) return nothing;\n return html`\n <div part=\"paginator\" role=\"navigation\" aria-label=${this.state.localize('pagination.label')}>\n ${this.renderSizeSelect()} ${this.renderInfo()} ${this.renderControls()}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridPaginator.tagName]: ApexGridPaginator<object>;\n }\n}\n"]}
package/components/row.js CHANGED
@@ -5,10 +5,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { consume } from '@lit/context';
8
- import { html, LitElement, nothing } from 'lit';
8
+ import { html, LitElement, nothing, render } from 'lit';
9
9
  import { property, queryAll } from 'lit/decorators.js';
10
+ import { keyed } from 'lit/directives/keyed.js';
11
+ import { live } from 'lit/directives/live.js';
10
12
  import { repeat } from 'lit/directives/repeat.js';
13
+ import { captureRowGhost } from '../controllers/row-reorder.js';
11
14
  import { gridStateContext } from '../controllers/state.js';
15
+ import { cancelFlips, FLIP_ID_Y, hasFlipsInFlight } from '../internal/flip.js';
12
16
  import { registerComponent } from '../internal/register.js';
13
17
  import { GRID_ROW_TAG } from '../internal/tags.js';
14
18
  import { getPinEdge } from '../internal/utils.js';
@@ -28,6 +32,70 @@ const GRIP_ICON = html `<svg
28
32
  <circle cx="6" cy="12.5" r="1.25" />
29
33
  <circle cx="10" cy="12.5" r="1.25" />
30
34
  </svg>`;
35
+ let reboundPending = new Set();
36
+ let reboundPainted = new Set();
37
+ let reboundFrame = 0;
38
+ function clearRebound() {
39
+ reboundFrame = 0;
40
+ for (const row of reboundPainted)
41
+ row.removeAttribute('data-rebound');
42
+ reboundPainted = reboundPending;
43
+ reboundPending = new Set();
44
+ if (reboundPainted.size)
45
+ reboundFrame = requestAnimationFrame(clearRebound);
46
+ }
47
+ function markRebound(row) {
48
+ row.setAttribute('data-rebound', '');
49
+ reboundPainted.delete(row);
50
+ reboundPending.add(row);
51
+ if (!reboundFrame)
52
+ reboundFrame = requestAnimationFrame(clearRebound);
53
+ }
54
+ let detailKey = 0;
55
+ class DetailRoots {
56
+ #roots = new Map();
57
+ #frame = 0;
58
+ show(record, content, host, row) {
59
+ let root = this.#roots.get(record);
60
+ if (!root) {
61
+ const node = document.createElement('div');
62
+ node.style.display = 'contents';
63
+ root = { node, part: render(nothing, node, { host }), owner: null, key: 0 };
64
+ this.#roots.set(record, root);
65
+ }
66
+ if (root.owner !== row) {
67
+ root.owner = row;
68
+ root.key = ++detailKey;
69
+ }
70
+ render(content, root.node);
71
+ return keyed(root.key, root.node);
72
+ }
73
+ drop(record) {
74
+ const root = this.#roots.get(record);
75
+ if (!root)
76
+ return;
77
+ this.#roots.delete(record);
78
+ root.part.setConnected(false);
79
+ }
80
+ schedule() {
81
+ if (this.#frame || this.#roots.size === 0)
82
+ return;
83
+ this.#frame = requestAnimationFrame(() => {
84
+ this.#frame = 0;
85
+ for (const [record, root] of this.#roots) {
86
+ if (!inBodyRow(root.node))
87
+ this.drop(record);
88
+ }
89
+ });
90
+ }
91
+ }
92
+ function inBodyRow(node) {
93
+ if (!node.parentNode)
94
+ return false;
95
+ const row = node.getRootNode().host;
96
+ return row?.parentNode?.nodeType === Node.ELEMENT_NODE;
97
+ }
98
+ const detailRoots = new WeakMap();
31
99
  const ROW_PARTS = 'cell,row-number-cell,row-number,reorder-handle-cell,reorder-handle,reorder-grip,selection-cell,selection-checkbox,expansion-cell,expansion-toggle,expansion-chevron,detail-panel,group-row';
32
100
  export default class ApexGridRow extends LitElement {
33
101
  constructor() {
@@ -45,8 +113,6 @@ export default class ApexGridRow extends LitElement {
45
113
  this.dataVersion = 0;
46
114
  this.validationVersion = 0;
47
115
  this.#presented = null;
48
- this.#dragStartX = 0;
49
- this.#dragStartY = 0;
50
116
  this.#handleReorderPointerDown = (event) => {
51
117
  const reorder = this.state?.rowReorder;
52
118
  if (!reorder?.enabled || event.button !== 0 || !this.data)
@@ -68,9 +134,9 @@ export default class ApexGridRow extends LitElement {
68
134
  return;
69
135
  }
70
136
  }
71
- this.#dragStartX = event.clientX;
72
- this.#dragStartY = event.clientY;
73
- reorder.armPointerDrag(this.data, () => this.#captureGhost(this.#dragStartX, this.#dragStartY), event);
137
+ const data = this.data;
138
+ const { clientX, clientY } = event;
139
+ reorder.armPointerDrag(data, () => (this.data === data ? this.#captureGhost(clientX, clientY) : null), event);
74
140
  };
75
141
  this.ariaRowOffset = 1;
76
142
  }
@@ -90,20 +156,9 @@ export default class ApexGridRow extends LitElement {
90
156
  : null;
91
157
  }
92
158
  #presented;
93
- #dragStartX;
94
- #dragStartY;
95
159
  #handleReorderPointerDown;
96
160
  #captureGhost(clientX, clientY) {
97
- const rect = this.getBoundingClientRect();
98
- const cells = this.cells.map((cell) => {
99
- const el = cell;
100
- return {
101
- text: (el.textContent ?? '').replace(/\s+/g, ' ').trim(),
102
- width: el.getBoundingClientRect().width,
103
- align: getComputedStyle(el).textAlign,
104
- };
105
- });
106
- return { rect, clientX, clientY, cells };
161
+ return captureRowGhost(this, this.cells, clientX, clientY);
107
162
  }
108
163
  connectedCallback() {
109
164
  super.connectedCallback();
@@ -112,16 +167,30 @@ export default class ApexGridRow extends LitElement {
112
167
  }
113
168
  disconnectedCallback() {
114
169
  this.removeEventListener('pointerdown', this.#handleReorderPointerDown);
170
+ const host = this.state?.host;
171
+ if (host)
172
+ detailRoots.get(host)?.schedule();
115
173
  super.disconnectedCallback();
116
174
  }
175
+ #renderedData;
117
176
  willUpdate() {
177
+ if (this.data !== this.#renderedData) {
178
+ const rebound = this.#renderedData !== undefined;
179
+ if (rebound && hasFlipsInFlight())
180
+ cancelFlips(this, FLIP_ID_Y);
181
+ this.#renderedData = this.data;
182
+ if (rebound || this.state?.host?.rowRecycling)
183
+ markRebound(this);
184
+ }
118
185
  this.setAttribute('aria-rowindex', String(this.index + this.ariaRowOffset + 1));
186
+ this.toggleAttribute('data-alt', this.index % 2 === 1);
119
187
  this.#presented = this.state
120
188
  ? this.state.presentRow(this.data, { columns: this.columns, rowIndex: this.index })
121
189
  : null;
122
190
  this.#syncExportParts();
123
191
  if (this.#presented) {
124
192
  this.selected = false;
193
+ this.expanded = false;
125
194
  this.removeAttribute('aria-selected');
126
195
  if (typeof this.#presented.level === 'number') {
127
196
  this.setAttribute('aria-level', String(this.#presented.level));
@@ -137,9 +206,10 @@ export default class ApexGridRow extends LitElement {
137
206
  }
138
207
  return;
139
208
  }
140
- this.selected = Boolean(this.state?.selection.isSelected(this.data));
209
+ const selection = this.state?.selection;
210
+ this.selected = Boolean(selection?.isSelected(this.data));
141
211
  this.expanded = Boolean(this.state?.expansion.isExpanded(this.data));
142
- if (this.state?.selection.enabled) {
212
+ if (selection?.enabled && (this.selected || selection.isSelectable(this.data))) {
143
213
  this.setAttribute('aria-selected', this.selected ? 'true' : 'false');
144
214
  }
145
215
  else {
@@ -177,7 +247,8 @@ export default class ApexGridRow extends LitElement {
177
247
  }
178
248
  else {
179
249
  this.removeAttribute('aria-level');
180
- if (this.state?.expansion.enabled) {
250
+ if (this.state?.hierarchical &&
251
+ (this.expanded || this.state.expansion.canExpand(this.data))) {
181
252
  this.setAttribute('aria-expanded', this.expanded ? 'true' : 'false');
182
253
  }
183
254
  else {
@@ -241,7 +312,7 @@ export default class ApexGridRow extends LitElement {
241
312
  type="button"
242
313
  part="expansion-toggle"
243
314
  aria-label=${expanded ? this.state.localize('row.collapse') : this.state.localize('row.expand')}
244
- aria-expanded=${expanded ? 'true' : 'false'}
315
+ aria-expanded=${canExpand ? String(expanded) : nothing}
245
316
  ?disabled=${!canExpand}
246
317
  @click=${handleClick}
247
318
  >
@@ -266,17 +337,42 @@ export default class ApexGridRow extends LitElement {
266
337
  }
267
338
  renderDetailPanel() {
268
339
  const expansion = this.state?.expansion;
269
- if (!expansion?.isExpanded(this.data))
340
+ const host = this.state?.host;
341
+ const roots = host && detailRoots.get(host);
342
+ roots?.schedule();
343
+ if (!expansion?.isExpanded(this.data)) {
344
+ roots?.drop(this.data);
270
345
  return nothing;
271
- const template = this.state.host.expansion?.detailTemplate;
346
+ }
347
+ const template = host.expansion?.detailTemplate;
272
348
  if (typeof template !== 'function')
273
349
  return nothing;
274
350
  const content = template({
275
351
  data: this.data,
276
352
  rowIndex: this.index,
277
- parent: this.state.host,
353
+ parent: host,
278
354
  });
279
- return html `<div part="detail-panel" role="region" aria-label=${this.state.localize('row.detail')}>${content}</div>`;
355
+ let detail;
356
+ if (host.rowRecycling && !this.state.rowPin.isPinned(this.data)) {
357
+ let own = roots;
358
+ if (!own) {
359
+ own = new DetailRoots();
360
+ detailRoots.set(host, own);
361
+ }
362
+ detail = own.show(this.data, content, host, this);
363
+ own.schedule();
364
+ }
365
+ else {
366
+ detail = keyed(this.data, content);
367
+ }
368
+ return html `<div
369
+ part="detail-panel"
370
+ role="gridcell"
371
+ aria-colindex="1"
372
+ aria-colspan=${this.state.colCount}
373
+ >
374
+ <div role="region" aria-label=${this.state.localize('row.detail')}>${detail}</div>
375
+ </div>`;
280
376
  }
281
377
  renderSelectionCell(colindex) {
282
378
  const selection = this.state?.selection;
@@ -298,8 +394,20 @@ export default class ApexGridRow extends LitElement {
298
394
  };
299
395
  const handleChange = (event) => {
300
396
  const input = event.target;
301
- void selection.toggleRow(this.data).then(() => {
302
- input.checked = selection.isSelected(this.data);
397
+ const cell = input.parentElement;
398
+ const focused = this.renderRoot instanceof ShadowRoot && this.renderRoot.activeElement === input;
399
+ const record = this.data;
400
+ void selection.toggleRow(record).then(async () => {
401
+ if (this.data === record)
402
+ input.checked = selection.isSelected(record);
403
+ if (!focused || !cell)
404
+ return;
405
+ await this.updateComplete;
406
+ if (input.isConnected)
407
+ return;
408
+ cell.tabIndex = -1;
409
+ cell.addEventListener('blur', () => cell.removeAttribute('tabindex'), { once: true });
410
+ cell.focus({ preventScroll: true });
303
411
  });
304
412
  };
305
413
  const handleClick = (event) => {
@@ -314,6 +422,16 @@ export default class ApexGridRow extends LitElement {
314
422
  .querySelector('input[type="checkbox"]')
315
423
  ?.click();
316
424
  };
425
+ const checkbox = this.selected || selection.isSelectable(this.data)
426
+ ? html `<input
427
+ type="checkbox"
428
+ part="selection-checkbox"
429
+ aria-label=${this.state.localize('row.select')}
430
+ .checked=${live(this.selected)}
431
+ @click=${handleClick}
432
+ @change=${handleChange}
433
+ />`
434
+ : nothing;
317
435
  return html `<div
318
436
  part="selection-cell"
319
437
  role="gridcell"
@@ -321,26 +439,16 @@ export default class ApexGridRow extends LitElement {
321
439
  data-pinned="start"
322
440
  @click=${forwardToCheckbox}
323
441
  >
324
- <input
325
- type="checkbox"
326
- part="selection-checkbox"
327
- aria-label=${this.state.localize('row.select')}
328
- .checked=${this.selected}
329
- @click=${handleClick}
330
- @change=${handleChange}
331
- />
442
+ ${checkbox}
332
443
  </div>`;
333
444
  }
334
445
  render() {
335
446
  if (this.#presented) {
336
- const colspan = this.columns.filter((column) => !column.hidden).length +
337
- (this.state?.selection.showCheckboxColumn ? 1 : 0) +
338
- (this.state?.expansion.showToggleColumn ? 1 : 0);
339
447
  return html `<div
340
448
  part=${this.#presented.part ?? 'group-row'}
341
449
  role="gridcell"
342
450
  aria-colindex="1"
343
- aria-colspan=${Math.max(1, colspan)}
451
+ aria-colspan=${Math.max(1, this.state.colCount)}
344
452
  tabindex=${this.activeNode?.row === this.index ? 0 : -1}
345
453
  data-presented-cell
346
454
  style="grid-column: 1 / -1"
@@ -377,6 +485,7 @@ export default class ApexGridRow extends LitElement {
377
485
  .editing=${editing}
378
486
  .column=${column}
379
487
  .row=${this}
488
+ .record=${this.data}
380
489
  .value=${this.data[column.key]}
381
490
  .colindex=${ariaColindex}
382
491
  .rowIndex=${this.index}
@@ -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 type { RowGhostInit } from '../controllers/row-reorder.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport type { PresentedRow } from '../internal/feature-module.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_ROW_TAG } from '../internal/tags.js';\nimport type { ActiveNode, ColumnConfiguration, Keys } from '../internal/types.js';\nimport { getPinEdge } from '../internal/utils.js';\nimport { styles } from '../styles/body-row/body-row.css.js';\nimport ApexGridCell from './cell.js';\n\n/** The six-dot grip drawn inside the row-reorder drag handle. */\nconst GRIP_ICON = html`<svg\n part=\"reorder-grip\"\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n>\n <circle cx=\"6\" cy=\"3.5\" r=\"1.25\" />\n <circle cx=\"10\" cy=\"3.5\" r=\"1.25\" />\n <circle cx=\"6\" cy=\"8\" r=\"1.25\" />\n <circle cx=\"10\" cy=\"8\" r=\"1.25\" />\n <circle cx=\"6\" cy=\"12.5\" r=\"1.25\" />\n <circle cx=\"10\" cy=\"12.5\" r=\"1.25\" />\n</svg>`;\n\n/**\n * Every part a row renders in its own shadow root. Rows live in the grid's\n * shadow root, so the row's `exportparts` is the whole surface that\n * `apex-grid::part(...)` can reach; a part missing here cannot be styled.\n * `group-row` is the default container part of a module-rendered row.\n */\nconst ROW_PARTS =\n 'cell,row-number-cell,row-number,reorder-handle-cell,reorder-handle,reorder-grip,selection-cell,selection-checkbox,expansion-cell,expansion-toggle,expansion-chevron,detail-panel,group-row';\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 /**\n * The single focus target of a row a feature module renders full width (a\n * group header, a total row), or `null` for a normal cell-rendered row.\n * Keyboard navigation lands here, whatever the active column, so the body\n * keeps a tab stop on rows that render no cells.\n */\n public get presentedCell(): HTMLElement | null {\n return this.#presented\n ? this.renderRoot.querySelector<HTMLElement>('[data-presented-cell]')\n : null;\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n @property({ attribute: false })\n public activeNode!: ActiveNode<T>;\n\n @property({ attribute: false, type: Number })\n public index = -1;\n\n /** Reflects current selection state so SCSS can highlight the row. */\n @property({ type: Boolean, reflect: true })\n public selected = false;\n\n /** Reflects current expansion state so SCSS can rotate the chevron. */\n @property({ type: Boolean, reflect: true })\n public expanded = false;\n\n /** Reflects pointer-drag state (row reorder) so SCSS can dim the source. */\n @property({ type: Boolean, reflect: true })\n public dragging = false;\n\n /** Reflects keyboard-grab state (row reorder) so SCSS can outline the row. */\n @property({ type: Boolean, reflect: true })\n public grabbed = false;\n\n /** Reveal the spreadsheet row-number gutter cell (transient formula coordinate hint). */\n @property({ type: Boolean })\n public coordinateHints = false;\n\n /** The column key currently being edited in this row, or `null`. */\n @property({ attribute: false })\n public editingKey: Keys<T> | null = null;\n\n /**\n * Reactive token from {@link StateController.decorationVersion}, forwarded to\n * each cell so a decoration-only change re-renders the row's cells. Stays `0`\n * for the community grid.\n */\n @property({ attribute: false, type: Number })\n public decorationVersion = 0;\n\n /**\n * Reactive token from {@link StateController.dataVersion}, forwarded to each\n * cell so a pipeline run (edit, data change, tree toggle) refreshes the row's\n * ARIA and the cells that read their row. Stays `0` for pinned rows.\n */\n @property({ attribute: false })\n public dataVersion = 0;\n\n /**\n * Reactive token from {@link EditingController.validationVersion}, forwarded to\n * each cell so a validation-only change re-renders the row's cells (toggling\n * `aria-invalid` and the inline error node). Stays `0` until the first\n * validation failure.\n */\n @property({ attribute: false, type: Number })\n public validationVersion = 0;\n\n /**\n * Result of the feature-module row presenter for the current update, or\n * `null` when no module renders this row full-width (the normal case).\n * Computed in {@link willUpdate} and consumed in {@link render}.\n */\n #presented: PresentedRow | null = null;\n\n #dragStartX = 0;\n #dragStartY = 0;\n\n /**\n * Arms a row drag. In handle mode only the grip starts one; in whole-row mode\n * a press anywhere except an interactive sub-part does. The move / up plumbing\n * lives on the grid host (see {@link RowReorderController.armPointerDrag}), so\n * a live-swap that recycles this row's DOM can't break the gesture.\n */\n #handleReorderPointerDown = (event: PointerEvent) => {\n const reorder = this.state?.rowReorder;\n if (!reorder?.enabled || event.button !== 0 || !this.data) return;\n // Pinned rows are not reorder sources (F4 scope).\n if (this.state.rowPin.isPinned(this.data)) return;\n\n const path = event.composedPath();\n const onHandle = path.some(\n (node) =>\n node instanceof Element && (node.getAttribute?.('part') ?? '').includes('reorder-handle')\n );\n\n if (reorder.handleMode) {\n // Handle mode: only the grip starts a drag. The rest of the row stays free\n // for selection / editing / text selection.\n if (!onHandle) return;\n // Own the gesture: keep the grid's body handler from treating the press as\n // a cell interaction, and suppress native text/element drag-selection.\n event.preventDefault();\n event.stopPropagation();\n } else {\n // Whole-row mode: a drag begins anywhere except an interactive sub-part\n // (editor, checkbox, button).\n const target = path[0];\n if (\n target instanceof Element &&\n target.closest?.('input, button, a, select, textarea, [data-apex-editor]')\n ) {\n return;\n }\n }\n\n this.#dragStartX = event.clientX;\n this.#dragStartY = event.clientY;\n // The controller snapshots the ghost the instant the drag engages (the row\n // is still in place then), seeded from the original press point.\n reorder.armPointerDrag(\n this.data,\n () => this.#captureGhost(this.#dragStartX, this.#dragStartY),\n event\n );\n };\n\n /**\n * Snapshots the row's visible cells (text, width, alignment) and bounding rect\n * so the controller can paint a faithful floating ghost. Invoked once, at the\n * moment the drag engages.\n */\n #captureGhost(clientX: number, clientY: number): RowGhostInit {\n const rect = this.getBoundingClientRect();\n const cells = this.cells.map((cell) => {\n const el = cell as unknown as HTMLElement;\n return {\n text: (el.textContent ?? '').replace(/\\s+/g, ' ').trim(),\n width: el.getBoundingClientRect().width,\n align: getComputedStyle(el).textAlign,\n };\n });\n return { rect, clientX, clientY, cells };\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('role', 'row');\n this.addEventListener('pointerdown', this.#handleReorderPointerDown);\n }\n\n public override disconnectedCallback(): void {\n this.removeEventListener('pointerdown', this.#handleReorderPointerDown);\n super.disconnectedCallback();\n }\n\n /**\n * The number of \"chrome\" rows (header + filter) above the body. Used to\n * derive `aria-rowindex` from {@link index}. Set by the parent grid.\n */\n @property({ attribute: false, type: Number })\n public ariaRowOffset = 1;\n\n protected override willUpdate() {\n this.setAttribute('aria-rowindex', String(this.index + this.ariaRowOffset + 1));\n\n // Ask feature modules whether this row is rendered full-width (e.g. an\n // enterprise group header). When one owns it, the row is not a selectable\n // data row — it carries its own level/expanded semantics and skips the\n // selection/tree aria below.\n this.#presented = this.state\n ? this.state.presentRow(this.data, { columns: this.columns, rowIndex: this.index })\n : null;\n this.#syncExportParts();\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 // A module may attach tree/expansion ARIA to a normal cell-rendered row\n // (e.g. pivoting's expandable parent rows, which keep their value cells).\n const aria = this.state?.describeRow(this.data, {\n columns: this.columns,\n rowIndex: this.index,\n });\n if (aria) {\n if (typeof aria.level === 'number') {\n this.setAttribute('aria-level', String(aria.level));\n } else {\n this.removeAttribute('aria-level');\n }\n if (typeof aria.expanded === 'boolean') {\n this.setAttribute('aria-expanded', aria.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n } else {\n this.removeAttribute('aria-level');\n if (this.state?.expansion.enabled) {\n this.setAttribute('aria-expanded', this.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n }\n }\n }\n\n /**\n * Re-exports the row's own parts plus the ones a module declares for the\n * content it renders here: a presented row's container part and\n * {@link PresentedRow.exportParts}, or the expansion config's\n * `exportParts` for the detail panel content. Re-run on every update, so a\n * row element the virtualizer reuses for another record drops the parts of\n * the one it showed before.\n */\n #syncExportParts() {\n // Runs on every row update, scroll recycling included, so the common\n // case (no extra parts) builds no arrays.\n const presented = this.#presented;\n const own = presented?.part?.split(' ').join(',');\n const list = presented ? presented.exportParts : this.state?.host.expansion?.exportParts;\n let value = ROW_PARTS;\n if (own) value += `,${own}`;\n if (list?.length) value += `,${list.join(',')}`;\n if (this.getAttribute('exportparts') !== value) {\n this.setAttribute('exportparts', value);\n }\n }\n\n /**\n * Leading row-number gutter cell (transient spreadsheet coordinate hint). Shown\n * only while `coordinateHints` is on. A feature module that addresses the data\n * (the enterprise formula engine) supplies the label, so it matches what a\n * reference reads; otherwise it is the view position, and pinned rows render\n * an empty spacer (their band-local index is not a meaningful row number) so\n * the track stays aligned. Presentational: the accessible row index is\n * `aria-rowindex`.\n */\n protected renderRowNumber() {\n if (!this.coordinateHints) return nothing;\n let label: string | number | null | undefined = this.state?.rowCoordinate(this.data);\n if (label === undefined) {\n label = this.state?.rowPin?.isPinned(this.data) ? null : this.index + 1;\n }\n return html`<div part=\"row-number-cell\" data-pinned=\"start\" aria-hidden=\"true\">\n ${label === null ? nothing : html`<span part=\"row-number\">${label}</span>`}\n </div>`;\n }\n\n /**\n * Leading drag-handle (grip) cell. Rendered only in handle mode; pinned rows\n * get an empty spacer so the grid track stays aligned. The cell is\n * presentational (`aria-hidden`) — the accessible reorder path is the keyboard\n * grab flow, not this pointer affordance.\n */\n protected renderReorderHandle() {\n const reorder = this.state?.rowReorder;\n if (!reorder?.showHandleColumn) return nothing;\n const draggable = !this.state?.rowPin?.isPinned(this.data);\n return html`<div part=\"reorder-handle-cell\" data-pinned=\"start\" aria-hidden=\"true\">\n ${draggable ? html`<span part=\"reorder-handle\">${GRIP_ICON}</span>` : nothing}\n </div>`;\n }\n\n protected renderExpansionToggle(colindex: number) {\n const expansion = this.state?.expansion;\n if (!expansion?.showToggleColumn) return nothing;\n const canExpand = expansion.canExpand(this.data) || expansion.isExpanded(this.data);\n const expanded = this.expanded;\n const handleClick = (event: MouseEvent) => {\n event.stopPropagation();\n if (!canExpand) return;\n void expansion.toggleRow(this.data);\n };\n return html`<div\n part=\"expansion-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <button\n type=\"button\"\n part=\"expansion-toggle\"\n aria-label=${\n expanded ? this.state.localize('row.collapse') : this.state.localize('row.expand')\n }\n aria-expanded=${expanded ? 'true' : 'false'}\n ?disabled=${!canExpand}\n @click=${handleClick}\n >\n <svg\n part=\"expansion-chevron\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n width=\"14\"\n height=\"14\"\n >\n <path\n d=\"M9 6l6 6-6 6\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>`;\n }\n\n protected renderDetailPanel() {\n const expansion = this.state?.expansion;\n if (!expansion?.isExpanded(this.data)) return nothing;\n const template = this.state.host.expansion?.detailTemplate;\n if (typeof template !== 'function') return nothing;\n const content = template({\n data: this.data,\n rowIndex: this.index,\n parent: this.state.host,\n });\n return html`<div part=\"detail-panel\" role=\"region\" aria-label=${this.state.localize('row.detail')}>${content}</div>`;\n }\n\n protected renderSelectionCell(colindex: number) {\n const selection = this.state?.selection;\n if (!selection?.showCheckboxColumn) return nothing;\n // Shift extends a range from the anchor and Ctrl or Cmd toggles one row\n // without moving it (multiple mode only). Shared by the checkbox and the\n // cell around it, so both give the same result for the same gesture.\n // Returns false for a plain click, which the checkbox toggles itself.\n const modifierToggle = (event: MouseEvent): boolean => {\n if (selection.mode !== 'multiple') return false;\n if (event.shiftKey) {\n void selection.rangeToggle(this.data);\n } else if (event.ctrlKey || event.metaKey) {\n void selection.additiveToggle(this.data);\n } else {\n return false;\n }\n return true;\n };\n // The native `change` carries no modifier keys (they ride on the click\n // above), so it covers plain clicks and Space on a focused checkbox. The\n // click has already flipped `checked`; a `rowSelecting` listener that\n // cancels leaves the row as it was without a re-render, so write the\n // real state back once the selection has decided.\n const handleChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n void selection.toggleRow(this.data).then(() => {\n input.checked = selection.isSelected(this.data);\n });\n };\n const handleClick = (event: MouseEvent) => {\n // Keeps checkbox clicks from bubbling to the cell's forwarder below and\n // to app click listeners on the grid (the grid's own body handler runs\n // in the capture phase and ignores this target).\n event.stopPropagation();\n // A modifier click is handled here, so cancel the native toggle.\n if (modifierToggle(event)) event.preventDefault();\n };\n // The checkbox itself is 14x14, well under the 24x24 WCAG 2.2 AA minimum\n // (2.5.8), and growing it would make a chunky box out of a deliberately\n // small mark. Instead the whole cell is the target: a click anywhere in it\n // acts like a click on the checkbox, modifiers included, which is both\n // compliant and what people expect of a selection column. Clicks that land\n // on the checkbox are left alone, or the forward would toggle twice and\n // cancel out.\n const forwardToCheckbox = (event: MouseEvent) => {\n if (event.target instanceof HTMLInputElement || modifierToggle(event)) return;\n (event.currentTarget as HTMLElement)\n .querySelector<HTMLInputElement>('input[type=\"checkbox\"]')\n ?.click();\n };\n return html`<div\n part=\"selection-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n @click=${forwardToCheckbox}\n >\n <input\n type=\"checkbox\"\n part=\"selection-checkbox\"\n aria-label=${this.state.localize('row.select')}\n .checked=${this.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 const colspan =\n this.columns.filter((column) => !column.hidden).length +\n (this.state?.selection.showCheckboxColumn ? 1 : 0) +\n (this.state?.expansion.showToggleColumn ? 1 : 0);\n return html`<div\n part=${this.#presented.part ?? 'group-row'}\n role=\"gridcell\"\n aria-colindex=\"1\"\n aria-colspan=${Math.max(1, colspan)}\n tabindex=${this.activeNode?.row === this.index ? 0 : -1}\n data-presented-cell\n style=\"grid-column: 1 / -1\"\n >\n ${this.#presented.content}\n </div>`;\n }\n\n // A row index can transiently fall beyond the current data — e.g. while a\n // server-side / infinite row model resizes `data` on a filter or sort\n // change, the virtualizer may render a stale index for a frame. Render\n // nothing until the real item arrives, rather than dereferencing undefined.\n if (this.data == null) return nothing;\n\n const { column: key, row: index } = this.activeNode;\n\n // Track aria-colindex (1-based) across the auto chrome columns and the\n // data columns. Selection comes first, then expansion, then data.\n let colCursor = 0;\n const selectionCol = this.state?.selection.showCheckboxColumn ? ++colCursor : 0;\n const expansionCol = this.state?.expansion.showToggleColumn ? ++colCursor : 0;\n\n // Keyed by column.key so the same `<apex-grid-cell>` follows its\n // column through a reorder swap — required for the column-reorder FLIP\n // animation in ReorderController to track motion per cell.\n return html`\n ${this.renderRowNumber()}\n ${this.renderReorderHandle()}\n ${this.renderSelectionCell(selectionCol)}\n ${this.renderExpansionToggle(expansionCol)}\n ${repeat(\n this.columns,\n (column) => String(column.key),\n (column, colIndex) => {\n if (column.hidden) return nothing;\n const offset = this.pinOffsets.get(column.key);\n const pinStyle =\n column.pinned && typeof offset === 'number' ? `--apex-pin-offset:${offset}px` : '';\n const edge = getPinEdge(this.columns, colIndex);\n const editing = this.editingKey === column.key;\n const ariaColindex = ++colCursor;\n return html`<apex-grid-cell\n part=\"cell\"\n data-pinned=${column.pinned ?? 'none'}\n data-pin-edge=${edge ?? 'none'}\n data-cell-type=${column.type ?? 'string'}\n style=${pinStyle}\n .active=${key === column.key && index === this.index}\n .editing=${editing}\n .column=${column}\n .row=${this as ApexGridRow<T>}\n .value=${this.data[column.key]}\n .colindex=${ariaColindex}\n .rowIndex=${this.index}\n .decorationVersion=${this.decorationVersion}\n .dataVersion=${this.dataVersion}\n .validationVersion=${this.validationVersion}\n ></apex-grid-cell>`;\n }\n )}\n ${this.renderDetailPanel()}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridRow.tagName]: ApexGridRow<object>;\n }\n}\n"]}
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, type RootPart, render } from 'lit';\nimport { property, queryAll } from 'lit/decorators.js';\nimport { keyed } from 'lit/directives/keyed.js';\nimport { live } from 'lit/directives/live.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { captureRowGhost, type RowGhostInit } from '../controllers/row-reorder.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport type { PresentedRow } from '../internal/feature-module.js';\nimport { cancelFlips, FLIP_ID_Y, hasFlipsInFlight } from '../internal/flip.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_ROW_TAG } from '../internal/tags.js';\nimport type { ActiveNode, ColumnConfiguration, Keys } from '../internal/types.js';\nimport { getPinEdge } from '../internal/utils.js';\nimport { styles } from '../styles/body-row/body-row.css.js';\nimport ApexGridCell from './cell.js';\n\n/** The six-dot grip drawn inside the row-reorder drag handle. */\nconst GRIP_ICON = html`<svg\n part=\"reorder-grip\"\n viewBox=\"0 0 16 16\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n>\n <circle cx=\"6\" cy=\"3.5\" r=\"1.25\" />\n <circle cx=\"10\" cy=\"3.5\" r=\"1.25\" />\n <circle cx=\"6\" cy=\"8\" r=\"1.25\" />\n <circle cx=\"10\" cy=\"8\" r=\"1.25\" />\n <circle cx=\"6\" cy=\"12.5\" r=\"1.25\" />\n <circle cx=\"10\" cy=\"12.5\" r=\"1.25\" />\n</svg>`;\n\n/**\n * Rows marked `data-rebound` whose frame has not painted yet, and the ones\n * whose frame has: the mark comes off one frame after the frame that paints\n * the new record. A `requestAnimationFrame` callback runs before that frame's\n * style pass, so clearing in the first one would let the change animate.\n */\nlet reboundPending = new Set<Element>();\nlet reboundPainted = new Set<Element>();\nlet reboundFrame = 0;\n\nfunction clearRebound() {\n reboundFrame = 0;\n for (const row of reboundPainted) row.removeAttribute('data-rebound');\n reboundPainted = reboundPending;\n reboundPending = new Set();\n if (reboundPainted.size) reboundFrame = requestAnimationFrame(clearRebound);\n}\n\n/**\n * Marks a row that now shows another record (or, under row recycling, its\n * first one) for one painted frame. `body-row.scss` zeroes the motion tokens\n * under the mark, and they inherit into everything the row renders, the\n * cells' shadow roots included, so nothing animates from what the element\n * showed before.\n */\nfunction markRebound(row: Element) {\n row.setAttribute('data-rebound', '');\n reboundPainted.delete(row);\n reboundPending.add(row);\n if (!reboundFrame) reboundFrame = requestAnimationFrame(clearRebound);\n}\n\n/** One record's detail content, rendered into a node of its own. */\ninterface DetailRoot {\n readonly node: HTMLElement;\n readonly part: RootPart;\n /** The row that last took the node. */\n owner: Element | null;\n /** Changes whenever another row takes the node (see {@link DetailRoots.show}). */\n key: number;\n}\n\n/** Source of {@link DetailRoot.key} values, unique across grids. */\nlet detailKey = 0;\n\n/**\n * Detail panel content per record, for a grid that recycles its body rows\n * (`rowRecycling`). A body row element there shows whatever record its slot\n * holds next, so a sort or `moveRow` would hand one record's detail DOM to\n * another, or (keyed) rebuild it. Instead each record's content is rendered\n * into a root node of its own and the row hands Lit that node, which then\n * moves into whichever row shows the record, its DOM state (typed text, a\n * nested grid's sort) intact. A root is dropped when a row renders its record\n * collapsed or the record is no longer in a body row, which is what item\n * keys destroy.\n */\nclass DetailRoots {\n readonly #roots = new Map<object, DetailRoot>();\n #frame = 0;\n\n /**\n * Renders `content` into the root of `record` and returns the root's node\n * for `row` to commit. The node comes keyed by the row that last took it: a\n * row set aside as a spare keeps the node as its committed value after\n * another row took it, so without a new key Lit would skip committing the\n * same node when the spare shows the record again.\n */\n public show(record: object, content: unknown, host: object, row: Element): unknown {\n let root = this.#roots.get(record);\n if (!root) {\n const node = document.createElement('div');\n // Layout-neutral: the content lays out as if it sat in the panel.\n node.style.display = 'contents';\n // The grid is the stable `this` for listeners: the row changes.\n root = { node, part: render(nothing, node, { host }), owner: null, key: 0 };\n this.#roots.set(record, root);\n }\n if (root.owner !== row) {\n root.owner = row;\n root.key = ++detailKey;\n }\n render(content, root.node);\n return keyed(root.key, root.node);\n }\n\n /** Drops the root of `record`, disconnecting the directives it rendered. */\n public drop(record: object) {\n const root = this.#roots.get(record);\n if (!root) return;\n this.#roots.delete(record);\n root.part.setConnected(false);\n }\n\n /**\n * Prunes, at the next frame, the roots no body row shows. Within one batch\n * of row renders a root can sit detached between the row that let go of it\n * and the row that takes it, so the check waits for the batch to finish.\n */\n public schedule() {\n if (this.#frame || this.#roots.size === 0) return;\n this.#frame = requestAnimationFrame(() => {\n this.#frame = 0;\n for (const [record, root] of this.#roots) {\n if (!inBodyRow(root.node)) this.drop(record);\n }\n });\n }\n}\n\n/**\n * Whether a detail root sits in a row the body still holds. A row the body\n * removed has no parent, and one set aside for reuse sits in a fragment. A\n * grid out of the document keeps its rows, so this is not `isConnected`.\n */\nfunction inBodyRow(node: Node): boolean {\n if (!node.parentNode) return false;\n const row = (node.getRootNode() as ShadowRoot).host;\n return row?.parentNode?.nodeType === Node.ELEMENT_NODE;\n}\n\n/** Detail roots per grid: one record may show in several grids. */\nconst detailRoots = new WeakMap<object, DetailRoots>();\n\n/**\n * Every part a row renders in its own shadow root. Rows live in the grid's\n * shadow root, so the row's `exportparts` is the whole surface that\n * `apex-grid::part(...)` can reach; a part missing here cannot be styled.\n * `group-row` is the default container part of a module-rendered row.\n */\nconst ROW_PARTS =\n 'cell,row-number-cell,row-number,reorder-handle-cell,reorder-handle,reorder-grip,selection-cell,selection-checkbox,expansion-cell,expansion-toggle,expansion-chevron,detail-panel,group-row';\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 /**\n * The single focus target of a row a feature module renders full width (a\n * group header, a total row), or `null` for a normal cell-rendered row.\n * Keyboard navigation lands here, whatever the active column, so the body\n * keeps a tab stop on rows that render no cells.\n */\n public get presentedCell(): HTMLElement | null {\n return this.#presented\n ? this.renderRoot.querySelector<HTMLElement>('[data-presented-cell]')\n : null;\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n @property({ attribute: false })\n public activeNode!: ActiveNode<T>;\n\n @property({ attribute: false, type: Number })\n public index = -1;\n\n /** Reflects current selection state so SCSS can highlight the row. */\n @property({ type: Boolean, reflect: true })\n public selected = false;\n\n /** Reflects current expansion state so SCSS can rotate the chevron. */\n @property({ type: Boolean, reflect: true })\n public expanded = false;\n\n /** Reflects pointer-drag state (row reorder) so SCSS can dim the source. */\n @property({ type: Boolean, reflect: true })\n public dragging = false;\n\n /** Reflects keyboard-grab state (row reorder) so SCSS can outline the row. */\n @property({ type: Boolean, reflect: true })\n public grabbed = false;\n\n /** Reveal the spreadsheet row-number gutter cell (transient formula coordinate hint). */\n @property({ type: Boolean })\n public coordinateHints = false;\n\n /** The column key currently being edited in this row, or `null`. */\n @property({ attribute: false })\n public editingKey: Keys<T> | null = null;\n\n /**\n * Reactive token from {@link StateController.decorationVersion}, forwarded to\n * each cell so a decoration-only change re-renders the row's cells. Stays `0`\n * for the community grid.\n */\n @property({ attribute: false, type: Number })\n public decorationVersion = 0;\n\n /**\n * Reactive token from {@link StateController.dataVersion}, forwarded to each\n * cell so a pipeline run (edit, data change, tree toggle) refreshes the row's\n * ARIA and the cells that read their row. Stays `0` for pinned rows.\n */\n @property({ attribute: false })\n public dataVersion = 0;\n\n /**\n * Reactive token from {@link EditingController.validationVersion}, forwarded to\n * each cell so a validation-only change re-renders the row's cells (toggling\n * `aria-invalid` and the inline error node). Stays `0` until the first\n * validation failure.\n */\n @property({ attribute: false, type: Number })\n public validationVersion = 0;\n\n /**\n * Result of the feature-module row presenter for the current update, or\n * `null` when no module renders this row full-width (the normal case).\n * Computed in {@link willUpdate} and consumed in {@link render}.\n */\n #presented: PresentedRow | null = null;\n\n /**\n * Arms a row drag. In handle mode only the grip starts one; in whole-row mode\n * a press anywhere except an interactive sub-part does. The move / up plumbing\n * lives on the grid host (see {@link RowReorderController.armPointerDrag}), so\n * a live-swap that recycles this row's DOM can't break the gesture.\n */\n #handleReorderPointerDown = (event: PointerEvent) => {\n const reorder = this.state?.rowReorder;\n if (!reorder?.enabled || event.button !== 0 || !this.data) return;\n // Pinned rows are not reorder sources (F4 scope).\n if (this.state.rowPin.isPinned(this.data)) return;\n\n const path = event.composedPath();\n const onHandle = path.some(\n (node) =>\n node instanceof Element && (node.getAttribute?.('part') ?? '').includes('reorder-handle')\n );\n\n if (reorder.handleMode) {\n // Handle mode: only the grip starts a drag. The rest of the row stays free\n // for selection / editing / text selection.\n if (!onHandle) return;\n // Own the gesture: keep the grid's body handler from treating the press as\n // a cell interaction, and suppress native text/element drag-selection.\n event.preventDefault();\n event.stopPropagation();\n } else {\n // Whole-row mode: a drag begins anywhere except an interactive sub-part\n // (editor, checkbox, button).\n const target = path[0];\n if (\n target instanceof Element &&\n target.closest?.('input, button, a, select, textarea, [data-apex-editor]')\n ) {\n return;\n }\n }\n\n // The controller snapshots the ghost the instant the drag engages, seeded\n // from the original press point, from whichever row renders the pressed\n // record then. This row may show another record by that time (a re-bind),\n // so its own snapshot declines once it does.\n const data = this.data;\n const { clientX, clientY } = event;\n reorder.armPointerDrag(\n data,\n () => (this.data === data ? this.#captureGhost(clientX, clientY) : null),\n event\n );\n };\n\n /**\n * Snapshots the row's visible cells (text, width, alignment) and bounding rect\n * so the controller can paint a faithful floating ghost.\n */\n #captureGhost(clientX: number, clientY: number): RowGhostInit {\n return captureRowGhost(this, this.cells as unknown as Element[], clientX, clientY);\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('role', 'row');\n this.addEventListener('pointerdown', this.#handleReorderPointerDown);\n }\n\n public override disconnectedCallback(): void {\n this.removeEventListener('pointerdown', this.#handleReorderPointerDown);\n // A row leaving the body (set aside as a spare, or removed) renders\n // nothing more, so it prunes the detail roots itself: a range that\n // shrinks to no rows would otherwise keep them until some later render.\n const host = this.state?.host;\n if (host) detailRoots.get(host)?.schedule();\n super.disconnectedCallback();\n }\n\n /**\n * The number of \"chrome\" rows (header + filter) above the body. Used to\n * derive `aria-rowindex` from {@link index}. Set by the parent grid.\n */\n @property({ attribute: false, type: Number })\n public ariaRowOffset = 1;\n\n /** The record this element rendered last, to spot a re-bind to another one. */\n #renderedData: T | undefined;\n\n protected override willUpdate() {\n // A row FLIP moves the record it was started for. Re-bound to another\n // record mid-flight, the element would carry that motion over to the new\n // one, so it stops. Checked only while a FLIP runs: scroll re-binds pay\n // nothing.\n // A re-bind must not animate either: a progress bar growing from the\n // previous record's value, a selected wash fading out, a chevron turning.\n // Under row recycling a new row counts too, as a spare or fresh body row\n // can be styled before its first update; item mode keeps today's path\n // for new rows. A real toggle keeps the record, so it still animates.\n if (this.data !== this.#renderedData) {\n const rebound = this.#renderedData !== undefined;\n if (rebound && hasFlipsInFlight()) cancelFlips(this, FLIP_ID_Y);\n this.#renderedData = this.data;\n if (rebound || this.state?.host?.rowRecycling) markRebound(this);\n }\n this.setAttribute('aria-rowindex', String(this.index + this.ariaRowOffset + 1));\n // Zebra parity from the row index, not the DOM position (body-row.scss).\n this.toggleAttribute('data-alt', this.index % 2 === 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 this.#syncExportParts();\n if (this.#presented) {\n // Data-row state does not apply, and an element re-bound from a data\n // row (a pinned band, a recycled body slot) must not carry it over.\n // `dragging` and `grabbed` are bound by record on every render.\n this.selected = false;\n this.expanded = 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 const selection = this.state?.selection;\n this.selected = Boolean(selection?.isSelected(this.data));\n this.expanded = Boolean(this.state?.expansion.isExpanded(this.data));\n // The grid pattern marks selectable rows with aria-selected; a row that\n // cannot be selected (`isRowSelectable`) omits it rather than claiming\n // an unselected state the user cannot change, unless it is still\n // selected (it can be deselected).\n if (selection?.enabled && (this.selected || selection.isSelectable(this.data))) {\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 // A module may attach tree/expansion ARIA to a normal cell-rendered row\n // (e.g. pivoting's expandable parent rows, which keep their value cells).\n const aria = this.state?.describeRow(this.data, {\n columns: this.columns,\n rowIndex: this.index,\n });\n if (aria) {\n if (typeof aria.level === 'number') {\n this.setAttribute('aria-level', String(aria.level));\n } else {\n this.removeAttribute('aria-level');\n }\n if (typeof aria.expanded === 'boolean') {\n this.setAttribute('aria-expanded', aria.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n } else {\n this.removeAttribute('aria-level');\n // Only a row that can open (or is open) is announced as collapsible,\n // and only under the treegrid role: a grid row may not carry\n // aria-expanded, so this follows the same rule as the role.\n if (\n this.state?.hierarchical &&\n (this.expanded || this.state.expansion.canExpand(this.data))\n ) {\n this.setAttribute('aria-expanded', this.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n }\n }\n }\n\n /**\n * Re-exports the row's own parts plus the ones a module declares for the\n * content it renders here: a presented row's container part and\n * {@link PresentedRow.exportParts}, or the expansion config's\n * `exportParts` for the detail panel content. Re-run on every update, so a\n * row element the virtualizer reuses for another record drops the parts of\n * the one it showed before.\n */\n #syncExportParts() {\n // Runs on every row update, scroll recycling included, so the common\n // case (no extra parts) builds no arrays.\n const presented = this.#presented;\n const own = presented?.part?.split(' ').join(',');\n const list = presented ? presented.exportParts : this.state?.host.expansion?.exportParts;\n let value = ROW_PARTS;\n if (own) value += `,${own}`;\n if (list?.length) value += `,${list.join(',')}`;\n if (this.getAttribute('exportparts') !== value) {\n this.setAttribute('exportparts', value);\n }\n }\n\n /**\n * Leading row-number gutter cell (transient spreadsheet coordinate hint). Shown\n * only while `coordinateHints` is on. A feature module that addresses the data\n * (the enterprise formula engine) supplies the label, so it matches what a\n * reference reads; otherwise it is the view position, and pinned rows render\n * an empty spacer (their band-local index is not a meaningful row number) so\n * the track stays aligned. Presentational: the accessible row index is\n * `aria-rowindex`.\n */\n protected renderRowNumber() {\n if (!this.coordinateHints) return nothing;\n let label: string | number | null | undefined = this.state?.rowCoordinate(this.data);\n if (label === undefined) {\n label = this.state?.rowPin?.isPinned(this.data) ? null : this.index + 1;\n }\n return html`<div part=\"row-number-cell\" data-pinned=\"start\" aria-hidden=\"true\">\n ${label === null ? nothing : html`<span part=\"row-number\">${label}</span>`}\n </div>`;\n }\n\n /**\n * Leading drag-handle (grip) cell. Rendered only in handle mode; pinned rows\n * get an empty spacer so the grid track stays aligned. The cell is\n * presentational (`aria-hidden`) — the accessible reorder path is the keyboard\n * grab flow, not this pointer affordance.\n */\n protected renderReorderHandle() {\n const reorder = this.state?.rowReorder;\n if (!reorder?.showHandleColumn) return nothing;\n const draggable = !this.state?.rowPin?.isPinned(this.data);\n return html`<div part=\"reorder-handle-cell\" data-pinned=\"start\" aria-hidden=\"true\">\n ${draggable ? html`<span part=\"reorder-handle\">${GRIP_ICON}</span>` : nothing}\n </div>`;\n }\n\n protected renderExpansionToggle(colindex: number) {\n const expansion = this.state?.expansion;\n if (!expansion?.showToggleColumn) return nothing;\n const canExpand = expansion.canExpand(this.data) || expansion.isExpanded(this.data);\n const expanded = this.expanded;\n const handleClick = (event: MouseEvent) => {\n event.stopPropagation();\n if (!canExpand) return;\n void expansion.toggleRow(this.data);\n };\n return html`<div\n part=\"expansion-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <button\n type=\"button\"\n part=\"expansion-toggle\"\n aria-label=${\n expanded ? this.state.localize('row.collapse') : this.state.localize('row.expand')\n }\n aria-expanded=${canExpand ? String(expanded) : nothing}\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 const host = this.state?.host;\n const roots = host && detailRoots.get(host);\n roots?.schedule();\n if (!expansion?.isExpanded(this.data)) {\n // Rendered collapsed, the panel closed: an expand builds it fresh.\n roots?.drop(this.data);\n return nothing;\n }\n const template = host.expansion?.detailTemplate;\n if (typeof template !== 'function') return nothing;\n const content = template({\n data: this.data,\n rowIndex: this.index,\n parent: host,\n });\n // A row owns only cells, so the panel is one cell across the whole row.\n // A recycled body row takes the record's own root (see DetailRoots).\n // Otherwise the content is keyed by record: a row element re-bound to\n // another record (a pinned band) builds fresh detail DOM rather than\n // showing the previous record's (a typed input, a nested grid's sort). A\n // row that keeps its record keeps its detail DOM.\n let detail: unknown;\n if (host.rowRecycling && !this.state.rowPin.isPinned(this.data)) {\n let own = roots;\n if (!own) {\n own = new DetailRoots();\n detailRoots.set(host, own);\n }\n detail = own.show(this.data, content, host, this);\n own.schedule();\n } else {\n detail = keyed(this.data, content);\n }\n return html`<div\n part=\"detail-panel\"\n role=\"gridcell\"\n aria-colindex=\"1\"\n aria-colspan=${this.state.colCount}\n >\n <div role=\"region\" aria-label=${this.state.localize('row.detail')}>${detail}</div>\n </div>`;\n }\n\n protected renderSelectionCell(colindex: number) {\n const selection = this.state?.selection;\n if (!selection?.showCheckboxColumn) return nothing;\n // Shift extends a range from the anchor and Ctrl or Cmd toggles one row\n // without moving it (multiple mode only). Shared by the checkbox and the\n // cell around it, so both give the same result for the same gesture.\n // Returns false for a plain click, which the checkbox toggles itself.\n const modifierToggle = (event: MouseEvent): boolean => {\n if (selection.mode !== 'multiple') return false;\n if (event.shiftKey) {\n void selection.rangeToggle(this.data);\n } else if (event.ctrlKey || event.metaKey) {\n void selection.additiveToggle(this.data);\n } else {\n return false;\n }\n return true;\n };\n // The native `change` carries no modifier keys (they ride on the click\n // above), so it covers plain clicks and Space on a focused checkbox. The\n // click has already flipped `checked`; a `rowSelecting` listener that\n // cancels leaves the row as it was without a re-render, so write the\n // real state back once the selection has decided.\n const handleChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n const cell = input.parentElement;\n const focused =\n this.renderRoot instanceof ShadowRoot && this.renderRoot.activeElement === input;\n // The record clicked, captured before the await: by the time the\n // selection settles this row may show another record, whose state its\n // own render (the live `.checked` binding below) already wrote.\n const record = this.data;\n void selection.toggleRow(record).then(async () => {\n if (this.data === record) input.checked = selection.isSelected(record);\n // A rejected row that was still selected loses its checkbox once\n // deselected. Keep focus in its cell rather than letting it fall to\n // the body, where the grid's keys no longer reach.\n if (!focused || !cell) return;\n await this.updateComplete;\n if (input.isConnected) return;\n cell.tabIndex = -1;\n cell.addEventListener('blur', () => cell.removeAttribute('tabindex'), { once: true });\n cell.focus({ preventScroll: true });\n });\n };\n const handleClick = (event: MouseEvent) => {\n // Keeps checkbox clicks from bubbling to the cell's forwarder below and\n // to app click listeners on the grid (the grid's own body handler runs\n // in the capture phase and ignores this target).\n event.stopPropagation();\n // A modifier click is handled here, so cancel the native toggle.\n if (modifierToggle(event)) event.preventDefault();\n };\n // The checkbox itself is 14x14, well under the 24x24 WCAG 2.2 AA minimum\n // (2.5.8), and growing it would make a chunky box out of a deliberately\n // small mark. Instead the whole cell is the target: a click anywhere in it\n // acts like a click on the checkbox, modifiers included, which is both\n // compliant and what people expect of a selection column. Clicks that land\n // on the checkbox are left alone, or the forward would toggle twice and\n // cancel out.\n const forwardToCheckbox = (event: MouseEvent) => {\n if (event.target instanceof HTMLInputElement || modifierToggle(event)) return;\n (event.currentTarget as HTMLElement)\n .querySelector<HTMLInputElement>('input[type=\"checkbox\"]')\n ?.click();\n };\n // A row `isRowSelectable` rejects keeps the cell (the columns stay\n // aligned) but no control, as the controller refuses to select it; a\n // still-selected one keeps its checkbox so it can be deselected. `live`\n // checks against the box itself: a click flips it before the binding\n // knows, so a row re-bound in the same render to a record with the old\n // binding value would otherwise keep the clicked state.\n const checkbox =\n this.selected || selection.isSelectable(this.data)\n ? html`<input\n type=\"checkbox\"\n part=\"selection-checkbox\"\n aria-label=${this.state.localize('row.select')}\n .checked=${live(this.selected)}\n @click=${handleClick}\n @change=${handleChange}\n />`\n : nothing;\n return html`<div\n part=\"selection-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n @click=${forwardToCheckbox}\n >\n ${checkbox}\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\n part=${this.#presented.part ?? 'group-row'}\n role=\"gridcell\"\n aria-colindex=\"1\"\n aria-colspan=${Math.max(1, this.state.colCount)}\n tabindex=${this.activeNode?.row === this.index ? 0 : -1}\n data-presented-cell\n style=\"grid-column: 1 / -1\"\n >\n ${this.#presented.content}\n </div>`;\n }\n\n // A row index can transiently fall beyond the current data — e.g. while a\n // server-side / infinite row model resizes `data` on a filter or sort\n // change, the virtualizer may render a stale index for a frame. Render\n // nothing until the real item arrives, rather than dereferencing undefined.\n if (this.data == null) return nothing;\n\n const { column: key, row: index } = this.activeNode;\n\n // Track aria-colindex (1-based) across the auto chrome columns and the\n // data columns. Selection comes first, then expansion, then data.\n let colCursor = 0;\n const selectionCol = this.state?.selection.showCheckboxColumn ? ++colCursor : 0;\n const expansionCol = this.state?.expansion.showToggleColumn ? ++colCursor : 0;\n\n // Keyed by column.key so the same `<apex-grid-cell>` follows its\n // column through a reorder swap — required for the column-reorder FLIP\n // animation in ReorderController to track motion per cell.\n return html`\n ${this.renderRowNumber()}\n ${this.renderReorderHandle()}\n ${this.renderSelectionCell(selectionCol)}\n ${this.renderExpansionToggle(expansionCol)}\n ${repeat(\n this.columns,\n (column) => String(column.key),\n (column, colIndex) => {\n if (column.hidden) return nothing;\n const offset = this.pinOffsets.get(column.key);\n const pinStyle =\n column.pinned && typeof offset === 'number' ? `--apex-pin-offset:${offset}px` : '';\n const edge = getPinEdge(this.columns, colIndex);\n const editing = this.editingKey === column.key;\n const ariaColindex = ++colCursor;\n return html`<apex-grid-cell\n part=\"cell\"\n data-pinned=${column.pinned ?? 'none'}\n data-pin-edge=${edge ?? 'none'}\n data-cell-type=${column.type ?? 'string'}\n style=${pinStyle}\n .active=${key === column.key && index === this.index}\n .editing=${editing}\n .column=${column}\n .row=${this as ApexGridRow<T>}\n .record=${this.data}\n .value=${this.data[column.key]}\n .colindex=${ariaColindex}\n .rowIndex=${this.index}\n .decorationVersion=${this.decorationVersion}\n .dataVersion=${this.dataVersion}\n .validationVersion=${this.validationVersion}\n ></apex-grid-cell>`;\n }\n )}\n ${this.renderDetailPanel()}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridRow.tagName]: ApexGridRow<object>;\n }\n}\n"]}
@@ -2,7 +2,8 @@ import { LitElement, nothing } from 'lit';
2
2
  import { type StateController } from '../controllers/state.js';
3
3
  /**
4
4
  * Toolbar shown above the grid's header row. Hosts opt-in toolbar features
5
- * such as the quick-filter (global search) input and the export menu.
5
+ * such as the quick-filter (global search) input and the export menu. The grid
6
+ * re-exports every part, so `apex-grid::part(name)` styles it.
6
7
  *
7
8
  * @element apex-grid-toolbar
8
9
  *
@@ -13,7 +14,10 @@ import { type StateController } from '../controllers/state.js';
13
14
  * @csspart search-input - The text input itself.
14
15
  * @csspart toolbar-actions - The trailing actions area (right side).
15
16
  * @csspart toolbar-action - A custom host-contributed action button (e.g. "Create chart").
17
+ * @csspart export - The export menu wrapper (trigger plus dropdown).
16
18
  * @csspart export-trigger - The export menu trigger button.
19
+ * @csspart export-icon - The download icon in the trigger.
20
+ * @csspart export-caret - The caret icon in the trigger.
17
21
  * @csspart export-menu - The dropdown menu containing export options.
18
22
  * @csspart export-menu-item - A single menu item inside the export dropdown.
19
23
  */
@@ -138,11 +138,14 @@ export default class ApexGridToolbar extends LitElement {
138
138
  super.disconnectedCallback();
139
139
  }
140
140
  #emit(value) {
141
- this.dispatchEvent(new CustomEvent('apex-quick-filter', {
141
+ const applied = this.dispatchEvent(new CustomEvent('apex-quick-filter', {
142
142
  detail: value,
143
143
  bubbles: true,
144
144
  composed: true,
145
+ cancelable: true,
145
146
  }));
147
+ if (!applied && this.input)
148
+ this.input.value = this.value;
146
149
  }
147
150
  #handleInput;
148
151
  #handleKeydown;