@perspective-dev/viewer-datagrid 4.4.0 → 4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn/perspective-viewer-datagrid.js +4 -22
- package/dist/cdn/perspective-viewer-datagrid.js.map +4 -4
- package/dist/css/perspective-viewer-datagrid-toolbar.css +1 -1
- package/dist/css/perspective-viewer-datagrid.css +1 -1
- package/dist/esm/color_utils.d.ts +22 -0
- package/dist/esm/custom_elements/datagrid.d.ts +5 -5
- package/dist/esm/data_listener/format_cell.d.ts +1 -1
- package/dist/esm/data_listener/formatter_cache.d.ts +1 -1
- package/dist/esm/data_listener/index.d.ts +3 -2
- package/dist/esm/event_handlers/click/edit_click.d.ts +3 -2
- package/dist/esm/event_handlers/click.d.ts +4 -6
- package/dist/esm/event_handlers/dispatch_click.d.ts +3 -2
- package/dist/esm/event_handlers/expand_collapse.d.ts +1 -1
- package/dist/esm/event_handlers/focus.d.ts +4 -5
- package/dist/esm/event_handlers/header_click.d.ts +5 -3
- package/dist/esm/event_handlers/keydown/edit_keydown.d.ts +3 -4
- package/dist/esm/event_handlers/select_region.d.ts +3 -1
- package/dist/esm/event_handlers/sort.d.ts +8 -7
- package/dist/esm/model/create.d.ts +1 -1
- package/dist/esm/perspective-viewer-datagrid.js +3 -3
- package/dist/esm/perspective-viewer-datagrid.js.map +4 -4
- package/dist/esm/plugin/activate.d.ts +1 -1
- package/dist/esm/plugin/column_style_controls.d.ts +1 -1
- package/dist/esm/style_handlers/body.d.ts +3 -3
- package/dist/esm/style_handlers/column_header.d.ts +4 -3
- package/dist/esm/style_handlers/consolidated.d.ts +3 -47
- package/dist/esm/style_handlers/editable.d.ts +3 -2
- package/dist/esm/style_handlers/focus.d.ts +4 -4
- package/dist/esm/style_handlers/group_header.d.ts +1 -1
- package/dist/esm/style_handlers/table_cell/boolean.d.ts +1 -1
- package/dist/esm/style_handlers/table_cell/cell_flash.d.ts +1 -1
- package/dist/esm/style_handlers/table_cell/datetime.d.ts +1 -1
- package/dist/esm/style_handlers/table_cell/numeric.d.ts +1 -1
- package/dist/esm/style_handlers/table_cell/row_header.d.ts +1 -1
- package/dist/esm/style_handlers/table_cell/string.d.ts +1 -1
- package/dist/esm/style_handlers/types.d.ts +0 -4
- package/dist/esm/types.d.ts +10 -17
- package/package.json +2 -4
- package/src/css/regular_table.css +87 -31
- package/src/css/row-hover.css +20 -7
- package/src/css/toolbar.css +11 -0
- package/src/ts/color_utils.ts +144 -16
- package/src/ts/custom_elements/datagrid.ts +11 -12
- package/src/ts/custom_elements/toolbar.ts +4 -5
- package/src/ts/data_listener/format_cell.ts +28 -9
- package/src/ts/data_listener/formatter_cache.ts +1 -1
- package/src/ts/data_listener/index.ts +4 -8
- package/src/ts/event_handlers/click/edit_click.ts +7 -6
- package/src/ts/event_handlers/click.ts +39 -68
- package/src/ts/event_handlers/dispatch_click.ts +24 -25
- package/src/ts/event_handlers/expand_collapse.ts +7 -7
- package/src/ts/event_handlers/focus.ts +38 -35
- package/src/ts/event_handlers/header_click.ts +101 -62
- package/src/ts/event_handlers/keydown/edit_keydown.ts +49 -52
- package/src/ts/event_handlers/select_region.ts +144 -133
- package/src/ts/event_handlers/sort.ts +16 -24
- package/src/ts/model/column_overrides.ts +13 -4
- package/src/ts/model/create.ts +51 -55
- package/src/ts/model/toolbar.ts +23 -7
- package/src/ts/plugin/activate.ts +120 -92
- package/src/ts/plugin/column_style_controls.ts +1 -1
- package/src/ts/plugin/save.ts +1 -0
- package/src/ts/style_handlers/body.ts +44 -51
- package/src/ts/style_handlers/column_header.ts +16 -19
- package/src/ts/style_handlers/consolidated.ts +22 -123
- package/src/ts/style_handlers/editable.ts +10 -8
- package/src/ts/style_handlers/focus.ts +5 -5
- package/src/ts/style_handlers/group_header.ts +3 -2
- package/src/ts/style_handlers/table_cell/boolean.ts +3 -3
- package/src/ts/style_handlers/table_cell/cell_flash.ts +11 -11
- package/src/ts/style_handlers/table_cell/datetime.ts +3 -3
- package/src/ts/style_handlers/table_cell/numeric.ts +24 -25
- package/src/ts/style_handlers/table_cell/row_header.ts +2 -2
- package/src/ts/style_handlers/table_cell/string.ts +20 -18
- package/src/ts/style_handlers/types.ts +0 -10
- package/src/ts/types.ts +28 -20
- package/dist/esm/event_handlers/deselect_all.d.ts +0 -5
- package/dist/esm/event_handlers/row_select_click.d.ts +0 -4
- package/src/ts/event_handlers/deselect_all.ts +0 -28
- package/src/ts/event_handlers/row_select_click.ts +0 -92
|
@@ -14,9 +14,7 @@ import { RegularTableElement } from "regular-table";
|
|
|
14
14
|
|
|
15
15
|
import {
|
|
16
16
|
type DatagridModel,
|
|
17
|
-
type PerspectiveViewerElement,
|
|
18
17
|
type ColumnsConfig,
|
|
19
|
-
type DatagridPluginElement,
|
|
20
18
|
get_psp_type,
|
|
21
19
|
} from "../types.js";
|
|
22
20
|
|
|
@@ -25,39 +23,31 @@ import { cell_style_string } from "./table_cell/string.js";
|
|
|
25
23
|
import { cell_style_datetime } from "./table_cell/datetime.js";
|
|
26
24
|
import { cell_style_boolean } from "./table_cell/boolean.js";
|
|
27
25
|
import { cell_style_row_header } from "./table_cell/row_header.js";
|
|
28
|
-
import {
|
|
29
|
-
CollectedCell,
|
|
30
|
-
LocalSelectedPositionMap,
|
|
31
|
-
LocalSelectedRowsMap,
|
|
32
|
-
} from "./types.js";
|
|
26
|
+
import { CollectedCell } from "./types.js";
|
|
33
27
|
|
|
34
28
|
/**
|
|
35
29
|
* Apply styles to all body cells in a single pass.
|
|
36
30
|
*/
|
|
37
31
|
export function applyBodyCellStyles(
|
|
38
|
-
|
|
32
|
+
model: DatagridModel,
|
|
39
33
|
cells: CollectedCell[],
|
|
40
34
|
plugins: ColumnsConfig,
|
|
41
35
|
isSettingsOpen: boolean,
|
|
42
36
|
isSelectable: boolean,
|
|
43
37
|
isEditable: boolean,
|
|
44
38
|
regularTable: RegularTableElement,
|
|
45
|
-
selectedRowsMap: LocalSelectedRowsMap,
|
|
46
|
-
selectedPositionMap: LocalSelectedPositionMap,
|
|
47
|
-
viewer: PerspectiveViewerElement,
|
|
48
39
|
): void {
|
|
49
|
-
const
|
|
50
|
-
const selected = selectedRowsMap.get(regularTable);
|
|
40
|
+
const selectedId = isSelectable ? model._tree_selection_id : undefined;
|
|
51
41
|
|
|
52
42
|
regularTable.classList.toggle(
|
|
53
43
|
"flat-group-rollup-mode",
|
|
54
|
-
|
|
44
|
+
model._config.group_rollup_mode === "flat",
|
|
55
45
|
);
|
|
56
46
|
|
|
57
47
|
for (const { element: td, metadata, isHeader } of cells) {
|
|
58
48
|
const column_name =
|
|
59
|
-
metadata.column_header?.[
|
|
60
|
-
const type = get_psp_type(
|
|
49
|
+
metadata.column_header?.[model._config.split_by.length];
|
|
50
|
+
const type = get_psp_type(model, metadata);
|
|
61
51
|
const plugin = column_name
|
|
62
52
|
? plugins[column_name.toString()]
|
|
63
53
|
: undefined;
|
|
@@ -66,13 +56,13 @@ export function applyBodyCellStyles(
|
|
|
66
56
|
// Calculate aggregate depth visibility
|
|
67
57
|
// @ts-ignore
|
|
68
58
|
metadata._is_hidden_by_aggregate_depth =
|
|
69
|
-
|
|
59
|
+
model._config.group_rollup_mode === "rollup" &&
|
|
70
60
|
((x?: number) =>
|
|
71
61
|
x === 0 || x === undefined
|
|
72
62
|
? false
|
|
73
63
|
: x - 1 <
|
|
74
64
|
Math.min(
|
|
75
|
-
|
|
65
|
+
model._config.group_by.length,
|
|
76
66
|
plugin?.aggregate_depth || 0,
|
|
77
67
|
))(
|
|
78
68
|
(metadata.row_header as unknown[] | undefined)?.filter(
|
|
@@ -82,19 +72,19 @@ export function applyBodyCellStyles(
|
|
|
82
72
|
|
|
83
73
|
// Apply type-specific cell styling
|
|
84
74
|
if (is_numeric) {
|
|
85
|
-
cell_style_numeric
|
|
86
|
-
|
|
75
|
+
cell_style_numeric(
|
|
76
|
+
model,
|
|
87
77
|
plugin as any,
|
|
88
78
|
td,
|
|
89
79
|
metadata as any,
|
|
90
80
|
isSettingsOpen,
|
|
91
81
|
);
|
|
92
82
|
} else if (type === "boolean") {
|
|
93
|
-
cell_style_boolean
|
|
83
|
+
cell_style_boolean(model, plugin, td, metadata as any);
|
|
94
84
|
} else if (type === "string") {
|
|
95
|
-
cell_style_string
|
|
85
|
+
cell_style_string(model, plugin as any, td, metadata as any);
|
|
96
86
|
} else if (type === "date" || type === "datetime") {
|
|
97
|
-
cell_style_datetime
|
|
87
|
+
cell_style_datetime(model, plugin as any, td, metadata);
|
|
98
88
|
} else {
|
|
99
89
|
td.style.backgroundColor = "";
|
|
100
90
|
td.style.color = "";
|
|
@@ -109,10 +99,10 @@ export function applyBodyCellStyles(
|
|
|
109
99
|
td.classList.toggle("psp-null", metadata.value === null);
|
|
110
100
|
td.classList.toggle("psp-align-right", !isHeader && is_numeric);
|
|
111
101
|
td.classList.toggle("psp-align-left", isHeader || !is_numeric);
|
|
112
|
-
if (
|
|
102
|
+
if (model._column_settings_selected_column) {
|
|
113
103
|
td.classList.toggle(
|
|
114
104
|
"psp-menu-open",
|
|
115
|
-
column_name ===
|
|
105
|
+
column_name === model._column_settings_selected_column,
|
|
116
106
|
);
|
|
117
107
|
} else {
|
|
118
108
|
td.classList.toggle("psp-menu-open", false);
|
|
@@ -123,9 +113,14 @@ export function applyBodyCellStyles(
|
|
|
123
113
|
plugin?.number_fg_mode === "bar" && is_numeric,
|
|
124
114
|
);
|
|
125
115
|
|
|
116
|
+
td.classList.toggle(
|
|
117
|
+
"psp-color-mode-label-bar",
|
|
118
|
+
plugin?.number_fg_mode === "label-bar" && is_numeric,
|
|
119
|
+
);
|
|
120
|
+
|
|
126
121
|
// Apply row header styling
|
|
127
122
|
if (isHeader) {
|
|
128
|
-
cell_style_row_header
|
|
123
|
+
cell_style_row_header(model, regularTable, td, metadata as any);
|
|
129
124
|
}
|
|
130
125
|
|
|
131
126
|
// Set data attributes
|
|
@@ -152,55 +147,53 @@ export function applyBodyCellStyles(
|
|
|
152
147
|
delete td.dataset.x;
|
|
153
148
|
}
|
|
154
149
|
|
|
155
|
-
// Apply selection styling (
|
|
150
|
+
// Apply tree selection styling (SELECT_ROW_TREE).
|
|
151
|
+
// psp-select-region-inactive is exclusively a tree-selection class,
|
|
152
|
+
// so always clean it up. psp-select-region is shared with the
|
|
153
|
+
// coordinate-based selection modes, so only touch it when in
|
|
154
|
+
// SELECT_ROW_TREE mode (isSelectable).
|
|
155
|
+
td.classList.toggle("psp-select-region-inactive", false);
|
|
156
156
|
if (isSelectable) {
|
|
157
|
-
if (!
|
|
158
|
-
td.classList.toggle("psp-
|
|
159
|
-
td.classList.toggle("psp-row-subselected", false);
|
|
157
|
+
if (!selectedId) {
|
|
158
|
+
td.classList.toggle("psp-select-region", false);
|
|
160
159
|
} else {
|
|
161
|
-
const id =
|
|
162
|
-
const key_match =
|
|
160
|
+
const id = model._ids[(metadata.y ?? 0) - (metadata.y0 ?? 0)];
|
|
161
|
+
const key_match = selectedId.reduce<boolean>(
|
|
163
162
|
(agg, x, i) => agg && x === id[i],
|
|
164
163
|
true,
|
|
165
164
|
);
|
|
166
165
|
|
|
167
|
-
const
|
|
166
|
+
const isExact = id.length === selectedId.length && key_match;
|
|
167
|
+
const isSub = id.length !== selectedId.length && key_match;
|
|
168
|
+
|
|
168
169
|
if (isHeader) {
|
|
169
170
|
if (
|
|
170
171
|
metadata.type === "row_header" &&
|
|
171
172
|
metadata.row_header_x !== undefined &&
|
|
172
173
|
!!id[metadata.row_header_x]
|
|
173
174
|
) {
|
|
174
|
-
td.classList.toggle("psp-
|
|
175
|
-
td.classList.toggle("psp-row-subselected", false);
|
|
175
|
+
td.classList.toggle("psp-select-region", false);
|
|
176
176
|
} else {
|
|
177
|
+
td.classList.toggle("psp-select-region", isExact);
|
|
177
178
|
td.classList.toggle(
|
|
178
|
-
"psp-
|
|
179
|
-
|
|
180
|
-
);
|
|
181
|
-
td.classList.toggle(
|
|
182
|
-
"psp-row-subselected",
|
|
183
|
-
id.length !== selectedArr.length && key_match,
|
|
179
|
+
"psp-select-region-inactive",
|
|
180
|
+
isSub,
|
|
184
181
|
);
|
|
185
182
|
}
|
|
186
183
|
} else {
|
|
187
|
-
td.classList.toggle(
|
|
188
|
-
|
|
189
|
-
id.length === selectedArr.length && key_match,
|
|
190
|
-
);
|
|
191
|
-
td.classList.toggle(
|
|
192
|
-
"psp-row-subselected",
|
|
193
|
-
id.length !== selectedArr.length && key_match,
|
|
194
|
-
);
|
|
184
|
+
td.classList.toggle("psp-select-region", isExact);
|
|
185
|
+
td.classList.toggle("psp-select-region-inactive", isSub);
|
|
195
186
|
}
|
|
196
187
|
}
|
|
188
|
+
} else {
|
|
189
|
+
td.classList.toggle("psp-select-region", false);
|
|
197
190
|
}
|
|
198
191
|
|
|
199
192
|
// Apply editable styling (if editable)
|
|
200
193
|
if (!isHeader && metadata.type === "body") {
|
|
201
|
-
if (isEditable &&
|
|
194
|
+
if (isEditable && model._is_editable[metadata.x]) {
|
|
202
195
|
const col_name =
|
|
203
|
-
metadata.column_header?.[
|
|
196
|
+
metadata.column_header?.[model._config.split_by.length];
|
|
204
197
|
const col_name_str = col_name?.toString();
|
|
205
198
|
if (
|
|
206
199
|
col_name_str &&
|
|
@@ -11,12 +11,9 @@
|
|
|
11
11
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
12
|
|
|
13
13
|
import { RegularTableElement } from "regular-table";
|
|
14
|
-
import {
|
|
15
|
-
get_psp_type,
|
|
16
|
-
type DatagridModel,
|
|
17
|
-
type PerspectiveViewerElement,
|
|
18
|
-
} from "../types.js";
|
|
14
|
+
import { get_psp_type, type DatagridModel } from "../types.js";
|
|
19
15
|
import { CollectedHeaderRow } from "./types.js";
|
|
16
|
+
import type { HTMLPerspectiveViewerElement } from "@perspective-dev/viewer";
|
|
20
17
|
|
|
21
18
|
/**
|
|
22
19
|
* Apply selected column styling in response to column settings toggle events.
|
|
@@ -24,9 +21,9 @@ import { CollectedHeaderRow } from "./types.js";
|
|
|
24
21
|
* the column settings panel.
|
|
25
22
|
*/
|
|
26
23
|
export function style_selected_column(
|
|
27
|
-
|
|
24
|
+
model: DatagridModel,
|
|
28
25
|
regularTable: RegularTableElement,
|
|
29
|
-
viewer:
|
|
26
|
+
viewer: HTMLPerspectiveViewerElement,
|
|
30
27
|
selectedColumn: string | undefined,
|
|
31
28
|
): void {
|
|
32
29
|
const group_header_trs = Array.from(
|
|
@@ -72,7 +69,7 @@ export function style_selected_column(
|
|
|
72
69
|
const open = title.textContent === selectedColumn;
|
|
73
70
|
title.classList.toggle("psp-menu-open", open);
|
|
74
71
|
editBtn.classList.toggle("psp-menu-open", open);
|
|
75
|
-
if (
|
|
72
|
+
if (model._config.columns.length > 1) {
|
|
76
73
|
for (const r of regularTable.querySelectorAll("td")) {
|
|
77
74
|
const meta = regularTable.getMeta(r);
|
|
78
75
|
if (!meta?.column_header) continue;
|
|
@@ -92,16 +89,16 @@ export function style_selected_column(
|
|
|
92
89
|
* Style a single column header row.
|
|
93
90
|
*/
|
|
94
91
|
export function styleColumnHeaderRow(
|
|
95
|
-
|
|
92
|
+
model: DatagridModel,
|
|
96
93
|
headerRow: CollectedHeaderRow,
|
|
97
94
|
regularTable: RegularTableElement,
|
|
98
95
|
is_menu_row: boolean,
|
|
99
96
|
): void {
|
|
100
97
|
const header_depth =
|
|
101
|
-
|
|
102
|
-
(
|
|
98
|
+
model._config.group_by.length -
|
|
99
|
+
(model._config.group_rollup_mode === "flat" ? 1 : 0);
|
|
103
100
|
|
|
104
|
-
const selectedColumn =
|
|
101
|
+
const selectedColumn = model._column_settings_selected_column;
|
|
105
102
|
for (const { element: td, metadata } of headerRow.cells) {
|
|
106
103
|
if (
|
|
107
104
|
!metadata ||
|
|
@@ -111,15 +108,15 @@ export function styleColumnHeaderRow(
|
|
|
111
108
|
continue;
|
|
112
109
|
|
|
113
110
|
const column_name =
|
|
114
|
-
metadata.column_header?.[
|
|
111
|
+
metadata.column_header?.[model._config.split_by.length];
|
|
115
112
|
|
|
116
|
-
const sort =
|
|
113
|
+
const sort = model._config.sort.find((x) => x[0] === column_name);
|
|
117
114
|
const is_corner = typeof metadata.x === "undefined";
|
|
118
115
|
const needs_border =
|
|
119
116
|
(metadata.type === "corner" &&
|
|
120
117
|
metadata.row_header_x === header_depth) ||
|
|
121
118
|
(!is_corner &&
|
|
122
|
-
(metadata.x + 1) %
|
|
119
|
+
(metadata.x + 1) % model._config.columns.length === 0);
|
|
123
120
|
|
|
124
121
|
td.classList.toggle("psp-header-border", needs_border);
|
|
125
122
|
td.classList.toggle("psp-header-group", false);
|
|
@@ -159,7 +156,7 @@ export function styleColumnHeaderRow(
|
|
|
159
156
|
!is_menu_row && !!sort && sort[1] === "col desc abs",
|
|
160
157
|
);
|
|
161
158
|
|
|
162
|
-
const type = get_psp_type(
|
|
159
|
+
const type = get_psp_type(model, metadata);
|
|
163
160
|
const is_numeric = type === "integer" || type === "float";
|
|
164
161
|
const is_string = type === "string";
|
|
165
162
|
const is_date = type === "date";
|
|
@@ -171,13 +168,13 @@ export function styleColumnHeaderRow(
|
|
|
171
168
|
"psp-menu-enabled",
|
|
172
169
|
(is_string || is_numeric || is_date || is_datetime) &&
|
|
173
170
|
!is_corner &&
|
|
174
|
-
metadata.column_header_y ===
|
|
171
|
+
metadata.column_header_y === model._config.split_by.length + 1,
|
|
175
172
|
);
|
|
176
173
|
td.classList.toggle(
|
|
177
174
|
"psp-sort-enabled",
|
|
178
175
|
(is_string || is_numeric || is_date || is_datetime) &&
|
|
179
176
|
!is_corner &&
|
|
180
|
-
metadata.column_header_y ===
|
|
177
|
+
metadata.column_header_y === model._config.split_by.length,
|
|
181
178
|
);
|
|
182
179
|
td.classList.toggle(
|
|
183
180
|
"psp-is-width-override",
|
|
@@ -185,7 +182,7 @@ export function styleColumnHeaderRow(
|
|
|
185
182
|
);
|
|
186
183
|
|
|
187
184
|
// Apply menu-open for selected column
|
|
188
|
-
if (
|
|
185
|
+
if (model._config.columns.length > 1 && selectedColumn) {
|
|
189
186
|
const isOpen =
|
|
190
187
|
metadata.column_header?.[metadata.column_header.length - 2] ===
|
|
191
188
|
selectedColumn;
|
|
@@ -14,69 +14,19 @@ import { RegularTableElement } from "regular-table";
|
|
|
14
14
|
import { PRIVATE_PLUGIN_SYMBOL } from "../model/index.js";
|
|
15
15
|
import type {
|
|
16
16
|
DatagridModel,
|
|
17
|
-
PerspectiveViewerElement,
|
|
18
17
|
ColumnsConfig,
|
|
19
18
|
DatagridPluginElement,
|
|
20
|
-
|
|
19
|
+
SelectedPositionMap,
|
|
21
20
|
} from "../types.js";
|
|
21
|
+
import { isEditableMode } from "../types.js";
|
|
22
|
+
import type { HTMLPerspectiveViewerElement } from "@perspective-dev/viewer";
|
|
22
23
|
|
|
23
24
|
import { applyFocusStyle } from "./focus.js";
|
|
24
|
-
import { styleColumnHeaderRow } from "./column_header.js";
|
|
25
25
|
import { applyColumnHeaderStyles } from "./editable.js";
|
|
26
26
|
import { applyGroupHeaderStyles } from "./group_header.js";
|
|
27
27
|
import { applyBodyCellStyles } from "./body.js";
|
|
28
28
|
import { CellMetadata } from "regular-table/dist/esm/types.js";
|
|
29
|
-
|
|
30
|
-
interface CollectedCell {
|
|
31
|
-
element: HTMLElement;
|
|
32
|
-
metadata: CellMetadata;
|
|
33
|
-
isHeader: boolean;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface CollectedHeaderRow {
|
|
37
|
-
row: HTMLTableRowElement;
|
|
38
|
-
cells: Array<{
|
|
39
|
-
element: HTMLTableCellElement;
|
|
40
|
-
metadata: CellMetadata | undefined;
|
|
41
|
-
}>;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Context object passed through consolidated styling
|
|
46
|
-
*/
|
|
47
|
-
export interface StyleContext {
|
|
48
|
-
model: DatagridModel;
|
|
49
|
-
regularTable: RegularTableElement;
|
|
50
|
-
viewer: PerspectiveViewerElement;
|
|
51
|
-
datagrid: DatagridPluginElement;
|
|
52
|
-
plugins: ColumnsConfig;
|
|
53
|
-
isSettingsOpen: boolean;
|
|
54
|
-
isSelectable: boolean;
|
|
55
|
-
isEditable: boolean;
|
|
56
|
-
selectedRowsMap: Map<RegularTableElement, unknown[]>;
|
|
57
|
-
selectedPositionMap: Map<RegularTableElement, SelectedPosition>;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Local types for selection maps - match the actual runtime usage
|
|
61
|
-
// (activate.ts uses `as any` casts when passing these)
|
|
62
|
-
type LocalSelectedRowsMap = WeakMap<RegularTableElement, unknown[]>;
|
|
63
|
-
type LocalSelectedPositionMap = WeakMap<RegularTableElement, SelectedPosition>;
|
|
64
|
-
|
|
65
|
-
function isEditableMode(
|
|
66
|
-
model: DatagridModel,
|
|
67
|
-
viewer: PerspectiveViewerElement,
|
|
68
|
-
allowed: boolean = false,
|
|
69
|
-
): boolean {
|
|
70
|
-
const has_pivots =
|
|
71
|
-
model._config.group_by.length === 0 &&
|
|
72
|
-
model._config.split_by.length === 0;
|
|
73
|
-
const selectable = viewer.hasAttribute("selectable");
|
|
74
|
-
const plugin = viewer.children[0] as
|
|
75
|
-
| (DatagridPluginElement & { dataset: DOMStringMap })
|
|
76
|
-
| undefined;
|
|
77
|
-
const editable = allowed || plugin?.dataset?.editMode === "EDIT";
|
|
78
|
-
return has_pivots && !selectable && editable;
|
|
79
|
-
}
|
|
29
|
+
import { CollectedCell, CollectedHeaderRow } from "./types.js";
|
|
80
30
|
|
|
81
31
|
/**
|
|
82
32
|
* Consolidated style listener that handles all cell styling in a single pass.
|
|
@@ -86,24 +36,18 @@ function isEditableMode(
|
|
|
86
36
|
*/
|
|
87
37
|
export function createConsolidatedStyleListener(
|
|
88
38
|
datagrid: DatagridPluginElement,
|
|
89
|
-
|
|
90
|
-
selectedPositionMap: LocalSelectedPositionMap,
|
|
91
|
-
): (
|
|
92
|
-
this: DatagridModel,
|
|
39
|
+
model: DatagridModel,
|
|
93
40
|
regularTable: RegularTableElement,
|
|
94
|
-
viewer:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
regularTable: RegularTableElement,
|
|
99
|
-
viewer: PerspectiveViewerElement,
|
|
100
|
-
): void {
|
|
41
|
+
viewer: HTMLPerspectiveViewerElement,
|
|
42
|
+
selectedPositionMap: SelectedPositionMap,
|
|
43
|
+
): () => void {
|
|
44
|
+
return function consolidatedStyleListener(): void {
|
|
101
45
|
const plugins: ColumnsConfig =
|
|
102
46
|
(regularTable as any)[PRIVATE_PLUGIN_SYMBOL] || {};
|
|
103
47
|
const isSettingsOpen = viewer.hasAttribute("settings");
|
|
104
|
-
const isSelectable =
|
|
105
|
-
const isEditable = isEditableMode(
|
|
106
|
-
const isEditableAllowed = isEditableMode(
|
|
48
|
+
const isSelectable = model._edit_mode === "SELECT_ROW_TREE";
|
|
49
|
+
const isEditable = isEditableMode(model, viewer);
|
|
50
|
+
const isEditableAllowed = isEditableMode(model, viewer, true);
|
|
107
51
|
|
|
108
52
|
// Toggle edit mode class on datagrid
|
|
109
53
|
datagrid.classList.toggle("edit-mode-allowed", isEditableAllowed);
|
|
@@ -117,7 +61,11 @@ export function createConsolidatedStyleListener(
|
|
|
117
61
|
cell as HTMLElement,
|
|
118
62
|
) as CellMetadata | undefined;
|
|
119
63
|
|
|
120
|
-
if (
|
|
64
|
+
if (
|
|
65
|
+
metadata &&
|
|
66
|
+
(metadata.type === "body" ||
|
|
67
|
+
metadata.type === "row_header")
|
|
68
|
+
) {
|
|
121
69
|
const isHeader = cell.tagName === "TH";
|
|
122
70
|
bodyCells.push({
|
|
123
71
|
element: cell as HTMLElement,
|
|
@@ -152,67 +100,18 @@ export function createConsolidatedStyleListener(
|
|
|
152
100
|
}
|
|
153
101
|
}
|
|
154
102
|
|
|
155
|
-
|
|
103
|
+
applyBodyCellStyles(
|
|
104
|
+
model,
|
|
156
105
|
bodyCells,
|
|
157
106
|
plugins,
|
|
158
107
|
isSettingsOpen,
|
|
159
108
|
isSelectable,
|
|
160
109
|
isEditable,
|
|
161
110
|
regularTable,
|
|
162
|
-
selectedRowsMap,
|
|
163
|
-
selectedPositionMap,
|
|
164
|
-
viewer,
|
|
165
111
|
);
|
|
166
112
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
113
|
+
applyGroupHeaderStyles(model, groupHeaderRows, regularTable);
|
|
114
|
+
applyColumnHeaderStyles(model, groupHeaderRows, regularTable, viewer);
|
|
115
|
+
applyFocusStyle(model, bodyCells, regularTable, selectedPositionMap);
|
|
170
116
|
};
|
|
171
117
|
}
|
|
172
|
-
|
|
173
|
-
declare module "../types.js" {
|
|
174
|
-
interface DatagridModel {
|
|
175
|
-
_applyBodyCellStyles(
|
|
176
|
-
cells: CollectedCell[],
|
|
177
|
-
plugins: ColumnsConfig,
|
|
178
|
-
isSettingsOpen: boolean,
|
|
179
|
-
isSelectable: boolean,
|
|
180
|
-
isEditable: boolean,
|
|
181
|
-
regularTable: RegularTableElement,
|
|
182
|
-
selectedRowsMap: LocalSelectedRowsMap,
|
|
183
|
-
selectedPositionMap: LocalSelectedPositionMap,
|
|
184
|
-
viewer: PerspectiveViewerElement,
|
|
185
|
-
): void;
|
|
186
|
-
_applyGroupHeaderStyles(
|
|
187
|
-
headerRows: CollectedHeaderRow[],
|
|
188
|
-
regularTable: RegularTableElement,
|
|
189
|
-
): void;
|
|
190
|
-
_applyColumnHeaderStyles(
|
|
191
|
-
headerRows: CollectedHeaderRow[],
|
|
192
|
-
regularTable: RegularTableElement,
|
|
193
|
-
viewer: PerspectiveViewerElement,
|
|
194
|
-
): void;
|
|
195
|
-
_applyFocusStyle(
|
|
196
|
-
cells: CollectedCell[],
|
|
197
|
-
regularTable: RegularTableElement,
|
|
198
|
-
selectedPositionMap: LocalSelectedPositionMap,
|
|
199
|
-
): void;
|
|
200
|
-
_styleColumnHeaderRow(
|
|
201
|
-
headerRow: CollectedHeaderRow,
|
|
202
|
-
regularTable: RegularTableElement,
|
|
203
|
-
is_menu_row: boolean,
|
|
204
|
-
): void;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Install the styling methods on the DatagridModel prototype.
|
|
210
|
-
* This should be called once during module initialization.
|
|
211
|
-
*/
|
|
212
|
-
export function installConsolidatedStyleMethods(modelPrototype: any): void {
|
|
213
|
-
modelPrototype._applyBodyCellStyles = applyBodyCellStyles;
|
|
214
|
-
modelPrototype._applyGroupHeaderStyles = applyGroupHeaderStyles;
|
|
215
|
-
modelPrototype._applyColumnHeaderStyles = applyColumnHeaderStyles;
|
|
216
|
-
modelPrototype._applyFocusStyle = applyFocusStyle;
|
|
217
|
-
modelPrototype._styleColumnHeaderRow = styleColumnHeaderRow;
|
|
218
|
-
}
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
|
|
13
13
|
import { RegularTableElement } from "regular-table";
|
|
14
14
|
|
|
15
|
-
import type { DatagridModel
|
|
15
|
+
import type { DatagridModel } from "../types.js";
|
|
16
|
+
import type { HTMLPerspectiveViewerElement } from "@perspective-dev/viewer";
|
|
17
|
+
import { styleColumnHeaderRow } from "./column_header.js";
|
|
16
18
|
|
|
17
19
|
import { CollectedHeaderRow } from "./types.js";
|
|
18
20
|
|
|
@@ -20,15 +22,15 @@ import { CollectedHeaderRow } from "./types.js";
|
|
|
20
22
|
* Apply styles to column header rows.
|
|
21
23
|
*/
|
|
22
24
|
export function applyColumnHeaderStyles(
|
|
23
|
-
|
|
25
|
+
model: DatagridModel,
|
|
24
26
|
headerRows: CollectedHeaderRow[],
|
|
25
27
|
regularTable: RegularTableElement,
|
|
26
|
-
viewer:
|
|
28
|
+
viewer: HTMLPerspectiveViewerElement,
|
|
27
29
|
): void {
|
|
28
30
|
if (headerRows.length === 0) return;
|
|
29
31
|
|
|
30
32
|
// Style selected column for settings panel
|
|
31
|
-
const selectedColumn =
|
|
33
|
+
const selectedColumn = model._column_settings_selected_column;
|
|
32
34
|
const len = headerRows.length;
|
|
33
35
|
const settings_open = viewer.hasAttribute("settings");
|
|
34
36
|
|
|
@@ -76,19 +78,19 @@ export function applyColumnHeaderStyles(
|
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
// Style the actual column header rows
|
|
79
|
-
const colHeadersIndex =
|
|
81
|
+
const colHeadersIndex = model._config.split_by.length;
|
|
80
82
|
if (colHeadersIndex < headerRows.length) {
|
|
81
83
|
const colHeaders = headerRows[colHeadersIndex];
|
|
82
84
|
if (colHeaders) {
|
|
83
|
-
|
|
85
|
+
styleColumnHeaderRow(model, colHeaders, regularTable, false);
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
|
|
87
|
-
const menuHeadersIndex =
|
|
89
|
+
const menuHeadersIndex = model._config.split_by.length + 1;
|
|
88
90
|
if (menuHeadersIndex < headerRows.length) {
|
|
89
91
|
const menuHeaders = headerRows[menuHeadersIndex];
|
|
90
92
|
if (menuHeaders) {
|
|
91
|
-
|
|
93
|
+
styleColumnHeaderRow(model, menuHeaders, regularTable, true);
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
96
|
}
|
|
@@ -11,18 +11,18 @@
|
|
|
11
11
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
12
|
|
|
13
13
|
import { RegularTableElement } from "regular-table";
|
|
14
|
-
import type { DatagridModel,
|
|
15
|
-
import { CollectedCell
|
|
14
|
+
import type { DatagridModel, SelectedPositionMap } from "../types.js";
|
|
15
|
+
import { CollectedCell } from "./types.js";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Apply focus style to the selected cell.
|
|
19
19
|
* Optimized to use collected cells instead of querySelectorAll.
|
|
20
20
|
*/
|
|
21
21
|
export function applyFocusStyle(
|
|
22
|
-
|
|
22
|
+
_model: DatagridModel,
|
|
23
23
|
cells: CollectedCell[],
|
|
24
24
|
regularTable: RegularTableElement,
|
|
25
|
-
selectedPositionMap:
|
|
25
|
+
selectedPositionMap: SelectedPositionMap,
|
|
26
26
|
): void {
|
|
27
27
|
const selected_position = selectedPositionMap.get(regularTable);
|
|
28
28
|
const host = regularTable.getRootNode() as Document;
|
|
@@ -60,7 +60,7 @@ export function applyFocusStyle(
|
|
|
60
60
|
*/
|
|
61
61
|
export function focusSelectedCell(
|
|
62
62
|
regularTable: RegularTableElement,
|
|
63
|
-
selectedPositionMap:
|
|
63
|
+
selectedPositionMap: SelectedPositionMap,
|
|
64
64
|
): boolean {
|
|
65
65
|
const selected_position = selectedPositionMap.get(regularTable);
|
|
66
66
|
if (!selected_position) {
|
|
@@ -19,11 +19,11 @@ import { CollectedHeaderRow } from "./types.js";
|
|
|
19
19
|
* Apply styles to group header rows.
|
|
20
20
|
*/
|
|
21
21
|
export function applyGroupHeaderStyles(
|
|
22
|
-
|
|
22
|
+
model: DatagridModel,
|
|
23
23
|
headerRows: CollectedHeaderRow[],
|
|
24
24
|
regularTable: RegularTableElement,
|
|
25
25
|
): void {
|
|
26
|
-
const header_depth =
|
|
26
|
+
const header_depth = model._config.group_by.length;
|
|
27
27
|
const m: boolean[][] = [];
|
|
28
28
|
let marked = new Set<number>();
|
|
29
29
|
|
|
@@ -54,6 +54,7 @@ export function applyGroupHeaderStyles(
|
|
|
54
54
|
);
|
|
55
55
|
|
|
56
56
|
td.classList.toggle("psp-color-mode-bar", false);
|
|
57
|
+
td.classList.toggle("psp-color-mode-label-bar", false);
|
|
57
58
|
td.classList.toggle("psp-header-sort-asc", false);
|
|
58
59
|
td.classList.toggle("psp-header-sort-desc", false);
|
|
59
60
|
td.classList.toggle("psp-header-sort-col-asc", false);
|
|
@@ -14,7 +14,7 @@ import { CellMetadata } from "regular-table/dist/esm/types.js";
|
|
|
14
14
|
import type { DatagridModel, ColumnConfig, ColorRecord } from "../../types.js";
|
|
15
15
|
|
|
16
16
|
export function cell_style_boolean(
|
|
17
|
-
|
|
17
|
+
model: DatagridModel,
|
|
18
18
|
_plugin: ColumnConfig | undefined,
|
|
19
19
|
td: HTMLElement,
|
|
20
20
|
metadata: CellMetadata,
|
|
@@ -26,9 +26,9 @@ export function cell_style_boolean(
|
|
|
26
26
|
} else {
|
|
27
27
|
const [hex]: ColorRecord | [string, number, number, number, string] =
|
|
28
28
|
metadata.user === true
|
|
29
|
-
?
|
|
29
|
+
? model._pos_fg_color
|
|
30
30
|
: metadata.user === false
|
|
31
|
-
?
|
|
31
|
+
? model._neg_fg_color
|
|
32
32
|
: ["", 0, 0, 0, ""];
|
|
33
33
|
td.style.backgroundColor = "";
|
|
34
34
|
td.style.color = hex;
|