@absreim/react-bootstrap-data-grid-pro 2.5.0 → 2.6.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 (82) hide show
  1. package/grid/Grid.js +26 -30
  2. package/grid/InternalGrid.d.ts +1 -0
  3. package/grid/InternalGrid.js +17 -18
  4. package/grid/editing/EditControlsCell.js +3 -4
  5. package/grid/editing/EditableRow.js +11 -17
  6. package/grid/editing/inputStrsToRowData.js +4 -4
  7. package/grid/export/ExportForm.js +25 -49
  8. package/grid/export/useExportFn.js +34 -58
  9. package/grid/filtering/DateFilterRow.js +17 -33
  10. package/grid/filtering/FilterOptionsTable.js +60 -96
  11. package/grid/filtering/FilterRow.js +4 -13
  12. package/grid/filtering/NumberFilterRow.js +10 -25
  13. package/grid/filtering/StringFilterRow.js +10 -25
  14. package/grid/filtering/types.js +6 -6
  15. package/grid/filtering/useFilterFormState.js +52 -65
  16. package/grid/main/BodyRows.d.ts +3 -1
  17. package/grid/main/BodyRows.js +6 -13
  18. package/grid/main/ColHeaderCell/index.js +4 -4
  19. package/grid/main/ColHeaderCell/useSortHeaderStates.js +10 -10
  20. package/grid/main/ToggleButton.js +3 -4
  21. package/grid/pagination/PageSelector.js +17 -18
  22. package/grid/pagination/PageSizeSelector.js +5 -6
  23. package/grid/pagination/Pagination.js +6 -7
  24. package/grid/pipeline/useAugFormattedRows.js +5 -20
  25. package/grid/pipeline/useCombinedPipeline/index.d.ts +2 -2
  26. package/grid/pipeline/useCombinedPipeline/index.js +21 -22
  27. package/grid/pipeline/useCombinedPipeline/useCurrentPageRows.d.ts +3 -3
  28. package/grid/pipeline/useCombinedPipeline/useCurrentPageRows.js +29 -24
  29. package/grid/pipeline/useCombinedPipeline/useDisplayRows.d.ts +2 -2
  30. package/grid/pipeline/useCombinedPipeline/useDisplayRows.js +40 -41
  31. package/grid/pipeline/useCombinedPipeline/useFilter.d.ts +2 -2
  32. package/grid/pipeline/useCombinedPipeline/useFilter.js +9 -9
  33. package/grid/pipeline/useCombinedPipeline/useFilterStateFromEditable.js +5 -6
  34. package/grid/pipeline/useCombinedPipeline/useFilterStateStore.js +6 -7
  35. package/grid/pipeline/useCombinedPipeline/useSortedRows.d.ts +3 -3
  36. package/grid/pipeline/useCombinedPipeline/useSortedRows.js +22 -27
  37. package/grid/pipeline/useGetInputStrSubmitCallback.js +6 -6
  38. package/grid/pipeline/useGridSelectionFns.js +30 -30
  39. package/grid/pipeline/useUnwrappedGridStyles.js +5 -7
  40. package/grid/selection/SelectAllHeaderCell.d.ts +1 -0
  41. package/grid/selection/SelectAllHeaderCell.js +9 -10
  42. package/grid/selection/SelectionInput.js +4 -6
  43. package/grid/sorting/arrowPlaceholder.js +1 -1
  44. package/grid/sorting/downArrow.js +1 -1
  45. package/grid/sorting/sortOrderToAriaSort.d.ts +4 -0
  46. package/grid/sorting/sortOrderToAriaSort.js +11 -0
  47. package/grid/sorting/upArrow.js +1 -10
  48. package/grid/styling/styleModelUnwrappers.js +22 -33
  49. package/grid/toolbar/Toolbar.js +13 -16
  50. package/grid/toolbar/ToolbarContainer.js +3 -4
  51. package/grid/toolbar/useInterfaces.js +5 -17
  52. package/grid/types.d.ts +9 -5
  53. package/grid/util/datetime.js +2 -4
  54. package/grid/util/getWidthStyle.js +6 -8
  55. package/grid/util/isSubset.js +3 -4
  56. package/grid/util/useControlledHover.js +8 -8
  57. package/grid-pro/ColHeaderCellPro.js +52 -44
  58. package/grid-pro/GridPro.js +42 -32
  59. package/grid-pro/assets/HorizontalGrip.d.ts +6 -0
  60. package/grid-pro/assets/HorizontalGrip.js +3 -0
  61. package/grid-pro/assets/VerticalGrip.d.ts +6 -0
  62. package/grid-pro/assets/VerticalGrip.js +3 -0
  63. package/grid-pro/index.d.ts +3 -0
  64. package/grid-pro/index.js +3 -0
  65. package/grid-pro/reorder/ReorderHandleCell.d.ts +12 -0
  66. package/grid-pro/reorder/ReorderHandleCell.js +220 -0
  67. package/grid-pro/reorder/ReorderHeaderCell.d.ts +3 -0
  68. package/grid-pro/reorder/ReorderHeaderCell.js +4 -0
  69. package/grid-pro/reorder/types.d.ts +12 -0
  70. package/grid-pro/reorder/types.js +1 -0
  71. package/grid-pro/resize/useResizeModel.js +40 -62
  72. package/grid-pro/types.d.ts +9 -2
  73. package/grid-pro/util/index.d.ts +1 -0
  74. package/grid-pro/util/index.js +1 -0
  75. package/grid-pro/util/regDragCleanup.d.ts +3 -0
  76. package/grid-pro/util/regDragCleanup.js +28 -0
  77. package/grid-pro/util/reorderRows.d.ts +3 -0
  78. package/grid-pro/util/reorderRows.js +17 -0
  79. package/grid-pro/util/types.d.ts +10 -0
  80. package/grid-pro/util/types.js +1 -0
  81. package/package.json +1 -1
  82. package/style.css +1 -1
@@ -1,25 +1,30 @@
1
1
  "use client";
2
- import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useCallback, useMemo, useRef, } from "react";
4
4
  import classNames from "classnames";
5
5
  import getWidthStyle from "../grid/util/getWidthStyle";
6
6
  import useSortHeaderStates from "../grid/main/ColHeaderCell/useSortHeaderStates";
7
- var setWidthStyle = function (cells, width) {
8
- cells.forEach(function (cell) {
9
- cell.style.minWidth = "".concat(width, "px");
10
- cell.style.maxWidth = "".concat(width, "px");
7
+ import VerticalGrip from "./assets/VerticalGrip";
8
+ import regDragCleanup from "./util/regDragCleanup";
9
+ import sortOrderToAriaSort from "../grid/sorting/sortOrderToAriaSort";
10
+ const setWidthStyle = (cells, width) => {
11
+ cells.forEach((cell) => {
12
+ cell.style.minWidth = `${width}px`;
13
+ cell.style.maxWidth = `${width}px`;
11
14
  });
12
15
  };
13
- var ColHeaderCellPro = function (_a) {
14
- var label = _a.label, sortModel = _a.sortModel, ariaColIndex = _a.ariaColIndex, additionalClasses = _a.additionalClasses, width = _a.width, displayMode = _a.displayMode, setWidth = _a.setWidth, minResizeWidth = _a.minResizeWidth, maxResizeWidth = _a.maxResizeWidth, keyboardResizeStep = _a.keyboardResizeStep;
15
- var resizeable = setWidth !== undefined;
16
- var cellIsClickable = !!(resizeable && sortModel);
17
- var sortDivClickable = resizeable && sortModel;
18
- var _b = useSortHeaderStates(sortModel), handleClick = _b.handleClick, handleMouseOver = _b.handleMouseOver, handleMouseOut = _b.handleMouseOut, sortSymbol = _b.sortSymbol;
19
- var defaultMinResizeWidth = sortModel ? 64 : 32;
20
- var effectiveMinResizeWidth = minResizeWidth || defaultMinResizeWidth;
21
- var effectiveKbdResizeStep = keyboardResizeStep || 10;
22
- var clickToSortCellContents = useMemo(function () {
16
+ const ColHeaderCellPro = ({ label, sortModel, ariaColIndex, additionalClasses, width, displayMode, setWidth, minResizeWidth, maxResizeWidth, keyboardResizeStep, }) => {
17
+ const resizeable = setWidth !== undefined;
18
+ const cellIsClickable = !!(!resizeable && sortModel);
19
+ const sortDivClickable = resizeable && sortModel;
20
+ const { handleClick, handleMouseOver, handleMouseOut, sortSymbol } = useSortHeaderStates(sortModel);
21
+ const defaultMinResizeWidth = sortModel ? 64 : 32;
22
+ const effectiveMinResizeWidth = minResizeWidth || defaultMinResizeWidth;
23
+ const effectiveKbdResizeStep = keyboardResizeStep || 10;
24
+ const clickToSortCellContents = useMemo(() => {
25
+ if (!sortModel) {
26
+ return _jsx(_Fragment, { children: label });
27
+ }
23
28
  if (!width || displayMode === "table") {
24
29
  // Testing has shown that content gets cut off in a table cell only if
25
30
  // the table "display" property is "block" and both "min-width" and
@@ -43,7 +48,7 @@ var ColHeaderCellPro = function (_a) {
43
48
  sortSymbol,
44
49
  width,
45
50
  ]);
46
- var onKeyDown = useCallback(function (e) {
51
+ const onKeyDown = useCallback((e) => {
47
52
  if (setWidth === undefined || width === undefined) {
48
53
  return;
49
54
  }
@@ -62,9 +67,9 @@ var ColHeaderCellPro = function (_a) {
62
67
  setWidth,
63
68
  width,
64
69
  ]);
65
- var thRef = useRef(null);
66
- var onPointerDown = useCallback(function (event) {
67
- if (event.button === 2) {
70
+ const thRef = useRef(null);
71
+ const onPointerDown = useCallback((event) => {
72
+ if (event.button !== 0) {
68
73
  return;
69
74
  }
70
75
  if (thRef.current === null ||
@@ -79,48 +84,51 @@ var ColHeaderCellPro = function (_a) {
79
84
  // in a ref and having this component conditionally render based on the
80
85
  // value of the ref. I.e., if the ref has a value, use that value for the
81
86
  // width instead of the "width" prop.
82
- var target = event.target;
87
+ const target = event.target;
83
88
  target.setPointerCapture(event.pointerId);
84
- var table = thRef.current.parentElement.parentElement
89
+ const table = thRef.current.parentElement.parentElement
85
90
  .parentElement;
86
- var tds = table.querySelectorAll(":scope > tbody > tr > td:nth-child(".concat(ariaColIndex, ")"));
87
- var cellsToUpdate = Array.from(tds).concat(thRef.current);
88
- var origX = event.clientX;
89
- var onPointerMove = function (event) {
90
- var diff = event.clientX - origX;
91
- var newWidth = Math.max(effectiveMinResizeWidth, width + diff);
91
+ const tds = table.querySelectorAll(`:scope > tbody > tr > td:nth-child(${ariaColIndex})`);
92
+ const cellsToUpdate = Array.from(tds).concat(thRef.current);
93
+ const origX = event.clientX;
94
+ const onPointerMove = (event) => {
95
+ const diff = event.clientX - origX;
96
+ let newWidth = Math.max(effectiveMinResizeWidth, width + diff);
92
97
  if (maxResizeWidth) {
93
98
  newWidth = Math.min(maxResizeWidth, newWidth);
94
99
  }
95
100
  setWidthStyle(cellsToUpdate, newWidth);
96
101
  };
97
- target.addEventListener("pointermove", onPointerMove);
98
- var removePointerMove = function () {
99
- return target.removeEventListener("pointermove", onPointerMove);
100
- };
101
- var onKeyDown = function (event) {
102
+ const onKeyDown = (removeListeners) => (event) => {
102
103
  if (event.code === "Escape") {
103
104
  setWidthStyle(cellsToUpdate, width);
104
- removePointerMove();
105
+ removeListeners();
105
106
  }
106
107
  };
107
- document.addEventListener("keydown", onKeyDown, { once: true });
108
- var onPointerUp = function () {
108
+ const onPointerUp = (removeListeners) => () => {
109
109
  if (thRef.current !== null) {
110
- var newWidth = Number(thRef.current.style.minWidth.replace("px", ""));
110
+ const newWidth = Number(thRef.current.style.minWidth.replace("px", ""));
111
111
  setWidth(newWidth);
112
112
  }
113
- removePointerMove();
114
- document.removeEventListener("keydown", onKeyDown);
113
+ removeListeners();
114
+ };
115
+ const onContextMenu = (event) => {
116
+ event.preventDefault();
115
117
  };
116
- target.addEventListener("pointerup", onPointerUp, { once: true });
118
+ regDragCleanup({
119
+ element: target,
120
+ onPointerMove,
121
+ onPointerUp,
122
+ onPointerCancel: onPointerUp,
123
+ onKeyDown,
124
+ onContextMenu,
125
+ });
117
126
  }, [ariaColIndex, effectiveMinResizeWidth, maxResizeWidth, setWidth, width]);
118
- var cellContents = useMemo(function () {
127
+ const cellContents = useMemo(() => {
119
128
  if (!resizeable) {
120
129
  return clickToSortCellContents;
121
130
  }
122
- var dragHandleIcon = (_jsx("svg", { "aria-hidden": true, xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "currentColor", viewBox: "0 0 16 16", className: "rdbg-drag-marker", children: _jsx("path", { d: "M7 2a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0M7 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0M7 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0m-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0m-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0" }) }));
123
- return (_jsxs("div", { className: "d-flex justify-content-between", children: [clickToSortCellContents, _jsx("div", { className: "rdbg-drag-marker-container", onPointerDown: onPointerDown, role: "separator", tabIndex: 0, "aria-label": "Resize column", "aria-valuenow": width, "aria-valuemin": minResizeWidth, "aria-valuemax": maxResizeWidth, onKeyDown: onKeyDown, onClick: function (e) { return e.stopPropagation(); }, children: dragHandleIcon })] }));
131
+ return (_jsxs("div", { className: "d-flex justify-content-between", children: [clickToSortCellContents, _jsx("div", { className: "rbdg-draggable-container rbdg-resize-container", onPointerDown: onPointerDown, role: "separator", tabIndex: 0, title: "Resize column", "aria-label": "Resize column", "aria-valuenow": width, "aria-valuemin": minResizeWidth, "aria-valuemax": maxResizeWidth, onKeyDown: onKeyDown, onClick: (e) => e.stopPropagation(), children: _jsx(VerticalGrip, { className: "rbdg-draggable-icon" }) })] }));
124
132
  }, [
125
133
  clickToSortCellContents,
126
134
  maxResizeWidth,
@@ -134,7 +142,7 @@ var ColHeaderCellPro = function (_a) {
134
142
  "rbdg-sort-toggler": cellIsClickable,
135
143
  "table-active": sortModel === null || sortModel === void 0 ? void 0 : sortModel.sortOrder,
136
144
  }, additionalClasses || []), onClick: cellIsClickable ? handleClick : undefined, onMouseOver: cellIsClickable ? handleMouseOver : undefined, onMouseOut: cellIsClickable ? handleMouseOut : undefined, "aria-description": sortModel
137
- ? "Column header"
138
- : "Column header that can be clicked to change the sorting mode", "aria-colindex": ariaColIndex, style: getWidthStyle(width), children: cellContents }));
145
+ ? "Column header that can be clicked to change the sorting mode"
146
+ : "Column header", "aria-colindex": ariaColIndex, "aria-sort": sortModel ? sortOrderToAriaSort(sortModel.sortOrder) : undefined, style: getWidthStyle(width), children: cellContents }));
139
147
  };
140
148
  export default ColHeaderCellPro;
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { useMemo } from "react";
3
+ import { useCallback, useMemo } from "react";
4
4
  import useCombinedPipeline from "../grid/pipeline/useCombinedPipeline";
5
5
  import InternalGrid from "../grid/InternalGrid";
6
6
  import ColHeaderCellPro from "./ColHeaderCellPro";
@@ -10,47 +10,57 @@ import useGetInputStrSubmitCallback from "../grid/pipeline/useGetInputStrSubmitC
10
10
  import useAugFormattedRows from "../grid/pipeline/useAugFormattedRows";
11
11
  import useResizeModel from "./resize/useResizeModel";
12
12
  import BodyRows from "../grid/main/BodyRows";
13
- var GridPro = function (props) {
14
- var rows = props.rows, cols = props.cols, editModel = props.editModel, filterModel = props.filterModel, sortModel = props.sortModel, pagination = props.pagination, selectModel = props.selectModel, styleModel = props.styleModel, displayMode = props.displayMode;
15
- var combinedPipelineOutput = useCombinedPipeline({
16
- rows: rows,
17
- cols: cols,
18
- filterModel: filterModel,
19
- sortModel: sortModel,
20
- pagination: pagination,
21
- selectModel: selectModel,
13
+ import ReorderHeaderCell from "./reorder/ReorderHeaderCell";
14
+ import ReorderHandleCell from "./reorder/ReorderHandleCell";
15
+ const GridPro = (props) => {
16
+ const { rows, cols, editModel, filterModel, sortModel, pagination, selectModel, styleModel, displayMode, reorder, } = props;
17
+ const combinedPipelineOutput = useCombinedPipeline({
18
+ rows,
19
+ cols,
20
+ filterModel,
21
+ sortModel,
22
+ pagination,
23
+ selectModel,
22
24
  });
23
- var _a = combinedPipelineOutput.sortedRowsOutput, sortColDef = _a.sortColDef, setSortColDef = _a.setSortColDef, sortingEnabled = _a.sortingEnabled, showSelectCol = combinedPipelineOutput.showSelectCol, displayRows = combinedPipelineOutput.displayRows;
24
- var gridSelectionFns = useGridSelectionFns(selectModel, rows);
25
- var unwrappedStyles = useUnwrappedGridStyles(styleModel);
26
- var getInputStrSubmitCallback = useGetInputStrSubmitCallback(editModel, cols);
27
- var resizeModel = useResizeModel(cols, displayMode);
28
- var colNameToWidth = useMemo(function () {
29
- return Object.keys(resizeModel).reduce(function (prev, fieldName) {
30
- prev[fieldName] = resizeModel[fieldName].width;
31
- return prev;
32
- }, {});
33
- }, [resizeModel]);
34
- var augFormattedRows = useAugFormattedRows(colNameToWidth, displayRows);
35
- var colHeaderCells = cols.map(function (_a, index) {
36
- var _b;
37
- var name = _a.name, label = _a.label, sortable = _a.sortable, minResizeWidth = _a.minResizeWidth, maxResizeWidth = _a.maxResizeWidth, keyboardResizeStep = _a.keyboardResizeStep;
38
- var colSortModel = sortingEnabled && sortable
25
+ const { sortedRowsOutput: { sortColDef, setSortColDef, sortingEnabled }, showSelectCol, displayRows, filterState, } = combinedPipelineOutput;
26
+ const gridSelectionFns = useGridSelectionFns(selectModel, rows);
27
+ const unwrappedStyles = useUnwrappedGridStyles(styleModel);
28
+ const getInputStrSubmitCallback = useGetInputStrSubmitCallback(editModel, cols);
29
+ const resizeModel = useResizeModel(cols, displayMode);
30
+ const colNameToWidth = useMemo(() => Object.keys(resizeModel).reduce((prev, fieldName) => {
31
+ prev[fieldName] = resizeModel[fieldName].width;
32
+ return prev;
33
+ }, {}), [resizeModel]);
34
+ const augFormattedRows = useAugFormattedRows(colNameToWidth, displayRows);
35
+ const colHeaderCells = cols.map(({ name, label, sortable, minResizeWidth, maxResizeWidth, keyboardResizeStep, }, index) => {
36
+ var _a;
37
+ const colSortModel = sortingEnabled && sortable
39
38
  ? {
40
39
  sortOrder: (sortColDef === null || sortColDef === void 0 ? void 0 : sortColDef.name) === name ? sortColDef.order : null,
41
- setSortOrder: function (order) {
42
- setSortColDef && setSortColDef(order && { name: name, order: order });
40
+ setSortOrder: (order) => {
41
+ setSortColDef && setSortColDef(order && { name, order });
43
42
  },
44
43
  }
45
44
  : undefined;
46
- return (_jsx(ColHeaderCellPro, { label: label, sortModel: colSortModel, ariaColIndex: index + 1 + (showSelectCol ? 1 : 0), additionalClasses: ((_b = styleModel === null || styleModel === void 0 ? void 0 : styleModel.mainTableStyleModel) === null || _b === void 0 ? void 0 : _b.theadTh) &&
45
+ return (_jsx(ColHeaderCellPro, { label: label, sortModel: colSortModel, ariaColIndex: index + 1 + (showSelectCol ? 1 : 0), additionalClasses: ((_a = styleModel === null || styleModel === void 0 ? void 0 : styleModel.mainTableStyleModel) === null || _a === void 0 ? void 0 : _a.theadTh) &&
47
46
  styleModel.mainTableStyleModel.theadTh(index), width: resizeModel[name].width, displayMode: displayMode, setWidth: resizeModel[name].setWidth, minResizeWidth: minResizeWidth, maxResizeWidth: maxResizeWidth, keyboardResizeStep: keyboardResizeStep }, name));
48
47
  });
49
- var bodyRows = (_jsx(BodyRows, { augFormattedRows: augFormattedRows, gridSelectionFns: gridSelectionFns, selectModel: selectModel, unwrappedStyles: unwrappedStyles, combinedPipelineOutput: combinedPipelineOutput, editModel: editModel, getInputStrSubmitCallback: getInputStrSubmitCallback }));
48
+ const filteringOccurring = !!(filterState &&
49
+ Object.values(filterState).find(({ editableState }) => editableState.enabled));
50
+ const sortingOccurring = !!sortColDef;
51
+ const renderPrefixCells = useCallback((augRow) => {
52
+ if (!reorder) {
53
+ return null;
54
+ }
55
+ const reorderCallback = (destIndex) => reorder.callback(augRow.id, destIndex);
56
+ return (_jsx(ReorderHandleCell, { rowId: augRow.id, ariaRowIndex: augRow.prePaginationIndex + 2, disabled: filteringOccurring || sortingOccurring, reorderCallback: reorderCallback, styleModel: styleModel === null || styleModel === void 0 ? void 0 : styleModel.reorderModel }));
57
+ }, [filteringOccurring, reorder, sortingOccurring, styleModel === null || styleModel === void 0 ? void 0 : styleModel.reorderModel]);
58
+ const bodyRows = (_jsx(BodyRows, { augFormattedRows: augFormattedRows, gridSelectionFns: gridSelectionFns, selectModel: selectModel, unwrappedStyles: unwrappedStyles, combinedPipelineOutput: combinedPipelineOutput, editModel: editModel, getInputStrSubmitCallback: getInputStrSubmitCallback, renderPrefixCells: renderPrefixCells, additionalColIndexOffset: reorder ? 1 : 0 }));
59
+ const prefixHeader = reorder ? _jsx(ReorderHeaderCell, {}) : null;
50
60
  return (_jsx(InternalGrid, { gridProps: props, hooks: {
51
61
  pipelineOutput: combinedPipelineOutput,
52
62
  selectFns: gridSelectionFns,
53
- unwrappedStyles: unwrappedStyles,
54
- }, slots: { colHeaderCells: colHeaderCells, bodyRows: bodyRows } }));
63
+ unwrappedStyles,
64
+ }, slots: { colHeaderCells, bodyRows, prefixHeader } }));
55
65
  };
56
66
  export default GridPro;
@@ -0,0 +1,6 @@
1
+ import { FC } from "react";
2
+ export interface HorizontalGripProps {
3
+ className?: string;
4
+ }
5
+ declare const HorizontalGrip: FC<HorizontalGripProps>;
6
+ export default HorizontalGrip;
@@ -0,0 +1,3 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ const HorizontalGrip = ({ className }) => (_jsxs("svg", { "aria-hidden": true, xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "currentColor", viewBox: "0 0 16 16", className: className, children: [_jsx("title", { children: "Horizontal Grip" }), _jsx("desc", { children: "A 2-row by 5-column array of dots" }), _jsx("path", { d: "M2 8a1 1 0 1 1 0 2 1 1 0 0 1 0-2m0-3a1 1 0 1 1 0 2 1 1 0 0 1 0-2m3 3a1 1 0 1 1 0 2 1 1 0 0 1 0-2m0-3a1 1 0 1 1 0 2 1 1 0 0 1 0-2m3 3a1 1 0 1 1 0 2 1 1 0 0 1 0-2m0-3a1 1 0 1 1 0 2 1 1 0 0 1 0-2m3 3a1 1 0 1 1 0 2 1 1 0 0 1 0-2m0-3a1 1 0 1 1 0 2 1 1 0 0 1 0-2m3 3a1 1 0 1 1 0 2 1 1 0 0 1 0-2m0-3a1 1 0 1 1 0 2 1 1 0 0 1 0-2" })] }));
3
+ export default HorizontalGrip;
@@ -0,0 +1,6 @@
1
+ import { FC } from "react";
2
+ export interface VerticalGripProps {
3
+ className?: string;
4
+ }
5
+ declare const VerticalGrip: FC<VerticalGripProps>;
6
+ export default VerticalGrip;
@@ -0,0 +1,3 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ const VerticalGrip = ({ className }) => (_jsxs("svg", { "aria-hidden": true, xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "currentColor", viewBox: "0 0 16 16", className: className, children: [_jsx("title", { children: "Vertical Grip" }), _jsx("desc", { children: "A 5-row by 2-column array of dots" }), _jsx("path", { d: "M7 2a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0M7 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0M7 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0m-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0m-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0" })] }));
3
+ export default VerticalGrip;
@@ -1,3 +1,6 @@
1
1
  export * from "../grid";
2
2
  export { default } from "./GridPro";
3
3
  export * from "./types";
4
+ export * from "./util";
5
+ export * from "./reorder/types";
6
+ export * from "./resize/types";
package/grid-pro/index.js CHANGED
@@ -1,3 +1,6 @@
1
1
  export * from "../grid";
2
2
  export { default } from "./GridPro";
3
3
  export * from "./types";
4
+ export * from "./util";
5
+ export * from "./reorder/types";
6
+ export * from "./resize/types";
@@ -0,0 +1,12 @@
1
+ import { FC } from "react";
2
+ import { RowId } from "../";
3
+ import { ReorderStyleModel } from "./types";
4
+ export type ReorderHandleCellProps = {
5
+ rowId: RowId;
6
+ ariaRowIndex: number;
7
+ reorderCallback: (destIndex: number) => void;
8
+ disabled: boolean;
9
+ styleModel?: ReorderStyleModel;
10
+ };
11
+ declare const ReorderHandleCell: FC<ReorderHandleCellProps>;
12
+ export default ReorderHandleCell;
@@ -0,0 +1,220 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useCallback, useMemo } from "react";
3
+ import HorizontalGrip from "../assets/HorizontalGrip";
4
+ import regDragCleanup from "../util/regDragCleanup";
5
+ import classNames from "classnames";
6
+ function dropTargetRefValuesEqual(first, second) {
7
+ if (first === null && second === null) {
8
+ return true;
9
+ }
10
+ if (first === null || second === null) {
11
+ return false;
12
+ }
13
+ return first.index === second.index && first.upper === second.upper;
14
+ }
15
+ const ReorderHandleCell = ({ rowId, ariaRowIndex, disabled, reorderCallback, styleModel, }) => {
16
+ const intDraggedRowClasses = useMemo(() => (styleModel === null || styleModel === void 0 ? void 0 : styleModel.draggedRowClasses) || ["rbdg-reorder-dragged-row"], [styleModel === null || styleModel === void 0 ? void 0 : styleModel.draggedRowClasses]);
17
+ const intDraggedRowPredecessorClasses = useMemo(() => (styleModel === null || styleModel === void 0 ? void 0 : styleModel.draggedRowPredecessorClasses) || [
18
+ "rbdg-reorder-dragged-row-pred",
19
+ ], [styleModel === null || styleModel === void 0 ? void 0 : styleModel.draggedRowPredecessorClasses]);
20
+ const intTopBorderRowClasses = useMemo(() => (styleModel === null || styleModel === void 0 ? void 0 : styleModel.topBorderRowClasses) || ["rbdg-reorder-above-drag-target-row"], [styleModel === null || styleModel === void 0 ? void 0 : styleModel.topBorderRowClasses]);
21
+ const intBottomBorderRowClasses = useMemo(() => (styleModel === null || styleModel === void 0 ? void 0 : styleModel.bottomBorderRowClasses) || [
22
+ "rbdg-reorder-below-drag-target-row",
23
+ ], [styleModel === null || styleModel === void 0 ? void 0 : styleModel.bottomBorderRowClasses]);
24
+ const intGhostTableClasses = useMemo(() => (styleModel === null || styleModel === void 0 ? void 0 : styleModel.ghostDivClasses) || ["border", "rbdg-drag-ghost"], [styleModel === null || styleModel === void 0 ? void 0 : styleModel.ghostDivClasses]);
25
+ const onPointerDown = useCallback((event) => {
26
+ const target = event.target;
27
+ const { pointerId, clientX, clientY, button } = event;
28
+ if (button !== 0) {
29
+ return;
30
+ }
31
+ function createDragGhost() {
32
+ const ghostDiv = document.createElement("div");
33
+ ghostDiv.className = intGhostTableClasses.join(" ");
34
+ ghostDiv.style.left = `${clientX}px`;
35
+ ghostDiv.style.top = `${clientY}px`;
36
+ ghostDiv.textContent = `ID: ${rowId}`;
37
+ ghostDiv.setAttribute("data-testid", "rbdg-drag-ghost");
38
+ document.body.appendChild(ghostDiv);
39
+ return ghostDiv;
40
+ }
41
+ const drageeTh = target.parentElement;
42
+ const drageeTr = drageeTh.parentElement;
43
+ const tbody = drageeTr.parentElement;
44
+ const thead = tbody.parentElement.firstChild;
45
+ const headTr = thead.firstChild;
46
+ const trs = Array.from(tbody.children);
47
+ const drageeTrIndex = Number(drageeTr.ariaRowIndex) - 2;
48
+ const origClassesByIndex = trs.map((tr) => tr.className);
49
+ const origHeadTrClasses = headTr.className;
50
+ function applyRowClassesFromOrig(trIndex, classes) {
51
+ trs[trIndex].className = [
52
+ origClassesByIndex[trIndex],
53
+ classes.join(" "),
54
+ ]
55
+ .join(" ")
56
+ .trim();
57
+ }
58
+ function applyDrageeStyles() {
59
+ applyRowClassesFromOrig(drageeTrIndex, intDraggedRowClasses);
60
+ if (drageeTrIndex - 1 === -1) {
61
+ headTr.className = [
62
+ origHeadTrClasses,
63
+ intDraggedRowPredecessorClasses.join(" "),
64
+ ]
65
+ .join(" ")
66
+ .trim();
67
+ return;
68
+ }
69
+ applyRowClassesFromOrig(drageeTrIndex - 1, intDraggedRowPredecessorClasses);
70
+ }
71
+ applyDrageeStyles();
72
+ const baseClassesByIndex = trs.map((tr) => tr.className);
73
+ const baseHeadTrClasses = headTr.className;
74
+ const rectToIndex = trs.reduce((map, element, trIndex) => {
75
+ if (trIndex !== drageeTrIndex) {
76
+ map.set(element.getBoundingClientRect(), trIndex);
77
+ }
78
+ return map;
79
+ }, new Map());
80
+ const dropTargetRef = {
81
+ current: null,
82
+ };
83
+ function detectEnclosure(clientX, clientY) {
84
+ for (const rect of rectToIndex.keys()) {
85
+ if (clientY < rect.top ||
86
+ clientY > rect.bottom ||
87
+ clientX < rect.left ||
88
+ clientX > rect.right) {
89
+ continue;
90
+ }
91
+ const midY = Math.floor(rect.top + rect.bottom) / 2;
92
+ const rectIndex = rectToIndex.get(rect);
93
+ if (clientY <= midY && rectIndex - 1 === drageeTrIndex) {
94
+ return null;
95
+ }
96
+ if (clientY <= midY && rectIndex - 1 !== drageeTrIndex) {
97
+ return { index: rectIndex, upper: true };
98
+ }
99
+ if (clientY > midY && rectIndex + 1 === drageeTrIndex) {
100
+ return null;
101
+ }
102
+ if (clientY > midY && rectIndex + 1 !== drageeTrIndex) {
103
+ return { index: rectIndex, upper: false };
104
+ }
105
+ }
106
+ return null;
107
+ }
108
+ function restoreOrigRowClasses(trIndex) {
109
+ trs[trIndex].className = origClassesByIndex[trIndex];
110
+ }
111
+ function restoreOrigClasses() {
112
+ trs.forEach((_, trIndex) => restoreOrigRowClasses(trIndex));
113
+ headTr.className = origHeadTrClasses;
114
+ }
115
+ function restoreBaseRowClasses(trIndex) {
116
+ trs[trIndex].className = baseClassesByIndex[trIndex];
117
+ }
118
+ function restoreBaseClasses() {
119
+ trs.forEach((_, trIndex) => restoreBaseRowClasses(trIndex));
120
+ headTr.className = baseHeadTrClasses;
121
+ }
122
+ function applyRowClassesFromBase(trIndex, classes) {
123
+ trs[trIndex].className = [
124
+ baseClassesByIndex[trIndex],
125
+ classes.join(" "),
126
+ ]
127
+ .join(" ")
128
+ .trim();
129
+ }
130
+ function applyDragStyles(trIndex, upper) {
131
+ if (upper) {
132
+ applyRowClassesFromBase(trIndex, intBottomBorderRowClasses);
133
+ }
134
+ if (upper && trIndex - 1 >= 0) {
135
+ applyRowClassesFromBase(trIndex - 1, intTopBorderRowClasses);
136
+ }
137
+ if (upper && trIndex - 1 === -1) {
138
+ headTr.className = [
139
+ baseHeadTrClasses,
140
+ intTopBorderRowClasses.join(" "),
141
+ ]
142
+ .join(" ")
143
+ .trim();
144
+ }
145
+ if (!upper) {
146
+ applyRowClassesFromBase(trIndex, intTopBorderRowClasses);
147
+ }
148
+ if (!upper && trIndex + 1 < trs.length) {
149
+ applyRowClassesFromBase(trIndex + 1, intBottomBorderRowClasses);
150
+ }
151
+ }
152
+ function updateRowStyles(currentDropTargetVal) {
153
+ if (dropTargetRefValuesEqual(dropTargetRef.current, currentDropTargetVal)) {
154
+ return;
155
+ }
156
+ if (currentDropTargetVal === null) {
157
+ restoreBaseClasses();
158
+ dropTargetRef.current = null;
159
+ return;
160
+ }
161
+ if (dropTargetRef.current !== null) {
162
+ restoreBaseClasses();
163
+ }
164
+ applyDragStyles(currentDropTargetVal.index, currentDropTargetVal.upper);
165
+ dropTargetRef.current = currentDropTargetVal;
166
+ }
167
+ target.setPointerCapture(pointerId);
168
+ const dragGhost = createDragGhost();
169
+ applyDrageeStyles();
170
+ function onPointerMove({ clientX, clientY }) {
171
+ dragGhost.style.left = `${clientX}px`;
172
+ dragGhost.style.top = `${clientY}px`;
173
+ const dragTargetVal = detectEnclosure(clientX, clientY);
174
+ updateRowStyles(dragTargetVal);
175
+ }
176
+ function onContextMenu(event) {
177
+ event.preventDefault();
178
+ }
179
+ function cleanUpDragStates() {
180
+ dragGhost.remove();
181
+ restoreOrigClasses();
182
+ }
183
+ const onKeyDown = (removeListeners) => (event) => {
184
+ if (event.code === "Escape") {
185
+ removeListeners();
186
+ cleanUpDragStates();
187
+ dropTargetRef.current = null;
188
+ }
189
+ };
190
+ const onPointerUp = (removeListeners) => () => {
191
+ removeListeners();
192
+ cleanUpDragStates();
193
+ if (dropTargetRef.current !== null) {
194
+ reorderCallback(dropTargetRef.current.index + (dropTargetRef.current.upper ? 0 : 1));
195
+ }
196
+ };
197
+ target.focus();
198
+ regDragCleanup({
199
+ element: target,
200
+ onPointerMove,
201
+ onPointerUp,
202
+ onPointerCancel: onPointerUp,
203
+ onKeyDown,
204
+ onContextMenu,
205
+ });
206
+ }, [
207
+ intBottomBorderRowClasses,
208
+ intDraggedRowClasses,
209
+ intDraggedRowPredecessorClasses,
210
+ intGhostTableClasses,
211
+ intTopBorderRowClasses,
212
+ reorderCallback,
213
+ rowId,
214
+ ]);
215
+ const label = `Reorder Row ${ariaRowIndex}`;
216
+ return (_jsx("th", { "aria-colindex": 1, children: _jsx("button", { onClick: (event) => event.stopPropagation(), "aria-label": label, title: label, onPointerDown: onPointerDown, className: classNames("rbdg-draggable-container", "rbdg-reorder-container", "rbdg-plain-icon-button", {
217
+ "bs-btn-disabled": disabled,
218
+ }), disabled: disabled, children: _jsx(HorizontalGrip, { className: "rbdg-draggable-icon" }) }) }));
219
+ };
220
+ export default ReorderHandleCell;
@@ -0,0 +1,3 @@
1
+ import { FC } from "react";
2
+ declare const ReorderHeaderCell: FC;
3
+ export default ReorderHeaderCell;
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ const spinningArrowIcon = (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "currentColor", viewBox: "0 0 16 16", "aria-hidden": "true", children: [_jsx("desc", { children: "Two arrows that are following each other and pointing clockwise" }), _jsx("path", { d: "M11.534 7h3.932a.25.25 0 0 1 .192.41l-1.966 2.36a.25.25 0 0 1-.384 0l-1.966-2.36a.25.25 0 0 1 .192-.41m-11 2h3.932a.25.25 0 0 0 .192-.41L2.692 6.23a.25.25 0 0 0-.384 0L.342 8.59A.25.25 0 0 0 .534 9" }), _jsx("path", { fillRule: "evenodd", d: "M8 3c-1.552 0-2.94.707-3.857 1.818a.5.5 0 1 1-.771-.636A6.002 6.002 0 0 1 13.917 7H12.9A5 5 0 0 0 8 3M3.1 9a5.002 5.002 0 0 0 8.757 2.182.5.5 0 1 1 .771.636A6.002 6.002 0 0 1 2.083 9z" })] }));
3
+ const ReorderHeaderCell = () => (_jsx("th", { "aria-colindex": 1, title: "Reorder Controls", "aria-label": "Reorder Controls", "aria-description": "Header cell for column with drag handles for reordering rows", children: spinningArrowIcon }));
4
+ export default ReorderHeaderCell;
@@ -0,0 +1,12 @@
1
+ import { RowId } from "../";
2
+ export type ReorderCallback = (id: RowId, destIndex: number) => void;
3
+ export interface ReorderModel {
4
+ callback: ReorderCallback;
5
+ }
6
+ export interface ReorderStyleModel {
7
+ draggedRowClasses?: string[];
8
+ draggedRowPredecessorClasses?: string[];
9
+ topBorderRowClasses?: string[];
10
+ bottomBorderRowClasses?: string[];
11
+ ghostDivClasses?: string[];
12
+ }
@@ -0,0 +1 @@
1
+ export {};