apex-grid 3.1.0 → 3.3.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 (200) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/README.md +201 -53
  3. package/components/cell.d.ts +14 -1
  4. package/components/cell.js +48 -6
  5. package/components/cell.js.map +1 -1
  6. package/components/filter-row.d.ts +3 -6
  7. package/components/filter-row.js +79 -109
  8. package/components/filter-row.js.map +1 -1
  9. package/components/grid.d.ts +416 -70
  10. package/components/grid.js +398 -11
  11. package/components/grid.js.map +1 -1
  12. package/components/group-header-row.d.ts +34 -0
  13. package/components/group-header-row.js +125 -0
  14. package/components/group-header-row.js.map +1 -0
  15. package/components/header-row.d.ts +13 -2
  16. package/components/header-row.js +33 -18
  17. package/components/header-row.js.map +1 -1
  18. package/components/header.d.ts +11 -0
  19. package/components/header.js +136 -6
  20. package/components/header.js.map +1 -1
  21. package/components/paginator.d.ts +6 -1
  22. package/components/paginator.js +17 -11
  23. package/components/paginator.js.map +1 -1
  24. package/components/row.d.ts +28 -0
  25. package/components/row.js +100 -3
  26. package/components/row.js.map +1 -1
  27. package/components/toolbar.d.ts +8 -1
  28. package/components/toolbar.js +25 -7
  29. package/components/toolbar.js.map +1 -1
  30. package/controllers/data-operation.js +1 -0
  31. package/controllers/data-operation.js.map +1 -1
  32. package/controllers/dom.d.ts +24 -6
  33. package/controllers/dom.js +62 -5
  34. package/controllers/dom.js.map +1 -1
  35. package/controllers/editing.d.ts +68 -1
  36. package/controllers/editing.js +129 -44
  37. package/controllers/editing.js.map +1 -1
  38. package/controllers/filter.d.ts +1 -1
  39. package/controllers/filter.js +16 -5
  40. package/controllers/filter.js.map +1 -1
  41. package/controllers/history.d.ts +86 -0
  42. package/controllers/history.js +118 -0
  43. package/controllers/history.js.map +1 -0
  44. package/controllers/navigation.d.ts +15 -0
  45. package/controllers/navigation.js +53 -0
  46. package/controllers/navigation.js.map +1 -1
  47. package/controllers/reorder.js +3 -1
  48. package/controllers/reorder.js.map +1 -1
  49. package/controllers/row-pin.d.ts +59 -0
  50. package/controllers/row-pin.js +75 -0
  51. package/controllers/row-pin.js.map +1 -0
  52. package/controllers/row-reorder.d.ts +161 -0
  53. package/controllers/row-reorder.js +332 -0
  54. package/controllers/row-reorder.js.map +1 -0
  55. package/controllers/sort.d.ts +1 -1
  56. package/controllers/sort.js +11 -3
  57. package/controllers/sort.js.map +1 -1
  58. package/controllers/state.d.ts +33 -0
  59. package/controllers/state.js +37 -2
  60. package/controllers/state.js.map +1 -1
  61. package/controllers/tree.d.ts +8 -0
  62. package/controllers/tree.js +0 -0
  63. package/controllers/tree.js.map +1 -1
  64. package/custom-elements.json +4415 -875
  65. package/docs/assets/hierarchy.js +1 -1
  66. package/docs/assets/highlight.css +28 -0
  67. package/docs/assets/navigation.js +1 -1
  68. package/docs/assets/search.js +1 -1
  69. package/docs/functions/custom.html +3 -0
  70. package/docs/functions/interpolate.html +4 -0
  71. package/docs/functions/localize.html +8 -0
  72. package/docs/functions/max.html +3 -0
  73. package/docs/functions/min.html +3 -0
  74. package/docs/functions/pattern.html +3 -0
  75. package/docs/functions/required.html +3 -0
  76. package/docs/hierarchy.html +1 -1
  77. package/docs/index.html +185 -55
  78. package/docs/interfaces/ApexCellValidationFailedEvent.html +13 -0
  79. package/docs/interfaces/ApexCellValueChangedEvent.html +1 -1
  80. package/docs/interfaces/ApexCellValueChangingEvent.html +2 -2
  81. package/docs/interfaces/ApexColumnGroupContext.html +6 -0
  82. package/docs/interfaces/ApexColumnMovedEvent.html +2 -2
  83. package/docs/interfaces/ApexColumnMovingEvent.html +1 -1
  84. package/docs/interfaces/ApexDetailContext.html +2 -2
  85. package/docs/interfaces/ApexGridEventMap.html +37 -9
  86. package/docs/interfaces/ApexHistoryChangedEvent.html +6 -0
  87. package/docs/interfaces/ApexPageChangedEvent.html +1 -1
  88. package/docs/interfaces/ApexRowMovingEvent.html +9 -0
  89. package/docs/interfaces/ApexRowPinningEvent.html +8 -0
  90. package/docs/interfaces/ApexStateChangedEvent.html +4 -0
  91. package/docs/interfaces/BaseApexCellContext.html +1 -1
  92. package/docs/interfaces/BaseApexEditorContext.html +1 -1
  93. package/docs/interfaces/BaseColumnConfiguration.html +42 -17
  94. package/docs/interfaces/CSVExportOptions.html +2 -2
  95. package/docs/interfaces/ColumnGroupConfiguration.html +12 -0
  96. package/docs/interfaces/ColumnLayoutState.html +2 -0
  97. package/docs/interfaces/ColumnSchema.html +22 -0
  98. package/docs/interfaces/DataPipelineConfiguration.html +2 -2
  99. package/docs/interfaces/EditingHistoryConfiguration.html +10 -0
  100. package/docs/interfaces/ExportFormat.html +2 -2
  101. package/docs/interfaces/ExportOptions.html +1 -1
  102. package/docs/interfaces/FilterStateSnapshot.html +4 -0
  103. package/docs/interfaces/GetStateOptions.html +4 -0
  104. package/docs/interfaces/GridCapabilities.html +8 -0
  105. package/docs/interfaces/GridEditingConfiguration.html +4 -2
  106. package/docs/interfaces/GridRowPinningConfiguration.html +5 -0
  107. package/docs/interfaces/GridRowReorderingConfiguration.html +22 -0
  108. package/docs/interfaces/GridSchema.html +19 -0
  109. package/docs/interfaces/GridState.html +41 -0
  110. package/docs/interfaces/GridTreeConfiguration.html +2 -2
  111. package/docs/interfaces/PaginationConfiguration.html +1 -1
  112. package/docs/interfaces/PaginationState.html +1 -1
  113. package/docs/interfaces/SetStateOptions.html +9 -0
  114. package/docs/interfaces/SetStateResult.html +11 -0
  115. package/docs/interfaces/SortStateSnapshot.html +2 -0
  116. package/docs/interfaces/ValidatorContext.html +8 -0
  117. package/docs/media/_tokens.scss +131 -44
  118. package/docs/media/package.json +1 -1
  119. package/docs/media/state-persistence.html +189 -0
  120. package/docs/modules.html +1 -1
  121. package/docs/types/DataPipelineParams.html +2 -2
  122. package/docs/types/EditMode.html +2 -2
  123. package/docs/types/GridLocaleKey.html +3 -0
  124. package/docs/types/GridLocaleText.html +5 -0
  125. package/docs/types/LocaleParams.html +2 -0
  126. package/docs/types/PaginationMode.html +1 -1
  127. package/docs/types/RowDropPosition.html +2 -0
  128. package/docs/types/RowPinPosition.html +2 -0
  129. package/docs/types/RowRef.html +3 -0
  130. package/docs/types/Validator.html +4 -0
  131. package/docs/variables/EN_LOCALE.html +9 -0
  132. package/docs/variables/esLocale.html +8 -0
  133. package/i18n/en.d.ts +151 -0
  134. package/i18n/en.js +125 -0
  135. package/i18n/en.js.map +1 -0
  136. package/i18n/es.d.ts +18 -0
  137. package/i18n/es.js +125 -0
  138. package/i18n/es.js.map +1 -0
  139. package/i18n/index.d.ts +3 -0
  140. package/i18n/index.js +4 -0
  141. package/i18n/index.js.map +1 -0
  142. package/i18n/localize.d.ts +23 -0
  143. package/i18n/localize.js +15 -0
  144. package/i18n/localize.js.map +1 -0
  145. package/index.d.ts +8 -2
  146. package/index.js +2 -0
  147. package/index.js.map +1 -1
  148. package/internal/feature-module.d.ts +46 -0
  149. package/internal/feature-module.js +11 -0
  150. package/internal/feature-module.js.map +1 -1
  151. package/internal/flip.js +1 -1
  152. package/internal/flip.js.map +1 -1
  153. package/internal/icons.d.ts +9 -7
  154. package/internal/icons.js +75 -35
  155. package/internal/icons.js.map +1 -1
  156. package/internal/index.d.ts +5 -3
  157. package/internal/index.js +2 -1
  158. package/internal/index.js.map +1 -1
  159. package/internal/state-schema.d.ts +85 -0
  160. package/internal/state-schema.js +27 -0
  161. package/internal/state-schema.js.map +1 -0
  162. package/internal/state-snapshot.d.ts +152 -0
  163. package/internal/state-snapshot.js +115 -0
  164. package/internal/state-snapshot.js.map +1 -0
  165. package/internal/tags.d.ts +1 -0
  166. package/internal/tags.js +1 -0
  167. package/internal/tags.js.map +1 -1
  168. package/internal/types.d.ts +162 -2
  169. package/internal/types.js.map +1 -1
  170. package/internal/utils.d.ts +12 -0
  171. package/internal/utils.js +17 -0
  172. package/internal/utils.js.map +1 -1
  173. package/internal/validators.d.ts +31 -0
  174. package/internal/validators.js +44 -0
  175. package/internal/validators.js.map +1 -0
  176. package/package.json +1 -1
  177. package/styles/_tokens.css.js +1 -1
  178. package/styles/_tokens.css.js.map +1 -1
  179. package/styles/body-cell/body-cell.css.js +1 -1
  180. package/styles/body-cell/body-cell.css.js.map +1 -1
  181. package/styles/body-row/body-row.css.js +1 -1
  182. package/styles/body-row/body-row.css.js.map +1 -1
  183. package/styles/filter-row/filter-row.css.js +1 -1
  184. package/styles/filter-row/filter-row.css.js.map +1 -1
  185. package/styles/grid/_grid.base.css.js +1 -1
  186. package/styles/grid/_grid.base.css.js.map +1 -1
  187. package/styles/grid/grid.css.js +1 -1
  188. package/styles/grid/grid.css.js.map +1 -1
  189. package/styles/group-header-row/group-header-row.css.d.ts +1 -0
  190. package/styles/group-header-row/group-header-row.css.js +3 -0
  191. package/styles/group-header-row/group-header-row.css.js.map +1 -0
  192. package/styles/header-cell/header-cell.css.js +1 -1
  193. package/styles/header-cell/header-cell.css.js.map +1 -1
  194. package/styles/header-row/header-row.base.css.js +1 -1
  195. package/styles/header-row/header-row.base.css.js.map +1 -1
  196. package/styles/paginator/paginator.css.js +1 -1
  197. package/styles/paginator/paginator.css.js.map +1 -1
  198. package/styles/toolbar/toolbar.css.js +1 -1
  199. package/styles/toolbar/toolbar.css.js.map +1 -1
  200. package/docs/classes/ApexGrid.html +0 -393
@@ -1 +1 @@
1
- {"version":3,"file":"row.js","sourceRoot":"","sources":["../../src/components/row.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property, queryAll } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport type { PresentedRow } from '../internal/feature-module.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_ROW_TAG } from '../internal/tags.js';\nimport type { ActiveNode, ColumnConfiguration, Keys } from '../internal/types.js';\nimport { getPinEdge } from '../internal/utils.js';\nimport { styles } from '../styles/body-row/body-row.css.js';\nimport ApexGridCell from './cell.js';\n\n/**\n * Component representing the DOM row in the Apex grid.\n */\nexport default class ApexGridRow<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_ROW_TAG;\n }\n public static override styles = styles;\n\n public static register(): void {\n registerComponent(ApexGridRow, ApexGridCell);\n }\n\n @queryAll(ApexGridCell.tagName)\n protected _cells!: NodeListOf<ApexGridCell<T>>;\n\n @property({ attribute: false })\n public data!: T;\n\n @property({ attribute: false })\n public columns: Array<ColumnConfiguration<T>> = [];\n\n /** Cumulative pin offsets (px) keyed by column key. */\n @property({ attribute: false })\n public pinOffsets: Map<unknown, number> = new Map();\n\n public get cells() {\n return Array.from(this._cells);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n @property({ attribute: false })\n public activeNode!: ActiveNode<T>;\n\n @property({ attribute: false, type: Number })\n public index = -1;\n\n /** Reflects current selection state so SCSS can highlight the row. */\n @property({ type: Boolean, reflect: true })\n public selected = false;\n\n /** Reflects current expansion state so SCSS can rotate the chevron. */\n @property({ type: Boolean, reflect: true })\n public expanded = false;\n\n /** The column key currently being edited in this row, or `null`. */\n @property({ attribute: false })\n public editingKey: Keys<T> | null = null;\n\n /**\n * Reactive token from {@link StateController.decorationVersion}, forwarded to\n * each cell so a decoration-only change re-renders the row's cells. Stays `0`\n * for the community grid.\n */\n @property({ attribute: false, type: Number })\n public decorationVersion = 0;\n\n /**\n * Result of the feature-module row presenter for the current update, or\n * `null` when no module renders this row full-width (the normal case).\n * Computed in {@link willUpdate} and consumed in {@link render}.\n */\n #presented: PresentedRow | null = null;\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('exportparts', 'cell');\n this.setAttribute('role', 'row');\n }\n\n /**\n * The number of \"chrome\" rows (header + filter) above the body. Used to\n * derive `aria-rowindex` from {@link index}. Set by the parent grid.\n */\n @property({ attribute: false, type: Number })\n public ariaRowOffset = 1;\n\n protected override willUpdate() {\n this.setAttribute('aria-rowindex', String(this.index + this.ariaRowOffset + 1));\n\n // Ask feature modules whether this row is rendered full-width (e.g. an\n // enterprise group header). When one owns it, the row is not a selectable\n // data row — it carries its own level/expanded semantics and skips the\n // selection/tree aria below.\n this.#presented = this.state\n ? this.state.presentRow(this.data, { columns: this.columns, rowIndex: this.index })\n : null;\n if (this.#presented) {\n this.selected = false;\n this.removeAttribute('aria-selected');\n if (typeof this.#presented.level === 'number') {\n this.setAttribute('aria-level', String(this.#presented.level));\n } else {\n this.removeAttribute('aria-level');\n }\n if (typeof this.#presented.expanded === 'boolean') {\n this.setAttribute('aria-expanded', this.#presented.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n return;\n }\n\n this.selected = Boolean(this.state?.selection.isSelected(this.data));\n this.expanded = Boolean(this.state?.expansion.isExpanded(this.data));\n if (this.state?.selection.enabled) {\n this.setAttribute('aria-selected', this.selected ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-selected');\n }\n\n // Tree mode reports aria-level (1-based depth) and aria-expanded for\n // parent rows; expansion mode shares the same attribute on detail-panel\n // rows. Tree wins when both are enabled since it's the more structural\n // semantic (the row represents a tree node).\n const tree = this.state?.tree;\n const treeMeta = tree?.enabled ? tree.getMeta(this.data) : undefined;\n if (treeMeta) {\n this.setAttribute('aria-level', String(treeMeta.depth + 1));\n if (treeMeta.hasChildren) {\n this.setAttribute('aria-expanded', tree!.isExpanded(this.data) ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n } else {\n this.removeAttribute('aria-level');\n if (this.state?.expansion.enabled) {\n this.setAttribute('aria-expanded', this.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n }\n }\n\n protected renderExpansionToggle(colindex: number) {\n const expansion = this.state?.expansion;\n if (!expansion?.showToggleColumn) return nothing;\n const canExpand = expansion.canExpand(this.data) || expansion.isExpanded(this.data);\n const expanded = this.expanded;\n const handleClick = (event: MouseEvent) => {\n event.stopPropagation();\n if (!canExpand) return;\n void expansion.toggleRow(this.data);\n };\n return html`<div\n part=\"expansion-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <button\n type=\"button\"\n part=\"expansion-toggle\"\n aria-label=${expanded ? 'Collapse row' : 'Expand row'}\n aria-expanded=${expanded ? 'true' : 'false'}\n ?disabled=${!canExpand}\n @click=${handleClick}\n >\n <svg\n part=\"expansion-chevron\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n width=\"14\"\n height=\"14\"\n >\n <path\n d=\"M9 6l6 6-6 6\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>`;\n }\n\n protected renderDetailPanel() {\n const expansion = this.state?.expansion;\n if (!expansion?.isExpanded(this.data)) return nothing;\n const template = this.state.host.expansion?.detailTemplate;\n if (typeof template !== 'function') return nothing;\n const content = template({\n data: this.data,\n rowIndex: this.index,\n parent: this.state.host,\n });\n return html`<div part=\"detail-panel\" role=\"region\" aria-label=\"Row detail\">${content}</div>`;\n }\n\n protected renderSelectionCell(colindex: number) {\n if (!this.state?.selection.showCheckboxColumn) return nothing;\n const selected = this.selected;\n const handleChange = (event: Event) => {\n const mouseEvent = event as Event & {\n shiftKey?: boolean;\n ctrlKey?: boolean;\n metaKey?: boolean;\n };\n // The native `change` event on a checkbox doesn't expose modifier keys\n // — they're carried on the preceding `click`. We handle Shift/Ctrl in\n // the click listener below; the change handler covers keyboard toggles\n // (Space on a focused checkbox) which always behave as plain toggles.\n void mouseEvent;\n this.state.selection.toggleRow(this.data);\n };\n const handleClick = (event: MouseEvent) => {\n // Prevent the click from bubbling to the grid's body click handler\n // (which would otherwise re-target the active cell to a non-existent\n // selection column).\n event.stopPropagation();\n if (event.shiftKey && this.state.selection.mode === 'multiple') {\n event.preventDefault();\n void this.state.selection.rangeToggle(this.data);\n return;\n }\n if ((event.ctrlKey || event.metaKey) && this.state.selection.mode === 'multiple') {\n event.preventDefault();\n void this.state.selection.additiveToggle(this.data);\n return;\n }\n // Plain click: let the default checkbox toggle proceed; `change` will\n // commit the new state via `toggleRow`.\n };\n return html`<div\n part=\"selection-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <input\n type=\"checkbox\"\n part=\"selection-checkbox\"\n aria-label=\"Select row\"\n .checked=${selected}\n @click=${handleClick}\n @change=${handleChange}\n />\n </div>`;\n }\n\n protected override render() {\n // Full-width module-rendered row (e.g. a group header): render the module's\n // content spanning all columns, like the master-detail panel, and skip the\n // normal selection/expansion/cell grid.\n if (this.#presented) {\n return html`<div part=${this.#presented.part ?? 'group-row'} style=\"grid-column: 1 / -1\">\n ${this.#presented.content}\n </div>`;\n }\n\n // A row index can transiently fall beyond the current data — e.g. while a\n // server-side / infinite row model resizes `data` on a filter or sort\n // change, the virtualizer may render a stale index for a frame. Render\n // nothing until the real item arrives, rather than dereferencing undefined.\n if (this.data == null) return nothing;\n\n const { column: key, row: index } = this.activeNode;\n\n // Track aria-colindex (1-based) across the auto chrome columns and the\n // data columns. Selection comes first, then expansion, then data.\n let colCursor = 0;\n const selectionCol = this.state?.selection.showCheckboxColumn ? ++colCursor : 0;\n const expansionCol = this.state?.expansion.showToggleColumn ? ++colCursor : 0;\n\n // Keyed by column.key so the same `<apex-grid-cell>` follows its\n // column through a reorder swap — required for the column-reorder FLIP\n // animation in ReorderController to track motion per cell.\n return html`\n ${this.renderSelectionCell(selectionCol)}\n ${this.renderExpansionToggle(expansionCol)}\n ${repeat(\n this.columns,\n (column) => String(column.key),\n (column, colIndex) => {\n if (column.hidden) return nothing;\n const offset = this.pinOffsets.get(column.key);\n const pinStyle =\n column.pinned && typeof offset === 'number' ? `--apex-pin-offset:${offset}px` : '';\n const edge = getPinEdge(this.columns, colIndex);\n const editing = this.editingKey === column.key;\n const ariaColindex = ++colCursor;\n return html`<apex-grid-cell\n part=\"cell\"\n data-pinned=${column.pinned ?? 'none'}\n data-pin-edge=${edge ?? 'none'}\n data-cell-type=${column.type ?? 'string'}\n style=${pinStyle}\n .active=${key === column.key && index === this.index}\n .editing=${editing}\n .column=${column}\n .row=${this as ApexGridRow<T>}\n .value=${this.data[column.key]}\n .colindex=${ariaColindex}\n .decorationVersion=${this.decorationVersion}\n ></apex-grid-cell>`;\n }\n )}\n ${this.renderDetailPanel()}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridRow.tagName]: ApexGridRow<object>;\n }\n}\n"]}
1
+ {"version":3,"file":"row.js","sourceRoot":"","sources":["../../src/components/row.ts"],"names":[],"mappings":"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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 * Component representing the DOM row in the Apex grid.\n */\nexport default class ApexGridRow<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_ROW_TAG;\n }\n public static override styles = styles;\n\n public static register(): void {\n registerComponent(ApexGridRow, ApexGridCell);\n }\n\n @queryAll(ApexGridCell.tagName)\n protected _cells!: NodeListOf<ApexGridCell<T>>;\n\n @property({ attribute: false })\n public data!: T;\n\n @property({ attribute: false })\n public columns: Array<ColumnConfiguration<T>> = [];\n\n /** Cumulative pin offsets (px) keyed by column key. */\n @property({ attribute: false })\n public pinOffsets: Map<unknown, number> = new Map();\n\n public get cells() {\n return Array.from(this._cells);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n @property({ attribute: false })\n public activeNode!: ActiveNode<T>;\n\n @property({ attribute: false, type: Number })\n public index = -1;\n\n /** Reflects current selection state so SCSS can highlight the row. */\n @property({ type: Boolean, reflect: true })\n public selected = false;\n\n /** Reflects current expansion state so SCSS can rotate the chevron. */\n @property({ type: Boolean, reflect: true })\n public expanded = false;\n\n /** Reflects pointer-drag state (row reorder) so SCSS can dim the source. */\n @property({ type: Boolean, reflect: true })\n public dragging = false;\n\n /** Reflects keyboard-grab state (row reorder) so SCSS can outline the row. */\n @property({ type: Boolean, reflect: true })\n public grabbed = false;\n\n /** Reveal the spreadsheet row-number gutter cell (transient formula coordinate hint). */\n @property({ type: Boolean })\n public coordinateHints = false;\n\n /** The column key currently being edited in this row, or `null`. */\n @property({ attribute: false })\n public editingKey: Keys<T> | null = null;\n\n /**\n * Reactive token from {@link StateController.decorationVersion}, forwarded to\n * each cell so a decoration-only change re-renders the row's cells. Stays `0`\n * for the community grid.\n */\n @property({ attribute: false, type: Number })\n public decorationVersion = 0;\n\n /**\n * Reactive token from {@link EditingController.validationVersion}, forwarded to\n * each cell so a validation-only change re-renders the row's cells (toggling\n * `aria-invalid` and the inline error node). Stays `0` until the first\n * validation failure.\n */\n @property({ attribute: false, type: Number })\n public validationVersion = 0;\n\n /**\n * Result of the feature-module row presenter for the current update, or\n * `null` when no module renders this row full-width (the normal case).\n * Computed in {@link willUpdate} and consumed in {@link render}.\n */\n #presented: PresentedRow | null = null;\n\n #dragStartX = 0;\n #dragStartY = 0;\n\n /**\n * Arms a row drag. In handle mode only the grip starts one; in whole-row mode\n * a press anywhere except an interactive sub-part does. The move / up plumbing\n * lives on the grid host (see {@link RowReorderController.armPointerDrag}), so\n * a live-swap that recycles this row's DOM can't break the gesture.\n */\n #handleReorderPointerDown = (event: PointerEvent) => {\n const reorder = this.state?.rowReorder;\n if (!reorder?.enabled || event.button !== 0 || !this.data) return;\n // Pinned rows are not reorder sources (F4 scope).\n if (this.state.rowPin.isPinned(this.data)) return;\n\n const path = event.composedPath();\n const onHandle = path.some(\n (node) =>\n node instanceof Element && (node.getAttribute?.('part') ?? '').includes('reorder-handle')\n );\n\n if (reorder.handleMode) {\n // Handle mode: only the grip starts a drag. The rest of the row stays free\n // for selection / editing / text selection.\n if (!onHandle) return;\n // Own the gesture: keep the grid's body handler from treating the press as\n // a cell interaction, and suppress native text/element drag-selection.\n event.preventDefault();\n event.stopPropagation();\n } else {\n // Whole-row mode: a drag begins anywhere except an interactive sub-part\n // (editor, checkbox, button).\n const target = path[0];\n if (\n target instanceof Element &&\n target.closest?.('input, button, a, select, textarea, [data-apex-editor]')\n ) {\n return;\n }\n }\n\n this.#dragStartX = event.clientX;\n this.#dragStartY = event.clientY;\n // The controller snapshots the ghost the instant the drag engages (the row\n // is still in place then), seeded from the original press point.\n reorder.armPointerDrag(\n this.data,\n () => this.#captureGhost(this.#dragStartX, this.#dragStartY),\n event\n );\n };\n\n /**\n * Snapshots the row's visible cells (text, width, alignment) and bounding rect\n * so the controller can paint a faithful floating ghost. Invoked once, at the\n * moment the drag engages.\n */\n #captureGhost(clientX: number, clientY: number): RowGhostInit {\n const rect = this.getBoundingClientRect();\n const cells = this.cells.map((cell) => {\n const el = cell as unknown as HTMLElement;\n return {\n text: (el.textContent ?? '').replace(/\\s+/g, ' ').trim(),\n width: el.getBoundingClientRect().width,\n align: getComputedStyle(el).textAlign,\n };\n });\n return { rect, clientX, clientY, cells };\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('exportparts', 'cell');\n this.setAttribute('role', 'row');\n this.addEventListener('pointerdown', this.#handleReorderPointerDown);\n }\n\n public override disconnectedCallback(): void {\n this.removeEventListener('pointerdown', this.#handleReorderPointerDown);\n super.disconnectedCallback();\n }\n\n /**\n * The number of \"chrome\" rows (header + filter) above the body. Used to\n * derive `aria-rowindex` from {@link index}. Set by the parent grid.\n */\n @property({ attribute: false, type: Number })\n public ariaRowOffset = 1;\n\n protected override willUpdate() {\n this.setAttribute('aria-rowindex', String(this.index + this.ariaRowOffset + 1));\n\n // Ask feature modules whether this row is rendered full-width (e.g. an\n // enterprise group header). When one owns it, the row is not a selectable\n // data row — it carries its own level/expanded semantics and skips the\n // selection/tree aria below.\n this.#presented = this.state\n ? this.state.presentRow(this.data, { columns: this.columns, rowIndex: this.index })\n : null;\n if (this.#presented) {\n this.selected = false;\n this.removeAttribute('aria-selected');\n if (typeof this.#presented.level === 'number') {\n this.setAttribute('aria-level', String(this.#presented.level));\n } else {\n this.removeAttribute('aria-level');\n }\n if (typeof this.#presented.expanded === 'boolean') {\n this.setAttribute('aria-expanded', this.#presented.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n return;\n }\n\n this.selected = Boolean(this.state?.selection.isSelected(this.data));\n this.expanded = Boolean(this.state?.expansion.isExpanded(this.data));\n if (this.state?.selection.enabled) {\n this.setAttribute('aria-selected', this.selected ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-selected');\n }\n\n // Tree mode reports aria-level (1-based depth) and aria-expanded for\n // parent rows; expansion mode shares the same attribute on detail-panel\n // rows. Tree wins when both are enabled since it's the more structural\n // semantic (the row represents a tree node).\n const tree = this.state?.tree;\n const treeMeta = tree?.enabled ? tree.getMeta(this.data) : undefined;\n if (treeMeta) {\n this.setAttribute('aria-level', String(treeMeta.depth + 1));\n if (treeMeta.hasChildren) {\n this.setAttribute('aria-expanded', tree!.isExpanded(this.data) ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n } else {\n this.removeAttribute('aria-level');\n if (this.state?.expansion.enabled) {\n this.setAttribute('aria-expanded', this.expanded ? 'true' : 'false');\n } else {\n this.removeAttribute('aria-expanded');\n }\n }\n }\n\n /**\n * Leading row-number gutter cell (transient spreadsheet coordinate hint). Shown\n * only while `coordinateHints` is on; pinned rows render an empty spacer (their\n * band-local index is not a meaningful A1 row number) so the track stays\n * aligned. Presentational: the accessible row index is `aria-rowindex`.\n */\n protected renderRowNumber() {\n if (!this.coordinateHints) return nothing;\n const pinned = Boolean(this.state?.rowPin?.isPinned(this.data));\n return html`<div part=\"row-number-cell\" data-pinned=\"start\" aria-hidden=\"true\">\n ${pinned ? nothing : html`<span part=\"row-number\">${this.index + 1}</span>`}\n </div>`;\n }\n\n /**\n * Leading drag-handle (grip) cell. Rendered only in handle mode; pinned rows\n * get an empty spacer so the grid track stays aligned. The cell is\n * presentational (`aria-hidden`) — the accessible reorder path is the keyboard\n * grab flow, not this pointer affordance.\n */\n protected renderReorderHandle() {\n const reorder = this.state?.rowReorder;\n if (!reorder?.showHandleColumn) return nothing;\n const draggable = !this.state?.rowPin?.isPinned(this.data);\n return html`<div part=\"reorder-handle-cell\" data-pinned=\"start\" aria-hidden=\"true\">\n ${draggable ? html`<span part=\"reorder-handle\">${GRIP_ICON}</span>` : nothing}\n </div>`;\n }\n\n protected renderExpansionToggle(colindex: number) {\n const expansion = this.state?.expansion;\n if (!expansion?.showToggleColumn) return nothing;\n const canExpand = expansion.canExpand(this.data) || expansion.isExpanded(this.data);\n const expanded = this.expanded;\n const handleClick = (event: MouseEvent) => {\n event.stopPropagation();\n if (!canExpand) return;\n void expansion.toggleRow(this.data);\n };\n return html`<div\n part=\"expansion-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <button\n type=\"button\"\n part=\"expansion-toggle\"\n aria-label=${\n expanded ? this.state.localize('row.collapse') : this.state.localize('row.expand')\n }\n aria-expanded=${expanded ? 'true' : 'false'}\n ?disabled=${!canExpand}\n @click=${handleClick}\n >\n <svg\n part=\"expansion-chevron\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n width=\"14\"\n height=\"14\"\n >\n <path\n d=\"M9 6l6 6-6 6\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>`;\n }\n\n protected renderDetailPanel() {\n const expansion = this.state?.expansion;\n if (!expansion?.isExpanded(this.data)) return nothing;\n const template = this.state.host.expansion?.detailTemplate;\n if (typeof template !== 'function') return nothing;\n const content = template({\n data: this.data,\n rowIndex: this.index,\n parent: this.state.host,\n });\n return html`<div part=\"detail-panel\" role=\"region\" aria-label=${this.state.localize('row.detail')}>${content}</div>`;\n }\n\n protected renderSelectionCell(colindex: number) {\n if (!this.state?.selection.showCheckboxColumn) return nothing;\n const selected = this.selected;\n const handleChange = (event: Event) => {\n const mouseEvent = event as Event & {\n shiftKey?: boolean;\n ctrlKey?: boolean;\n metaKey?: boolean;\n };\n // The native `change` event on a checkbox doesn't expose modifier keys\n // — they're carried on the preceding `click`. We handle Shift/Ctrl in\n // the click listener below; the change handler covers keyboard toggles\n // (Space on a focused checkbox) which always behave as plain toggles.\n void mouseEvent;\n this.state.selection.toggleRow(this.data);\n };\n const handleClick = (event: MouseEvent) => {\n // Prevent the click from bubbling to the grid's body click handler\n // (which would otherwise re-target the active cell to a non-existent\n // selection column).\n event.stopPropagation();\n if (event.shiftKey && this.state.selection.mode === 'multiple') {\n event.preventDefault();\n void this.state.selection.rangeToggle(this.data);\n return;\n }\n if ((event.ctrlKey || event.metaKey) && this.state.selection.mode === 'multiple') {\n event.preventDefault();\n void this.state.selection.additiveToggle(this.data);\n return;\n }\n // Plain click: let the default checkbox toggle proceed; `change` will\n // commit the new state via `toggleRow`.\n };\n return html`<div\n part=\"selection-cell\"\n role=\"gridcell\"\n aria-colindex=${colindex}\n data-pinned=\"start\"\n >\n <input\n type=\"checkbox\"\n part=\"selection-checkbox\"\n aria-label=${this.state.localize('row.select')}\n .checked=${selected}\n @click=${handleClick}\n @change=${handleChange}\n />\n </div>`;\n }\n\n protected override render() {\n // Full-width module-rendered row (e.g. a group header): render the module's\n // content spanning all columns, like the master-detail panel, and skip the\n // normal selection/expansion/cell grid.\n if (this.#presented) {\n return html`<div part=${this.#presented.part ?? 'group-row'} style=\"grid-column: 1 / -1\">\n ${this.#presented.content}\n </div>`;\n }\n\n // A row index can transiently fall beyond the current data — e.g. while a\n // server-side / infinite row model resizes `data` on a filter or sort\n // change, the virtualizer may render a stale index for a frame. Render\n // nothing until the real item arrives, rather than dereferencing undefined.\n if (this.data == null) return nothing;\n\n const { column: key, row: index } = this.activeNode;\n\n // Track aria-colindex (1-based) across the auto chrome columns and the\n // data columns. Selection comes first, then expansion, then data.\n let colCursor = 0;\n const selectionCol = this.state?.selection.showCheckboxColumn ? ++colCursor : 0;\n const expansionCol = this.state?.expansion.showToggleColumn ? ++colCursor : 0;\n\n // Keyed by column.key so the same `<apex-grid-cell>` follows its\n // column through a reorder swap — required for the column-reorder FLIP\n // animation in ReorderController to track motion per cell.\n return html`\n ${this.renderRowNumber()}\n ${this.renderReorderHandle()}\n ${this.renderSelectionCell(selectionCol)}\n ${this.renderExpansionToggle(expansionCol)}\n ${repeat(\n this.columns,\n (column) => String(column.key),\n (column, colIndex) => {\n if (column.hidden) return nothing;\n const offset = this.pinOffsets.get(column.key);\n const pinStyle =\n column.pinned && typeof offset === 'number' ? `--apex-pin-offset:${offset}px` : '';\n const edge = getPinEdge(this.columns, colIndex);\n const editing = this.editingKey === column.key;\n const ariaColindex = ++colCursor;\n return html`<apex-grid-cell\n part=\"cell\"\n data-pinned=${column.pinned ?? 'none'}\n data-pin-edge=${edge ?? 'none'}\n data-cell-type=${column.type ?? 'string'}\n style=${pinStyle}\n .active=${key === column.key && index === this.index}\n .editing=${editing}\n .column=${column}\n .row=${this as ApexGridRow<T>}\n .value=${this.data[column.key]}\n .colindex=${ariaColindex}\n .decorationVersion=${this.decorationVersion}\n .validationVersion=${this.validationVersion}\n ></apex-grid-cell>`;\n }\n )}\n ${this.renderDetailPanel()}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridRow.tagName]: ApexGridRow<object>;\n }\n}\n"]}
@@ -12,6 +12,7 @@ import { type StateController } from '../controllers/state.js';
12
12
  * @csspart search-icon - The leading search icon.
13
13
  * @csspart search-input - The text input itself.
14
14
  * @csspart toolbar-actions - The trailing actions area (right side).
15
+ * @csspart toolbar-action - A custom host-contributed action button (e.g. "Create chart").
15
16
  * @csspart export-trigger - The export menu trigger button.
16
17
  * @csspart export-menu - The dropdown menu containing export options.
17
18
  * @csspart export-menu-item - A single menu item inside the export dropdown.
@@ -31,8 +32,13 @@ export default class ApexGridToolbar<T extends object> extends LitElement {
31
32
  value: string;
32
33
  /**
33
34
  * The placeholder rendered in the search input.
35
+ *
36
+ * @remarks
37
+ * When unset, falls back to the grid's localized `toolbar.searchPlaceholder`
38
+ * text (see {@link ApexGrid.localeText}).
34
39
  */
35
40
  placeholder: string;
41
+ protected get searchPlaceholder(): string;
36
42
  /**
37
43
  * Debounce window (ms) before {@link ApexGrid.quickFilter} updates.
38
44
  */
@@ -51,7 +57,8 @@ export default class ApexGridToolbar<T extends object> extends LitElement {
51
57
  disconnectedCallback(): void;
52
58
  protected renderQuickFilter(): import("lit-html").TemplateResult<1> | typeof nothing;
53
59
  protected renderExportMenu(): import("lit-html").TemplateResult<1> | typeof nothing;
54
- protected render(): import("lit-html").TemplateResult<1>;
60
+ protected renderToolbarActions(): import("lit-html").TemplateResult<1> | typeof nothing;
61
+ protected render(): import("lit-html").TemplateResult<1> | typeof nothing;
55
62
  }
56
63
  declare global {
57
64
  interface HTMLElementTagNameMap {
@@ -16,7 +16,7 @@ export default class ApexGridToolbar extends LitElement {
16
16
  constructor() {
17
17
  super(...arguments);
18
18
  this.value = '';
19
- this.placeholder = 'Search…';
19
+ this.placeholder = '';
20
20
  this.debounce = 200;
21
21
  this.showQuickFilter = true;
22
22
  this.showExport = false;
@@ -118,6 +118,9 @@ export default class ApexGridToolbar extends LitElement {
118
118
  static register() {
119
119
  registerComponent(ApexGridToolbar);
120
120
  }
121
+ get searchPlaceholder() {
122
+ return this.placeholder || this.state?.localize('toolbar.searchPlaceholder') || 'Search…';
123
+ }
121
124
  #debounceHandle;
122
125
  connectedCallback() {
123
126
  super.connectedCallback();
@@ -166,8 +169,8 @@ export default class ApexGridToolbar extends LitElement {
166
169
  part="search-input"
167
170
  type="search"
168
171
  role="searchbox"
169
- aria-label=${this.placeholder}
170
- placeholder=${this.placeholder}
172
+ aria-label=${this.searchPlaceholder}
173
+ placeholder=${this.searchPlaceholder}
171
174
  .value=${this.value}
172
175
  @input=${this.#handleInput}
173
176
  @keydown=${this.#handleKeydown}
@@ -183,7 +186,7 @@ export default class ApexGridToolbar extends LitElement {
183
186
  <button
184
187
  type="button"
185
188
  part="export-trigger"
186
- aria-label="Export"
189
+ aria-label=${this.state.localize('toolbar.export')}
187
190
  aria-haspopup="menu"
188
191
  aria-expanded=${open ? 'true' : 'false'}
189
192
  @click=${this.#toggleExportMenu}
@@ -195,7 +198,7 @@ export default class ApexGridToolbar extends LitElement {
195
198
  <ul
196
199
  part="export-menu"
197
200
  role="menu"
198
- aria-label="Export options"
201
+ aria-label=${this.state.localize('toolbar.exportOptions')}
199
202
  ?hidden=${!open}
200
203
  @keydown=${this.#handleMenuKeydown}
201
204
  >
@@ -213,11 +216,26 @@ export default class ApexGridToolbar extends LitElement {
213
216
  </ul>
214
217
  </div>`;
215
218
  }
219
+ renderToolbarActions() {
220
+ const actions = this.state?.host?.toolbarActions ?? [];
221
+ if (!actions.length)
222
+ return nothing;
223
+ return html `${actions.map((action) => html `<button
224
+ type="button"
225
+ part="toolbar-action"
226
+ data-action-id=${action.id ?? ''}
227
+ @click=${() => action.run()}
228
+ >
229
+ ${action.label}
230
+ </button>`)}`;
231
+ }
216
232
  render() {
233
+ if (!this.state)
234
+ return nothing;
217
235
  return html `
218
- <div part="toolbar" role="toolbar" aria-label="Grid toolbar">
236
+ <div part="toolbar" role="toolbar" aria-label=${this.state.localize('toolbar.label')}>
219
237
  ${this.renderQuickFilter()}
220
- <div part="toolbar-actions">${this.renderExportMenu()}</div>
238
+ <div part="toolbar-actions">${this.renderToolbarActions()}${this.renderExportMenu()}</div>
221
239
  </div>
222
240
  `;
223
241
  }
@@ -1 +1 @@
1
- {"version":3,"file":"toolbar.js","sourceRoot":"","sources":["../../src/components/toolbar.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAwB,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAkB1D,MAAM,CAAC,OAAO,OAAO,eAAkC,SAAQ,UAAU;IAAzE;;QAsBS,UAAK,GAAG,EAAE,CAAC;QAMX,gBAAW,GAAG,SAAS,CAAC;QAMxB,aAAQ,GAAG,GAAG,CAAC;QAIf,oBAAe,GAAG,IAAI,CAAC;QAIvB,eAAU,GAAG,KAAK,CAAC;QAInB,mBAAc,GAAG,MAAM,CAAC;QAYrB,mBAAc,GAAG,KAAK,CAAC;QAEjC,oBAAe,GAAyC,IAAI,CAAC;QA4B7D,iBAAY,GAAG,CAAC,KAAY,EAAE,EAAE;YAC9B,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,MAAM,IAAI,GAAI,KAAK,CAAC,MAA2B,CAAC,KAAK,IAAI,EAAE,CAAC;YAC5D,IAAI,IAAI,CAAC,eAAe;gBAAE,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAE7D,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC;gBACvB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjB,OAAO;YACT,CAAC;YAED,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC,GAAG,EAAE;gBACrC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpB,CAAC,CAAC;QAEF,mBAAc,GAAG,CAAC,KAAoB,EAAE,EAAE;YAExC,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC/C,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;gBACtB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;oBACzB,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;oBACnC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC9B,CAAC;gBACD,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC;QACH,CAAC,CAAC;QAEF,sBAAiB,GAAG,CAAC,KAAa,EAAE,EAAE;YACpC,KAAK,EAAE,eAAe,EAAE,CAAC;YACzB,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC;QAC7C,CAAC,CAAC;QAWF,0BAAqB,GAAG,CAAC,KAAmB,EAAE,EAAE;YAC9C,IAAI,CAAC,IAAI,CAAC,cAAc;gBAAE,OAAO;YACjC,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC;gBAAE,OAAO;YAClF,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,CAAC,CAAC;QAEF,uBAAkB,GAAG,CAAC,KAAoB,EAAE,EAAE;YAC5C,IAAI,CAAC,IAAI,CAAC,cAAc;gBAAE,OAAO;YACjC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC3B,KAAK,CAAC,eAAe,EAAE,CAAC;gBACxB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC,CAAC;QAEF,kBAAa,GAAG,CAAC,QAAgB,EAAE,EAAE;YACnC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC;YAC9B,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;QAC7D,CAAC,CAAC;QAGF,0BAAqB,GAAG,CAAC,KAAoB,EAAE,EAAE;YAC/C,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;gBACtD,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,cAAc;oBAAE,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBACrD,qBAAqB,CAAC,GAAG,EAAE;oBACzB,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,aAAa,CAAc,mBAAmB,CAAC,CAAC;oBACjF,KAAK,EAAE,KAAK,EAAE,CAAC;gBACjB,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC;QAEF,uBAAkB,GAAG,CAAC,KAAoB,EAAE,EAAE;YAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CACtB,IAAI,CAAC,YAAY,EAAE,gBAAgB,CAAc,mBAAmB,CAAC,IAAI,EAAE,CAC5E,CAAC;YACF,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,aAA4B,CAAC,CAAC;YACrE,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;gBACtD,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;YAC/C,CAAC;iBAAM,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;gBACzD,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,CAAC,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;YAC9D,CAAC;iBAAM,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;gBAChC,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;YACpB,CAAC;iBAAM,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;gBAC/B,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;YACnC,CAAC;iBAAM,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;gBAE/B,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC;IAqEJ,CAAC;IA/PQ,MAAM,KAAK,OAAO;QACvB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;aAEsB,WAAM,GAAG,MAAM,AAAT,CAAU;IAKhC,MAAM,CAAC,QAAQ;QACpB,iBAAiB,CAAC,eAAe,CAAC,CAAC;IACrC,CAAC;IAgDD,eAAe,CAA8C;IAE7C,iBAAiB;QAC/B,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;QAC3E,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;IACtE,CAAC;IAEe,oBAAoB;QAClC,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;QAC9E,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QACvE,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACnC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,KAAK,CAAC,oBAAoB,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,KAAa;QACjB,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAS,mBAAmB,EAAE;YAC3C,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;SACf,CAAC,CACH,CAAC;IACJ,CAAC;IAED,YAAY,CAcV;IAEF,cAAc,CAYZ;IAEF,iBAAiB,CAGf;IAEF,gBAAgB,CAAC,WAAW,GAAG,KAAK;QAClC,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO;QACjC,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,WAAW,EAAE,CAAC;YAEhB,qBAAqB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,qBAAqB,CAKnB;IAEF,kBAAkB,CAMhB;IAEF,aAAa,CAKX;IAGF,qBAAqB,CASnB;IAEF,kBAAkB,CAqBhB;IAEQ,iBAAiB;QACzB,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO,OAAO,CAAC;QAC1C,OAAO,IAAI,CAAA;;UAEL,UAAU,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;;;;;uBAKhC,IAAI,CAAC,WAAW;wBACf,IAAI,CAAC,WAAW;mBACrB,IAAI,CAAC,KAAK;mBACV,IAAI,CAAC,YAAY;qBACf,IAAI,CAAC,cAAc;;;WAG7B,CAAC;IACV,CAAC;IAES,gBAAgB;QACxB,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO,OAAO,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC;QACjC,OAAO,IAAI,CAAA;;;;;;wBAMS,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;iBAC9B,IAAI,CAAC,iBAAiB;mBACpB,IAAI,CAAC,qBAAqB;;UAEnC,UAAU,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;UAC/C,UAAU,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;;;;;;kBAM5C,CAAC,IAAI;mBACJ,IAAI,CAAC,kBAAkB;;UAEhC,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC,GAAG,CAC3C,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAA;;;;;;uBAMH,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;;gBAE1C,MAAM,CAAC,KAAK;;gBAEZ,CACP;;WAEE,CAAC;IACV,CAAC;IAEkB,MAAM;QACvB,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,iBAAiB,EAAE;sCACI,IAAI,CAAC,gBAAgB,EAAE;;KAExD,CAAC;IACJ,CAAC;;AA/OM;IAFN,OAAO,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACvD,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;8CACG;AAM3B;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CACT;AAMX;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oDACI;AAMxB;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;iDAC5B;AAIf;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;wDAChB;AAIvB;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;mDACpB;AAInB;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uDACd;AAGrB;IADT,KAAK,CAAC,OAAO,CAAC;8CACoB;AAGzB;IADT,KAAK,CAAC,yBAAyB,CAAC;sDACW;AAGlC;IADT,KAAK,CAAC,sBAAsB,CAAC;qDACO;AAG3B;IADT,KAAK,EAAE;uDACyB","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { renderIcon } from '../internal/icons.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_TOOLBAR_TAG } from '../internal/tags.js';\nimport { styles } from '../styles/toolbar/toolbar.css.js';\n\n/**\n * Toolbar shown above the grid's header row. Hosts opt-in toolbar features\n * such as the quick-filter (global search) input and the export menu.\n *\n * @element apex-grid-toolbar\n *\n * @csspart toolbar - The toolbar's container element.\n * @csspart toolbar-search - The quick-filter input wrapper.\n * @csspart search-field - The bordered field containing the icon + input.\n * @csspart search-icon - The leading search icon.\n * @csspart search-input - The text input itself.\n * @csspart toolbar-actions - The trailing actions area (right side).\n * @csspart export-trigger - The export menu trigger button.\n * @csspart export-menu - The dropdown menu containing export options.\n * @csspart export-menu-item - A single menu item inside the export dropdown.\n */\nexport default class ApexGridToolbar<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_TOOLBAR_TAG;\n }\n\n public static override styles = styles;\n\n /**\n * Registers the `<apex-grid-toolbar>` element. Idempotent.\n */\n public static register() {\n registerComponent(ApexGridToolbar);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n /**\n * The current quick-filter value, mirrored from {@link ApexGrid.quickFilter}.\n */\n @property({ type: String })\n public value = '';\n\n /**\n * The placeholder rendered in the search input.\n */\n @property({ type: String })\n public placeholder = 'Search…';\n\n /**\n * Debounce window (ms) before {@link ApexGrid.quickFilter} updates.\n */\n @property({ type: Number, attribute: 'debounce' })\n public debounce = 200;\n\n /** Whether to render the quick-filter input. Driven by the parent grid. */\n @property({ attribute: false, type: Boolean })\n public showQuickFilter = true;\n\n /** Whether to render the export menu trigger. Driven by the parent grid. */\n @property({ attribute: false, type: Boolean })\n public showExport = false;\n\n /** Optional override filename (without extension) for exports. */\n @property({ attribute: false, type: String })\n public exportFilename = 'data';\n\n @query('input')\n protected input!: HTMLInputElement;\n\n @query('[part=\"export-trigger\"]')\n protected exportTrigger!: HTMLButtonElement;\n\n @query('[part=\"export-menu\"]')\n protected exportMenuEl!: HTMLElement;\n\n @state()\n protected exportMenuOpen = false;\n\n #debounceHandle: ReturnType<typeof setTimeout> | null = null;\n\n public override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('pointerdown', this.#handleOutsidePointer, true);\n document.addEventListener('keydown', this.#handleDocumentKey, true);\n }\n\n public override disconnectedCallback(): void {\n document.removeEventListener('pointerdown', this.#handleOutsidePointer, true);\n document.removeEventListener('keydown', this.#handleDocumentKey, true);\n if (this.#debounceHandle) {\n clearTimeout(this.#debounceHandle);\n this.#debounceHandle = null;\n }\n super.disconnectedCallback();\n }\n\n #emit(value: string) {\n this.dispatchEvent(\n new CustomEvent<string>('apex-quick-filter', {\n detail: value,\n bubbles: true,\n composed: true,\n })\n );\n }\n\n #handleInput = (event: Event) => {\n event.stopPropagation();\n const next = (event.target as HTMLInputElement).value ?? '';\n if (this.#debounceHandle) clearTimeout(this.#debounceHandle);\n\n if (this.debounce <= 0) {\n this.#emit(next);\n return;\n }\n\n this.#debounceHandle = setTimeout(() => {\n this.#debounceHandle = null;\n this.#emit(next);\n }, this.debounce);\n };\n\n #handleKeydown = (event: KeyboardEvent) => {\n // Don't let arrow keys bubble into the grid navigation controller.\n event.stopPropagation();\n if (event.key === 'Escape' && this.input.value) {\n event.preventDefault();\n this.input.value = '';\n if (this.#debounceHandle) {\n clearTimeout(this.#debounceHandle);\n this.#debounceHandle = null;\n }\n this.#emit('');\n }\n };\n\n #toggleExportMenu = (event?: Event) => {\n event?.stopPropagation();\n this.exportMenuOpen = !this.exportMenuOpen;\n };\n\n #closeExportMenu(returnFocus = false) {\n if (!this.exportMenuOpen) return;\n this.exportMenuOpen = false;\n if (returnFocus) {\n // Return focus to the trigger so keyboard users don't lose their place.\n requestAnimationFrame(() => this.exportTrigger?.focus());\n }\n }\n\n #handleOutsidePointer = (event: PointerEvent) => {\n if (!this.exportMenuOpen) return;\n const path = event.composedPath();\n if (path.includes(this.exportTrigger) || path.includes(this.exportMenuEl)) return;\n this.#closeExportMenu();\n };\n\n #handleDocumentKey = (event: KeyboardEvent) => {\n if (!this.exportMenuOpen) return;\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.#closeExportMenu(true);\n }\n };\n\n #handleExport = (formatId: string) => {\n this.#closeExportMenu();\n const grid = this.state?.host;\n if (!grid) return;\n grid.exportAs(formatId, { filename: this.exportFilename });\n };\n\n /** Lets keyboard users land in the menu when it opens via arrow-down. */\n #handleTriggerKeydown = (event: KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault();\n if (!this.exportMenuOpen) this.exportMenuOpen = true;\n requestAnimationFrame(() => {\n const first = this.exportMenuEl?.querySelector<HTMLElement>('[role=\"menuitem\"]');\n first?.focus();\n });\n }\n };\n\n #handleMenuKeydown = (event: KeyboardEvent) => {\n const items = Array.from(\n this.exportMenuEl?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]') ?? []\n );\n const current = items.indexOf(document.activeElement as HTMLElement);\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault();\n items[(current + 1) % items.length]?.focus();\n } else if (event.key === 'ArrowUp' || event.key === 'Up') {\n event.preventDefault();\n items[(current - 1 + items.length) % items.length]?.focus();\n } else if (event.key === 'Home') {\n event.preventDefault();\n items[0]?.focus();\n } else if (event.key === 'End') {\n event.preventDefault();\n items[items.length - 1]?.focus();\n } else if (event.key === 'Tab') {\n // Tab closes the menu so focus moves naturally to the next focusable.\n this.#closeExportMenu();\n }\n };\n\n protected renderQuickFilter() {\n if (!this.showQuickFilter) return nothing;\n return html`<div part=\"toolbar-search\">\n <label part=\"search-field\">\n ${renderIcon('search', { part: 'search-icon' })}\n <input\n part=\"search-input\"\n type=\"search\"\n role=\"searchbox\"\n aria-label=${this.placeholder}\n placeholder=${this.placeholder}\n .value=${this.value}\n @input=${this.#handleInput}\n @keydown=${this.#handleKeydown}\n />\n </label>\n </div>`;\n }\n\n protected renderExportMenu() {\n if (!this.showExport) return nothing;\n const open = this.exportMenuOpen;\n return html`<div part=\"export\">\n <button\n type=\"button\"\n part=\"export-trigger\"\n aria-label=\"Export\"\n aria-haspopup=\"menu\"\n aria-expanded=${open ? 'true' : 'false'}\n @click=${this.#toggleExportMenu}\n @keydown=${this.#handleTriggerKeydown}\n >\n ${renderIcon('download', { part: 'export-icon' })}\n ${renderIcon('chevron-down', { part: 'export-caret' })}\n </button>\n <ul\n part=\"export-menu\"\n role=\"menu\"\n aria-label=\"Export options\"\n ?hidden=${!open}\n @keydown=${this.#handleMenuKeydown}\n >\n ${(this.state?.host?.exportFormats ?? []).map(\n (format) => html`<li role=\"none\">\n <button\n type=\"button\"\n role=\"menuitem\"\n part=\"export-menu-item\"\n tabindex=\"-1\"\n @click=${() => this.#handleExport(format.id)}\n >\n ${format.label}\n </button>\n </li>`\n )}\n </ul>\n </div>`;\n }\n\n protected override render() {\n return html`\n <div part=\"toolbar\" role=\"toolbar\" aria-label=\"Grid toolbar\">\n ${this.renderQuickFilter()}\n <div part=\"toolbar-actions\">${this.renderExportMenu()}</div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridToolbar.tagName]: ApexGridToolbar<object>;\n }\n}\n"]}
1
+ {"version":3,"file":"toolbar.js","sourceRoot":"","sources":["../../src/components/toolbar.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { renderIcon } from '../internal/icons.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_TOOLBAR_TAG } from '../internal/tags.js';\nimport { styles } from '../styles/toolbar/toolbar.css.js';\n\n/**\n * Toolbar shown above the grid's header row. Hosts opt-in toolbar features\n * such as the quick-filter (global search) input and the export menu.\n *\n * @element apex-grid-toolbar\n *\n * @csspart toolbar - The toolbar's container element.\n * @csspart toolbar-search - The quick-filter input wrapper.\n * @csspart search-field - The bordered field containing the icon + input.\n * @csspart search-icon - The leading search icon.\n * @csspart search-input - The text input itself.\n * @csspart toolbar-actions - The trailing actions area (right side).\n * @csspart toolbar-action - A custom host-contributed action button (e.g. \"Create chart\").\n * @csspart export-trigger - The export menu trigger button.\n * @csspart export-menu - The dropdown menu containing export options.\n * @csspart export-menu-item - A single menu item inside the export dropdown.\n */\nexport default class ApexGridToolbar<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_TOOLBAR_TAG;\n }\n\n public static override styles = styles;\n\n /**\n * Registers the `<apex-grid-toolbar>` element. Idempotent.\n */\n public static register() {\n registerComponent(ApexGridToolbar);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n /**\n * The current quick-filter value, mirrored from {@link ApexGrid.quickFilter}.\n */\n @property({ type: String })\n public value = '';\n\n /**\n * The placeholder rendered in the search input.\n *\n * @remarks\n * When unset, falls back to the grid's localized `toolbar.searchPlaceholder`\n * text (see {@link ApexGrid.localeText}).\n */\n @property({ type: String })\n public placeholder = '';\n\n protected get searchPlaceholder() {\n return this.placeholder || this.state?.localize('toolbar.searchPlaceholder') || 'Search…';\n }\n\n /**\n * Debounce window (ms) before {@link ApexGrid.quickFilter} updates.\n */\n @property({ type: Number, attribute: 'debounce' })\n public debounce = 200;\n\n /** Whether to render the quick-filter input. Driven by the parent grid. */\n @property({ attribute: false, type: Boolean })\n public showQuickFilter = true;\n\n /** Whether to render the export menu trigger. Driven by the parent grid. */\n @property({ attribute: false, type: Boolean })\n public showExport = false;\n\n /** Optional override filename (without extension) for exports. */\n @property({ attribute: false, type: String })\n public exportFilename = 'data';\n\n @query('input')\n protected input!: HTMLInputElement;\n\n @query('[part=\"export-trigger\"]')\n protected exportTrigger!: HTMLButtonElement;\n\n @query('[part=\"export-menu\"]')\n protected exportMenuEl!: HTMLElement;\n\n @state()\n protected exportMenuOpen = false;\n\n #debounceHandle: ReturnType<typeof setTimeout> | null = null;\n\n public override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('pointerdown', this.#handleOutsidePointer, true);\n document.addEventListener('keydown', this.#handleDocumentKey, true);\n }\n\n public override disconnectedCallback(): void {\n document.removeEventListener('pointerdown', this.#handleOutsidePointer, true);\n document.removeEventListener('keydown', this.#handleDocumentKey, true);\n if (this.#debounceHandle) {\n clearTimeout(this.#debounceHandle);\n this.#debounceHandle = null;\n }\n super.disconnectedCallback();\n }\n\n #emit(value: string) {\n this.dispatchEvent(\n new CustomEvent<string>('apex-quick-filter', {\n detail: value,\n bubbles: true,\n composed: true,\n })\n );\n }\n\n #handleInput = (event: Event) => {\n event.stopPropagation();\n const next = (event.target as HTMLInputElement).value ?? '';\n if (this.#debounceHandle) clearTimeout(this.#debounceHandle);\n\n if (this.debounce <= 0) {\n this.#emit(next);\n return;\n }\n\n this.#debounceHandle = setTimeout(() => {\n this.#debounceHandle = null;\n this.#emit(next);\n }, this.debounce);\n };\n\n #handleKeydown = (event: KeyboardEvent) => {\n // Don't let arrow keys bubble into the grid navigation controller.\n event.stopPropagation();\n if (event.key === 'Escape' && this.input.value) {\n event.preventDefault();\n this.input.value = '';\n if (this.#debounceHandle) {\n clearTimeout(this.#debounceHandle);\n this.#debounceHandle = null;\n }\n this.#emit('');\n }\n };\n\n #toggleExportMenu = (event?: Event) => {\n event?.stopPropagation();\n this.exportMenuOpen = !this.exportMenuOpen;\n };\n\n #closeExportMenu(returnFocus = false) {\n if (!this.exportMenuOpen) return;\n this.exportMenuOpen = false;\n if (returnFocus) {\n // Return focus to the trigger so keyboard users don't lose their place.\n requestAnimationFrame(() => this.exportTrigger?.focus());\n }\n }\n\n #handleOutsidePointer = (event: PointerEvent) => {\n if (!this.exportMenuOpen) return;\n const path = event.composedPath();\n if (path.includes(this.exportTrigger) || path.includes(this.exportMenuEl)) return;\n this.#closeExportMenu();\n };\n\n #handleDocumentKey = (event: KeyboardEvent) => {\n if (!this.exportMenuOpen) return;\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.#closeExportMenu(true);\n }\n };\n\n #handleExport = (formatId: string) => {\n this.#closeExportMenu();\n const grid = this.state?.host;\n if (!grid) return;\n grid.exportAs(formatId, { filename: this.exportFilename });\n };\n\n /** Lets keyboard users land in the menu when it opens via arrow-down. */\n #handleTriggerKeydown = (event: KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault();\n if (!this.exportMenuOpen) this.exportMenuOpen = true;\n requestAnimationFrame(() => {\n const first = this.exportMenuEl?.querySelector<HTMLElement>('[role=\"menuitem\"]');\n first?.focus();\n });\n }\n };\n\n #handleMenuKeydown = (event: KeyboardEvent) => {\n const items = Array.from(\n this.exportMenuEl?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]') ?? []\n );\n const current = items.indexOf(document.activeElement as HTMLElement);\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault();\n items[(current + 1) % items.length]?.focus();\n } else if (event.key === 'ArrowUp' || event.key === 'Up') {\n event.preventDefault();\n items[(current - 1 + items.length) % items.length]?.focus();\n } else if (event.key === 'Home') {\n event.preventDefault();\n items[0]?.focus();\n } else if (event.key === 'End') {\n event.preventDefault();\n items[items.length - 1]?.focus();\n } else if (event.key === 'Tab') {\n // Tab closes the menu so focus moves naturally to the next focusable.\n this.#closeExportMenu();\n }\n };\n\n protected renderQuickFilter() {\n if (!this.showQuickFilter) return nothing;\n return html`<div part=\"toolbar-search\">\n <label part=\"search-field\">\n ${renderIcon('search', { part: 'search-icon' })}\n <input\n part=\"search-input\"\n type=\"search\"\n role=\"searchbox\"\n aria-label=${this.searchPlaceholder}\n placeholder=${this.searchPlaceholder}\n .value=${this.value}\n @input=${this.#handleInput}\n @keydown=${this.#handleKeydown}\n />\n </label>\n </div>`;\n }\n\n protected renderExportMenu() {\n if (!this.showExport) return nothing;\n const open = this.exportMenuOpen;\n return html`<div part=\"export\">\n <button\n type=\"button\"\n part=\"export-trigger\"\n aria-label=${this.state.localize('toolbar.export')}\n aria-haspopup=\"menu\"\n aria-expanded=${open ? 'true' : 'false'}\n @click=${this.#toggleExportMenu}\n @keydown=${this.#handleTriggerKeydown}\n >\n ${renderIcon('download', { part: 'export-icon' })}\n ${renderIcon('chevron-down', { part: 'export-caret' })}\n </button>\n <ul\n part=\"export-menu\"\n role=\"menu\"\n aria-label=${this.state.localize('toolbar.exportOptions')}\n ?hidden=${!open}\n @keydown=${this.#handleMenuKeydown}\n >\n ${(this.state?.host?.exportFormats ?? []).map(\n (format) => html`<li role=\"none\">\n <button\n type=\"button\"\n role=\"menuitem\"\n part=\"export-menu-item\"\n tabindex=\"-1\"\n @click=${() => this.#handleExport(format.id)}\n >\n ${format.label}\n </button>\n </li>`\n )}\n </ul>\n </div>`;\n }\n\n protected renderToolbarActions() {\n const actions = this.state?.host?.toolbarActions ?? [];\n if (!actions.length) return nothing;\n return html`${actions.map(\n (action) => html`<button\n type=\"button\"\n part=\"toolbar-action\"\n data-action-id=${action.id ?? ''}\n @click=${() => action.run()}\n >\n ${action.label}\n </button>`\n )}`;\n }\n\n protected override render() {\n if (!this.state) return nothing;\n return html`\n <div part=\"toolbar\" role=\"toolbar\" aria-label=${this.state.localize('toolbar.label')}>\n ${this.renderQuickFilter()}\n <div part=\"toolbar-actions\">${this.renderToolbarActions()}${this.renderExportMenu()}</div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridToolbar.tagName]: ApexGridToolbar<object>;\n }\n}\n"]}
@@ -44,6 +44,7 @@ export class DataOperationsController {
44
44
  transformed = this.hasCustomSort
45
45
  ? await this.customSort({ data: transformed, grid: this.host, type: 'sort' })
46
46
  : this.sorting.apply(transformed, sorting.state);
47
+ transformed = state.rowReorder.apply(transformed);
47
48
  if (state.tree.enabled) {
48
49
  transformed = state.tree.process(transformed);
49
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"data-operation.js","sourceRoot":"","sources":["../../src/controllers/data-operation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport { isDefined } from '../internal/is-defined.js';\nimport type { GridHost } from '../internal/types.js';\nimport FilterDataOperation from '../operations/filter.js';\nimport QuickFilterDataOperation from '../operations/quick-filter.js';\nimport SortDataOperation from '../operations/sort.js';\nimport type { StateController } from './state.js';\n\nexport class DataOperationsController<T extends object> implements ReactiveController {\n protected sorting = new SortDataOperation<T>();\n protected filtering = new FilterDataOperation<T>();\n protected quickFiltering = new QuickFilterDataOperation<T>();\n\n constructor(protected host: GridHost<T>) {\n this.host.addController(this);\n }\n\n public hostConnected() {}\n\n protected get hasCustomSort() {\n return isDefined(this.host.dataPipelineConfiguration?.sort);\n }\n\n protected get hasCustomFilter() {\n return isDefined(this.host.dataPipelineConfiguration?.filter);\n }\n\n protected get hasCustomQuickFilter() {\n return isDefined(this.host.dataPipelineConfiguration?.quickFilter);\n }\n\n protected get customFilter() {\n return this.host.dataPipelineConfiguration!.filter!;\n }\n\n protected get customSort() {\n return this.host.dataPipelineConfiguration!.sort!;\n }\n\n protected get customQuickFilter() {\n return this.host.dataPipelineConfiguration!.quickFilter!;\n }\n\n /**\n * Applies the quick-filter (global search), column-filter, and sort steps of the\n * data pipeline.\n *\n * @remarks\n * The returned dataset is the full post-filter, post-sort view. Pagination is\n * intentionally not applied here so callers can derive `totalItems` and the\n * paginator's `pageCount` from a stable value. The grid slices the page for\n * the virtualizer at render time.\n */\n public async apply(data: T[], state: StateController<T>) {\n const { filtering, sorting } = state;\n let transformed: T[];\n\n const quickFilterTerm = (this.host.quickFilter ?? '').trim();\n transformed = this.hasCustomQuickFilter\n ? await this.customQuickFilter({ data, grid: this.host, type: 'quickFilter' })\n : quickFilterTerm\n ? this.quickFiltering.apply(data, quickFilterTerm, this.host.columns)\n : data;\n\n transformed = this.hasCustomFilter\n ? await this.customFilter({ data: transformed, grid: this.host, type: 'filter' })\n : this.filtering.apply(transformed, filtering.state);\n\n transformed = this.hasCustomSort\n ? await this.customSort({ data: transformed, grid: this.host, type: 'sort' })\n : this.sorting.apply(transformed, sorting.state);\n\n // Tree mode flattens the post-sort rows according to the current\n // expansion set. Disabled is a no-op pass-through, so flat tables keep\n // their existing behaviour untouched.\n if (state.tree.enabled) {\n transformed = state.tree.process(transformed);\n }\n\n // Feature modules (e.g. enterprise row grouping) may inject or reorder rows\n // after the built-in pipeline, before pagination slices the page. With no\n // modules registered this is an identity pass-through, so the community\n // `<apex-grid>` behaviour is unchanged.\n transformed = state.applyModuleTransforms(transformed);\n\n return transformed;\n }\n}\n"]}
1
+ {"version":3,"file":"data-operation.js","sourceRoot":"","sources":["../../src/controllers/data-operation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport { isDefined } from '../internal/is-defined.js';\nimport type { GridHost } from '../internal/types.js';\nimport FilterDataOperation from '../operations/filter.js';\nimport QuickFilterDataOperation from '../operations/quick-filter.js';\nimport SortDataOperation from '../operations/sort.js';\nimport type { StateController } from './state.js';\n\nexport class DataOperationsController<T extends object> implements ReactiveController {\n protected sorting = new SortDataOperation<T>();\n protected filtering = new FilterDataOperation<T>();\n protected quickFiltering = new QuickFilterDataOperation<T>();\n\n constructor(protected host: GridHost<T>) {\n this.host.addController(this);\n }\n\n public hostConnected() {}\n\n protected get hasCustomSort() {\n return isDefined(this.host.dataPipelineConfiguration?.sort);\n }\n\n protected get hasCustomFilter() {\n return isDefined(this.host.dataPipelineConfiguration?.filter);\n }\n\n protected get hasCustomQuickFilter() {\n return isDefined(this.host.dataPipelineConfiguration?.quickFilter);\n }\n\n protected get customFilter() {\n return this.host.dataPipelineConfiguration!.filter!;\n }\n\n protected get customSort() {\n return this.host.dataPipelineConfiguration!.sort!;\n }\n\n protected get customQuickFilter() {\n return this.host.dataPipelineConfiguration!.quickFilter!;\n }\n\n /**\n * Applies the quick-filter (global search), column-filter, and sort steps of the\n * data pipeline.\n *\n * @remarks\n * The returned dataset is the full post-filter, post-sort view. Pagination is\n * intentionally not applied here so callers can derive `totalItems` and the\n * paginator's `pageCount` from a stable value. The grid slices the page for\n * the virtualizer at render time.\n */\n public async apply(data: T[], state: StateController<T>) {\n const { filtering, sorting } = state;\n let transformed: T[];\n\n const quickFilterTerm = (this.host.quickFilter ?? '').trim();\n transformed = this.hasCustomQuickFilter\n ? await this.customQuickFilter({ data, grid: this.host, type: 'quickFilter' })\n : quickFilterTerm\n ? this.quickFiltering.apply(data, quickFilterTerm, this.host.columns)\n : data;\n\n transformed = this.hasCustomFilter\n ? await this.customFilter({ data: transformed, grid: this.host, type: 'filter' })\n : this.filtering.apply(transformed, filtering.state);\n\n transformed = this.hasCustomSort\n ? await this.customSort({ data: transformed, grid: this.host, type: 'sort' })\n : this.sorting.apply(transformed, sorting.state);\n\n // Manual row order (drag-reorder) is applied after sort. Identity\n // pass-through when no manual order is active, so the natural order is\n // untouched.\n transformed = state.rowReorder.apply(transformed);\n\n // Tree mode flattens the post-sort rows according to the current\n // expansion set. Disabled is a no-op pass-through, so flat tables keep\n // their existing behaviour untouched.\n if (state.tree.enabled) {\n transformed = state.tree.process(transformed);\n }\n\n // Feature modules (e.g. enterprise row grouping) may inject or reorder rows\n // after the built-in pipeline, before pagination slices the page. With no\n // modules registered this is an identity pass-through, so the community\n // `<apex-grid>` behaviour is unchanged.\n transformed = state.applyModuleTransforms(transformed);\n\n return transformed;\n }\n}\n"]}
@@ -21,7 +21,23 @@ export declare class GridDOMController<T extends object> implements ReactiveCont
21
21
  * {@link recomputePinOffsets}.
22
22
  */
23
23
  pinOffsets: Map<keyof T, number>;
24
+ /**
25
+ * Number of chrome rows above the body for `aria-rowindex`: an optional group
26
+ * header row and the column header (always present). The filter panel is a
27
+ * floating overlay rather than a table row, so it is not counted here.
28
+ */
29
+ protected get headerRowCount(): number;
24
30
  rowRenderer: RenderItemFunction<T>;
31
+ /**
32
+ * Renders a single pinned row for a sticky band. Reuses {@link ApexGridRow}
33
+ * so selection / expansion / decoration all work by data reference, but pins a
34
+ * sentinel {@link ActiveNode} (pinned rows are presentation + selection
35
+ * surfaces in v1, never the active/edited cell) and renders no editor.
36
+ *
37
+ * @param localIndex - position within the band (drives the active sentinel id).
38
+ * @param ariaRowOffset - so `aria-rowindex` continues the unified sequence.
39
+ */
40
+ pinnedRowRenderer(data: T, localIndex: number, ariaRowOffset: number): import("lit-html").TemplateResult<1>;
25
41
  hostConnected(): Promise<void>;
26
42
  hostUpdate(): void;
27
43
  hostUpdated(): void;
@@ -43,12 +59,14 @@ export declare class GridDOMController<T extends object> implements ReactiveCont
43
59
  recomputePinOffsets(): void;
44
60
  protected observeHeaderCells(): void;
45
61
  /**
46
- * Writes the cumulative height of the sticky top rows into CSS custom
47
- * properties used by the header/filter rows for their `inset-block-start`
48
- * offsets. The toolbar is always at `top: 0`; the header sits below it
49
- * (`--apex-row-top-header`) and the filter sits below the header
50
- * (`--apex-row-top-filter`). Writes are skipped when the values haven't
51
- * changed so the ResizeObserver feedback loop terminates.
62
+ * Writes the cumulative heights of the sticky chrome rows into CSS custom
63
+ * properties used for their `inset-block-start` / `inset-block-end` offsets.
64
+ * The toolbar is at `top: 0`; the header sits below it
65
+ * (`--apex-row-top-header`), the filter below the header
66
+ * (`--apex-row-top-filter`), and the pinned-top band below the filter
67
+ * (`--apex-row-top-pinned`). The pinned-bottom band sticks above the
68
+ * paginator (`--apex-row-bottom-pinned`). Writes are skipped when values are
69
+ * unchanged so the ResizeObserver feedback loop terminates.
52
70
  */
53
71
  recomputeStickyRowOffsets(): void;
54
72
  protected observeStickyRows(): void;
@@ -1,5 +1,6 @@
1
1
  import { html } from 'lit';
2
2
  import { styleMap } from 'lit/directives/style-map.js';
3
+ import { SENTINEL_NODE } from '../internal/constants.js';
3
4
  import { applyColumnWidths, getDisplayColumns } from '../internal/utils.js';
4
5
  export class GridDOMController {
5
6
  constructor(host, state) {
@@ -21,8 +22,7 @@ export class GridDOMController {
21
22
  this.rowRenderer = (data, index) => {
22
23
  const editingCell = this.state.editing.activeCell;
23
24
  const editingKey = editingCell?.rowIndex === index ? editingCell.columnKey : null;
24
- const hasFilter = this.host.columns.some((column) => column.filter);
25
- const ariaRowOffset = hasFilter ? 2 : 1;
25
+ const ariaRowOffset = this.headerRowCount + this.state.rowPin.pinnedRows.top.length;
26
26
  return html `
27
27
  <apex-grid-row
28
28
  part="row"
@@ -35,12 +35,19 @@ export class GridDOMController {
35
35
  .editingKey=${editingKey}
36
36
  .ariaRowOffset=${ariaRowOffset}
37
37
  .decorationVersion=${this.state.decorationVersion}
38
+ .validationVersion=${this.state.editing.validationVersion}
39
+ .dragging=${this.state.rowReorder.dragging === data}
40
+ .grabbed=${this.state.rowReorder.grabbed === data}
41
+ .coordinateHints=${Boolean(this.host.coordinateHints)}
38
42
  >
39
43
  </apex-grid-row>
40
44
  `;
41
45
  };
46
+ this.#lastGroupTop = -1;
42
47
  this.#lastHeaderTop = -1;
43
48
  this.#lastFilterTop = -1;
49
+ this.#lastPinnedTop = -1;
50
+ this.#lastPinnedBottom = -1;
44
51
  this.#lastHostWidth = -1;
45
52
  this.#hostWidthObserver = null;
46
53
  this.host.addController(this);
@@ -56,6 +63,28 @@ export class GridDOMController {
56
63
  get displayColumns() {
57
64
  return getDisplayColumns(this.host.columns);
58
65
  }
66
+ get headerRowCount() {
67
+ return this.host.columnGroupDepth + 1;
68
+ }
69
+ pinnedRowRenderer(data, localIndex, ariaRowOffset) {
70
+ return html `
71
+ <apex-grid-row
72
+ part="row pinned-row"
73
+ style=${styleMap(this.columnSizes)}
74
+ .index=${localIndex}
75
+ .activeNode=${SENTINEL_NODE}
76
+ .data=${data}
77
+ .columns=${this.displayColumns}
78
+ .pinOffsets=${this.pinOffsets}
79
+ .editingKey=${null}
80
+ .ariaRowOffset=${ariaRowOffset}
81
+ .decorationVersion=${this.state.decorationVersion}
82
+ .validationVersion=${this.state.editing.validationVersion}
83
+ .coordinateHints=${Boolean(this.host.coordinateHints)}
84
+ >
85
+ </apex-grid-row>
86
+ `;
87
+ }
59
88
  async hostConnected() {
60
89
  this.setGridColumnSizes();
61
90
  await this.host.updateComplete;
@@ -103,6 +132,8 @@ export class GridDOMController {
103
132
  this.columnSizes = applyColumnWidths(this.displayColumns, {
104
133
  showSelectionColumn: this.state.selection.showCheckboxColumn,
105
134
  showExpansionColumn: this.state.expansion.showToggleColumn,
135
+ showReorderHandle: this.state.rowReorder.showHandleColumn,
136
+ showRowNumbers: Boolean(this.host.coordinateHints),
106
137
  });
107
138
  }
108
139
  getActiveRowStyles(index) {
@@ -164,8 +195,11 @@ export class GridDOMController {
164
195
  }
165
196
  this.#observedHeaders = next;
166
197
  }
198
+ #lastGroupTop;
167
199
  #lastHeaderTop;
168
200
  #lastFilterTop;
201
+ #lastPinnedTop;
202
+ #lastPinnedBottom;
169
203
  #lastHostWidth;
170
204
  #hostWidthObserver;
171
205
  recomputeStickyRowOffsets() {
@@ -173,11 +207,23 @@ export class GridDOMController {
173
207
  if (!root)
174
208
  return;
175
209
  const toolbar = root.querySelector('apex-grid-toolbar');
210
+ const groupHeader = root.querySelector('apex-grid-group-header-row');
176
211
  const header = root.querySelector('apex-grid-header-row');
212
+ const filter = root.querySelector('apex-filter-row');
213
+ const paginator = root.querySelector('apex-grid-paginator');
177
214
  const toolbarH = toolbar?.offsetHeight ?? 0;
215
+ const groupH = groupHeader?.offsetHeight ?? 0;
178
216
  const headerH = header?.offsetHeight ?? 0;
179
- const headerTop = toolbarH;
180
- const filterTop = toolbarH + headerH;
217
+ const filterH = filter?.offsetHeight ?? 0;
218
+ const paginatorH = paginator?.offsetHeight ?? 0;
219
+ const groupTop = toolbarH;
220
+ const headerTop = toolbarH + groupH;
221
+ const filterTop = toolbarH + groupH + headerH;
222
+ const pinnedTop = toolbarH + groupH + headerH + filterH;
223
+ if (groupTop !== this.#lastGroupTop) {
224
+ this.host.style.setProperty('--apex-row-top-group', `${groupTop}px`);
225
+ this.#lastGroupTop = groupTop;
226
+ }
181
227
  if (headerTop !== this.#lastHeaderTop) {
182
228
  this.host.style.setProperty('--apex-row-top-header', `${headerTop}px`);
183
229
  this.#lastHeaderTop = headerTop;
@@ -186,19 +232,30 @@ export class GridDOMController {
186
232
  this.host.style.setProperty('--apex-row-top-filter', `${filterTop}px`);
187
233
  this.#lastFilterTop = filterTop;
188
234
  }
235
+ if (pinnedTop !== this.#lastPinnedTop) {
236
+ this.host.style.setProperty('--apex-row-top-pinned', `${pinnedTop}px`);
237
+ this.#lastPinnedTop = pinnedTop;
238
+ }
239
+ if (paginatorH !== this.#lastPinnedBottom) {
240
+ this.host.style.setProperty('--apex-row-bottom-pinned', `${paginatorH}px`);
241
+ this.#lastPinnedBottom = paginatorH;
242
+ }
189
243
  }
190
244
  observeStickyRows() {
191
245
  const root = this.host.shadowRoot;
192
246
  if (!root)
193
247
  return;
194
248
  const toolbar = root.querySelector('apex-grid-toolbar');
249
+ const groupHeader = root.querySelector('apex-grid-group-header-row');
195
250
  const header = root.querySelector('apex-grid-header-row');
251
+ const filter = root.querySelector('apex-filter-row');
252
+ const paginator = root.querySelector('apex-grid-paginator');
196
253
  if (!this.#stickyRowObserver) {
197
254
  this.#stickyRowObserver = new ResizeObserver(() => {
198
255
  requestAnimationFrame(() => this.recomputeStickyRowOffsets());
199
256
  });
200
257
  }
201
- const next = new Set([toolbar, header].filter((el) => !!el));
258
+ const next = new Set([toolbar, groupHeader, header, filter, paginator].filter((el) => !!el));
202
259
  for (const element of this.#observedStickyRows) {
203
260
  if (!next.has(element))
204
261
  this.#stickyRowObserver.unobserve(element);