apex-grid 3.4.0 → 3.6.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.
- package/CHANGELOG.md +439 -0
- package/LICENSE.md +125 -0
- package/README.md +107 -14
- package/components/cell.d.ts +30 -4
- package/components/cell.js +199 -53
- 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 +257 -20
- package/components/grid.js +463 -99
- 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 +7 -5
- package/components/header-row.js +19 -9
- package/components/header-row.js.map +1 -1
- package/components/header.js +36 -22
- package/components/header.js.map +1 -1
- package/components/row.d.ts +19 -3
- package/components/row.js +96 -22
- package/components/row.js.map +1 -1
- package/components/toolbar.js +2 -1
- package/components/toolbar.js.map +1 -1
- package/components/virtualizer.d.ts +45 -1
- package/components/virtualizer.js +184 -3
- package/components/virtualizer.js.map +1 -1
- package/controllers/dom.d.ts +4 -4
- package/controllers/dom.js +40 -22
- 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 +68 -13
- package/controllers/navigation.js +196 -51
- package/controllers/navigation.js.map +1 -1
- package/controllers/pagination.d.ts +6 -0
- package/controllers/pagination.js +10 -2
- package/controllers/pagination.js.map +1 -1
- package/controllers/reorder.js +42 -24
- 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 +20 -2
- package/controllers/row-pin.js +16 -9
- package/controllers/row-pin.js.map +1 -1
- package/controllers/row-reorder.d.ts +31 -11
- package/controllers/row-reorder.js +117 -37
- package/controllers/row-reorder.js.map +1 -1
- package/controllers/selection.d.ts +11 -4
- package/controllers/selection.js +26 -11
- package/controllers/selection.js.map +1 -1
- package/controllers/sort.d.ts +22 -2
- package/controllers/sort.js +29 -23
- package/controllers/sort.js.map +1 -1
- package/controllers/state.d.ts +65 -10
- package/controllers/state.js +86 -6
- 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 +3589 -452
- 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 +660 -0
- package/docs/classes/ApexGridPaginator.html +36 -0
- package/docs/classes/ApexGridToolbar.html +67 -0
- package/docs/functions/localize.html +2 -2
- package/docs/functions/setup.html +1 -2
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +105 -15
- package/docs/interfaces/ApexCellValidationFailedEvent.html +3 -2
- package/docs/interfaces/ApexCellValueChangedEvent.html +4 -2
- package/docs/interfaces/ApexCellValueChangingEvent.html +3 -2
- package/docs/interfaces/ApexColumnMovedEvent.html +2 -2
- package/docs/interfaces/ApexColumnMovingEvent.html +1 -1
- package/docs/interfaces/ApexDetailContext.html +2 -2
- package/docs/interfaces/ApexGridEventMap.html +9 -6
- 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 +1 -1
- package/docs/interfaces/BaseApexEditorContext.html +1 -1
- package/docs/interfaces/BaseColumnConfiguration.html +3 -3
- package/docs/interfaces/BaseFilterExpression.html +2 -2
- package/docs/interfaces/CSVExportOptions.html +13 -5
- package/docs/interfaces/DataPipelineConfiguration.html +2 -2
- package/docs/interfaces/EditingHistoryConfiguration.html +1 -1
- package/docs/interfaces/ExportFormat.html +2 -2
- package/docs/interfaces/ExportOptions.html +5 -3
- package/docs/interfaces/GridExpansionConfiguration.html +6 -2
- package/docs/interfaces/GridRowPinningConfiguration.html +1 -1
- package/docs/interfaces/GridRowReorderingConfiguration.html +2 -2
- package/docs/interfaces/PaginationConfiguration.html +1 -1
- package/docs/interfaces/PaginationState.html +1 -1
- 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 +5 -5
- package/docs/media/state-persistence.html +0 -10
- package/docs/modules.html +1 -1
- package/docs/types/DataPipelineParams.html +2 -2
- package/docs/types/EditMode.html +2 -2
- package/docs/types/ExportSource.html +6 -4
- package/docs/types/GridLocaleText.html +1 -1
- package/docs/types/OperandKeys.html +9 -0
- package/docs/types/PaginationMode.html +1 -1
- package/docs/variables/EN_LOCALE.html +3 -3
- package/docs/variables/esLocale.html +1 -1
- package/i18n/en.d.ts +19 -0
- package/i18n/en.js +19 -0
- package/i18n/en.js.map +1 -1
- package/i18n/es.js +19 -0
- package/i18n/es.js.map +1 -1
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/internal/column-types.d.ts +27 -1
- package/internal/column-types.js +75 -49
- 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 +39 -7
- package/internal/export.js +35 -34
- package/internal/export.js.map +1 -1
- package/internal/feature-module.d.ts +82 -3
- package/internal/feature-module.js +11 -0
- package/internal/feature-module.js.map +1 -1
- package/internal/index.d.ts +6 -4
- package/internal/index.js +5 -3
- 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 +17 -2
- package/internal/types.js.map +1 -1
- package/internal/utils.d.ts +48 -6
- package/internal/utils.js +35 -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 +13 -1
- 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 +8 -4
- package/setup.d.ts +23 -11
- package/setup.js +19 -21
- package/setup.js.map +1 -1
- package/styles/_common.css.js +1 -1
- package/styles/_common.css.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 -193
|
@@ -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,6 +33,13 @@ 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;
|
|
36
|
+
/**
|
|
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.
|
|
42
|
+
*/
|
|
41
43
|
protected renderSelectionHeader(): import("lit-html").TemplateResult<1> | typeof nothing;
|
|
42
44
|
/**
|
|
43
45
|
* Floating "ghost" element that follows the cursor while a header is
|
package/components/header-row.js
CHANGED
|
@@ -120,32 +120,36 @@ export default class ApexGridHeaderRow extends LitElement {
|
|
|
120
120
|
}
|
|
121
121
|
const allChecked = selection.allSelected();
|
|
122
122
|
const indeterminate = selection.someSelected();
|
|
123
|
-
const
|
|
123
|
+
const syncState = (el) => {
|
|
124
124
|
if (el instanceof HTMLInputElement) {
|
|
125
|
+
el.checked = allChecked;
|
|
125
126
|
el.indeterminate = indeterminate;
|
|
126
127
|
}
|
|
127
128
|
};
|
|
128
129
|
const handleChange = (event) => {
|
|
129
130
|
const checked = event.target.checked;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
void (checked ? selection.selectAll() : selection.clear()).then(() => this.requestUpdate());
|
|
132
|
+
};
|
|
133
|
+
const forwardToCheckbox = (event) => {
|
|
134
|
+
const target = event.target;
|
|
135
|
+
if (target instanceof HTMLInputElement)
|
|
136
|
+
return;
|
|
137
|
+
event.currentTarget instanceof HTMLElement &&
|
|
138
|
+
event.currentTarget.querySelector('input[type="checkbox"]')?.click();
|
|
136
139
|
};
|
|
137
140
|
return html `<div
|
|
138
141
|
part="selection-header"
|
|
139
142
|
role="columnheader"
|
|
140
143
|
aria-colindex="1"
|
|
141
144
|
data-pinned="start"
|
|
145
|
+
@click=${forwardToCheckbox}
|
|
142
146
|
>
|
|
143
147
|
<input
|
|
144
148
|
type="checkbox"
|
|
145
149
|
part="selection-checkbox"
|
|
146
150
|
aria-label=${this.state.localize('header.selectAll')}
|
|
147
151
|
.checked=${allChecked}
|
|
148
|
-
${ref(
|
|
152
|
+
${ref(syncState)}
|
|
149
153
|
@change=${handleChange}
|
|
150
154
|
/>
|
|
151
155
|
</div>`;
|
|
@@ -174,6 +178,10 @@ export default class ApexGridHeaderRow extends LitElement {
|
|
|
174
178
|
if (this.state?.expansion.showToggleColumn)
|
|
175
179
|
colCursor++;
|
|
176
180
|
let coordCol = 0;
|
|
181
|
+
const letterFor = (key, position) => {
|
|
182
|
+
const label = this.state?.columnCoordinate(key);
|
|
183
|
+
return label === undefined ? columnLetter(position) : (label ?? '');
|
|
184
|
+
};
|
|
177
185
|
return html `${this.renderRowNumberHeader()}${this.renderReorderHandleHeader()}${this.renderSelectionHeader()}${this.renderExpansionHeader()}${repeat(this.columns, (column) => String(column.key), (column, index) => {
|
|
178
186
|
if (column.hidden)
|
|
179
187
|
return nothing;
|
|
@@ -182,7 +190,9 @@ export default class ApexGridHeaderRow extends LitElement {
|
|
|
182
190
|
const edge = getPinEdge(this.columns, index);
|
|
183
191
|
const isDragSource = reorderState?.sourceKey === column.key;
|
|
184
192
|
const ariaColindex = ++colCursor;
|
|
185
|
-
const coordinateLetter = this.coordinateHints
|
|
193
|
+
const coordinateLetter = this.coordinateHints
|
|
194
|
+
? letterFor(String(column.key), coordCol)
|
|
195
|
+
: '';
|
|
186
196
|
coordCol += 1;
|
|
187
197
|
return html `<apex-grid-header
|
|
188
198
|
part=${partNameMap({
|
|
@@ -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 return html`<div\n part=\"selection-header\"\n role=\"columnheader\"\n aria-colindex=\"1\"\n data-pinned=\"start\"\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 { 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 * 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 /**\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. 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 )}${this.renderDragGhost()}`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridHeaderRow.tagName]: ApexGridHeaderRow<object>;\n }\n}\n"]}
|
package/components/header.js
CHANGED
|
@@ -13,6 +13,7 @@ import { renderIcon, renderSortArrows } from '../internal/icons.js';
|
|
|
13
13
|
import { partNameMap } from '../internal/part-map.js';
|
|
14
14
|
import { registerComponent } from '../internal/register.js';
|
|
15
15
|
import { GRID_HEADER_TAG } from '../internal/tags.js';
|
|
16
|
+
import { isRTL } from '../internal/utils.js';
|
|
16
17
|
import { styles } from '../styles/header-cell/header-cell.css.js';
|
|
17
18
|
const DRAG_THRESHOLD_PX = 4;
|
|
18
19
|
export default class ApexGridHeader extends LitElement {
|
|
@@ -22,10 +23,10 @@ export default class ApexGridHeader extends LitElement {
|
|
|
22
23
|
this.coordinateLetter = '';
|
|
23
24
|
this.menuOpen = false;
|
|
24
25
|
this.#handleResize = ({ clientX }) => {
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
this.resizeController.resize(this.column, width,
|
|
26
|
+
const rect = this.getBoundingClientRect();
|
|
27
|
+
const rtl = isRTL(this);
|
|
28
|
+
const width = Math.max(rtl ? rect.right - clientX : clientX - rect.left, MIN_COL_RESIZE_WIDTH);
|
|
29
|
+
this.resizeController.resize(this.column, width, this.resizeController.edge(this, width, rtl));
|
|
29
30
|
};
|
|
30
31
|
this.#handlePointerLost = () => {
|
|
31
32
|
this.resizeController.indicatorActive = false;
|
|
@@ -42,22 +43,21 @@ export default class ApexGridHeader extends LitElement {
|
|
|
42
43
|
return;
|
|
43
44
|
if (event.button !== 0)
|
|
44
45
|
return;
|
|
45
|
-
const
|
|
46
|
-
const target = path[0];
|
|
46
|
+
const target = event.composedPath()[0];
|
|
47
47
|
if (target instanceof Element &&
|
|
48
|
-
target.closest
|
|
48
|
+
target.closest('[part~="resizable"],[part~="action"],[part~="col-menu"],input,textarea,select,button,a[href],[contenteditable]:not([contenteditable="false"])')) {
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
this.#dragStartX = event.clientX;
|
|
52
52
|
this.#dragStartY = event.clientY;
|
|
53
53
|
this.#dragPointerId = event.pointerId;
|
|
54
|
-
this
|
|
55
|
-
this.addEventListener('pointerup', this.#handleReorderPointerUp);
|
|
56
|
-
this.addEventListener('pointercancel', this.#handleReorderPointerUp);
|
|
54
|
+
this.#listenReorder(true);
|
|
57
55
|
};
|
|
58
56
|
this.#handleReorderPointerMove = (event) => {
|
|
59
57
|
if (event.pointerId !== this.#dragPointerId)
|
|
60
58
|
return;
|
|
59
|
+
if (event.pointerType === 'mouse' && !(event.buttons & 1))
|
|
60
|
+
return this.#endReorder();
|
|
61
61
|
if (!this.#isDragging) {
|
|
62
62
|
const dx = event.clientX - this.#dragStartX;
|
|
63
63
|
const dy = event.clientY - this.#dragStartY;
|
|
@@ -75,9 +75,6 @@ export default class ApexGridHeader extends LitElement {
|
|
|
75
75
|
this.#handleReorderPointerUp = (event) => {
|
|
76
76
|
if (event.pointerId !== this.#dragPointerId)
|
|
77
77
|
return;
|
|
78
|
-
this.removeEventListener('pointermove', this.#handleReorderPointerMove);
|
|
79
|
-
this.removeEventListener('pointerup', this.#handleReorderPointerUp);
|
|
80
|
-
this.removeEventListener('pointercancel', this.#handleReorderPointerUp);
|
|
81
78
|
try {
|
|
82
79
|
if (this.hasPointerCapture(event.pointerId)) {
|
|
83
80
|
this.releasePointerCapture(event.pointerId);
|
|
@@ -85,12 +82,7 @@ export default class ApexGridHeader extends LitElement {
|
|
|
85
82
|
}
|
|
86
83
|
catch {
|
|
87
84
|
}
|
|
88
|
-
|
|
89
|
-
this.#isDragging = false;
|
|
90
|
-
this.removeAttribute('data-dragging');
|
|
91
|
-
this.reorderController.end();
|
|
92
|
-
}
|
|
93
|
-
this.#dragPointerId = -1;
|
|
85
|
+
this.#endReorder();
|
|
94
86
|
};
|
|
95
87
|
this.#handleFilterClick = (e) => {
|
|
96
88
|
e.stopPropagation();
|
|
@@ -180,7 +172,7 @@ export default class ApexGridHeader extends LitElement {
|
|
|
180
172
|
};
|
|
181
173
|
}
|
|
182
174
|
get isSortable() {
|
|
183
|
-
return Boolean(this.
|
|
175
|
+
return Boolean(this.state?.sorting?.isSortable(this.column));
|
|
184
176
|
}
|
|
185
177
|
get isFilterable() {
|
|
186
178
|
return Boolean(this.column.filter);
|
|
@@ -226,8 +218,24 @@ export default class ApexGridHeader extends LitElement {
|
|
|
226
218
|
#dragPointerId;
|
|
227
219
|
#isDragging;
|
|
228
220
|
#handleReorderPointerDown;
|
|
221
|
+
#listenReorder(on) {
|
|
222
|
+
const doc = this.ownerDocument;
|
|
223
|
+
const toggle = on ? doc.addEventListener.bind(doc) : doc.removeEventListener.bind(doc);
|
|
224
|
+
toggle('pointermove', this.#handleReorderPointerMove, true);
|
|
225
|
+
toggle('pointerup', this.#handleReorderPointerUp, true);
|
|
226
|
+
toggle('pointercancel', this.#handleReorderPointerUp, true);
|
|
227
|
+
}
|
|
229
228
|
#handleReorderPointerMove;
|
|
230
229
|
#handleReorderPointerUp;
|
|
230
|
+
#endReorder() {
|
|
231
|
+
this.#listenReorder(false);
|
|
232
|
+
if (this.#isDragging) {
|
|
233
|
+
this.#isDragging = false;
|
|
234
|
+
this.removeAttribute('data-dragging');
|
|
235
|
+
this.reorderController.end();
|
|
236
|
+
}
|
|
237
|
+
this.#dragPointerId = -1;
|
|
238
|
+
}
|
|
231
239
|
#handleFilterClick;
|
|
232
240
|
#handleMenuClick;
|
|
233
241
|
#handleMenuOutside;
|
|
@@ -279,6 +287,12 @@ export default class ApexGridHeader extends LitElement {
|
|
|
279
287
|
disconnectedCallback() {
|
|
280
288
|
this.removeEventListener('pointerdown', this.#handleReorderPointerDown);
|
|
281
289
|
document.removeEventListener('pointerdown', this.#handleMenuOutside, true);
|
|
290
|
+
if (this.#dragPointerId !== -1) {
|
|
291
|
+
queueMicrotask(() => {
|
|
292
|
+
if (!this.isConnected)
|
|
293
|
+
this.#endReorder();
|
|
294
|
+
});
|
|
295
|
+
}
|
|
282
296
|
super.disconnectedCallback();
|
|
283
297
|
}
|
|
284
298
|
renderSortPart() {
|
|
@@ -361,7 +375,7 @@ export default class ApexGridHeader extends LitElement {
|
|
|
361
375
|
role="menuitem"
|
|
362
376
|
tabindex="-1"
|
|
363
377
|
@click=${() => {
|
|
364
|
-
this.state.sorting.
|
|
378
|
+
this.state.sorting.sortFromUI(this.column, { direction: 'ascending' });
|
|
365
379
|
this.menuOpen = false;
|
|
366
380
|
}}
|
|
367
381
|
>
|
|
@@ -373,7 +387,7 @@ export default class ApexGridHeader extends LitElement {
|
|
|
373
387
|
role="menuitem"
|
|
374
388
|
tabindex="-1"
|
|
375
389
|
@click=${() => {
|
|
376
|
-
this.state.sorting.
|
|
390
|
+
this.state.sorting.sortFromUI(this.column, { direction: 'descending' });
|
|
377
391
|
this.menuOpen = false;
|
|
378
392
|
}}
|
|
379
393
|
>
|