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