@ornery/ui-grid-vanilla 0.1.7 → 0.1.8
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/demo/index.html +145 -1
- package/demo/main.ts +53 -2
- package/dist/index.d.mts +114 -1
- package/dist/index.d.ts +114 -1
- package/dist/index.js +595 -16
- package/dist/index.mjs +597 -16
- package/package.json +1 -1
- package/src/grid-controller.ts +24 -0
- package/src/index.integration.test.ts +32 -0
- package/src/ui-grid-standalone.element.ts +702 -17
package/dist/index.mjs
CHANGED
|
@@ -5,9 +5,11 @@ import { registerRustWasmGridEngine } from "@ornery/ui-grid-core";
|
|
|
5
5
|
import {
|
|
6
6
|
GRID_CORE_CSS,
|
|
7
7
|
SORT_DIRECTIONS as SORT_DIRECTIONS2,
|
|
8
|
+
buildGridHeaderContext,
|
|
8
9
|
canGridMoveColumns as canGridMoveColumns2,
|
|
9
10
|
downloadGridCsvFile,
|
|
10
11
|
exportCsvRows,
|
|
12
|
+
formatGridHeaderDisplayValue,
|
|
11
13
|
getCellValue as getCellValue2,
|
|
12
14
|
sanitizeDownloadFilename
|
|
13
15
|
} from "@ornery/ui-grid-core";
|
|
@@ -198,6 +200,29 @@ var VanillaGridController = class {
|
|
|
198
200
|
this.apiRegistered = false;
|
|
199
201
|
this.refresh();
|
|
200
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Fast-path: swap only the row data and rebuild the pipeline without
|
|
205
|
+
* touching column state. Emits the new snapshot. The element uses this to
|
|
206
|
+
* patch cell content in-place without rebuilding the full shadow DOM.
|
|
207
|
+
*/
|
|
208
|
+
refreshData(data) {
|
|
209
|
+
this.options = { ...this.options, data };
|
|
210
|
+
this.pipeline = defaultGridEngine.buildPipeline({
|
|
211
|
+
options: this.options,
|
|
212
|
+
columns: this.visibleColumns,
|
|
213
|
+
activeFilters: this.activeFilters,
|
|
214
|
+
sortState: this.sortState,
|
|
215
|
+
groupByColumns: this.groupByColumns,
|
|
216
|
+
collapsedGroups: this.collapsedGroups,
|
|
217
|
+
hiddenRowReasons: this.hiddenRowReasons,
|
|
218
|
+
expandedRows: this.expandedRows,
|
|
219
|
+
expandedTreeRows: this.expandedTreeRows,
|
|
220
|
+
currentPage: this.currentPage,
|
|
221
|
+
pageSize: this.pageSize,
|
|
222
|
+
rowSize: this.getRowSize()
|
|
223
|
+
});
|
|
224
|
+
this.emit();
|
|
225
|
+
}
|
|
201
226
|
subscribe(subscriber) {
|
|
202
227
|
this.subscribers.add(subscriber);
|
|
203
228
|
subscriber(this.getSnapshot());
|
|
@@ -787,6 +812,8 @@ var UiGridStandaloneElement = class extends HTMLElement {
|
|
|
787
812
|
snapshot = null;
|
|
788
813
|
unsubscribe = null;
|
|
789
814
|
activeOptions = null;
|
|
815
|
+
attributeOptions = {};
|
|
816
|
+
attributeSyncScheduled = false;
|
|
790
817
|
iconOverrides = {};
|
|
791
818
|
templateObserver = null;
|
|
792
819
|
openPinMenuColumn = null;
|
|
@@ -801,6 +828,52 @@ var UiGridStandaloneElement = class extends HTMLElement {
|
|
|
801
828
|
measuredFilterStickyHeight = 0;
|
|
802
829
|
stickyHeightRelayoutQueued = false;
|
|
803
830
|
benchmarkAverage = "\u2014";
|
|
831
|
+
skipNextRender = false;
|
|
832
|
+
dataFrame = null;
|
|
833
|
+
static get observedAttributes() {
|
|
834
|
+
return [
|
|
835
|
+
// Scalar attributes
|
|
836
|
+
"grid-id",
|
|
837
|
+
"title",
|
|
838
|
+
"row-height",
|
|
839
|
+
"header-row-height",
|
|
840
|
+
"viewport-height",
|
|
841
|
+
"pagination-page-size",
|
|
842
|
+
"pagination-current-page",
|
|
843
|
+
"total-items",
|
|
844
|
+
"virtualization-threshold",
|
|
845
|
+
"tree-children-field",
|
|
846
|
+
"tree-indent",
|
|
847
|
+
"expandable-row-height",
|
|
848
|
+
"expandable-row-header-width",
|
|
849
|
+
"empty-message",
|
|
850
|
+
"infinite-scroll-rows-from-end",
|
|
851
|
+
// JSON attributes
|
|
852
|
+
"column-defs",
|
|
853
|
+
"data",
|
|
854
|
+
"grouping",
|
|
855
|
+
"pagination-page-sizes",
|
|
856
|
+
// Boolean flags
|
|
857
|
+
"enable-sorting",
|
|
858
|
+
"enable-filtering",
|
|
859
|
+
"enable-grouping",
|
|
860
|
+
"enable-pinning",
|
|
861
|
+
"enable-column-moving",
|
|
862
|
+
"enable-cell-edit",
|
|
863
|
+
"enable-cell-edit-on-focus",
|
|
864
|
+
"enable-pagination",
|
|
865
|
+
"enable-pagination-controls",
|
|
866
|
+
"use-external-pagination",
|
|
867
|
+
"enable-expandable",
|
|
868
|
+
"enable-tree-view",
|
|
869
|
+
"show-tree-expand-no-children",
|
|
870
|
+
"tree-row-header-always-visible",
|
|
871
|
+
"enable-auto-resize",
|
|
872
|
+
"enable-virtualization",
|
|
873
|
+
"infinite-scroll-up",
|
|
874
|
+
"infinite-scroll-down"
|
|
875
|
+
];
|
|
876
|
+
}
|
|
804
877
|
get options() {
|
|
805
878
|
return this.activeOptions ?? {
|
|
806
879
|
id: "__ui-grid-pending__",
|
|
@@ -813,6 +886,144 @@ var UiGridStandaloneElement = class extends HTMLElement {
|
|
|
813
886
|
this.iconOverrides = this.activeOptions.iconOverrides ?? {};
|
|
814
887
|
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
815
888
|
}
|
|
889
|
+
attributeChangedCallback(_name, _oldValue, _newValue) {
|
|
890
|
+
if (!this.attributeSyncScheduled) {
|
|
891
|
+
this.attributeSyncScheduled = true;
|
|
892
|
+
queueMicrotask(() => {
|
|
893
|
+
this.attributeSyncScheduled = false;
|
|
894
|
+
this.syncAttributesToOptions();
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
syncAttributesToOptions() {
|
|
899
|
+
this.attributeOptions = {};
|
|
900
|
+
const gridId = this.getAttribute("grid-id");
|
|
901
|
+
if (gridId !== null) this.attributeOptions.id = gridId;
|
|
902
|
+
const title = this.getAttribute("title");
|
|
903
|
+
if (title !== null) this.attributeOptions.title = title;
|
|
904
|
+
const emptyMessage = this.getAttribute("empty-message");
|
|
905
|
+
if (emptyMessage !== null) this.attributeOptions.emptyMessage = emptyMessage;
|
|
906
|
+
const treeChildrenField = this.getAttribute("tree-children-field");
|
|
907
|
+
if (treeChildrenField !== null) this.attributeOptions.treeChildrenField = treeChildrenField;
|
|
908
|
+
const rowHeight = this.parseNumberAttribute("row-height");
|
|
909
|
+
if (rowHeight !== void 0) this.attributeOptions.rowHeight = rowHeight;
|
|
910
|
+
const headerRowHeight = this.parseNumberAttribute("header-row-height");
|
|
911
|
+
if (headerRowHeight !== void 0)
|
|
912
|
+
this.attributeOptions.headerRowHeight = headerRowHeight;
|
|
913
|
+
const viewportHeight = this.parseNumberAttribute("viewport-height");
|
|
914
|
+
if (viewportHeight !== void 0) this.attributeOptions.viewportHeight = viewportHeight;
|
|
915
|
+
const paginationPageSize = this.parseNumberAttribute("pagination-page-size");
|
|
916
|
+
if (paginationPageSize !== void 0)
|
|
917
|
+
this.attributeOptions.paginationPageSize = paginationPageSize;
|
|
918
|
+
const paginationCurrentPage = this.parseNumberAttribute("pagination-current-page");
|
|
919
|
+
if (paginationCurrentPage !== void 0)
|
|
920
|
+
this.attributeOptions.paginationCurrentPage = paginationCurrentPage;
|
|
921
|
+
const totalItems = this.parseNumberAttribute("total-items");
|
|
922
|
+
if (totalItems !== void 0) this.attributeOptions.totalItems = totalItems;
|
|
923
|
+
const virtualizationThreshold = this.parseNumberAttribute("virtualization-threshold");
|
|
924
|
+
if (virtualizationThreshold !== void 0)
|
|
925
|
+
this.attributeOptions.virtualizationThreshold = virtualizationThreshold;
|
|
926
|
+
const treeIndent = this.parseNumberAttribute("tree-indent");
|
|
927
|
+
if (treeIndent !== void 0) this.attributeOptions.treeIndent = treeIndent;
|
|
928
|
+
const expandableRowHeight = this.parseNumberAttribute("expandable-row-height");
|
|
929
|
+
if (expandableRowHeight !== void 0)
|
|
930
|
+
this.attributeOptions.expandableRowHeight = expandableRowHeight;
|
|
931
|
+
const expandableRowHeaderWidth = this.parseNumberAttribute(
|
|
932
|
+
"expandable-row-header-width"
|
|
933
|
+
);
|
|
934
|
+
if (expandableRowHeaderWidth !== void 0)
|
|
935
|
+
this.attributeOptions.expandableRowHeaderWidth = expandableRowHeaderWidth;
|
|
936
|
+
const infiniteScrollRowsFromEnd = this.parseNumberAttribute(
|
|
937
|
+
"infinite-scroll-rows-from-end"
|
|
938
|
+
);
|
|
939
|
+
if (infiniteScrollRowsFromEnd !== void 0)
|
|
940
|
+
this.attributeOptions.infiniteScrollRowsFromEnd = infiniteScrollRowsFromEnd;
|
|
941
|
+
const enableSorting = this.parseBooleanAttribute("enable-sorting");
|
|
942
|
+
if (enableSorting !== void 0) this.attributeOptions.enableSorting = enableSorting;
|
|
943
|
+
const enableFiltering = this.parseBooleanAttribute("enable-filtering");
|
|
944
|
+
if (enableFiltering !== void 0) this.attributeOptions.enableFiltering = enableFiltering;
|
|
945
|
+
const enableGrouping = this.parseBooleanAttribute("enable-grouping");
|
|
946
|
+
if (enableGrouping !== void 0) this.attributeOptions.enableGrouping = enableGrouping;
|
|
947
|
+
const enablePinning = this.parseBooleanAttribute("enable-pinning");
|
|
948
|
+
if (enablePinning !== void 0) this.attributeOptions.enablePinning = enablePinning;
|
|
949
|
+
const enableColumnMoving = this.parseBooleanAttribute("enable-column-moving");
|
|
950
|
+
if (enableColumnMoving !== void 0)
|
|
951
|
+
this.attributeOptions.enableColumnMoving = enableColumnMoving;
|
|
952
|
+
const enableCellEdit = this.parseBooleanAttribute("enable-cell-edit");
|
|
953
|
+
if (enableCellEdit !== void 0) this.attributeOptions.enableCellEdit = enableCellEdit;
|
|
954
|
+
const enableCellEditOnFocus = this.parseBooleanAttribute("enable-cell-edit-on-focus");
|
|
955
|
+
if (enableCellEditOnFocus !== void 0)
|
|
956
|
+
this.attributeOptions.enableCellEditOnFocus = enableCellEditOnFocus;
|
|
957
|
+
const enablePagination = this.parseBooleanAttribute("enable-pagination");
|
|
958
|
+
if (enablePagination !== void 0)
|
|
959
|
+
this.attributeOptions.enablePagination = enablePagination;
|
|
960
|
+
const enablePaginationControls = this.parseBooleanAttribute(
|
|
961
|
+
"enable-pagination-controls"
|
|
962
|
+
);
|
|
963
|
+
if (enablePaginationControls !== void 0)
|
|
964
|
+
this.attributeOptions.enablePaginationControls = enablePaginationControls;
|
|
965
|
+
const useExternalPagination = this.parseBooleanAttribute("use-external-pagination");
|
|
966
|
+
if (useExternalPagination !== void 0)
|
|
967
|
+
this.attributeOptions.useExternalPagination = useExternalPagination;
|
|
968
|
+
const enableExpandable = this.parseBooleanAttribute("enable-expandable");
|
|
969
|
+
if (enableExpandable !== void 0) this.attributeOptions.enableExpandable = enableExpandable;
|
|
970
|
+
const enableTreeView = this.parseBooleanAttribute("enable-tree-view");
|
|
971
|
+
if (enableTreeView !== void 0) this.attributeOptions.enableTreeView = enableTreeView;
|
|
972
|
+
const showTreeExpandNoChildren = this.parseBooleanAttribute(
|
|
973
|
+
"show-tree-expand-no-children"
|
|
974
|
+
);
|
|
975
|
+
if (showTreeExpandNoChildren !== void 0)
|
|
976
|
+
this.attributeOptions.showTreeExpandNoChildren = showTreeExpandNoChildren;
|
|
977
|
+
const treeRowHeaderAlwaysVisible = this.parseBooleanAttribute(
|
|
978
|
+
"tree-row-header-always-visible"
|
|
979
|
+
);
|
|
980
|
+
if (treeRowHeaderAlwaysVisible !== void 0)
|
|
981
|
+
this.attributeOptions.treeRowHeaderAlwaysVisible = treeRowHeaderAlwaysVisible;
|
|
982
|
+
const enableAutoResize = this.parseBooleanAttribute("enable-auto-resize");
|
|
983
|
+
if (enableAutoResize !== void 0) this.attributeOptions.enableAutoResize = enableAutoResize;
|
|
984
|
+
const enableVirtualization = this.parseBooleanAttribute("enable-virtualization");
|
|
985
|
+
if (enableVirtualization !== void 0)
|
|
986
|
+
this.attributeOptions.enableVirtualization = enableVirtualization;
|
|
987
|
+
const infiniteScrollUp = this.parseBooleanAttribute("infinite-scroll-up");
|
|
988
|
+
if (infiniteScrollUp !== void 0) this.attributeOptions.infiniteScrollUp = infiniteScrollUp;
|
|
989
|
+
const infiniteScrollDown = this.parseBooleanAttribute("infinite-scroll-down");
|
|
990
|
+
if (infiniteScrollDown !== void 0)
|
|
991
|
+
this.attributeOptions.infiniteScrollDown = infiniteScrollDown;
|
|
992
|
+
const columnDefs = this.parseJsonAttribute("column-defs");
|
|
993
|
+
if (columnDefs !== void 0) this.attributeOptions.columnDefs = columnDefs;
|
|
994
|
+
const data = this.parseJsonAttribute("data");
|
|
995
|
+
if (data !== void 0) this.attributeOptions.data = data;
|
|
996
|
+
const grouping = this.parseJsonAttribute("grouping");
|
|
997
|
+
if (grouping !== void 0 && grouping !== null)
|
|
998
|
+
this.attributeOptions.grouping = grouping;
|
|
999
|
+
const paginationPageSizes = this.parseJsonAttribute(
|
|
1000
|
+
"pagination-page-sizes"
|
|
1001
|
+
);
|
|
1002
|
+
if (paginationPageSizes !== void 0)
|
|
1003
|
+
this.attributeOptions.paginationPageSizes = paginationPageSizes;
|
|
1004
|
+
if (this.activeOptions) {
|
|
1005
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
parseBooleanAttribute(name) {
|
|
1009
|
+
return this.hasAttribute(name) ? true : void 0;
|
|
1010
|
+
}
|
|
1011
|
+
parseNumberAttribute(name) {
|
|
1012
|
+
const raw = this.getAttribute(name);
|
|
1013
|
+
if (raw === null) return void 0;
|
|
1014
|
+
const parsed = Number(raw);
|
|
1015
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
1016
|
+
}
|
|
1017
|
+
parseJsonAttribute(name) {
|
|
1018
|
+
const raw = this.getAttribute(name);
|
|
1019
|
+
if (raw === null) return void 0;
|
|
1020
|
+
try {
|
|
1021
|
+
return JSON.parse(raw);
|
|
1022
|
+
} catch (e) {
|
|
1023
|
+
console.warn(`<ui-grid-element>: invalid JSON in "${name}" attribute`, e);
|
|
1024
|
+
return void 0;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
816
1027
|
get controlIcons() {
|
|
817
1028
|
return this.iconOverrides;
|
|
818
1029
|
}
|
|
@@ -820,12 +1031,337 @@ var UiGridStandaloneElement = class extends HTMLElement {
|
|
|
820
1031
|
this.iconOverrides = { ...value };
|
|
821
1032
|
this.render();
|
|
822
1033
|
}
|
|
1034
|
+
// ─────────────────────────────────────────────────────────────────
|
|
1035
|
+
// Individual property accessors (mirrors of HTML attributes)
|
|
1036
|
+
// ─────────────────────────────────────────────────────────────────
|
|
1037
|
+
get gridId() {
|
|
1038
|
+
return this.options.id ?? "";
|
|
1039
|
+
}
|
|
1040
|
+
set gridId(value) {
|
|
1041
|
+
this.activeOptions = { ...this.activeOptions, id: value };
|
|
1042
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1043
|
+
}
|
|
1044
|
+
// @ts-ignore: Intentional override of HTMLElement.title
|
|
1045
|
+
get title() {
|
|
1046
|
+
return this.options.title ?? "";
|
|
1047
|
+
}
|
|
1048
|
+
// @ts-ignore: Intentional override of HTMLElement.title
|
|
1049
|
+
set title(value) {
|
|
1050
|
+
this.activeOptions = { ...this.activeOptions, title: value };
|
|
1051
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1052
|
+
}
|
|
1053
|
+
get rowHeight() {
|
|
1054
|
+
return this.options.rowHeight ?? 40;
|
|
1055
|
+
}
|
|
1056
|
+
set rowHeight(value) {
|
|
1057
|
+
this.activeOptions = { ...this.activeOptions, rowHeight: value };
|
|
1058
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1059
|
+
}
|
|
1060
|
+
get headerRowHeight() {
|
|
1061
|
+
return this.options.headerRowHeight ?? 50;
|
|
1062
|
+
}
|
|
1063
|
+
set headerRowHeight(value) {
|
|
1064
|
+
this.activeOptions = { ...this.activeOptions, headerRowHeight: value };
|
|
1065
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1066
|
+
}
|
|
1067
|
+
get viewportHeight() {
|
|
1068
|
+
return this.options.viewportHeight ?? 560;
|
|
1069
|
+
}
|
|
1070
|
+
set viewportHeight(value) {
|
|
1071
|
+
this.activeOptions = { ...this.activeOptions, viewportHeight: value };
|
|
1072
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1073
|
+
}
|
|
1074
|
+
get paginationPageSize() {
|
|
1075
|
+
return this.options.paginationPageSize ?? 25;
|
|
1076
|
+
}
|
|
1077
|
+
set paginationPageSize(value) {
|
|
1078
|
+
this.activeOptions = { ...this.activeOptions, paginationPageSize: value };
|
|
1079
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1080
|
+
}
|
|
1081
|
+
get paginationCurrentPage() {
|
|
1082
|
+
return this.options.paginationCurrentPage ?? 1;
|
|
1083
|
+
}
|
|
1084
|
+
set paginationCurrentPage(value) {
|
|
1085
|
+
this.activeOptions = { ...this.activeOptions, paginationCurrentPage: value };
|
|
1086
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1087
|
+
}
|
|
1088
|
+
get totalItems() {
|
|
1089
|
+
return this.options.totalItems;
|
|
1090
|
+
}
|
|
1091
|
+
set totalItems(value) {
|
|
1092
|
+
this.activeOptions = { ...this.activeOptions, totalItems: value };
|
|
1093
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1094
|
+
}
|
|
1095
|
+
get virtualizationThreshold() {
|
|
1096
|
+
return this.options.virtualizationThreshold ?? 40;
|
|
1097
|
+
}
|
|
1098
|
+
set virtualizationThreshold(value) {
|
|
1099
|
+
this.activeOptions = { ...this.activeOptions, virtualizationThreshold: value };
|
|
1100
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1101
|
+
}
|
|
1102
|
+
get treeChildrenField() {
|
|
1103
|
+
return this.options.treeChildrenField ?? "children";
|
|
1104
|
+
}
|
|
1105
|
+
set treeChildrenField(value) {
|
|
1106
|
+
this.activeOptions = { ...this.activeOptions, treeChildrenField: value };
|
|
1107
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1108
|
+
}
|
|
1109
|
+
get treeIndent() {
|
|
1110
|
+
return this.options.treeIndent ?? 20;
|
|
1111
|
+
}
|
|
1112
|
+
set treeIndent(value) {
|
|
1113
|
+
this.activeOptions = { ...this.activeOptions, treeIndent: value };
|
|
1114
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1115
|
+
}
|
|
1116
|
+
get expandableRowHeight() {
|
|
1117
|
+
return this.options.expandableRowHeight ?? 150;
|
|
1118
|
+
}
|
|
1119
|
+
set expandableRowHeight(value) {
|
|
1120
|
+
this.activeOptions = { ...this.activeOptions, expandableRowHeight: value };
|
|
1121
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1122
|
+
}
|
|
1123
|
+
get expandableRowHeaderWidth() {
|
|
1124
|
+
return this.options.expandableRowHeaderWidth ?? 40;
|
|
1125
|
+
}
|
|
1126
|
+
set expandableRowHeaderWidth(value) {
|
|
1127
|
+
this.activeOptions = { ...this.activeOptions, expandableRowHeaderWidth: value };
|
|
1128
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1129
|
+
}
|
|
1130
|
+
get emptyMessage() {
|
|
1131
|
+
return this.options.emptyMessage ?? "No data available.";
|
|
1132
|
+
}
|
|
1133
|
+
set emptyMessage(value) {
|
|
1134
|
+
this.activeOptions = { ...this.activeOptions, emptyMessage: value };
|
|
1135
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1136
|
+
}
|
|
1137
|
+
get infiniteScrollRowsFromEnd() {
|
|
1138
|
+
return this.options.infiniteScrollRowsFromEnd ?? 10;
|
|
1139
|
+
}
|
|
1140
|
+
set infiniteScrollRowsFromEnd(value) {
|
|
1141
|
+
this.activeOptions = { ...this.activeOptions, infiniteScrollRowsFromEnd: value };
|
|
1142
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1143
|
+
}
|
|
1144
|
+
get columnDefs() {
|
|
1145
|
+
return this.options.columnDefs;
|
|
1146
|
+
}
|
|
1147
|
+
set columnDefs(value) {
|
|
1148
|
+
this.activeOptions = { ...this.activeOptions, columnDefs: value };
|
|
1149
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1150
|
+
}
|
|
1151
|
+
get data() {
|
|
1152
|
+
return this.options.data;
|
|
1153
|
+
}
|
|
1154
|
+
set data(value) {
|
|
1155
|
+
this.activeOptions = { ...this.activeOptions, data: value };
|
|
1156
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1157
|
+
}
|
|
1158
|
+
get enableSorting() {
|
|
1159
|
+
return this.options.enableSorting ?? true;
|
|
1160
|
+
}
|
|
1161
|
+
set enableSorting(value) {
|
|
1162
|
+
this.activeOptions = { ...this.activeOptions, enableSorting: value };
|
|
1163
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1164
|
+
}
|
|
1165
|
+
get enableFiltering() {
|
|
1166
|
+
return this.options.enableFiltering ?? true;
|
|
1167
|
+
}
|
|
1168
|
+
set enableFiltering(value) {
|
|
1169
|
+
this.activeOptions = { ...this.activeOptions, enableFiltering: value };
|
|
1170
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1171
|
+
}
|
|
1172
|
+
get enableGrouping() {
|
|
1173
|
+
return this.options.enableGrouping ?? true;
|
|
1174
|
+
}
|
|
1175
|
+
set enableGrouping(value) {
|
|
1176
|
+
this.activeOptions = { ...this.activeOptions, enableGrouping: value };
|
|
1177
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1178
|
+
}
|
|
1179
|
+
get enablePinning() {
|
|
1180
|
+
return this.options.enablePinning ?? true;
|
|
1181
|
+
}
|
|
1182
|
+
set enablePinning(value) {
|
|
1183
|
+
this.activeOptions = { ...this.activeOptions, enablePinning: value };
|
|
1184
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1185
|
+
}
|
|
1186
|
+
get enableColumnMoving() {
|
|
1187
|
+
return this.options.enableColumnMoving ?? true;
|
|
1188
|
+
}
|
|
1189
|
+
set enableColumnMoving(value) {
|
|
1190
|
+
this.activeOptions = { ...this.activeOptions, enableColumnMoving: value };
|
|
1191
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1192
|
+
}
|
|
1193
|
+
get enableCellEdit() {
|
|
1194
|
+
return this.options.enableCellEdit ?? false;
|
|
1195
|
+
}
|
|
1196
|
+
set enableCellEdit(value) {
|
|
1197
|
+
this.activeOptions = { ...this.activeOptions, enableCellEdit: value };
|
|
1198
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1199
|
+
}
|
|
1200
|
+
get enableCellEditOnFocus() {
|
|
1201
|
+
return this.options.enableCellEditOnFocus ?? false;
|
|
1202
|
+
}
|
|
1203
|
+
set enableCellEditOnFocus(value) {
|
|
1204
|
+
this.activeOptions = { ...this.activeOptions, enableCellEditOnFocus: value };
|
|
1205
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1206
|
+
}
|
|
1207
|
+
get enablePagination() {
|
|
1208
|
+
return this.options.enablePagination ?? false;
|
|
1209
|
+
}
|
|
1210
|
+
set enablePagination(value) {
|
|
1211
|
+
this.activeOptions = { ...this.activeOptions, enablePagination: value };
|
|
1212
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1213
|
+
}
|
|
1214
|
+
get enablePaginationControls() {
|
|
1215
|
+
return this.options.enablePaginationControls ?? true;
|
|
1216
|
+
}
|
|
1217
|
+
set enablePaginationControls(value) {
|
|
1218
|
+
this.activeOptions = { ...this.activeOptions, enablePaginationControls: value };
|
|
1219
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1220
|
+
}
|
|
1221
|
+
get useExternalPagination() {
|
|
1222
|
+
return this.options.useExternalPagination ?? false;
|
|
1223
|
+
}
|
|
1224
|
+
set useExternalPagination(value) {
|
|
1225
|
+
this.activeOptions = { ...this.activeOptions, useExternalPagination: value };
|
|
1226
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1227
|
+
}
|
|
1228
|
+
get enableExpandable() {
|
|
1229
|
+
return this.options.enableExpandable ?? false;
|
|
1230
|
+
}
|
|
1231
|
+
set enableExpandable(value) {
|
|
1232
|
+
this.activeOptions = { ...this.activeOptions, enableExpandable: value };
|
|
1233
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1234
|
+
}
|
|
1235
|
+
get enableTreeView() {
|
|
1236
|
+
return this.options.enableTreeView ?? false;
|
|
1237
|
+
}
|
|
1238
|
+
set enableTreeView(value) {
|
|
1239
|
+
this.activeOptions = { ...this.activeOptions, enableTreeView: value };
|
|
1240
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1241
|
+
}
|
|
1242
|
+
get showTreeExpandNoChildren() {
|
|
1243
|
+
return this.options.showTreeExpandNoChildren ?? false;
|
|
1244
|
+
}
|
|
1245
|
+
set showTreeExpandNoChildren(value) {
|
|
1246
|
+
this.activeOptions = { ...this.activeOptions, showTreeExpandNoChildren: value };
|
|
1247
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1248
|
+
}
|
|
1249
|
+
get treeRowHeaderAlwaysVisible() {
|
|
1250
|
+
return this.options.treeRowHeaderAlwaysVisible ?? false;
|
|
1251
|
+
}
|
|
1252
|
+
set treeRowHeaderAlwaysVisible(value) {
|
|
1253
|
+
this.activeOptions = { ...this.activeOptions, treeRowHeaderAlwaysVisible: value };
|
|
1254
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1255
|
+
}
|
|
1256
|
+
get enableAutoResize() {
|
|
1257
|
+
return this.options.enableAutoResize ?? false;
|
|
1258
|
+
}
|
|
1259
|
+
set enableAutoResize(value) {
|
|
1260
|
+
this.activeOptions = { ...this.activeOptions, enableAutoResize: value };
|
|
1261
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1262
|
+
}
|
|
1263
|
+
get enableVirtualization() {
|
|
1264
|
+
return this.options.enableVirtualization ?? true;
|
|
1265
|
+
}
|
|
1266
|
+
set enableVirtualization(value) {
|
|
1267
|
+
this.activeOptions = { ...this.activeOptions, enableVirtualization: value };
|
|
1268
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1269
|
+
}
|
|
1270
|
+
get infiniteScrollUp() {
|
|
1271
|
+
return this.options.infiniteScrollUp ?? false;
|
|
1272
|
+
}
|
|
1273
|
+
set infiniteScrollUp(value) {
|
|
1274
|
+
this.activeOptions = { ...this.activeOptions, infiniteScrollUp: value };
|
|
1275
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1276
|
+
}
|
|
1277
|
+
get infiniteScrollDown() {
|
|
1278
|
+
return this.options.infiniteScrollDown ?? false;
|
|
1279
|
+
}
|
|
1280
|
+
set infiniteScrollDown(value) {
|
|
1281
|
+
this.activeOptions = { ...this.activeOptions, infiniteScrollDown: value };
|
|
1282
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1283
|
+
}
|
|
1284
|
+
get grouping() {
|
|
1285
|
+
return this.options.grouping;
|
|
1286
|
+
}
|
|
1287
|
+
set grouping(value) {
|
|
1288
|
+
this.activeOptions = { ...this.activeOptions, grouping: value };
|
|
1289
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1290
|
+
}
|
|
1291
|
+
get paginationPageSizes() {
|
|
1292
|
+
return this.options.paginationPageSizes;
|
|
1293
|
+
}
|
|
1294
|
+
set paginationPageSizes(value) {
|
|
1295
|
+
this.activeOptions = { ...this.activeOptions, paginationPageSizes: value };
|
|
1296
|
+
this.ensureController(this.buildEffectiveOptions(this.activeOptions));
|
|
1297
|
+
}
|
|
823
1298
|
getState() {
|
|
824
1299
|
return this.controller?.getState() ?? null;
|
|
825
1300
|
}
|
|
826
1301
|
setState(state) {
|
|
827
1302
|
this.controller?.setState(state);
|
|
828
1303
|
}
|
|
1304
|
+
/**
|
|
1305
|
+
* Fast-path: update only row data without rebuilding the shadow DOM.
|
|
1306
|
+
* The pipeline is updated synchronously; DOM patching is deferred to the
|
|
1307
|
+
* next animation frame so it never interrupts an in-progress scroll paint.
|
|
1308
|
+
* If multiple ticks arrive before the frame fires, only the latest wins.
|
|
1309
|
+
* If a scroll-triggered full render fires first, the frame is cancelled
|
|
1310
|
+
* (the fresh innerHTML already reflects the latest data).
|
|
1311
|
+
*/
|
|
1312
|
+
setData(rows) {
|
|
1313
|
+
const controller = this.controller;
|
|
1314
|
+
if (!controller) {
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
this.skipNextRender = true;
|
|
1318
|
+
controller.refreshData(rows);
|
|
1319
|
+
this.skipNextRender = false;
|
|
1320
|
+
if (this.dataFrame !== null) {
|
|
1321
|
+
cancelAnimationFrame(this.dataFrame);
|
|
1322
|
+
}
|
|
1323
|
+
this.dataFrame = requestAnimationFrame(() => {
|
|
1324
|
+
this.dataFrame = null;
|
|
1325
|
+
this.patchCells();
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
patchCells() {
|
|
1329
|
+
const snapshot = this.snapshot;
|
|
1330
|
+
if (!snapshot) {
|
|
1331
|
+
return;
|
|
1332
|
+
}
|
|
1333
|
+
const root = this.shadowRoot;
|
|
1334
|
+
if (!root) {
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1337
|
+
const rowMap = /* @__PURE__ */ new Map();
|
|
1338
|
+
for (const row of snapshot.pipeline.visibleRows) {
|
|
1339
|
+
rowMap.set(row.id, row);
|
|
1340
|
+
}
|
|
1341
|
+
const colMap = /* @__PURE__ */ new Map();
|
|
1342
|
+
for (const col of snapshot.visibleColumns) {
|
|
1343
|
+
colMap.set(col.name, col);
|
|
1344
|
+
}
|
|
1345
|
+
const cells = root.querySelectorAll("[data-row][data-column]");
|
|
1346
|
+
for (const cell of cells) {
|
|
1347
|
+
const rowId = cell.dataset["row"];
|
|
1348
|
+
const colName = cell.dataset["column"];
|
|
1349
|
+
if (!rowId || !colName) continue;
|
|
1350
|
+
const row = rowMap.get(rowId);
|
|
1351
|
+
const column = colMap.get(colName);
|
|
1352
|
+
if (!row || !column) continue;
|
|
1353
|
+
const cellShell = cell.querySelector(".cell-shell");
|
|
1354
|
+
if (!cellShell) continue;
|
|
1355
|
+
const newContent = this.renderCellTemplate(row, column, 0);
|
|
1356
|
+
const toggles = cellShell.querySelectorAll(".row-toggle");
|
|
1357
|
+
if (toggles.length === 0) {
|
|
1358
|
+
cellShell.innerHTML = newContent;
|
|
1359
|
+
} else {
|
|
1360
|
+
const toggleHtml = Array.from(toggles).map((t) => t.outerHTML).join("");
|
|
1361
|
+
cellShell.innerHTML = toggleHtml + newContent;
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
829
1365
|
connectedCallback() {
|
|
830
1366
|
this.ensureShadowRoot();
|
|
831
1367
|
this.bindEvents();
|
|
@@ -882,16 +1418,17 @@ var UiGridStandaloneElement = class extends HTMLElement {
|
|
|
882
1418
|
});
|
|
883
1419
|
}
|
|
884
1420
|
buildEffectiveOptions(options) {
|
|
1421
|
+
const merged = {
|
|
1422
|
+
...this.attributeOptions,
|
|
1423
|
+
...options
|
|
1424
|
+
};
|
|
885
1425
|
const hasExpandableSlot = this.getTemplateMarkup("expandable-row") !== null;
|
|
886
|
-
if (
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
expandableRowTemplate: {
|
|
890
|
-
createEmbeddedView: () => void 0
|
|
891
|
-
}
|
|
1426
|
+
if (merged.enableExpandable && hasExpandableSlot && !merged.expandableRowTemplate) {
|
|
1427
|
+
merged.expandableRowTemplate = {
|
|
1428
|
+
createEmbeddedView: () => void 0
|
|
892
1429
|
};
|
|
893
1430
|
}
|
|
894
|
-
return
|
|
1431
|
+
return merged;
|
|
895
1432
|
}
|
|
896
1433
|
bindEvents() {
|
|
897
1434
|
const root = this.ensureShadowRoot();
|
|
@@ -1192,14 +1729,63 @@ var UiGridStandaloneElement = class extends HTMLElement {
|
|
|
1192
1729
|
}
|
|
1193
1730
|
this.scrollFrame = requestAnimationFrame(() => {
|
|
1194
1731
|
this.scrollFrame = null;
|
|
1195
|
-
this.
|
|
1732
|
+
this.renderVirtualBody();
|
|
1196
1733
|
});
|
|
1197
1734
|
},
|
|
1198
1735
|
true
|
|
1199
1736
|
);
|
|
1200
1737
|
root.__uiGridBound = true;
|
|
1201
1738
|
}
|
|
1739
|
+
/**
|
|
1740
|
+
* Targeted update for virtual scroll: replaces only the rendered rows inside
|
|
1741
|
+
* the existing `.grid-virtual-body` without touching the scroll container.
|
|
1742
|
+
* This preserves momentum/inertia scrolling because the `.grid-table` element
|
|
1743
|
+
* is never destroyed.
|
|
1744
|
+
*/
|
|
1745
|
+
renderVirtualBody() {
|
|
1746
|
+
const snapshot = this.snapshot;
|
|
1747
|
+
if (!snapshot?.pipeline.virtualizationEnabled) {
|
|
1748
|
+
this.render();
|
|
1749
|
+
return;
|
|
1750
|
+
}
|
|
1751
|
+
const root = this.shadowRoot;
|
|
1752
|
+
const virtualBody = root?.querySelector(".grid-virtual-body");
|
|
1753
|
+
if (!root || !virtualBody) {
|
|
1754
|
+
this.render();
|
|
1755
|
+
return;
|
|
1756
|
+
}
|
|
1757
|
+
if (this.dataFrame !== null) {
|
|
1758
|
+
cancelAnimationFrame(this.dataFrame);
|
|
1759
|
+
this.dataFrame = null;
|
|
1760
|
+
}
|
|
1761
|
+
const stickyChromeHeight = this.measuredHeaderStickyHeight + this.measuredFilterStickyHeight;
|
|
1762
|
+
const viewportHeight = snapshot.options.viewportHeight ?? 560;
|
|
1763
|
+
const bodyViewportHeight = Math.max(snapshot.rowSize, viewportHeight - stickyChromeHeight);
|
|
1764
|
+
const bodyScrollTop = Math.max(0, this.scrollPosition - stickyChromeHeight);
|
|
1765
|
+
const overscan = 4;
|
|
1766
|
+
const startIndex = Math.max(0, Math.floor(bodyScrollTop / snapshot.rowSize) - overscan);
|
|
1767
|
+
this.lastVirtualStartIndex = startIndex;
|
|
1768
|
+
const visibleCount = Math.ceil(bodyViewportHeight / snapshot.rowSize) + overscan * 2;
|
|
1769
|
+
const itemsToRender = snapshot.pipeline.displayItems.slice(
|
|
1770
|
+
startIndex,
|
|
1771
|
+
Math.min(snapshot.pipeline.displayItems.length, startIndex + visibleCount)
|
|
1772
|
+
);
|
|
1773
|
+
const virtualOffset = startIndex * snapshot.rowSize;
|
|
1774
|
+
virtualBody.style.top = `${virtualOffset}px`;
|
|
1775
|
+
virtualBody.innerHTML = itemsToRender.map((item, index) => this.renderDisplayItem(item, startIndex + index)).join("");
|
|
1776
|
+
}
|
|
1202
1777
|
render() {
|
|
1778
|
+
if (this.skipNextRender) {
|
|
1779
|
+
return;
|
|
1780
|
+
}
|
|
1781
|
+
if (this.dataFrame !== null) {
|
|
1782
|
+
cancelAnimationFrame(this.dataFrame);
|
|
1783
|
+
this.dataFrame = null;
|
|
1784
|
+
}
|
|
1785
|
+
if (this.scrollFrame !== null) {
|
|
1786
|
+
cancelAnimationFrame(this.scrollFrame);
|
|
1787
|
+
this.scrollFrame = null;
|
|
1788
|
+
}
|
|
1203
1789
|
const root = this.ensureShadowRoot();
|
|
1204
1790
|
const snapshot = this.snapshot;
|
|
1205
1791
|
const previousGridTable = root.querySelector(".grid-table");
|
|
@@ -1225,9 +1811,6 @@ var UiGridStandaloneElement = class extends HTMLElement {
|
|
|
1225
1811
|
const headerStickyTop = this.measuredHeaderStickyHeight || options.headerRowHeight || 50;
|
|
1226
1812
|
const stickyChromeHeight = this.measuredHeaderStickyHeight + this.measuredFilterStickyHeight;
|
|
1227
1813
|
const bodyViewportHeight = Math.max(snapshot.rowSize, viewportHeight - stickyChromeHeight);
|
|
1228
|
-
const visibleRowCount = snapshot.pipeline.visibleRows.length;
|
|
1229
|
-
const totalRows = options.data.length;
|
|
1230
|
-
const pinnedCount = Object.keys(snapshot.pinnedColumns).length;
|
|
1231
1814
|
let startIndex = 0;
|
|
1232
1815
|
let itemsToRender = snapshot.pipeline.displayItems;
|
|
1233
1816
|
let virtualOffset = 0;
|
|
@@ -1254,11 +1837,8 @@ var UiGridStandaloneElement = class extends HTMLElement {
|
|
|
1254
1837
|
const bodyContent = itemsToRender.map((item, index) => this.renderDisplayItem(item, startIndex + index)).join("");
|
|
1255
1838
|
const body = snapshot.pipeline.displayItems.length > 0 ? virtualizationEnabled ? `<div class="grid-virtual-spacer" style="height:${totalVirtualHeight}px"><div class="body-grid ui-grid-canvas grid-virtual-body" style="grid-template-columns:${templateColumns};top:${virtualOffset}px">${bodyContent}</div></div>` : `<div class="body-grid ui-grid-canvas" style="grid-template-columns:${templateColumns}">${bodyContent}</div>` : `<div class="empty-state ui-grid-no-row-overlay"><strong>${escapeHtml(options.emptyMessage ?? labels.emptyHeading)}</strong><p>${escapeHtml(labels.emptyDescription)}</p></div>`;
|
|
1256
1839
|
const pagination = paginationEnabled && showPagination ? this.renderPagination(snapshot) : "";
|
|
1257
|
-
const hero = `<header class="grid-hero"><div><p class="eyebrow">Vanilla web component</p><h1>${escapeHtml(options.title ?? "UI Grid")}</h1><p class="deck">Framework-neutral custom element with Shadow DOM styling, slot templates, pinning, virtualization, editing, tree view, grouping, and state restore.</p></div><div class="hero-actions"><button type="button" class="action action-secondary" data-action="benchmark">Benchmark</button><button type="button" class="action action-secondary" data-action="export-csv">Export CSV</button><div class="stats-card"><span>${visibleRowCount}</span><small>${escapeHtml(labels.statsVisibleRows)}</small></div></div></header>`;
|
|
1258
|
-
const metrics = `<section class="metrics-strip" aria-label="Grid metrics"><article><strong>${snapshot.pipeline.pipelineMs.toFixed(2)} ms</strong><span>pipeline</span></article><article><strong>${virtualizationEnabled ? "On" : "Off"}</strong><span>virtualization</span></article><article><strong>${pinnedCount}</strong><span>pinned columns</span></article><article><strong>${escapeHtml(this.benchmarkAverage)}</strong><span>benchmark avg</span></article></section>`;
|
|
1259
|
-
const toolbar = `<div class="grid-toolbar"><div><strong>${visibleRowCount}</strong><span>${escapeHtml(labels.toolbarOf)} ${totalRows} ${escapeHtml(labels.toolbarRows)}</span></div><p>${escapeHtml(options.id)}</p></div>`;
|
|
1260
1840
|
const gridTableStyle = `${virtualizationEnabled ? `height:${viewportHeight}px;overflow-y:auto;` : ""}--ui-grid-header-sticky-top:${headerStickyTop}px;`;
|
|
1261
|
-
root.innerHTML = `<style>${GRID_CORE_CSS}</style
|
|
1841
|
+
root.innerHTML = `<style>${GRID_CORE_CSS}</style>${slotRegistry}<section class="grid-frame ui-grid" role="grid" aria-label="${escapeHtml(options.title ?? "Data grid")}"><div class="grid-table ui-grid-contents-wrapper" style="${gridTableStyle}"><div class="header-grid ui-grid-header ui-grid-header-canvas" style="grid-template-columns:${templateColumns}">${header}</div>${filterRow}${body}</div>${pagination}</section>`;
|
|
1262
1842
|
const gridTable = root.querySelector(".grid-table");
|
|
1263
1843
|
if (gridTable && this.scrollPosition > 0 && virtualizationEnabled) {
|
|
1264
1844
|
this.suppressScrollEvent = true;
|
|
@@ -1313,7 +1893,8 @@ var UiGridStandaloneElement = class extends HTMLElement {
|
|
|
1313
1893
|
const sortIconKey = sortDirection === SORT_DIRECTIONS2.asc ? "sortAsc" : sortDirection === SORT_DIRECTIONS2.desc ? "sortDesc" : "sortNone";
|
|
1314
1894
|
const draggable = canGridMoveColumns2(options) ? 'draggable="true"' : "";
|
|
1315
1895
|
const pinLabel = isPinned ? this.snapshot?.labels.unpin ?? "Unpin" : this.snapshot?.labels.pinColumn ?? "Pin";
|
|
1316
|
-
|
|
1896
|
+
const headerValue = escapeHtml(formatGridHeaderDisplayValue(buildGridHeaderContext(column)));
|
|
1897
|
+
return `<div class="${classes}" data-column="${escapeHtml(column.name)}" ${draggable} style="${stickyStyle}"><span class="header-label">${headerValue}</span><span class="header-actions">${sortEnabled ? `<button type="button" class="header-action" data-action="sort" data-column="${escapeHtml(column.name)}" aria-label="${escapeHtml(sortLabel)}" ${canSort ? "" : "disabled"}>${this.renderControlIcon(sortIconKey)}<span class="sr-only">${escapeHtml(sortLabel)}</span></button>` : ""}${groupingEnabled ? `<button type="button" class="chip-action${controller.isColumnGrouped(column) ? " chip-action-active" : ""}" data-action="group" data-column="${escapeHtml(column.name)}" aria-label="${escapeHtml(groupingLabel)}" ${canGroup ? "" : "disabled"}>${this.renderControlIcon("group")}<span class="sr-only">${escapeHtml(groupingLabel)}</span></button>` : ""}${canPin ? `<div class="pin-control${this.openPinMenuColumn === column.name ? " pin-control-open" : ""}"><button type="button" class="chip-action pin-trigger${isPinned ? " chip-action-active" : ""}" data-action="pin-trigger" data-column="${escapeHtml(column.name)}" aria-label="${escapeHtml(pinLabel)}">${this.renderControlIcon("pin")}<span class="sr-only">${escapeHtml(pinLabel)}</span></button><div class="pin-menu" role="menu" aria-label="${escapeHtml(pinLabel)}"><button type="button" class="pin-menu-action" data-action="pin-left" data-column="${escapeHtml(column.name)}" aria-label="${escapeHtml(this.snapshot?.labels.pinLeft ?? "Pin left")}">${this.renderIconWithClass("control-icon", "pinLeft")}<span class="sr-only">${escapeHtml(this.snapshot?.labels.pinLeft ?? "Pin left")}</span></button><button type="button" class="pin-menu-action" data-action="pin-right" data-column="${escapeHtml(column.name)}" aria-label="${escapeHtml(this.snapshot?.labels.pinRight ?? "Pin right")}">${this.renderIconWithClass("control-icon", "pinRight")}<span class="sr-only">${escapeHtml(this.snapshot?.labels.pinRight ?? "Pin right")}</span></button></div></div>` : ""}</span></div>`;
|
|
1317
1898
|
}
|
|
1318
1899
|
renderFilterCell(column) {
|
|
1319
1900
|
const value = this.snapshot?.activeFilters[column.name] ?? "";
|