@perspective-dev/viewer-datagrid 4.3.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 +6 -2
- 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 +3 -5
- package/src/css/mitered-headers.css +64 -0
- package/src/css/perspective-viewer-datagrid.css +6 -0
- package/src/{less/pro.less → css/pro.css} +32 -31
- package/src/css/regular_table.css +589 -0
- package/src/{less/row-hover.less → css/row-hover.css} +48 -29
- package/src/{less/scrollbar.less → css/scrollbar.css} +16 -15
- package/src/{less/sub-cell-scroll.less → css/sub-cell-scroll.css} +14 -13
- package/src/{less/toolbar.less → css/toolbar.css} +57 -39
- 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 +55 -59
- 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 +56 -61
- 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 +14 -11
- 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/less/mitered-headers.less +0 -65
- package/src/less/regular_table.less +0 -526
- package/src/ts/event_handlers/deselect_all.ts +0 -28
- package/src/ts/event_handlers/row_select_click.ts +0 -92
|
@@ -14,25 +14,29 @@ import { focusSelectedCell } from "../../style_handlers/focus.js";
|
|
|
14
14
|
import type {
|
|
15
15
|
RegularTable,
|
|
16
16
|
DatagridModel,
|
|
17
|
-
|
|
18
|
-
SelectedPosition,
|
|
17
|
+
SelectedPositionMap,
|
|
19
18
|
} from "../../types.js";
|
|
19
|
+
import type { HTMLPerspectiveViewerElement } from "@perspective-dev/viewer";
|
|
20
20
|
|
|
21
|
-
type
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
type AsyncMoveFunction = (
|
|
22
|
+
model: DatagridModel,
|
|
23
|
+
table: RegularTable,
|
|
24
|
+
selected_position_map: SelectedPositionMap,
|
|
25
|
+
active_cell: HTMLElement,
|
|
26
|
+
dx: number,
|
|
27
|
+
dy: number,
|
|
28
|
+
) => Promise<void | undefined>;
|
|
27
29
|
|
|
28
|
-
function lock
|
|
29
|
-
body: AsyncFunction<T, R>,
|
|
30
|
-
): AsyncFunction<T, R | undefined> {
|
|
30
|
+
function lock(body: AsyncMoveFunction): AsyncMoveFunction {
|
|
31
31
|
let lockPromise: Promise<void> | undefined;
|
|
32
32
|
return async function (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
model: DatagridModel,
|
|
34
|
+
table: RegularTable,
|
|
35
|
+
selected_position_map: SelectedPositionMap,
|
|
36
|
+
active_cell: HTMLElement,
|
|
37
|
+
dx: number,
|
|
38
|
+
dy: number,
|
|
39
|
+
): Promise<void | undefined> {
|
|
36
40
|
if (lockPromise) {
|
|
37
41
|
await lockPromise;
|
|
38
42
|
return;
|
|
@@ -40,7 +44,14 @@ function lock<T extends unknown[], R>(
|
|
|
40
44
|
|
|
41
45
|
let resolve: () => void;
|
|
42
46
|
lockPromise = new Promise((x) => (resolve = x));
|
|
43
|
-
const result = await body
|
|
47
|
+
const result = await body(
|
|
48
|
+
model,
|
|
49
|
+
table,
|
|
50
|
+
selected_position_map,
|
|
51
|
+
active_cell,
|
|
52
|
+
dx,
|
|
53
|
+
dy,
|
|
54
|
+
);
|
|
44
55
|
lockPromise = undefined;
|
|
45
56
|
resolve!();
|
|
46
57
|
return result;
|
|
@@ -52,23 +63,23 @@ interface ContentEditableElement extends HTMLElement {
|
|
|
52
63
|
selectionStart?: number;
|
|
53
64
|
}
|
|
54
65
|
|
|
55
|
-
function getPos(
|
|
56
|
-
if (
|
|
57
|
-
const _range = (
|
|
66
|
+
function getPos(elem: ContentEditableElement): number {
|
|
67
|
+
if (elem.isContentEditable) {
|
|
68
|
+
const _range = (elem.getRootNode() as Document)
|
|
58
69
|
.getSelection()
|
|
59
70
|
?.getRangeAt(0);
|
|
60
71
|
if (!_range) return 0;
|
|
61
72
|
const range = _range.cloneRange();
|
|
62
|
-
range.selectNodeContents(
|
|
73
|
+
range.selectNodeContents(elem);
|
|
63
74
|
range.setEnd(_range.endContainer, _range.endOffset);
|
|
64
75
|
return range.toString().length;
|
|
65
76
|
} else {
|
|
66
|
-
return
|
|
77
|
+
return elem.selectionStart || 0;
|
|
67
78
|
}
|
|
68
79
|
}
|
|
69
80
|
|
|
70
81
|
const moveSelection = lock(async function (
|
|
71
|
-
|
|
82
|
+
model: DatagridModel,
|
|
72
83
|
table: RegularTable,
|
|
73
84
|
selected_position_map: SelectedPositionMap,
|
|
74
85
|
active_cell: HTMLElement,
|
|
@@ -77,8 +88,8 @@ const moveSelection = lock(async function (
|
|
|
77
88
|
): Promise<void> {
|
|
78
89
|
const meta = table.getMeta(active_cell);
|
|
79
90
|
if (!meta || meta.type !== "body") return;
|
|
80
|
-
const num_columns =
|
|
81
|
-
const num_rows =
|
|
91
|
+
const num_columns = model._column_paths.length;
|
|
92
|
+
const num_rows = model._num_rows;
|
|
82
93
|
const selected_position = selected_position_map.get(table);
|
|
83
94
|
if (!selected_position) {
|
|
84
95
|
return;
|
|
@@ -122,9 +133,9 @@ function isLastCell(
|
|
|
122
133
|
}
|
|
123
134
|
|
|
124
135
|
export function keydownListener(
|
|
125
|
-
|
|
136
|
+
model: DatagridModel,
|
|
126
137
|
table: RegularTable,
|
|
127
|
-
_viewer:
|
|
138
|
+
_viewer: HTMLPerspectiveViewerElement,
|
|
128
139
|
selected_position_map: SelectedPositionMap,
|
|
129
140
|
event: KeyboardEvent,
|
|
130
141
|
): void {
|
|
@@ -134,12 +145,12 @@ export function keydownListener(
|
|
|
134
145
|
switch (event.key) {
|
|
135
146
|
case "Enter":
|
|
136
147
|
event.preventDefault();
|
|
137
|
-
if (isLastCell(
|
|
148
|
+
if (isLastCell(model, table, target)) {
|
|
138
149
|
target.blur();
|
|
139
150
|
selected_position_map.delete(table);
|
|
140
151
|
} else if (event.shiftKey) {
|
|
141
|
-
moveSelection
|
|
142
|
-
|
|
152
|
+
moveSelection(
|
|
153
|
+
model,
|
|
143
154
|
table,
|
|
144
155
|
selected_position_map,
|
|
145
156
|
target,
|
|
@@ -147,8 +158,8 @@ export function keydownListener(
|
|
|
147
158
|
-1,
|
|
148
159
|
);
|
|
149
160
|
} else {
|
|
150
|
-
moveSelection
|
|
151
|
-
|
|
161
|
+
moveSelection(
|
|
162
|
+
model,
|
|
152
163
|
table,
|
|
153
164
|
selected_position_map,
|
|
154
165
|
target,
|
|
@@ -158,10 +169,10 @@ export function keydownListener(
|
|
|
158
169
|
}
|
|
159
170
|
break;
|
|
160
171
|
case "ArrowLeft":
|
|
161
|
-
if (getPos
|
|
172
|
+
if (getPos(target as ContentEditableElement) === 0) {
|
|
162
173
|
event.preventDefault();
|
|
163
|
-
moveSelection
|
|
164
|
-
|
|
174
|
+
moveSelection(
|
|
175
|
+
model,
|
|
165
176
|
table,
|
|
166
177
|
selected_position_map,
|
|
167
178
|
target,
|
|
@@ -172,23 +183,16 @@ export function keydownListener(
|
|
|
172
183
|
break;
|
|
173
184
|
case "ArrowUp":
|
|
174
185
|
event.preventDefault();
|
|
175
|
-
moveSelection
|
|
176
|
-
this,
|
|
177
|
-
table,
|
|
178
|
-
selected_position_map,
|
|
179
|
-
target,
|
|
180
|
-
0,
|
|
181
|
-
-1,
|
|
182
|
-
);
|
|
186
|
+
moveSelection(model, table, selected_position_map, target, 0, -1);
|
|
183
187
|
break;
|
|
184
188
|
case "ArrowRight":
|
|
185
189
|
if (
|
|
186
|
-
getPos
|
|
190
|
+
getPos(target as ContentEditableElement) ===
|
|
187
191
|
(target.textContent?.length || 0)
|
|
188
192
|
) {
|
|
189
193
|
event.preventDefault();
|
|
190
|
-
moveSelection
|
|
191
|
-
|
|
194
|
+
moveSelection(
|
|
195
|
+
model,
|
|
192
196
|
table,
|
|
193
197
|
selected_position_map,
|
|
194
198
|
target,
|
|
@@ -199,14 +203,7 @@ export function keydownListener(
|
|
|
199
203
|
break;
|
|
200
204
|
case "ArrowDown":
|
|
201
205
|
event.preventDefault();
|
|
202
|
-
moveSelection
|
|
203
|
-
this,
|
|
204
|
-
table,
|
|
205
|
-
selected_position_map,
|
|
206
|
-
target,
|
|
207
|
-
0,
|
|
208
|
-
1,
|
|
209
|
-
);
|
|
206
|
+
moveSelection(model, table, selected_position_map, target, 0, 1);
|
|
210
207
|
break;
|
|
211
208
|
default:
|
|
212
209
|
}
|
|
@@ -13,16 +13,24 @@
|
|
|
13
13
|
import { RegularTableElement } from "regular-table";
|
|
14
14
|
import type {
|
|
15
15
|
DatagridPluginElement,
|
|
16
|
-
|
|
16
|
+
EditMode,
|
|
17
17
|
SelectionArea,
|
|
18
18
|
} from "../types.js";
|
|
19
|
-
import {
|
|
19
|
+
import type { HTMLPerspectiveViewerElement } from "@perspective-dev/viewer";
|
|
20
|
+
import type { ViewWindow } from "@perspective-dev/client";
|
|
21
|
+
import type { CellMetadataBody } from "regular-table/dist/esm/types.js";
|
|
20
22
|
|
|
21
23
|
const MOUSE_SELECTED_AREA_CLASS = "mouse-selected-area";
|
|
22
24
|
|
|
25
|
+
export type OnSelectCallback = (
|
|
26
|
+
area: SelectionArea,
|
|
27
|
+
isDeselect: boolean,
|
|
28
|
+
) => void;
|
|
29
|
+
|
|
23
30
|
interface AddAreaMouseSelectionOptions {
|
|
24
31
|
className?: string;
|
|
25
32
|
selected?: SelectionArea[];
|
|
33
|
+
onSelect?: OnSelectCallback;
|
|
26
34
|
}
|
|
27
35
|
|
|
28
36
|
export const addAreaMouseSelection = (
|
|
@@ -31,6 +39,7 @@ export const addAreaMouseSelection = (
|
|
|
31
39
|
{
|
|
32
40
|
className = MOUSE_SELECTED_AREA_CLASS,
|
|
33
41
|
selected = [],
|
|
42
|
+
onSelect,
|
|
34
43
|
}: AddAreaMouseSelectionOptions = {},
|
|
35
44
|
): RegularTableElement => {
|
|
36
45
|
datagrid.model!._selection_state = {
|
|
@@ -50,7 +59,7 @@ export const addAreaMouseSelection = (
|
|
|
50
59
|
|
|
51
60
|
table.addEventListener(
|
|
52
61
|
"mouseup",
|
|
53
|
-
getMouseupListener(datagrid, table, className),
|
|
62
|
+
getMouseupListener(datagrid, table, className, onSelect),
|
|
54
63
|
);
|
|
55
64
|
|
|
56
65
|
table.addStyleListener(() =>
|
|
@@ -60,6 +69,10 @@ export const addAreaMouseSelection = (
|
|
|
60
69
|
return table;
|
|
61
70
|
};
|
|
62
71
|
|
|
72
|
+
function isSingleClickMode(mode: EditMode): boolean {
|
|
73
|
+
return mode === "SELECT_ROW_TREE";
|
|
74
|
+
}
|
|
75
|
+
|
|
63
76
|
const getMousedownListener =
|
|
64
77
|
(
|
|
65
78
|
datagrid: DatagridPluginElement,
|
|
@@ -70,10 +83,9 @@ const getMousedownListener =
|
|
|
70
83
|
const mouseEvent = event as MouseEvent;
|
|
71
84
|
if (
|
|
72
85
|
mouseEvent.button === 0 &&
|
|
73
|
-
(datagrid.model!._edit_mode
|
|
74
|
-
datagrid.model!._edit_mode === "SELECT_ROW" ||
|
|
75
|
-
datagrid.model!._edit_mode === "SELECT_COLUMN")
|
|
86
|
+
isSelectionMode(datagrid.model!._edit_mode)
|
|
76
87
|
) {
|
|
88
|
+
if (isSingleClickMode(datagrid.model!._edit_mode)) return;
|
|
77
89
|
datagrid.model!._selection_state.CURRENT_MOUSEDOWN_COORDINATES = {};
|
|
78
90
|
const meta = table.getMeta(mouseEvent.target as HTMLElement);
|
|
79
91
|
if (
|
|
@@ -122,11 +134,8 @@ const getMouseoverListener =
|
|
|
122
134
|
) =>
|
|
123
135
|
(event: Event): void => {
|
|
124
136
|
const mouseEvent = event as MouseEvent;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
datagrid.model!._edit_mode === "SELECT_ROW" ||
|
|
128
|
-
datagrid.model!._edit_mode === "SELECT_COLUMN"
|
|
129
|
-
) {
|
|
137
|
+
const mode = datagrid.model!._edit_mode;
|
|
138
|
+
if (isSelectionMode(mode) && !isSingleClickMode(mode)) {
|
|
130
139
|
if (
|
|
131
140
|
datagrid.model!._selection_state
|
|
132
141
|
.CURRENT_MOUSEDOWN_COORDINATES &&
|
|
@@ -183,17 +192,63 @@ const getMouseupListener =
|
|
|
183
192
|
datagrid: DatagridPluginElement,
|
|
184
193
|
table: RegularTableElement,
|
|
185
194
|
className: string,
|
|
195
|
+
onSelect?: OnSelectCallback,
|
|
186
196
|
) =>
|
|
187
197
|
(event: Event): void => {
|
|
188
198
|
const mouseEvent = event as MouseEvent;
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
datagrid.model!._edit_mode === "SELECT_ROW" ||
|
|
192
|
-
datagrid.model!._edit_mode === "SELECT_COLUMN"
|
|
193
|
-
) {
|
|
199
|
+
const mode = datagrid.model!._edit_mode;
|
|
200
|
+
if (isSelectionMode(mode)) {
|
|
194
201
|
const meta = table.getMeta(mouseEvent.target as HTMLElement);
|
|
195
202
|
if (!meta) return;
|
|
196
203
|
|
|
204
|
+
// For single-click modes (SELECT_ROW_TREE), handle toggle
|
|
205
|
+
if (isSingleClickMode(mode)) {
|
|
206
|
+
if (
|
|
207
|
+
(meta.type === "body" || meta.type === "row_header") &&
|
|
208
|
+
meta.y !== undefined &&
|
|
209
|
+
meta.y >= 0
|
|
210
|
+
) {
|
|
211
|
+
const existing =
|
|
212
|
+
datagrid.model!._selection_state.selected_areas;
|
|
213
|
+
const isSameRow =
|
|
214
|
+
existing.length > 0 && existing[0].y0 === meta.y;
|
|
215
|
+
|
|
216
|
+
if (isSameRow) {
|
|
217
|
+
// Deselect
|
|
218
|
+
datagrid.model!._selection_state.selected_areas = [];
|
|
219
|
+
datagrid.model!._selection_state.dirty = true;
|
|
220
|
+
applyMouseAreaSelections(
|
|
221
|
+
datagrid,
|
|
222
|
+
table,
|
|
223
|
+
className,
|
|
224
|
+
[],
|
|
225
|
+
);
|
|
226
|
+
onSelect?.(existing[0], true);
|
|
227
|
+
} else {
|
|
228
|
+
// Select new row
|
|
229
|
+
const area: SelectionArea = {
|
|
230
|
+
x0: 0,
|
|
231
|
+
x1: 0,
|
|
232
|
+
y0: meta.y,
|
|
233
|
+
y1: meta.y,
|
|
234
|
+
};
|
|
235
|
+
datagrid.model!._selection_state.selected_areas = [
|
|
236
|
+
area,
|
|
237
|
+
];
|
|
238
|
+
datagrid.model!._selection_state.dirty = true;
|
|
239
|
+
applyMouseAreaSelections(datagrid, table, className);
|
|
240
|
+
onSelect?.(area, false);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
datagrid.model!._selection_state.CURRENT_MOUSEDOWN_COORDINATES =
|
|
245
|
+
{};
|
|
246
|
+
datagrid.model!._selection_state.potential_selection =
|
|
247
|
+
undefined;
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Drag-based modes (SELECT_ROW, SELECT_COLUMN, SELECT_REGION)
|
|
197
252
|
if (
|
|
198
253
|
(datagrid.model!._selection_state.old_selected_areas?.length ??
|
|
199
254
|
0) > 0
|
|
@@ -260,80 +315,103 @@ const getMouseupListener =
|
|
|
260
315
|
}
|
|
261
316
|
};
|
|
262
317
|
|
|
318
|
+
function modeIncludesColumns(mode: EditMode): boolean {
|
|
319
|
+
return mode === "SELECT_COLUMN" || mode === "SELECT_REGION";
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function modeIncludesRows(mode: EditMode): boolean {
|
|
323
|
+
return (
|
|
324
|
+
mode === "SELECT_ROW" ||
|
|
325
|
+
mode === "SELECT_REGION" ||
|
|
326
|
+
mode === "SELECT_ROW_TREE"
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
263
330
|
function set_psp_selection(
|
|
264
|
-
viewer:
|
|
331
|
+
viewer: HTMLPerspectiveViewerElement,
|
|
265
332
|
datagrid: DatagridPluginElement,
|
|
266
333
|
{ x0, x1, y0, y1 }: SelectionArea,
|
|
267
334
|
): void {
|
|
268
335
|
const viewport: ViewWindow = {};
|
|
269
336
|
const mode = datagrid.model!._edit_mode;
|
|
270
|
-
if (
|
|
271
|
-
x0 !== undefined &&
|
|
272
|
-
["SELECT_COLUMN", "SELECT_REGION"].indexOf(mode) > -1
|
|
273
|
-
) {
|
|
337
|
+
if (x0 !== undefined && modeIncludesColumns(mode)) {
|
|
274
338
|
viewport.start_col = x0;
|
|
275
339
|
}
|
|
276
340
|
|
|
277
|
-
if (
|
|
278
|
-
x1 !== undefined &&
|
|
279
|
-
["SELECT_COLUMN", "SELECT_REGION"].indexOf(mode) > -1
|
|
280
|
-
) {
|
|
341
|
+
if (x1 !== undefined && modeIncludesColumns(mode)) {
|
|
281
342
|
viewport.end_col = x1 + 1;
|
|
282
343
|
}
|
|
283
344
|
|
|
284
|
-
if (
|
|
285
|
-
y0 !== undefined &&
|
|
286
|
-
["SELECT_ROW", "SELECT_REGION"].indexOf(mode) > -1
|
|
287
|
-
) {
|
|
345
|
+
if (y0 !== undefined && modeIncludesRows(mode)) {
|
|
288
346
|
viewport.start_row = y0;
|
|
289
347
|
}
|
|
290
348
|
|
|
291
|
-
if (
|
|
292
|
-
y1 !== undefined &&
|
|
293
|
-
["SELECT_ROW", "SELECT_REGION"].indexOf(mode) > -1
|
|
294
|
-
) {
|
|
349
|
+
if (y1 !== undefined && modeIncludesRows(mode)) {
|
|
295
350
|
viewport.end_row = y1 + 1;
|
|
296
351
|
}
|
|
297
352
|
|
|
298
353
|
viewer.setSelection(viewport);
|
|
299
354
|
}
|
|
300
355
|
|
|
356
|
+
type CellPredicate = (meta: CellMetadataBody, area: SelectionArea) => boolean;
|
|
357
|
+
|
|
358
|
+
const SELECTION_PREDICATES: Record<string, CellPredicate> = {
|
|
359
|
+
SELECT_REGION: (m, a) =>
|
|
360
|
+
a.x0 <= m.x && m.x <= a.x1 && a.y0 <= m.y && m.y <= a.y1,
|
|
361
|
+
SELECT_ROW: (m, a) => a.y0 <= m.y && m.y <= a.y1,
|
|
362
|
+
SELECT_ROW_TREE: (m, a) => a.y0 <= m.y && m.y <= a.y1,
|
|
363
|
+
SELECT_COLUMN: (m, a) => a.x0 <= m.x && m.x <= a.x1,
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
function isSelectionMode(mode: EditMode): boolean {
|
|
367
|
+
return (
|
|
368
|
+
mode === "SELECT_REGION" ||
|
|
369
|
+
mode === "SELECT_ROW" ||
|
|
370
|
+
mode === "SELECT_COLUMN" ||
|
|
371
|
+
mode === "SELECT_ROW_TREE"
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
|
|
301
375
|
export const applyMouseAreaSelections = (
|
|
302
376
|
datagrid: DatagridPluginElement,
|
|
303
377
|
table: RegularTableElement,
|
|
304
378
|
className: string,
|
|
305
379
|
selected?: SelectionArea[],
|
|
306
380
|
): void => {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
datagrid.model!._edit_mode === "SELECT_ROW" ||
|
|
310
|
-
datagrid.model!._edit_mode === "SELECT_COLUMN"
|
|
311
|
-
) {
|
|
381
|
+
const mode = datagrid.model!._edit_mode;
|
|
382
|
+
if (isSelectionMode(mode)) {
|
|
312
383
|
selected = datagrid.model!._selection_state.selected_areas.slice(0);
|
|
313
384
|
if (datagrid.model!._selection_state.potential_selection) {
|
|
314
385
|
selected.push(datagrid.model!._selection_state.potential_selection);
|
|
315
386
|
}
|
|
316
387
|
|
|
317
|
-
const tds = table.querySelectorAll("tbody td");
|
|
318
|
-
|
|
319
388
|
if (selected.length > 0) {
|
|
320
389
|
set_psp_selection(
|
|
321
|
-
datagrid.parentElement as
|
|
390
|
+
datagrid.parentElement as HTMLPerspectiveViewerElement,
|
|
322
391
|
datagrid,
|
|
323
392
|
selected[0],
|
|
324
393
|
);
|
|
325
|
-
|
|
394
|
+
|
|
395
|
+
// SELECT_ROW_TREE styling is handled entirely by the
|
|
396
|
+
// identity-based system in body.ts, which styles both td
|
|
397
|
+
// and th uniformly in a single draw pass.
|
|
398
|
+
if (!isSingleClickMode(mode)) {
|
|
399
|
+
applyMouseAreaSelection(datagrid, table, selected, className);
|
|
400
|
+
}
|
|
326
401
|
} else {
|
|
327
|
-
(
|
|
402
|
+
(
|
|
403
|
+
datagrid.parentElement as HTMLPerspectiveViewerElement
|
|
404
|
+
).setSelection();
|
|
405
|
+
const tds = table.querySelectorAll("tbody td");
|
|
328
406
|
for (const td of tds) {
|
|
329
407
|
td.classList.remove(className);
|
|
330
408
|
}
|
|
331
409
|
}
|
|
332
410
|
} else if (datagrid.model!._selection_state.dirty) {
|
|
333
411
|
datagrid.model!._selection_state.dirty = false;
|
|
334
|
-
const
|
|
335
|
-
for (const
|
|
336
|
-
|
|
412
|
+
const cells = table.querySelectorAll("tbody td, tbody th");
|
|
413
|
+
for (const cell of cells) {
|
|
414
|
+
cell.classList.remove(className);
|
|
337
415
|
}
|
|
338
416
|
}
|
|
339
417
|
};
|
|
@@ -344,96 +422,29 @@ const applyMouseAreaSelection = (
|
|
|
344
422
|
selected: SelectionArea[],
|
|
345
423
|
className: string,
|
|
346
424
|
): void => {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
)
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
meta.y <= y1
|
|
366
|
-
) {
|
|
367
|
-
rendered = true;
|
|
368
|
-
datagrid.model!._selection_state.dirty = true;
|
|
369
|
-
td.classList.add(className);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
if (!rendered) {
|
|
375
|
-
td.classList.remove(className);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
} else if (
|
|
379
|
-
datagrid.model!._edit_mode === "SELECT_ROW" &&
|
|
380
|
-
selected.length > 0
|
|
381
|
-
) {
|
|
382
|
-
const tds = table.querySelectorAll("tbody td");
|
|
383
|
-
|
|
384
|
-
for (const td of tds) {
|
|
385
|
-
const meta = table.getMeta(td as HTMLElement);
|
|
386
|
-
if (!meta) continue;
|
|
387
|
-
let rendered = false;
|
|
388
|
-
for (const { x0, x1, y0, y1 } of selected) {
|
|
389
|
-
if (
|
|
390
|
-
x0 !== undefined &&
|
|
391
|
-
y0 !== undefined &&
|
|
392
|
-
x1 !== undefined &&
|
|
393
|
-
y1 !== undefined &&
|
|
394
|
-
meta?.type === "body"
|
|
395
|
-
) {
|
|
396
|
-
if (y0 <= meta.y && meta.y <= y1) {
|
|
397
|
-
datagrid.model!._selection_state.dirty = true;
|
|
398
|
-
rendered = true;
|
|
399
|
-
td.classList.add(className);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
if (!rendered) {
|
|
405
|
-
td.classList.remove(className);
|
|
425
|
+
const predicate = SELECTION_PREDICATES[datagrid.model!._edit_mode];
|
|
426
|
+
if (!predicate || selected.length === 0) return;
|
|
427
|
+
const tds = table.querySelectorAll("tbody td");
|
|
428
|
+
for (const td of tds) {
|
|
429
|
+
const meta = table.getMeta(td as HTMLElement);
|
|
430
|
+
if (!meta || meta.type !== "body") continue;
|
|
431
|
+
let rendered = false;
|
|
432
|
+
for (const area of selected) {
|
|
433
|
+
if (
|
|
434
|
+
area.x0 !== undefined &&
|
|
435
|
+
area.y0 !== undefined &&
|
|
436
|
+
area.x1 !== undefined &&
|
|
437
|
+
area.y1 !== undefined &&
|
|
438
|
+
predicate(meta, area)
|
|
439
|
+
) {
|
|
440
|
+
rendered = true;
|
|
441
|
+
datagrid.model!._selection_state.dirty = true;
|
|
442
|
+
td.classList.add(className);
|
|
406
443
|
}
|
|
407
444
|
}
|
|
408
|
-
} else if (
|
|
409
|
-
datagrid.model!._edit_mode === "SELECT_COLUMN" &&
|
|
410
|
-
selected.length > 0
|
|
411
|
-
) {
|
|
412
|
-
const tds = table.querySelectorAll("tbody td");
|
|
413
|
-
|
|
414
|
-
for (const td of tds) {
|
|
415
|
-
const meta = table.getMeta(td as HTMLElement);
|
|
416
|
-
if (!meta) continue;
|
|
417
|
-
let rendered = false;
|
|
418
|
-
for (const { x0, x1, y0, y1 } of selected) {
|
|
419
|
-
if (
|
|
420
|
-
x0 !== undefined &&
|
|
421
|
-
y0 !== undefined &&
|
|
422
|
-
x1 !== undefined &&
|
|
423
|
-
y1 !== undefined &&
|
|
424
|
-
meta?.type === "body"
|
|
425
|
-
) {
|
|
426
|
-
if (x0 <= meta.x && meta.x <= x1) {
|
|
427
|
-
datagrid.model!._selection_state.dirty = true;
|
|
428
|
-
rendered = true;
|
|
429
|
-
td.classList.add(className);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
445
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
}
|
|
446
|
+
if (!rendered) {
|
|
447
|
+
td.classList.remove(className);
|
|
437
448
|
}
|
|
438
449
|
}
|
|
439
450
|
};
|