react-table-dnd 2.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Sami Odeh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,256 @@
1
+ <div align="center">
2
+
3
+ # react-table-dnd
4
+
5
+ <p>
6
+ <img src="./docs/desktop.gif" alt="react-table-dnd — drag rows and columns" width="680" />
7
+ </p>
8
+
9
+ <p><strong>Drag-and-drop row & column reordering for React tables.</strong></p>
10
+
11
+ <p>60fps animations &middot; Auto-scroll &middot; Mobile long-press &middot; Virtual scrolling &middot; Zero UI deps</p>
12
+
13
+ <p>
14
+ <a href="https://www.npmjs.com/package/react-table-dnd"><img src="https://img.shields.io/npm/v/react-table-dnd?color=6366f1&label=npm" alt="npm" /></a>
15
+ <a href="https://bundlephobia.com/package/react-table-dnd"><img src="https://img.shields.io/bundlephobia/minzip/react-table-dnd?color=6366f1&label=size" alt="bundle size" /></a>
16
+ <a href="https://www.npmjs.com/package/react-table-dnd"><img src="https://img.shields.io/npm/dm/react-table-dnd?color=6366f1" alt="downloads" /></a>
17
+ <a href="https://github.com/samiodeh1337/react-table-dnd/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/react-table-dnd?color=6366f1" alt="license" /></a>
18
+ </p>
19
+
20
+ <p>
21
+ <a href="https://samiodeh1337.github.io/react-table-dnd/"><strong>Live Demos & Docs</strong></a>
22
+ &nbsp;&middot;&nbsp;
23
+ <a href="#quick-start">Quick Start</a>
24
+ &nbsp;&middot;&nbsp;
25
+ <a href="#api">API</a>
26
+ &nbsp;&middot;&nbsp;
27
+ <a href="https://github.com/samiodeh1337/react-table-dnd">GitHub</a>
28
+ </p>
29
+
30
+ </div>
31
+
32
+ ---
33
+
34
+ ## Why react-table-dnd?
35
+
36
+ - **Rows & columns** — reorder both independently, automatic direction detection
37
+ - **60fps** — direct DOM transforms during drag, no React re-renders until drop
38
+ - **Mobile** — long-press to drag on touch devices, optimized for Chrome Android & Safari iOS
39
+ - **Auto-scroll** — accelerates when dragging near container edges
40
+ - **100k+ rows** — works with `@tanstack/react-virtual`
41
+ - **Drag handles** — restrict drag to a grip icon with `<DragHandle>`
42
+ - **Constraints** — lock specific rows or columns via drag range options
43
+ - **Drop animation** — clone smoothly flies to the drop target
44
+ - **Fully styleable** — `className` + `style` on every component — Tailwind, styled-components, CSS modules
45
+ - **TypeScript** — full type definitions out of the box
46
+ - **Tiny** — only peer dependency is React
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ npm install react-table-dnd
52
+ ```
53
+
54
+ > Requires `react` and `react-dom` >= 17.0.0
55
+
56
+ ## Quick Start
57
+
58
+ ```jsx
59
+ import {
60
+ TableContainer, TableHeader, ColumnCell,
61
+ TableBody, BodyRow, RowCell,
62
+ } from "react-table-dnd";
63
+
64
+ function arrayMove(arr, from, to) {
65
+ const next = [...arr];
66
+ const [item] = next.splice(from, 1);
67
+ next.splice(to, 0, item);
68
+ return next;
69
+ }
70
+
71
+ export default function App() {
72
+ const [cols, setCols] = useState([
73
+ { id: "name", label: "Name", width: 150 },
74
+ { id: "age", label: "Age", width: 100 },
75
+ { id: "city", label: "City", width: 160 },
76
+ ]);
77
+ const [rows, setRows] = useState([
78
+ { id: "1", name: "Alice", age: 28, city: "NYC" },
79
+ { id: "2", name: "Bob", age: 34, city: "LA" },
80
+ { id: "3", name: "Carol", age: 22, city: "SF" },
81
+ ]);
82
+
83
+ return (
84
+ <TableContainer
85
+ onDragEnd={({ sourceIndex, targetIndex, dragType }) => {
86
+ if (dragType === "column") setCols(arrayMove(cols, sourceIndex, targetIndex));
87
+ else setRows(arrayMove(rows, sourceIndex, targetIndex));
88
+ }}
89
+ >
90
+ <TableHeader>
91
+ {cols.map((col, i) => (
92
+ <ColumnCell key={col.id} id={col.id} index={i} style={{ width: col.width }}>
93
+ {col.label}
94
+ </ColumnCell>
95
+ ))}
96
+ </TableHeader>
97
+ <TableBody>
98
+ {rows.map((row, ri) => (
99
+ <BodyRow key={row.id} id={row.id} index={ri}>
100
+ {cols.map((col, ci) => (
101
+ <RowCell key={col.id} index={ci}>
102
+ {row[col.id]}
103
+ </RowCell>
104
+ ))}
105
+ </BodyRow>
106
+ ))}
107
+ </TableBody>
108
+ </TableContainer>
109
+ );
110
+ }
111
+ ```
112
+
113
+ ## API
114
+
115
+ ### Components
116
+
117
+ | Component | Props | Description |
118
+ |---|---|---|
119
+ | **`TableContainer`** | `onDragEnd`, `options`, `renderPlaceholder`, `className`, `style` | Root wrapper — provides drag context |
120
+ | **`TableHeader`** | `className`, `style` | Header row container |
121
+ | **`ColumnCell`** | **`id`**, **`index`**, `className`, `style` | Draggable column header cell |
122
+ | **`TableBody`** | `className`, `style` | Scrollable body — pass `ref` for virtual scrolling |
123
+ | **`BodyRow`** | **`id`**, **`index`**, `className`, `style` | Draggable row |
124
+ | **`RowCell`** | **`index`**, `className`, `style` | Cell within a row |
125
+ | **`DragHandle`** | `className`, `style` | Wrap inside BodyRow/ColumnCell to restrict drag to this element |
126
+
127
+ Bold props are required.
128
+
129
+ ### Column Width
130
+
131
+ Pass `width` inside the `style` prop on `ColumnCell`. Columns grow proportionally by default to fill available space. To fix a column at exactly its pixel size, also pass `flex`:
132
+
133
+ ```jsx
134
+ {/* Flex — grows proportionally to fill container (default) */}
135
+ <ColumnCell style={{ width: 150 }}>Name</ColumnCell>
136
+
137
+ {/* Fixed — stays exactly 150px regardless of container width */}
138
+ <ColumnCell style={{ width: 150, flex: "0 0 150px" }}>Name</ColumnCell>
139
+ ```
140
+
141
+ ### Types
142
+
143
+ ```typescript
144
+ interface DragEndResult {
145
+ sourceIndex: number;
146
+ targetIndex: number;
147
+ dragType: "row" | "column";
148
+ }
149
+
150
+ interface DragRange {
151
+ start?: number; // first draggable index
152
+ end?: number; // last draggable index (exclusive)
153
+ }
154
+ ```
155
+
156
+ ### Options
157
+
158
+ ```jsx
159
+ <TableContainer
160
+ options={{
161
+ rowDragRange: { start: 1 }, // lock first row
162
+ columnDragRange: { start: 1, end: 5 }, // lock first col, only 1-4 draggable
163
+ }}
164
+ />
165
+ ```
166
+
167
+ ### Drag Handle
168
+
169
+ ```jsx
170
+ import { DragHandle } from "react-table-dnd";
171
+
172
+ <BodyRow id="1" index={0}>
173
+ <RowCell index={0}>
174
+ <DragHandle><GripIcon /></DragHandle>
175
+ Content here
176
+ </RowCell>
177
+ </BodyRow>
178
+ ```
179
+
180
+ ### Custom Placeholder
181
+
182
+ ```jsx
183
+ <TableContainer
184
+ renderPlaceholder={() => (
185
+ <div style={{
186
+ background: "#6366f122",
187
+ border: "2px dashed #6366f1",
188
+ height: "100%",
189
+ }} />
190
+ )}
191
+ />
192
+ ```
193
+
194
+ ## Styling
195
+
196
+ Every component accepts `className` and `style`. No opinionated styles on cells.
197
+
198
+ <table>
199
+ <tr>
200
+ <td><strong>Inline</strong></td>
201
+ <td><strong>Tailwind</strong></td>
202
+ <td><strong>styled-components</strong></td>
203
+ </tr>
204
+ <tr>
205
+ <td>
206
+
207
+ ```jsx
208
+ <ColumnCell style={{
209
+ padding: "0 16px",
210
+ fontWeight: 700,
211
+ }} />
212
+ ```
213
+
214
+ </td>
215
+ <td>
216
+
217
+ ```jsx
218
+ <ColumnCell className="px-4
219
+ font-bold text-sm" />
220
+ ```
221
+
222
+ </td>
223
+ <td>
224
+
225
+ ```jsx
226
+ const Col = styled(ColumnCell)`
227
+ padding: 0 16px;
228
+ font-weight: 700;
229
+ `;
230
+ ```
231
+
232
+ </td>
233
+ </tr>
234
+ </table>
235
+
236
+ ## Browser Support
237
+
238
+ | | Chrome | Firefox | Safari | Edge |
239
+ |---|---|---|---|---|
240
+ | **Desktop** | ✅ | ✅ | ✅ | ✅ |
241
+ | **Mobile** | ✅ | ✅ | ✅ | ✅ |
242
+
243
+ Mobile uses long-press to initiate drag.
244
+
245
+ ## Contributing
246
+
247
+ ```bash
248
+ git clone https://github.com/samiodeh1337/react-table-dnd.git
249
+ cd react-table-dnd
250
+ npm install
251
+ npm run dev # docs site at localhost:5173
252
+ ```
253
+
254
+ ## License
255
+
256
+ [MIT](LICENSE) &copy; [Sami Odeh](https://github.com/samiodeh1337)
@@ -0,0 +1,9 @@
1
+ import { default as React, CSSProperties, ReactNode } from 'react';
2
+ interface BodyRowProps {
3
+ children: ReactNode;
4
+ style?: CSSProperties;
5
+ className?: string;
6
+ [propName: string]: any;
7
+ }
8
+ declare const BodyRow: React.FC<BodyRowProps>;
9
+ export default BodyRow;
@@ -0,0 +1,9 @@
1
+ import { default as React, ReactNode } from 'react';
2
+ interface ColumnCellProps {
3
+ children: ReactNode;
4
+ style?: React.CSSProperties;
5
+ className?: string;
6
+ [propName: string]: any;
7
+ }
8
+ declare const ColumnCell: React.FC<ColumnCellProps>;
9
+ export default ColumnCell;
@@ -0,0 +1,8 @@
1
+ import { default as React, ReactNode, CSSProperties } from 'react';
2
+ interface DragHandleProps {
3
+ children: ReactNode;
4
+ className?: string;
5
+ style?: CSSProperties;
6
+ }
7
+ declare const DragHandle: React.FC<DragHandleProps>;
8
+ export default DragHandle;
@@ -0,0 +1,12 @@
1
+ import { default as React, CSSProperties, ReactNode } from 'react';
2
+ import { DragType } from '../hooks/types';
3
+ export interface DraggableProps {
4
+ children: ReactNode;
5
+ id: number | string;
6
+ index: number;
7
+ type: DragType;
8
+ styles: CSSProperties;
9
+ disabled?: boolean;
10
+ }
11
+ declare const Draggable: React.FC<DraggableProps>;
12
+ export default Draggable;
@@ -0,0 +1,11 @@
1
+ import { default as React } from 'react';
2
+ interface RowCellProps {
3
+ children?: React.ReactNode;
4
+ width?: number;
5
+ index: number;
6
+ style?: React.CSSProperties;
7
+ className?: string;
8
+ [propName: string]: any;
9
+ }
10
+ declare const RowCell: React.FC<RowCellProps>;
11
+ export default RowCell;
@@ -0,0 +1,8 @@
1
+ import { default as React, ReactNode } from 'react';
2
+ interface TableBodyProps {
3
+ children: ReactNode;
4
+ style?: React.CSSProperties;
5
+ className?: string;
6
+ }
7
+ declare const TableBody: React.ForwardRefExoticComponent<TableBodyProps & React.RefAttributes<HTMLDivElement>>;
8
+ export default TableBody;
@@ -0,0 +1,15 @@
1
+ import { default as React, ReactNode } from 'react';
2
+ import { DragEndResult, DragRange } from '../../hooks/types';
3
+ interface TableProviderProps {
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ style?: React.CSSProperties;
7
+ onDragEnd?: (result: DragEndResult) => void;
8
+ renderPlaceholder?: () => ReactNode;
9
+ options?: {
10
+ columnDragRange: DragRange;
11
+ rowDragRange: DragRange;
12
+ };
13
+ }
14
+ declare const TableProvider: React.ForwardRefExoticComponent<TableProviderProps & React.RefAttributes<HTMLDivElement>>;
15
+ export default TableProvider;
@@ -0,0 +1,7 @@
1
+ import { TableState, TableAction } from '../../hooks/types';
2
+ export interface TableStore {
3
+ getState: () => TableState;
4
+ dispatch: (action: TableAction) => void;
5
+ subscribe: (listener: () => void) => () => void;
6
+ }
7
+ export declare function createTableStore(reducer: (state: TableState, action: TableAction) => TableState, initialState: TableState): TableStore;
@@ -0,0 +1,7 @@
1
+ import { ReactNode } from 'react';
2
+ interface StylesProps {
3
+ children: ReactNode;
4
+ className?: string;
5
+ }
6
+ export declare const Styles: ({ children, className }: StylesProps) => import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,9 @@
1
+ import { TableStore } from './store';
2
+ import { TableState, TableAction } from '../../hooks/types';
3
+ export declare const StoreContext: import('react').Context<TableStore | null>;
4
+ export declare const useTableStore: <T>(selector: (state: TableState) => T) => T;
5
+ export declare const useTableDispatch: () => ((action: TableAction) => void);
6
+ export declare const useTable: () => {
7
+ state: TableState;
8
+ dispatch: (action: TableAction) => void;
9
+ };
@@ -0,0 +1,8 @@
1
+ import { default as React, ReactNode } from 'react';
2
+ interface TableHeaderProps {
3
+ children: ReactNode;
4
+ style?: React.CSSProperties;
5
+ className?: string;
6
+ }
7
+ declare const TableHeader: React.ForwardRefExoticComponent<TableHeaderProps & React.RefAttributes<HTMLDivElement>>;
8
+ export default TableHeader;
@@ -0,0 +1,11 @@
1
+ import { default as TableContainer } from './TableContainer';
2
+ import { default as TableHeader } from './TableHeader';
3
+ import { default as ColumnCell } from './ColumnCell';
4
+ import { default as TableBody } from './TableBody';
5
+ import { default as BodyRow } from './BodyRow';
6
+ import { default as RowCell } from './RowCell';
7
+ import { default as DragHandle } from './DragHandle';
8
+ export { useTable, useTableStore, useTableDispatch } from './TableContainer/useTable';
9
+ export { TableContainer, TableHeader, ColumnCell, TableBody, BodyRow, RowCell, DragHandle };
10
+ export type { DragEndResult, DragRange, DragType } from '../hooks/types';
11
+ export type { DraggableProps } from './Draggable';
@@ -0,0 +1,5 @@
1
+ import { ColumnItem, RowItem } from '../hooks/types';
2
+ export declare const binarySearchDropIndex: (mouseY: number, items: RowItem[]) => number;
3
+ export declare const binarySearchDropIndexHeader: (mouseX: number, items: ColumnItem[]) => number;
4
+ export declare function isScrollbarClick(clientX: number, clientY: number, target: HTMLElement): boolean;
5
+ export declare const isIndexOutOfRange: (index: string | number, start?: number, end?: number) => boolean;
@@ -0,0 +1,125 @@
1
+ import { MutableRefObject, RefObject } from 'react';
2
+ export type DragType = 'row' | 'column';
3
+ export interface DragEndResult {
4
+ sourceIndex: number;
5
+ targetIndex: number;
6
+ dragType: DragType;
7
+ }
8
+ export interface DraggedState {
9
+ initial: {
10
+ x: number;
11
+ y: number;
12
+ };
13
+ translate: {
14
+ x: number;
15
+ y: number;
16
+ };
17
+ isDragging: boolean;
18
+ draggedID: string | null;
19
+ targetIndex: number | null;
20
+ sourceIndex: number | null;
21
+ }
22
+ export interface RectState {
23
+ draggedItemWidth: number;
24
+ draggedItemHeight: number;
25
+ }
26
+ export interface TableDimensions {
27
+ width: number;
28
+ height: number;
29
+ }
30
+ export interface DragRange {
31
+ start?: number;
32
+ end?: number;
33
+ }
34
+ export interface Options {
35
+ columnDragRange: DragRange;
36
+ rowDragRange: DragRange;
37
+ defaultSizing: number;
38
+ }
39
+ export interface HookRefs {
40
+ tableRef: RefObject<HTMLDivElement | null>;
41
+ bodyRef: RefObject<HTMLDivElement | null>;
42
+ headerRef: RefObject<HTMLDivElement | null>;
43
+ cloneRef: RefObject<HTMLDivElement | null>;
44
+ placeholderRef: RefObject<HTMLDivElement | null>;
45
+ }
46
+ export interface TableState {
47
+ dragged: DraggedState;
48
+ dragType: DragType | null;
49
+ rect: RectState;
50
+ tableDimensions: TableDimensions;
51
+ refs: HookRefs;
52
+ bodyScrollBarWidth: number;
53
+ options: Options;
54
+ widths: number[];
55
+ columnIds: string[];
56
+ }
57
+ export type TableAction = {
58
+ type: 'setDragged';
59
+ value: Partial<DraggedState>;
60
+ } | {
61
+ type: 'setDragType';
62
+ value: DragType | null;
63
+ } | {
64
+ type: 'setTableDimensions';
65
+ value: TableDimensions;
66
+ } | {
67
+ type: 'setRef';
68
+ refName: keyof HookRefs;
69
+ value: MutableRefObject<HTMLDivElement | null> | null;
70
+ } | {
71
+ type: 'setBodyScrollBarWidth';
72
+ value: number;
73
+ } | {
74
+ type: 'setWidths';
75
+ value: number[];
76
+ } | {
77
+ type: 'setColumnIds';
78
+ value: string[];
79
+ } | {
80
+ type: 'setOptions';
81
+ value: Partial<Options>;
82
+ } | {
83
+ type: 'dragStart';
84
+ value: {
85
+ rect: RectState;
86
+ dragged: {
87
+ initial: {
88
+ x: number;
89
+ y: number;
90
+ };
91
+ translate: {
92
+ x: number;
93
+ y: number;
94
+ };
95
+ draggedID: string | null;
96
+ isDragging: boolean;
97
+ sourceIndex: number;
98
+ };
99
+ dragType: DragType | null;
100
+ tableDimensions: TableDimensions;
101
+ };
102
+ } | {
103
+ type: 'dragEnd';
104
+ value: {
105
+ targetIndex: number | null;
106
+ sourceIndex: number | null;
107
+ };
108
+ };
109
+ export interface RowItem {
110
+ height: number;
111
+ itemTop: number;
112
+ itemBottom: number;
113
+ index: string;
114
+ }
115
+ export interface ColumnItem {
116
+ left: number;
117
+ width: number;
118
+ itemLeft: number;
119
+ itemRight: number;
120
+ index: string;
121
+ }
122
+ export interface Point {
123
+ x: number;
124
+ y: number;
125
+ }
@@ -0,0 +1,15 @@
1
+ import { HookRefs } from './types';
2
+ declare const useAutoScroll: (refs: HookRefs) => {
3
+ startAutoScroll: (speed: number, ref: HTMLDivElement, dir: "horizontal" | "vertical") => void;
4
+ stopAutoScroll: () => void;
5
+ setContainerRect: (rect: DOMRect) => void;
6
+ isAutoScrollingVertical: import('react').RefObject<boolean>;
7
+ isAutoScrollingHorizontal: import('react').RefObject<boolean>;
8
+ pointerRef: import('react').RefObject<{
9
+ x: number;
10
+ y: number;
11
+ }>;
12
+ BodyScrollHandle: import('react').UIEventHandler<HTMLDivElement>;
13
+ HeaderScrollHandle: import('react').UIEventHandler<HTMLDivElement>;
14
+ };
15
+ export default useAutoScroll;
@@ -0,0 +1,7 @@
1
+ import { Dispatch } from 'react';
2
+ import { HookRefs, DraggedState, DragType, Options, DragEndResult, TableAction } from './types';
3
+ declare const useDragContextEvents: (refs: HookRefs, dragged: DraggedState, dispatch: Dispatch<TableAction>, dragType: DragType | null, options: Options, onDragEnd: ((result: DragEndResult) => void) | undefined) => {
4
+ dragStart: (e: React.MouseEvent<HTMLDivElement>) => void;
5
+ touchStart: (e: React.TouchEvent<HTMLDivElement>) => void;
6
+ };
7
+ export default useDragContextEvents;
@@ -0,0 +1,13 @@
1
+ import { HookRefs, Options, RowItem, ColumnItem, DragType, Point } from './types';
2
+ interface DropTargetResult {
3
+ computeRowItems: () => RowItem[] | null;
4
+ computeColumnItems: () => ColumnItem[] | null;
5
+ resolveDropIndex: (clientX: number, clientY: number, dtype: DragType | null, rect: DOMRect, bodyScrollTop: number, initial: Point, size: {
6
+ width: number;
7
+ height: number;
8
+ }) => number;
9
+ cachedItemsRef: React.RefObject<RowItem[] | ColumnItem[] | null>;
10
+ cachedContainerRef: React.RefObject<DOMRect | null>;
11
+ }
12
+ declare const useDropTarget: (refs: HookRefs, options: Options) => DropTargetResult;
13
+ export default useDropTarget;
@@ -0,0 +1,15 @@
1
+ import { HookRefs } from './types';
2
+ import { IndexMap } from './useShiftTransforms';
3
+ interface IndexMapsResult {
4
+ rowIndexMapRef: React.RefObject<IndexMap>;
5
+ colIndexMapRef: React.RefObject<IndexMap>;
6
+ cellIndexMapRef: React.RefObject<Map<number, HTMLElement[]>>;
7
+ mapStaleRef: React.RefObject<boolean>;
8
+ buildMaps: (dtype: string | null | undefined, body: HTMLElement | null) => void;
9
+ rebuildRowMap: (container: HTMLElement) => void;
10
+ rebuildColumnMaps: (container: HTMLElement, header: HTMLElement | null) => void;
11
+ checkStaleness: () => void;
12
+ clearMaps: () => void;
13
+ }
14
+ declare const useIndexMaps: (refs: HookRefs) => IndexMapsResult;
15
+ export default useIndexMaps;
@@ -0,0 +1,14 @@
1
+ import { HookRefs } from './types';
2
+ /**
3
+ * Mobile long-press-to-drag.
4
+ * this hook implements JS-based scrolling with momentum/inertia when
5
+ * the long press is cancelled (user is scrolling, not dragging).
6
+ *
7
+ * preventDefault() is called on touchmove to stop any residual
8
+ * browser behavior during the 300ms detection window.
9
+ */
10
+ export default function useLongPress(refs: HookRefs, beginDrag: (e: React.TouchEvent<HTMLDivElement>, clientX: number, clientY: number) => void, dragEnd: () => void, onDragMove: (clientX: number, clientY: number) => void): {
11
+ touchStart: (e: React.TouchEvent<HTMLDivElement>) => void;
12
+ cancelLongPress: () => void;
13
+ isTouchActiveRef: import('react').RefObject<boolean>;
14
+ };
@@ -0,0 +1,16 @@
1
+ import { HookRefs, DragType } from './types';
2
+ export type IndexMap = Map<number, {
3
+ outer: HTMLElement;
4
+ inner: HTMLElement;
5
+ }>;
6
+ interface ShiftTransformsResult {
7
+ applyShiftTransforms: (sourceIndex: number | null, targetIndex: number | null, dtype: DragType | null) => void;
8
+ clearShiftTransforms: () => void;
9
+ prevTargetIndexRef: React.RefObject<number | null>;
10
+ draggedSizeRef: React.RefObject<{
11
+ width: number;
12
+ height: number;
13
+ }>;
14
+ }
15
+ declare const useShiftTransforms: (refs: HookRefs, rowIndexMapRef: React.RefObject<IndexMap>, colIndexMapRef: React.RefObject<IndexMap>, cellIndexMapRef: React.RefObject<Map<number, HTMLElement[]>>) => ShiftTransformsResult;
16
+ export default useShiftTransforms;