@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.
Files changed (80) hide show
  1. package/dist/cdn/perspective-viewer-datagrid.js +4 -22
  2. package/dist/cdn/perspective-viewer-datagrid.js.map +4 -4
  3. package/dist/css/perspective-viewer-datagrid-toolbar.css +1 -1
  4. package/dist/css/perspective-viewer-datagrid.css +1 -1
  5. package/dist/esm/color_utils.d.ts +22 -0
  6. package/dist/esm/custom_elements/datagrid.d.ts +5 -5
  7. package/dist/esm/data_listener/format_cell.d.ts +1 -1
  8. package/dist/esm/data_listener/formatter_cache.d.ts +1 -1
  9. package/dist/esm/data_listener/index.d.ts +3 -2
  10. package/dist/esm/event_handlers/click/edit_click.d.ts +3 -2
  11. package/dist/esm/event_handlers/click.d.ts +4 -6
  12. package/dist/esm/event_handlers/dispatch_click.d.ts +3 -2
  13. package/dist/esm/event_handlers/expand_collapse.d.ts +1 -1
  14. package/dist/esm/event_handlers/focus.d.ts +4 -5
  15. package/dist/esm/event_handlers/header_click.d.ts +5 -3
  16. package/dist/esm/event_handlers/keydown/edit_keydown.d.ts +3 -4
  17. package/dist/esm/event_handlers/select_region.d.ts +3 -1
  18. package/dist/esm/event_handlers/sort.d.ts +8 -7
  19. package/dist/esm/model/create.d.ts +1 -1
  20. package/dist/esm/perspective-viewer-datagrid.js +3 -3
  21. package/dist/esm/perspective-viewer-datagrid.js.map +4 -4
  22. package/dist/esm/plugin/activate.d.ts +1 -1
  23. package/dist/esm/plugin/column_style_controls.d.ts +1 -1
  24. package/dist/esm/style_handlers/body.d.ts +3 -3
  25. package/dist/esm/style_handlers/column_header.d.ts +4 -3
  26. package/dist/esm/style_handlers/consolidated.d.ts +3 -47
  27. package/dist/esm/style_handlers/editable.d.ts +3 -2
  28. package/dist/esm/style_handlers/focus.d.ts +4 -4
  29. package/dist/esm/style_handlers/group_header.d.ts +1 -1
  30. package/dist/esm/style_handlers/table_cell/boolean.d.ts +1 -1
  31. package/dist/esm/style_handlers/table_cell/cell_flash.d.ts +1 -1
  32. package/dist/esm/style_handlers/table_cell/datetime.d.ts +1 -1
  33. package/dist/esm/style_handlers/table_cell/numeric.d.ts +1 -1
  34. package/dist/esm/style_handlers/table_cell/row_header.d.ts +1 -1
  35. package/dist/esm/style_handlers/table_cell/string.d.ts +1 -1
  36. package/dist/esm/style_handlers/types.d.ts +0 -4
  37. package/dist/esm/types.d.ts +10 -17
  38. package/package.json +2 -4
  39. package/src/css/regular_table.css +87 -31
  40. package/src/css/row-hover.css +20 -7
  41. package/src/css/toolbar.css +11 -0
  42. package/src/ts/color_utils.ts +144 -16
  43. package/src/ts/custom_elements/datagrid.ts +11 -12
  44. package/src/ts/custom_elements/toolbar.ts +4 -5
  45. package/src/ts/data_listener/format_cell.ts +28 -9
  46. package/src/ts/data_listener/formatter_cache.ts +1 -1
  47. package/src/ts/data_listener/index.ts +4 -8
  48. package/src/ts/event_handlers/click/edit_click.ts +7 -6
  49. package/src/ts/event_handlers/click.ts +39 -68
  50. package/src/ts/event_handlers/dispatch_click.ts +24 -25
  51. package/src/ts/event_handlers/expand_collapse.ts +7 -7
  52. package/src/ts/event_handlers/focus.ts +38 -35
  53. package/src/ts/event_handlers/header_click.ts +101 -62
  54. package/src/ts/event_handlers/keydown/edit_keydown.ts +49 -52
  55. package/src/ts/event_handlers/select_region.ts +144 -133
  56. package/src/ts/event_handlers/sort.ts +16 -24
  57. package/src/ts/model/column_overrides.ts +13 -4
  58. package/src/ts/model/create.ts +51 -55
  59. package/src/ts/model/toolbar.ts +23 -7
  60. package/src/ts/plugin/activate.ts +120 -92
  61. package/src/ts/plugin/column_style_controls.ts +1 -1
  62. package/src/ts/plugin/save.ts +1 -0
  63. package/src/ts/style_handlers/body.ts +44 -51
  64. package/src/ts/style_handlers/column_header.ts +16 -19
  65. package/src/ts/style_handlers/consolidated.ts +22 -123
  66. package/src/ts/style_handlers/editable.ts +10 -8
  67. package/src/ts/style_handlers/focus.ts +5 -5
  68. package/src/ts/style_handlers/group_header.ts +3 -2
  69. package/src/ts/style_handlers/table_cell/boolean.ts +3 -3
  70. package/src/ts/style_handlers/table_cell/cell_flash.ts +11 -11
  71. package/src/ts/style_handlers/table_cell/datetime.ts +3 -3
  72. package/src/ts/style_handlers/table_cell/numeric.ts +24 -25
  73. package/src/ts/style_handlers/table_cell/row_header.ts +2 -2
  74. package/src/ts/style_handlers/table_cell/string.ts +20 -18
  75. package/src/ts/style_handlers/types.ts +0 -10
  76. package/src/ts/types.ts +28 -20
  77. package/dist/esm/event_handlers/deselect_all.d.ts +0 -5
  78. package/dist/esm/event_handlers/row_select_click.d.ts +0 -4
  79. package/src/ts/event_handlers/deselect_all.ts +0 -28
  80. package/src/ts/event_handlers/row_select_click.ts +0 -92
@@ -10,54 +10,57 @@
10
10
  // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
- import { is_editable } from "./click.js";
14
13
  import { write_cell } from "./click/edit_click.js";
15
14
  import type {
16
15
  RegularTable,
17
16
  DatagridModel,
18
- PerspectiveViewerElement,
19
17
  SelectedPosition,
18
+ SelectedPositionMap,
20
19
  } from "../types.js";
20
+ import { isEditableMode } from "../types.js";
21
+ import type { HTMLPerspectiveViewerElement } from "@perspective-dev/viewer";
21
22
 
22
- type SelectedPositionMap = Map<RegularTable, SelectedPosition>;
23
-
24
- export function focusoutListener(
25
- this: DatagridModel,
23
+ export function createFocusoutListener(
24
+ model: DatagridModel,
26
25
  table: RegularTable,
27
- viewer: PerspectiveViewerElement,
26
+ viewer: HTMLPerspectiveViewerElement,
28
27
  selected_position_map: SelectedPositionMap,
29
- event: FocusEvent,
30
- ): void {
31
- if (is_editable.call(this, viewer) && selected_position_map.has(table)) {
32
- const target = event.target as HTMLElement;
33
- target.classList.remove("psp-error");
34
- const selectedPosition = selected_position_map.get(table)!;
35
- selected_position_map.delete(table);
36
- if (selectedPosition.content !== target.textContent) {
37
- if (!write_cell(table, this, target)) {
38
- target.textContent = selectedPosition.content || "";
39
- target.classList.add("psp-error");
40
- target.focus();
28
+ ): EventListener {
29
+ return (event: Event): void => {
30
+ const focusEvent = event as FocusEvent;
31
+ if (isEditableMode(model, viewer) && selected_position_map.has(table)) {
32
+ const target = focusEvent.target as HTMLElement;
33
+ target.classList.remove("psp-error");
34
+ const selectedPosition = selected_position_map.get(table)!;
35
+ selected_position_map.delete(table);
36
+ if (selectedPosition.content !== target.textContent) {
37
+ if (!write_cell(table, model, target)) {
38
+ target.textContent = selectedPosition.content || "";
39
+ target.classList.add("psp-error");
40
+ target.focus();
41
+ }
41
42
  }
42
43
  }
43
- }
44
+ };
44
45
  }
45
46
 
46
- export function focusinListener(
47
- this: DatagridModel,
47
+ export function createFocusinListener(
48
+ _model: DatagridModel,
48
49
  table: RegularTable,
49
- _viewer: PerspectiveViewerElement,
50
+ _viewer: HTMLPerspectiveViewerElement,
50
51
  selected_position_map: SelectedPositionMap,
51
- event: FocusEvent,
52
- ): void {
53
- const target = event.target as HTMLElement;
54
- const meta = table.getMeta(target);
55
- if (meta?.type === "body") {
56
- const new_state: SelectedPosition = {
57
- x: meta.x,
58
- y: meta.y,
59
- content: target.textContent || undefined,
60
- };
61
- selected_position_map.set(table, new_state);
62
- }
52
+ ): EventListener {
53
+ return (event: Event): void => {
54
+ const focusEvent = event as FocusEvent;
55
+ const target = focusEvent.target as HTMLElement;
56
+ const meta = table.getMeta(target);
57
+ if (meta?.type === "body") {
58
+ const new_state: SelectedPosition = {
59
+ x: meta.x,
60
+ y: meta.y,
61
+ content: target.textContent || undefined,
62
+ };
63
+ selected_position_map.set(table, new_state);
64
+ }
65
+ };
63
66
  }
@@ -12,74 +12,113 @@
12
12
 
13
13
  import { sortHandler } from "./sort.js";
14
14
  import { expandCollapseHandler } from "./expand_collapse.js";
15
- import type {
16
- RegularTable,
17
- DatagridModel,
18
- PerspectiveViewerElement,
19
- } from "../types.js";
20
-
21
- export async function mousedown_listener(
22
- this: DatagridModel,
15
+ import type { RegularTable, DatagridModel } from "../types.js";
16
+ import type { HTMLPerspectiveViewerElement } from "@perspective-dev/viewer";
17
+
18
+ export function createMousedownListener(
19
+ model: DatagridModel,
23
20
  regularTable: RegularTable,
24
- viewer: PerspectiveViewerElement,
25
- event: MouseEvent,
26
- ): Promise<void> {
27
- if (event.which !== 1) {
28
- return;
29
- }
30
-
31
- let target = event.target as HTMLElement | null;
32
- if (target?.tagName === "A") {
33
- return;
34
- }
35
-
36
- while (target && target.tagName !== "TD" && target.tagName !== "TH") {
37
- target = target.parentElement;
38
- if (!target || !regularTable.contains(target)) {
21
+ viewer: HTMLPerspectiveViewerElement,
22
+ ): EventListener {
23
+ return async (event: Event): Promise<void> => {
24
+ const mouseEvent = event as MouseEvent;
25
+ if (mouseEvent.which !== 1) {
26
+ return;
27
+ }
28
+
29
+ let target = mouseEvent.target as HTMLElement | null;
30
+ if (target?.tagName === "A") {
39
31
  return;
40
32
  }
41
- }
42
-
43
- if (!target) return;
44
-
45
- if (target.classList.contains("psp-tree-label")) {
46
- expandCollapseHandler.call(this, regularTable, event);
47
- return;
48
- }
49
-
50
- if (target.classList.contains("psp-menu-enabled")) {
51
- const meta = regularTable.getMeta(target);
52
- const column_name = meta?.column_header?.[this._config.split_by.length];
53
- await viewer.toggleColumnSettings(`${column_name}`);
54
- } else if (target.classList.contains("psp-sort-enabled")) {
55
- sortHandler.call(this, regularTable, viewer, event, target);
56
- }
33
+
34
+ while (target && target.tagName !== "TD" && target.tagName !== "TH") {
35
+ target = target.parentElement;
36
+ if (!target || !regularTable.contains(target)) {
37
+ return;
38
+ }
39
+ }
40
+
41
+ if (!target) return;
42
+
43
+ if (target.classList.contains("psp-tree-label")) {
44
+ if (model._edit_mode !== "SELECT_ROW_TREE") {
45
+ expandCollapseHandler(model, regularTable, mouseEvent);
46
+ }
47
+
48
+ return;
49
+ }
50
+
51
+ if (target.classList.contains("psp-menu-enabled")) {
52
+ const meta = regularTable.getMeta(target);
53
+ const column_name =
54
+ meta?.column_header?.[model._config.split_by.length];
55
+ await viewer.toggleColumnSettings(`${column_name}`);
56
+ } else if (target.classList.contains("psp-sort-enabled")) {
57
+ sortHandler(model, regularTable, viewer, mouseEvent, target);
58
+ }
59
+ };
57
60
  }
58
61
 
59
- export function click_listener(
62
+ export function createDblclickListener(
63
+ model: DatagridModel,
60
64
  regularTable: RegularTable,
61
- event: MouseEvent,
62
- ): void {
63
- if (event.which !== 1) {
64
- return;
65
- }
66
-
67
- let target = event.target as HTMLElement | null;
68
- while (target && target.tagName !== "TD" && target.tagName !== "TH") {
69
- target = target.parentElement;
70
- if (!target || !regularTable.contains(target)) {
65
+ viewer: HTMLPerspectiveViewerElement,
66
+ ): EventListener {
67
+ return async (event: Event): Promise<void> => {
68
+ const mouseEvent = event as MouseEvent;
69
+ if (mouseEvent.which !== 1) {
70
+ return;
71
+ }
72
+
73
+ let target = mouseEvent.target as HTMLElement | null;
74
+ if (target?.tagName === "A") {
71
75
  return;
72
76
  }
73
- }
74
-
75
- if (!target) return;
76
-
77
- if (target.classList.contains("psp-tree-label") && event.offsetX < 26) {
78
- event.stopImmediatePropagation();
79
- } else if (
80
- target.classList.contains("psp-header-leaf") &&
81
- !target.classList.contains("psp-header-corner")
82
- ) {
83
- event.stopImmediatePropagation();
84
- }
77
+
78
+ while (target && target.tagName !== "TD" && target.tagName !== "TH") {
79
+ target = target.parentElement;
80
+ if (!target || !regularTable.contains(target)) {
81
+ return;
82
+ }
83
+ }
84
+
85
+ if (!target) return;
86
+
87
+ if (target.classList.contains("psp-tree-label")) {
88
+ if (model._edit_mode === "SELECT_ROW_TREE") {
89
+ expandCollapseHandler(model, regularTable, mouseEvent);
90
+ }
91
+ }
92
+ };
93
+ }
94
+
95
+ export function createClickListener(regularTable: RegularTable): EventListener {
96
+ return (event: Event): void => {
97
+ const mouseEvent = event as MouseEvent;
98
+ if (mouseEvent.which !== 1) {
99
+ return;
100
+ }
101
+
102
+ let target = mouseEvent.target as HTMLElement | null;
103
+ while (target && target.tagName !== "TD" && target.tagName !== "TH") {
104
+ target = target.parentElement;
105
+ if (!target || !regularTable.contains(target)) {
106
+ return;
107
+ }
108
+ }
109
+
110
+ if (!target) return;
111
+
112
+ if (
113
+ target.classList.contains("psp-tree-label") &&
114
+ mouseEvent.offsetX < 26
115
+ ) {
116
+ mouseEvent.stopImmediatePropagation();
117
+ } else if (
118
+ target.classList.contains("psp-header-leaf") &&
119
+ !target.classList.contains("psp-header-corner")
120
+ ) {
121
+ mouseEvent.stopImmediatePropagation();
122
+ }
123
+ };
85
124
  }
@@ -14,25 +14,29 @@ import { focusSelectedCell } from "../../style_handlers/focus.js";
14
14
  import type {
15
15
  RegularTable,
16
16
  DatagridModel,
17
- PerspectiveViewerElement,
18
- SelectedPosition,
17
+ SelectedPositionMap,
19
18
  } from "../../types.js";
19
+ import type { HTMLPerspectiveViewerElement } from "@perspective-dev/viewer";
20
20
 
21
- type SelectedPositionMap = Map<RegularTable, SelectedPosition>;
22
-
23
- type AsyncFunction<T extends unknown[], R> = (
24
- this: DatagridModel,
25
- ...args: T
26
- ) => Promise<R>;
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<T extends unknown[], R>(
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
- this: DatagridModel,
34
- ...args: T
35
- ): Promise<R | undefined> {
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.apply(this, args);
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(this: ContentEditableElement): number {
56
- if (this.isContentEditable) {
57
- const _range = (this.getRootNode() as Document)
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(this);
73
+ range.selectNodeContents(elem);
63
74
  range.setEnd(_range.endContainer, _range.endOffset);
64
75
  return range.toString().length;
65
76
  } else {
66
- return this.selectionStart || 0;
77
+ return elem.selectionStart || 0;
67
78
  }
68
79
  }
69
80
 
70
81
  const moveSelection = lock(async function (
71
- this: DatagridModel,
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 = this._column_paths.length;
81
- const num_rows = this._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
- this: DatagridModel,
136
+ model: DatagridModel,
126
137
  table: RegularTable,
127
- _viewer: PerspectiveViewerElement,
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(this, table, target)) {
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.call(
142
- this,
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.call(
151
- this,
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.call(target as ContentEditableElement) === 0) {
172
+ if (getPos(target as ContentEditableElement) === 0) {
162
173
  event.preventDefault();
163
- moveSelection.call(
164
- this,
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.call(
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.call(target as ContentEditableElement) ===
190
+ getPos(target as ContentEditableElement) ===
187
191
  (target.textContent?.length || 0)
188
192
  ) {
189
193
  event.preventDefault();
190
- moveSelection.call(
191
- this,
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.call(
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
  }