@vuu-ui/vuu-table 2.1.19-beta.1 → 2.1.19-beta.2

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 (85) hide show
  1. package/package.json +12 -13
  2. package/src/CellFocusState.mjs +25 -0
  3. package/src/Row.mjs +83 -0
  4. package/src/Table.css.js +441 -0
  5. package/src/Table.mjs +297 -0
  6. package/src/VirtualColSpan.mjs +12 -0
  7. package/src/applyHighlighting.mjs +28 -0
  8. package/src/bulk-edit/BulkEditPanel.css.js +27 -0
  9. package/src/bulk-edit/BulkEditPanel.mjs +77 -0
  10. package/src/bulk-edit/ColumnCascadingUpdateEditor.css.js +86 -0
  11. package/src/bulk-edit/ColumnCascadingUpdateEditor.mjs +59 -0
  12. package/src/bulk-edit/InsertNewRowEditor.css.js +86 -0
  13. package/src/bulk-edit/InsertNewRowEditor.mjs +59 -0
  14. package/src/bulk-edit/useBulkEditPanel.mjs +61 -0
  15. package/src/bulk-edit/useColumnCascadingEditor.mjs +124 -0
  16. package/src/cell-block/CellBlock.css.js +95 -0
  17. package/src/cell-block/CellBlock.mjs +32 -0
  18. package/src/cell-block/cellblock-utils.mjs +114 -0
  19. package/src/cell-block/useCellBlockSelection.mjs +245 -0
  20. package/src/cell-renderers/checkbox-cell/CheckboxCell.css.js +16 -0
  21. package/src/cell-renderers/checkbox-cell/CheckboxCell.mjs +56 -0
  22. package/src/cell-renderers/checkbox-cell/index.mjs +1 -0
  23. package/src/cell-renderers/checkbox-row-selector/CheckboxRowSelectorCell.css.js +19 -0
  24. package/src/cell-renderers/checkbox-row-selector/CheckboxRowSelectorCell.mjs +34 -0
  25. package/src/cell-renderers/checkbox-row-selector/index.mjs +1 -0
  26. package/src/cell-renderers/index.mjs +4 -0
  27. package/src/cell-renderers/input-cell/InputCell.css.js +81 -0
  28. package/src/cell-renderers/input-cell/InputCell.mjs +73 -0
  29. package/src/cell-renderers/input-cell/index.mjs +1 -0
  30. package/src/cell-renderers/input-cell/useInputCell.mjs +199 -0
  31. package/src/cell-renderers/toggle-cell/ToggleCell.css.js +31 -0
  32. package/src/cell-renderers/toggle-cell/ToggleCell.mjs +47 -0
  33. package/src/cell-renderers/toggle-cell/index.mjs +1 -0
  34. package/src/column-header-pill/ColumnHeaderPill.css.js +34 -0
  35. package/src/column-header-pill/ColumnHeaderPill.mjs +39 -0
  36. package/src/column-header-pill/GroupColumnPill.css.js +10 -0
  37. package/src/column-header-pill/GroupColumnPill.mjs +33 -0
  38. package/src/column-header-pill/SortIndicator.css.js +15 -0
  39. package/src/column-header-pill/SortIndicator.mjs +29 -0
  40. package/src/column-header-pill/index.mjs +3 -0
  41. package/src/column-resizing/ColumnResizer.css.js +32 -0
  42. package/src/column-resizing/ColumnResizer.mjs +69 -0
  43. package/src/column-resizing/index.mjs +2 -0
  44. package/src/column-resizing/useTableColumnResize.mjs +57 -0
  45. package/src/data-row/DataRow.mjs +298 -0
  46. package/src/header-cell/GroupHeaderCell.css.js +91 -0
  47. package/src/header-cell/GroupHeaderCell.mjs +98 -0
  48. package/src/header-cell/HeaderCell.css.js +182 -0
  49. package/src/header-cell/HeaderCell.mjs +126 -0
  50. package/src/header-cell/index.mjs +2 -0
  51. package/src/index.mjs +20 -0
  52. package/src/pagination/PaginationControl.css.js +18 -0
  53. package/src/pagination/PaginationControl.mjs +34 -0
  54. package/src/pagination/index.mjs +1 -0
  55. package/src/pagination/usePagination.mjs +29 -0
  56. package/src/table-cell/TableCell.css.js +67 -0
  57. package/src/table-cell/TableCell.mjs +54 -0
  58. package/src/table-cell/TableGroupCell.css.js +91 -0
  59. package/src/table-cell/TableGroupCell.mjs +61 -0
  60. package/src/table-cell/index.mjs +2 -0
  61. package/src/table-config/useTableConfig.mjs +49 -0
  62. package/src/table-config.mjs +38 -0
  63. package/src/table-data-source/DataRowMovingWindow.mjs +66 -0
  64. package/src/table-data-source/useDataSource.mjs +177 -0
  65. package/src/table-dom-utils.mjs +162 -0
  66. package/src/table-header/HeaderProvider.mjs +14 -0
  67. package/src/table-header/TableHeader.mjs +182 -0
  68. package/src/table-header/index.mjs +2 -0
  69. package/src/table-header/useTableHeader.mjs +69 -0
  70. package/src/useCell.mjs +22 -0
  71. package/src/useCellEditing.mjs +58 -0
  72. package/src/useCellFocus.mjs +112 -0
  73. package/src/useControlledTableNavigation.mjs +34 -0
  74. package/src/useEditableCell.mjs +18 -0
  75. package/src/useInitialValue.mjs +6 -0
  76. package/src/useKeyboardNavigation.mjs +275 -0
  77. package/src/useMeasuredHeight.mjs +44 -0
  78. package/src/useResizeObserver.mjs +118 -0
  79. package/src/useRowClassNameGenerators.mjs +21 -0
  80. package/src/useSelection.mjs +101 -0
  81. package/src/useTable.mjs +588 -0
  82. package/src/useTableContextMenu.mjs +54 -0
  83. package/src/useTableModel.mjs +344 -0
  84. package/src/useTableScroll.mjs +382 -0
  85. package/src/useTableViewport.mjs +120 -0
@@ -0,0 +1,199 @@
1
+ import { DataValidationError, dispatchCustomEvent, getTypedValue, isRpcError, isRpcSuccess } from "@vuu-ui/vuu-utils";
2
+ import { useCallback, useMemo, useRef, useState } from "react";
3
+ const stringValueOf = (value)=>value?.toString() ?? "";
4
+ const useInputCell = ({ column, value, onEdit, type = "string" })=>{
5
+ const [editState, setEditState] = useState({
6
+ editing: false,
7
+ value: stringValueOf(value)
8
+ });
9
+ const initialValueRef = useRef(value?.toString() ?? "");
10
+ const isDirtyRef = useRef(false);
11
+ useMemo(()=>{
12
+ if (initialValueRef.current !== value?.toString()) {
13
+ initialValueRef.current = stringValueOf(value);
14
+ setEditState((editState)=>({
15
+ ...editState,
16
+ message: void 0,
17
+ value: stringValueOf(value)
18
+ }));
19
+ }
20
+ }, [
21
+ value
22
+ ]);
23
+ const commit = useCallback(async ()=>{
24
+ const { value } = editState;
25
+ const result = column.clientSideEditValidationCheck?.(value, "*");
26
+ if (result?.ok === false) setEditState((state)=>({
27
+ ...state,
28
+ message: result?.messages?.join(",")
29
+ }));
30
+ else {
31
+ const { current: initialValue } = initialValueRef;
32
+ const previousValue = getTypedValue(initialValue, type);
33
+ try {
34
+ const typedValue = getTypedValue(value, type, true);
35
+ const response = await onEdit?.({
36
+ editType: "commit",
37
+ isValid: true,
38
+ previousValue,
39
+ value: typedValue
40
+ }, "commit");
41
+ if (isRpcSuccess(response)) {
42
+ isDirtyRef.current = false;
43
+ setEditState(({ previousValue, value })=>({
44
+ editing: false,
45
+ previousValue: previousValue === value ? void 0 : void 0 === previousValue ? initialValue : previousValue,
46
+ value
47
+ }));
48
+ } else if (isRpcError(response)) {
49
+ setEditState((state)=>({
50
+ ...state,
51
+ message: response.errorMessage
52
+ }));
53
+ return false;
54
+ }
55
+ initialValueRef.current = value;
56
+ return true;
57
+ } catch (e) {
58
+ if (e instanceof DataValidationError) {
59
+ const { actualType, expectedType, message } = e;
60
+ if (column) {
61
+ const { name, label = name } = column;
62
+ const message = `${label} is a ${expectedType} value, data entered is ${actualType} `;
63
+ setEditState((state)=>({
64
+ ...state,
65
+ message
66
+ }));
67
+ onEdit?.({
68
+ editType: "commit",
69
+ isValid: false,
70
+ previousValue,
71
+ value
72
+ }, "commit");
73
+ } else setEditState((state)=>({
74
+ ...state,
75
+ message
76
+ }));
77
+ }
78
+ }
79
+ }
80
+ return false;
81
+ }, [
82
+ column,
83
+ editState,
84
+ onEdit,
85
+ type
86
+ ]);
87
+ const toggleActivation = useCallback(async (input, cancel = false)=>{
88
+ if (editState.editing) if (isDirtyRef.current) if (cancel) {
89
+ const { value: previousValue } = editState;
90
+ isDirtyRef.current = false;
91
+ setEditState({
92
+ editing: false,
93
+ value: initialValueRef.current,
94
+ message: void 0
95
+ });
96
+ onEdit?.({
97
+ editType: "cancel",
98
+ isValid: true,
99
+ previousValue,
100
+ value: getTypedValue(initialValueRef.current, type, true)
101
+ }, "commit");
102
+ } else {
103
+ const commitSuccessful = await commit();
104
+ if (commitSuccessful) {
105
+ setEditState((editState)=>({
106
+ ...editState,
107
+ editing: false
108
+ }));
109
+ dispatchCustomEvent(input, "vuu-commit");
110
+ }
111
+ }
112
+ else setEditState((editState)=>({
113
+ ...editState,
114
+ editing: false
115
+ }));
116
+ else if (!cancel) {
117
+ setEditState((editState)=>({
118
+ ...editState,
119
+ editing: true
120
+ }));
121
+ input.select();
122
+ }
123
+ }, [
124
+ commit,
125
+ editState,
126
+ onEdit
127
+ ]);
128
+ const handleKeyDown = useCallback(async (evt)=>{
129
+ const { key, target } = evt;
130
+ const input = target;
131
+ if ("Enter" === key) toggleActivation(input);
132
+ else if ("ArrowRight" === key || "ArrowLeft" === key || "ArrowUp" === key || "ArrowDown" === key) {
133
+ if (editState.editing) evt.stopPropagation();
134
+ } else if ("Escape" === evt.key) toggleActivation(input, true);
135
+ }, [
136
+ editState,
137
+ toggleActivation
138
+ ]);
139
+ const handleFocus = useCallback((e)=>{
140
+ const input = e.target;
141
+ const source = e.relatedTarget;
142
+ if (source?.classList.contains("vuuTableCell") && source.contains(input)) toggleActivation(input);
143
+ }, [
144
+ toggleActivation
145
+ ]);
146
+ const handleBlur = useCallback(async ()=>{
147
+ if (editState.editing) {
148
+ if (isDirtyRef.current) {
149
+ const commitSuccessful = await commit();
150
+ console.log({
151
+ commitSuccessful
152
+ });
153
+ }
154
+ setEditState((editState)=>({
155
+ ...editState,
156
+ editing: false
157
+ }));
158
+ }
159
+ }, [
160
+ commit,
161
+ editState
162
+ ]);
163
+ const handleChange = useCallback((evt)=>{
164
+ const { value } = evt.target;
165
+ isDirtyRef.current = value !== initialValueRef.current;
166
+ const result = column.clientSideEditValidationCheck?.(value, "change");
167
+ setEditState({
168
+ editing: true,
169
+ value
170
+ });
171
+ onEdit?.({
172
+ editType: "change",
173
+ isValid: result?.ok !== false,
174
+ previousValue: initialValueRef.current,
175
+ value
176
+ }, "change");
177
+ if (result?.ok === false) setEditState({
178
+ editing: true,
179
+ value,
180
+ message: result.messages?.join(",")
181
+ });
182
+ }, [
183
+ column,
184
+ onEdit
185
+ ]);
186
+ return {
187
+ editing: editState.editing,
188
+ inputProps: {
189
+ onBlur: handleBlur,
190
+ onFocus: handleFocus,
191
+ onKeyDown: handleKeyDown
192
+ },
193
+ onChange: handleChange,
194
+ previousValue: editState.previousValue,
195
+ value: editState.value,
196
+ warningMessage: editState.message
197
+ };
198
+ };
199
+ export { useInputCell };
@@ -0,0 +1,31 @@
1
+ const css = `
2
+ .vuuTableToggleCell {
3
+ --saltButton-borderRadius: 4px;
4
+ --saltButton-height: 16px;
5
+ font-weight: 500;
6
+ position: relative;
7
+ top: 1px;
8
+ }
9
+
10
+ .vuuTableToggleCell-side {
11
+ --saltButton-minWidth: 40px;
12
+ }
13
+
14
+ .vuuTableToggleCell.vuuCycleStateButton-buy {
15
+ background-color: var(--vuu-color-green-50);
16
+ }
17
+
18
+ .vuuTableToggleCell.vuuCycleStateButton-sell {
19
+ background-color: var(--vuu-color-red-50);
20
+ }
21
+
22
+ .vuuTableCell .vuuTableToggleCell:focus {
23
+ border: solid 2px var(--vuu-color-purple-10) !important;
24
+ color: #fff !important;
25
+ height: 18px !important;
26
+ top: 0 !important;
27
+ }
28
+
29
+
30
+ `;
31
+ export default css;
@@ -0,0 +1,47 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { dataColumnAndKeyUnchanged, dispatchCustomEvent, isRpcSuccess, isTypeDescriptor, isValueListRenderer, registerComponent } from "@vuu-ui/vuu-utils";
3
+ import { useComponentCssInjection } from "@salt-ds/styles";
4
+ import { useWindow } from "@salt-ds/window";
5
+ import clsx from "clsx";
6
+ import { memo, useCallback } from "react";
7
+ import { CycleStateButton } from "@vuu-ui/vuu-ui-controls";
8
+ import ToggleCell_0 from "./ToggleCell.css";
9
+ const classBase = "vuuTableToggleCell";
10
+ const getValueList = ({ name, type })=>{
11
+ if (isTypeDescriptor(type) && isValueListRenderer(type.renderer)) return type.renderer.values;
12
+ throw Error(`useLookupValues column ${name} has not been configured with a values list`);
13
+ };
14
+ const ToggleCell_ToggleCell = /*#__PURE__*/ memo(function({ column, dataRow, onEdit }) {
15
+ const targetWindow = useWindow();
16
+ useComponentCssInjection({
17
+ testId: "vuu-toggle-cell",
18
+ css: ToggleCell_0,
19
+ window: targetWindow
20
+ });
21
+ const values = getValueList(column);
22
+ const value = dataRow[column.name];
23
+ const handleCommit = useCallback(async (evt, newValue)=>{
24
+ const res = await onEdit?.({
25
+ previousValue: value,
26
+ value: newValue
27
+ }, "commit");
28
+ if (isRpcSuccess(res)) dispatchCustomEvent(evt.target, "vuu-commit");
29
+ return res;
30
+ }, [
31
+ onEdit,
32
+ value
33
+ ]);
34
+ return /*#__PURE__*/ jsx(CycleStateButton, {
35
+ appearance: "solid",
36
+ className: clsx(classBase, `${classBase}-${column.name}`),
37
+ onCommit: handleCommit,
38
+ sentiment: "accented",
39
+ value: value,
40
+ values: values,
41
+ children: value
42
+ });
43
+ }, dataColumnAndKeyUnchanged);
44
+ registerComponent("toggle-cell", ToggleCell_ToggleCell, "cell-renderer", {
45
+ userCanAssign: false
46
+ });
47
+ export { ToggleCell_ToggleCell as ToggleCell };
@@ -0,0 +1 @@
1
+ export * from "./ToggleCell.mjs";
@@ -0,0 +1,34 @@
1
+ const css = `
2
+ .vuuColumnHeaderPill {
3
+ --vuu-icon-size: 14px;
4
+ --menu-item-icon-color: black;
5
+ --vuu-icon-color: var(--salt-actionable-bold-foreground);
6
+ --vuu-icon-height: 12px;
7
+ --vuu-icon-width: 12px;
8
+ background: var(--salt-actionable-bold-background);
9
+ color: var(--salt-actionable-bold-foreground);
10
+ flex: var(--vuuColumnHeaderPill-flex, none);
11
+ height: 16px;
12
+ margin: var(--vuuColumnHeaderPill-margin, 0);
13
+ border-radius: 3px;
14
+ align-items: center;
15
+ gap: 2px;
16
+ padding: 0 6px;
17
+ font-size: 11px;
18
+ display: flex;
19
+ position: relative;
20
+ }
21
+
22
+ .vuuColumnHeaderPill:hover {
23
+ --vuu-icon-color: var(--salt-actionable-bold-foreground-hover);
24
+ background-color: var(--salt-actionable-bold-background-hover);
25
+ color: var(--salt-actionable-bold-foreground-hover);
26
+ }
27
+
28
+ .vuuColumnHeaderPill-removeButton {
29
+ cursor: pointer;
30
+ }
31
+
32
+
33
+ `;
34
+ export default css;
@@ -0,0 +1,39 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import clsx from "clsx";
3
+ import { useComponentCssInjection } from "@salt-ds/styles";
4
+ import { useWindow } from "@salt-ds/window";
5
+ import { useCallback } from "react";
6
+ import ColumnHeaderPill from "./ColumnHeaderPill.css";
7
+ const classBase = "vuuColumnHeaderPill";
8
+ const ColumnHeaderPill_ColumnHeaderPill = ({ children, className, column, onRemove, removable, ...htmlAttributes })=>{
9
+ const targetWindow = useWindow();
10
+ useComponentCssInjection({
11
+ testId: "vuu-column-header-pill",
12
+ css: ColumnHeaderPill,
13
+ window: targetWindow
14
+ });
15
+ if (removable && "function" != typeof onRemove) throw Error("ColumnHeaderPill onRemove prop must be provided if Pill is removable");
16
+ const handleClickRemove = useCallback((evt)=>{
17
+ evt.preventDefault();
18
+ evt.stopPropagation();
19
+ onRemove?.(column);
20
+ }, [
21
+ column,
22
+ onRemove
23
+ ]);
24
+ return /*#__PURE__*/ jsxs("div", {
25
+ ...htmlAttributes,
26
+ className: clsx(classBase, className),
27
+ tabIndex: -1,
28
+ children: [
29
+ children,
30
+ removable ? /*#__PURE__*/ jsx("span", {
31
+ className: `${classBase}-removeButton`,
32
+ role: "button",
33
+ "data-icon": "cross",
34
+ onClick: handleClickRemove
35
+ }) : null
36
+ ]
37
+ });
38
+ };
39
+ export { ColumnHeaderPill_ColumnHeaderPill as ColumnHeaderPill };
@@ -0,0 +1,10 @@
1
+ const css = `
2
+ .vuuSortPosition {
3
+ padding-top: 1px;
4
+ font-size: 11px;
5
+ font-weight: 700;
6
+ }
7
+
8
+
9
+ `;
10
+ export default css;
@@ -0,0 +1,33 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useComponentCssInjection } from "@salt-ds/styles";
3
+ import { useWindow } from "@salt-ds/window";
4
+ import { ColumnHeaderPill } from "./ColumnHeaderPill.mjs";
5
+ import GroupColumnPill from "./GroupColumnPill.css";
6
+ const GroupColumnPill_GroupColumnPill = ({ column, ...columnHeaderProps })=>{
7
+ const targetWindow = useWindow();
8
+ useComponentCssInjection({
9
+ testId: "vuu-group-column-pill",
10
+ css: GroupColumnPill,
11
+ window: targetWindow
12
+ });
13
+ const { name, sorted } = column;
14
+ const icon = "number" == typeof sorted ? sorted < 0 ? "arrow-down" : "arrow-up" : "A" === sorted ? "arrow-up" : "D" === sorted ? "arrow-down" : void 0;
15
+ return /*#__PURE__*/ jsxs(ColumnHeaderPill, {
16
+ ...columnHeaderProps,
17
+ column: column,
18
+ children: [
19
+ /*#__PURE__*/ jsx("span", {
20
+ className: "vuuGroupColumnPill-label",
21
+ children: name
22
+ }),
23
+ void 0 !== icon ? /*#__PURE__*/ jsx("span", {
24
+ "data-icon": icon
25
+ }) : null,
26
+ "number" == typeof sorted ? /*#__PURE__*/ jsx("span", {
27
+ className: "vuuSortPosition",
28
+ children: Math.abs(sorted)
29
+ }) : null
30
+ ]
31
+ });
32
+ };
33
+ export { GroupColumnPill_GroupColumnPill as GroupColumnPill };
@@ -0,0 +1,15 @@
1
+ const css = `
2
+ .vuuSortIndicator {
3
+ flex: 0 16px;
4
+ padding: 0 2px;
5
+
6
+ & .vuuSortPosition {
7
+ padding-top: 1px;
8
+ font-size: 11px;
9
+ font-weight: 700;
10
+ }
11
+ }
12
+
13
+
14
+ `;
15
+ export default css;
@@ -0,0 +1,29 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useComponentCssInjection } from "@salt-ds/styles";
3
+ import { useWindow } from "@salt-ds/window";
4
+ import { ColumnHeaderPill } from "./ColumnHeaderPill.mjs";
5
+ import SortIndicator from "./SortIndicator.css";
6
+ const SortIndicator_SortIndicator = ({ column })=>{
7
+ const targetWindow = useWindow();
8
+ useComponentCssInjection({
9
+ testId: "vuu-table-sort-indicator",
10
+ css: SortIndicator,
11
+ window: targetWindow
12
+ });
13
+ if (!column.sorted) return null;
14
+ const icon = "number" == typeof column.sorted ? column.sorted < 0 ? "arrow-down" : "arrow-up" : "A" === column.sorted ? "arrow-up" : "arrow-down";
15
+ return /*#__PURE__*/ jsxs(ColumnHeaderPill, {
16
+ className: "vuuSortIndicator",
17
+ column: column,
18
+ children: [
19
+ /*#__PURE__*/ jsx("span", {
20
+ "data-icon": icon
21
+ }),
22
+ "number" == typeof column.sorted ? /*#__PURE__*/ jsx("span", {
23
+ className: "vuuSortPosition",
24
+ children: Math.abs(column.sorted)
25
+ }) : null
26
+ ]
27
+ });
28
+ };
29
+ export { SortIndicator_SortIndicator as SortIndicator };
@@ -0,0 +1,3 @@
1
+ export * from "./ColumnHeaderPill.mjs";
2
+ export * from "./GroupColumnPill.mjs";
3
+ export * from "./SortIndicator.mjs";
@@ -0,0 +1,32 @@
1
+ const css = `
2
+ .vuuColumnResizer {
3
+ cursor: col-resize;
4
+ height: var(--vuu-table-col-header-row-height);
5
+ margin-left: var(--columnResizer-left, auto);
6
+ z-index: 1;
7
+ width: 8px;
8
+ position: absolute;
9
+ right: -5px;
10
+ }
11
+
12
+ .vuuTableHeaderCell:not(.vuuTableHeaderCell-resizing) {
13
+ & .vuuColumnResizer:hover {
14
+ --columnResizer-color: var(--salt-selectable-background-selected);
15
+ }
16
+ }
17
+
18
+ .vuuColumnResizer:after {
19
+ background-color: var(--columnResizer-color, var(--salt-separable-tertiary-borderColor));
20
+ content: "";
21
+ height: var(--columnResizer-height, 0);
22
+ z-index: 1;
23
+ width: 2px;
24
+ position: absolute;
25
+ top: 0;
26
+ bottom: 0;
27
+ right: 3px;
28
+ }
29
+
30
+
31
+ `;
32
+ export default css;
@@ -0,0 +1,69 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useComponentCssInjection } from "@salt-ds/styles";
3
+ import { useWindow } from "@salt-ds/window";
4
+ import { useCallback, useRef } from "react";
5
+ import ColumnResizer from "./ColumnResizer.css";
6
+ const NOOP = ()=>void 0;
7
+ const baseClass = "vuuColumnResizer";
8
+ const ColumnResizer_ColumnResizer = ({ onDrag, onDragEnd = NOOP, onDragStart = NOOP })=>{
9
+ const targetWindow = useWindow();
10
+ useComponentCssInjection({
11
+ testId: "vuu-column-resizer",
12
+ css: ColumnResizer,
13
+ window: targetWindow
14
+ });
15
+ const positionRef = useRef({
16
+ start: 0,
17
+ now: 0
18
+ });
19
+ const elementRef = useRef(void 0);
20
+ const onPointerMove = useCallback((e)=>{
21
+ if (e.stopPropagation) e.stopPropagation();
22
+ if (e.preventDefault) e.preventDefault();
23
+ const { current: position } = positionRef;
24
+ const x = e.clientX;
25
+ const moveBy = Math.round(x - position.now);
26
+ const distanceMoved = Math.round(x - position.start);
27
+ positionRef.current.now = x;
28
+ if (0 !== moveBy) onDrag(e, moveBy, distanceMoved);
29
+ }, [
30
+ onDrag
31
+ ]);
32
+ const onPointerUp = useCallback((e)=>{
33
+ window.removeEventListener("pointerup", onPointerUp);
34
+ window.removeEventListener("pointermove", onPointerMove);
35
+ const { current: position } = positionRef;
36
+ const distanceMoved = position.now - position.start;
37
+ onDragEnd(e, distanceMoved);
38
+ }, [
39
+ onDragEnd,
40
+ onPointerMove
41
+ ]);
42
+ const handlePointerDown = useCallback((e)=>{
43
+ const { current: position } = positionRef;
44
+ onDragStart(e);
45
+ position.now = position.start = e.clientX;
46
+ window.addEventListener("pointerup", onPointerUp);
47
+ window.addEventListener("pointermove", onPointerMove);
48
+ if (e.stopPropagation) e.stopPropagation();
49
+ if (e.preventDefault) e.preventDefault();
50
+ }, [
51
+ onDragStart,
52
+ onPointerMove,
53
+ onPointerUp
54
+ ]);
55
+ const setRef = useCallback((el)=>{
56
+ if (el && void 0 === elementRef.current) {
57
+ el.addEventListener("pointerdown", handlePointerDown);
58
+ elementRef.current = el;
59
+ }
60
+ }, [
61
+ handlePointerDown
62
+ ]);
63
+ return /*#__PURE__*/ jsx("div", {
64
+ className: baseClass,
65
+ ref: setRef,
66
+ role: "separator"
67
+ });
68
+ };
69
+ export { ColumnResizer_ColumnResizer as ColumnResizer };
@@ -0,0 +1,2 @@
1
+ export * from "./ColumnResizer.mjs";
2
+ export * from "./useTableColumnResize.mjs";
@@ -0,0 +1,57 @@
1
+ import { useCallback, useRef, useState } from "react";
2
+ const useTableColumnResize = ({ column, onResize, rootRef })=>{
3
+ const widthRef = useRef({
4
+ start: 0,
5
+ now: 0
6
+ });
7
+ const [isResizing, setResizing] = useState(false);
8
+ const { name } = column;
9
+ const handleResizeStart = useCallback(()=>{
10
+ if (onResize && rootRef.current) {
11
+ const { current: width } = widthRef;
12
+ const { width: measuredWidth } = rootRef.current.getBoundingClientRect();
13
+ width.start = width.now = Math.round(measuredWidth);
14
+ setResizing(true);
15
+ onResize?.("begin", name);
16
+ }
17
+ }, [
18
+ name,
19
+ onResize,
20
+ rootRef
21
+ ]);
22
+ const handleResize = useCallback((_evt, moveBy, totalDistanceMoved)=>{
23
+ if (rootRef.current) {
24
+ if (onResize) {
25
+ const { current: width } = widthRef;
26
+ const newWidth = width.start + totalDistanceMoved;
27
+ if (newWidth !== width.now && newWidth > 0) {
28
+ onResize("resize", name, newWidth);
29
+ width.now = newWidth;
30
+ }
31
+ }
32
+ }
33
+ }, [
34
+ name,
35
+ onResize,
36
+ rootRef
37
+ ]);
38
+ const handleResizeEnd = useCallback(()=>{
39
+ if (onResize) {
40
+ const { current: width } = widthRef;
41
+ onResize("end", name, width.now);
42
+ setTimeout(()=>{
43
+ setResizing(false);
44
+ }, 80);
45
+ }
46
+ }, [
47
+ name,
48
+ onResize
49
+ ]);
50
+ return {
51
+ isResizing,
52
+ onDrag: handleResize,
53
+ onDragStart: handleResizeStart,
54
+ onDragEnd: handleResizeEnd
55
+ };
56
+ };
57
+ export { useTableColumnResize };