grid-cell-selection 1.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/README.md +65 -0
- package/dist/App.d.ts +3 -0
- package/dist/example/App.d.ts +3 -0
- package/dist/example/main.d.ts +1 -0
- package/dist/hooks/selectionComponents.d.ts +0 -0
- package/dist/hooks/useCellSelection.d.ts +9 -0
- package/dist/hooks/useMouseDragSelection.d.ts +6 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.esm.js +119 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +124 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +1 -0
- package/dist/types/index.d.ts +8 -0
- package/package.json +53 -0
package/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Grid Cell Selection
|
2
|
+
|
3
|
+
A React hook for grid cell selection. A simple headless hook that.
|
4
|
+
|
5
|
+
# Made by [Atticus](https://atticusthomson.com)
|
6
|
+
|
7
|
+

|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
```bash
|
12
|
+
npm install grid-cell-selection
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
```tsx
|
18
|
+
import React from "react";
|
19
|
+
import { useGridCellSelection } from "grid-cell-selection";
|
20
|
+
|
21
|
+
function App() {
|
22
|
+
const columns = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"];
|
23
|
+
const rows = 20;
|
24
|
+
|
25
|
+
const { isCellSelected, handleMouseDown, handleMouseEnter, handleMouseUp } = useGridCellSelection("multiple");
|
26
|
+
|
27
|
+
return (
|
28
|
+
<>
|
29
|
+
<table onMouseUp={handleMouseUp}>
|
30
|
+
<tbody>
|
31
|
+
{Array.from({ length: rows }, (_, row) => (
|
32
|
+
<tr key={row}>
|
33
|
+
{columns.map((column, col) => (
|
34
|
+
<td
|
35
|
+
onMouseEnter={(event) => handleMouseEnter({ row, col }, event)}
|
36
|
+
onMouseDown={(event) => handleMouseDown({ row, col }, event)}
|
37
|
+
className={`${isCellSelected({ row, col }) ? "selected" : ""}`}
|
38
|
+
>
|
39
|
+
{column}
|
40
|
+
{row}
|
41
|
+
</td>
|
42
|
+
))}
|
43
|
+
</tr>
|
44
|
+
))}
|
45
|
+
</tbody>
|
46
|
+
</table>
|
47
|
+
</>
|
48
|
+
);
|
49
|
+
}
|
50
|
+
```
|
51
|
+
|
52
|
+
## Cell Selection Behavior
|
53
|
+
|
54
|
+
### Single Cell Selection
|
55
|
+
|
56
|
+
- Click on a cell to select it.
|
57
|
+
- Clicking on a different cell deselects any previously selected cells.
|
58
|
+
|
59
|
+
### Range Selection
|
60
|
+
|
61
|
+
- Click and drag to select a range of cells
|
62
|
+
|
63
|
+
### Multiple Range Selection
|
64
|
+
|
65
|
+
- Hold Ctrl (or Cmd on Mac) or Shift to select multiple ranges
|
package/dist/App.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
import "./index.css";
|
File without changes
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/// <reference types="react" />
|
2
|
+
import { CellIdentifier } from "../types";
|
3
|
+
export declare const useGridCellSelection: () => {
|
4
|
+
selectedCells: Set<string>;
|
5
|
+
isCellSelected: (cell: CellIdentifier) => boolean;
|
6
|
+
handleMouseDown: (cell: CellIdentifier, event: import("react").MouseEvent<Element, MouseEvent>) => void;
|
7
|
+
handleMouseEnter: (cell: CellIdentifier, event: import("react").MouseEvent<Element, MouseEvent>) => void;
|
8
|
+
handleMouseUp: () => void;
|
9
|
+
};
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { CellIdentifier } from "../types";
|
2
|
+
export declare const useMouseDragSelection: (toggleCellSelection: (cell: CellIdentifier, ctrlKey: boolean, shiftKey: boolean, newSelection: boolean) => void) => {
|
3
|
+
handleMouseDown: (cell: CellIdentifier, event: React.MouseEvent) => void;
|
4
|
+
handleMouseEnter: (cell: CellIdentifier, event: React.MouseEvent) => void;
|
5
|
+
handleMouseUp: () => void;
|
6
|
+
};
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
import { useState } from 'react';
|
2
|
+
|
3
|
+
/******************************************************************************
|
4
|
+
Copyright (c) Microsoft Corporation.
|
5
|
+
|
6
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
7
|
+
purpose with or without fee is hereby granted.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
16
|
+
***************************************************************************** */
|
17
|
+
|
18
|
+
var __assign = function() {
|
19
|
+
__assign = Object.assign || function __assign(t) {
|
20
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
21
|
+
s = arguments[i];
|
22
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
23
|
+
}
|
24
|
+
return t;
|
25
|
+
};
|
26
|
+
return __assign.apply(this, arguments);
|
27
|
+
};
|
28
|
+
|
29
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
30
|
+
var e = new Error(message);
|
31
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
32
|
+
};
|
33
|
+
|
34
|
+
var useMouseDragSelection = function (toggleCellSelection) {
|
35
|
+
var _a = useState(false), isDragging = _a[0], setIsDragging = _a[1];
|
36
|
+
var handleMouseDown = function (cell, event) {
|
37
|
+
setIsDragging(true);
|
38
|
+
toggleCellSelection(cell, event.ctrlKey || event.metaKey, event.shiftKey, true);
|
39
|
+
};
|
40
|
+
var handleMouseEnter = function (cell, event) {
|
41
|
+
if (isDragging) {
|
42
|
+
toggleCellSelection(cell, event.ctrlKey || event.metaKey, event.shiftKey, false);
|
43
|
+
}
|
44
|
+
};
|
45
|
+
var handleMouseUp = function () {
|
46
|
+
setIsDragging(false);
|
47
|
+
};
|
48
|
+
return {
|
49
|
+
handleMouseDown: handleMouseDown,
|
50
|
+
handleMouseEnter: handleMouseEnter,
|
51
|
+
handleMouseUp: handleMouseUp,
|
52
|
+
};
|
53
|
+
};
|
54
|
+
|
55
|
+
var getCellKey = function (cell) {
|
56
|
+
return "".concat(cell.row, "-").concat(cell.col);
|
57
|
+
};
|
58
|
+
var useGridCellSelection = function () {
|
59
|
+
var _a = useState({
|
60
|
+
selectedCells: new Set(),
|
61
|
+
}), selectionState = _a[0], setSelectionState = _a[1];
|
62
|
+
var toggleCellSelection = function (cell, ctrlKey, shiftKey, newSelection) {
|
63
|
+
if (ctrlKey === void 0) { ctrlKey = false; }
|
64
|
+
if (shiftKey === void 0) { shiftKey = false; }
|
65
|
+
if (newSelection === void 0) { newSelection = false; }
|
66
|
+
setSelectionState(function (prevState) {
|
67
|
+
var selectedCells = new Set(prevState.selectedCells);
|
68
|
+
var cellKey = getCellKey(cell);
|
69
|
+
if (prevState.startCell && !newSelection) {
|
70
|
+
handleRangeSelection(selectedCells, prevState.startCell, cell);
|
71
|
+
}
|
72
|
+
else if ((shiftKey || ctrlKey) && newSelection) {
|
73
|
+
handleSingleOrMultipleSelection(selectedCells, cellKey);
|
74
|
+
}
|
75
|
+
else {
|
76
|
+
selectedCells.clear();
|
77
|
+
selectedCells.add(cellKey);
|
78
|
+
}
|
79
|
+
return __assign(__assign({}, prevState), { selectedCells: selectedCells, startCell: newSelection ? cell : prevState.startCell });
|
80
|
+
});
|
81
|
+
};
|
82
|
+
var isCellSelected = function (cell) {
|
83
|
+
return selectionState.selectedCells.has(getCellKey(cell));
|
84
|
+
};
|
85
|
+
var _b = useMouseDragSelection(toggleCellSelection), handleMouseDown = _b.handleMouseDown, handleMouseEnter = _b.handleMouseEnter, handleMouseUp = _b.handleMouseUp;
|
86
|
+
return {
|
87
|
+
selectedCells: selectionState.selectedCells,
|
88
|
+
isCellSelected: isCellSelected,
|
89
|
+
handleMouseDown: handleMouseDown,
|
90
|
+
handleMouseEnter: handleMouseEnter,
|
91
|
+
handleMouseUp: handleMouseUp,
|
92
|
+
};
|
93
|
+
};
|
94
|
+
// New helper functions
|
95
|
+
function handleRangeSelection(selectedCells, startCell, endCell) {
|
96
|
+
var action = selectedCells.has(getCellKey(startCell)) ? "add" : "delete";
|
97
|
+
var _a = [startCell.row, startCell.col], startRow = _a[0], startCol = _a[1];
|
98
|
+
var _b = [endCell.row, endCell.col], endRow = _b[0], endCol = _b[1];
|
99
|
+
var minRow = Math.min(startRow, endRow);
|
100
|
+
var maxRow = Math.max(startRow, endRow);
|
101
|
+
var minCol = Math.min(startCol, endCol);
|
102
|
+
var maxCol = Math.max(startCol, endCol);
|
103
|
+
for (var row = minRow; row <= maxRow; row++) {
|
104
|
+
for (var col = minCol; col <= maxCol; col++) {
|
105
|
+
selectedCells[action](getCellKey({ row: row, col: col }));
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
function handleSingleOrMultipleSelection(selectedCells, cellKey) {
|
110
|
+
if (selectedCells.has(cellKey)) {
|
111
|
+
selectedCells.delete(cellKey);
|
112
|
+
}
|
113
|
+
else {
|
114
|
+
selectedCells.add(cellKey);
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
export { useGridCellSelection, useMouseDragSelection };
|
119
|
+
//# sourceMappingURL=index.esm.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/hooks/useMouseDragSelection.ts","../src/hooks/useCellSelection.ts"],"sourcesContent":["import { useState } from \"react\";\nimport { CellIdentifier } from \"../types\";\n\nexport const useMouseDragSelection = (\n toggleCellSelection: (cell: CellIdentifier, ctrlKey: boolean, shiftKey: boolean, newSelection: boolean) => void\n) => {\n const [isDragging, setIsDragging] = useState(false);\n\n const handleMouseDown = (cell: CellIdentifier, event: React.MouseEvent) => {\n setIsDragging(true);\n toggleCellSelection(cell, event.ctrlKey || event.metaKey, event.shiftKey, true);\n };\n\n const handleMouseEnter = (cell: CellIdentifier, event: React.MouseEvent) => {\n if (isDragging) {\n toggleCellSelection(cell, event.ctrlKey || event.metaKey, event.shiftKey, false);\n }\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n };\n\n return {\n handleMouseDown,\n handleMouseEnter,\n handleMouseUp,\n };\n};\n","import { useState } from \"react\";\nimport { CellIdentifier, SelectionState } from \"../types\";\nimport { useMouseDragSelection } from \"./useMouseDragSelection\";\n\nconst getCellKey = (cell: Omit<CellIdentifier, \"id\">): string => {\n return `${cell.row}-${cell.col}`;\n};\n\nexport const useGridCellSelection = () => {\n const [selectionState, setSelectionState] = useState<SelectionState>({\n selectedCells: new Set(),\n });\n\n const toggleCellSelection = (cell: CellIdentifier, ctrlKey = false, shiftKey = false, newSelection = false) => {\n setSelectionState((prevState) => {\n const selectedCells = new Set(prevState.selectedCells);\n const cellKey = getCellKey(cell);\n\n if (prevState.startCell && !newSelection) {\n handleRangeSelection(selectedCells, prevState.startCell, cell);\n } else if ((shiftKey || ctrlKey) && newSelection) {\n handleSingleOrMultipleSelection(selectedCells, cellKey);\n } else {\n selectedCells.clear();\n selectedCells.add(cellKey);\n }\n\n return {\n ...prevState,\n selectedCells,\n startCell: newSelection ? cell : prevState.startCell,\n };\n });\n };\n\n const isCellSelected = (cell: CellIdentifier) => {\n return selectionState.selectedCells.has(getCellKey(cell));\n };\n\n const { handleMouseDown, handleMouseEnter, handleMouseUp } = useMouseDragSelection(toggleCellSelection);\n\n return {\n selectedCells: selectionState.selectedCells,\n isCellSelected,\n handleMouseDown,\n handleMouseEnter,\n handleMouseUp,\n };\n};\n\n// New helper functions\nfunction handleRangeSelection(selectedCells: Set<string>, startCell: CellIdentifier, endCell: CellIdentifier) {\n const action = selectedCells.has(getCellKey(startCell)) ? \"add\" : \"delete\";\n const [startRow, startCol] = [startCell.row, startCell.col];\n const [endRow, endCol] = [endCell.row, endCell.col];\n\n const minRow = Math.min(startRow, endRow);\n const maxRow = Math.max(startRow, endRow);\n const minCol = Math.min(startCol, endCol);\n const maxCol = Math.max(startCol, endCol);\n\n for (let row = minRow; row <= maxRow; row++) {\n for (let col = minCol; col <= maxCol; col++) {\n selectedCells[action](getCellKey({ row, col }));\n }\n }\n}\n\nfunction handleSingleOrMultipleSelection(selectedCells: Set<string>, cellKey: string) {\n if (selectedCells.has(cellKey)) {\n selectedCells.delete(cellKey);\n } else {\n selectedCells.add(cellKey);\n }\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
4
|
+
|
5
|
+
var react = require('react');
|
6
|
+
|
7
|
+
/******************************************************************************
|
8
|
+
Copyright (c) Microsoft Corporation.
|
9
|
+
|
10
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
11
|
+
purpose with or without fee is hereby granted.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
14
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
15
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
16
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
17
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
18
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
19
|
+
PERFORMANCE OF THIS SOFTWARE.
|
20
|
+
***************************************************************************** */
|
21
|
+
|
22
|
+
var __assign = function() {
|
23
|
+
__assign = Object.assign || function __assign(t) {
|
24
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
25
|
+
s = arguments[i];
|
26
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
27
|
+
}
|
28
|
+
return t;
|
29
|
+
};
|
30
|
+
return __assign.apply(this, arguments);
|
31
|
+
};
|
32
|
+
|
33
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
34
|
+
var e = new Error(message);
|
35
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
36
|
+
};
|
37
|
+
|
38
|
+
var useMouseDragSelection = function (toggleCellSelection) {
|
39
|
+
var _a = react.useState(false), isDragging = _a[0], setIsDragging = _a[1];
|
40
|
+
var handleMouseDown = function (cell, event) {
|
41
|
+
setIsDragging(true);
|
42
|
+
toggleCellSelection(cell, event.ctrlKey || event.metaKey, event.shiftKey, true);
|
43
|
+
};
|
44
|
+
var handleMouseEnter = function (cell, event) {
|
45
|
+
if (isDragging) {
|
46
|
+
toggleCellSelection(cell, event.ctrlKey || event.metaKey, event.shiftKey, false);
|
47
|
+
}
|
48
|
+
};
|
49
|
+
var handleMouseUp = function () {
|
50
|
+
setIsDragging(false);
|
51
|
+
};
|
52
|
+
return {
|
53
|
+
handleMouseDown: handleMouseDown,
|
54
|
+
handleMouseEnter: handleMouseEnter,
|
55
|
+
handleMouseUp: handleMouseUp,
|
56
|
+
};
|
57
|
+
};
|
58
|
+
|
59
|
+
var getCellKey = function (cell) {
|
60
|
+
return "".concat(cell.row, "-").concat(cell.col);
|
61
|
+
};
|
62
|
+
var useGridCellSelection = function () {
|
63
|
+
var _a = react.useState({
|
64
|
+
selectedCells: new Set(),
|
65
|
+
}), selectionState = _a[0], setSelectionState = _a[1];
|
66
|
+
var toggleCellSelection = function (cell, ctrlKey, shiftKey, newSelection) {
|
67
|
+
if (ctrlKey === void 0) { ctrlKey = false; }
|
68
|
+
if (shiftKey === void 0) { shiftKey = false; }
|
69
|
+
if (newSelection === void 0) { newSelection = false; }
|
70
|
+
setSelectionState(function (prevState) {
|
71
|
+
var selectedCells = new Set(prevState.selectedCells);
|
72
|
+
var cellKey = getCellKey(cell);
|
73
|
+
if (prevState.startCell && !newSelection) {
|
74
|
+
handleRangeSelection(selectedCells, prevState.startCell, cell);
|
75
|
+
}
|
76
|
+
else if ((shiftKey || ctrlKey) && newSelection) {
|
77
|
+
handleSingleOrMultipleSelection(selectedCells, cellKey);
|
78
|
+
}
|
79
|
+
else {
|
80
|
+
selectedCells.clear();
|
81
|
+
selectedCells.add(cellKey);
|
82
|
+
}
|
83
|
+
return __assign(__assign({}, prevState), { selectedCells: selectedCells, startCell: newSelection ? cell : prevState.startCell });
|
84
|
+
});
|
85
|
+
};
|
86
|
+
var isCellSelected = function (cell) {
|
87
|
+
return selectionState.selectedCells.has(getCellKey(cell));
|
88
|
+
};
|
89
|
+
var _b = useMouseDragSelection(toggleCellSelection), handleMouseDown = _b.handleMouseDown, handleMouseEnter = _b.handleMouseEnter, handleMouseUp = _b.handleMouseUp;
|
90
|
+
return {
|
91
|
+
selectedCells: selectionState.selectedCells,
|
92
|
+
isCellSelected: isCellSelected,
|
93
|
+
handleMouseDown: handleMouseDown,
|
94
|
+
handleMouseEnter: handleMouseEnter,
|
95
|
+
handleMouseUp: handleMouseUp,
|
96
|
+
};
|
97
|
+
};
|
98
|
+
// New helper functions
|
99
|
+
function handleRangeSelection(selectedCells, startCell, endCell) {
|
100
|
+
var action = selectedCells.has(getCellKey(startCell)) ? "add" : "delete";
|
101
|
+
var _a = [startCell.row, startCell.col], startRow = _a[0], startCol = _a[1];
|
102
|
+
var _b = [endCell.row, endCell.col], endRow = _b[0], endCol = _b[1];
|
103
|
+
var minRow = Math.min(startRow, endRow);
|
104
|
+
var maxRow = Math.max(startRow, endRow);
|
105
|
+
var minCol = Math.min(startCol, endCol);
|
106
|
+
var maxCol = Math.max(startCol, endCol);
|
107
|
+
for (var row = minRow; row <= maxRow; row++) {
|
108
|
+
for (var col = minCol; col <= maxCol; col++) {
|
109
|
+
selectedCells[action](getCellKey({ row: row, col: col }));
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
function handleSingleOrMultipleSelection(selectedCells, cellKey) {
|
114
|
+
if (selectedCells.has(cellKey)) {
|
115
|
+
selectedCells.delete(cellKey);
|
116
|
+
}
|
117
|
+
else {
|
118
|
+
selectedCells.add(cellKey);
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
exports.useGridCellSelection = useGridCellSelection;
|
123
|
+
exports.useMouseDragSelection = useMouseDragSelection;
|
124
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/hooks/useMouseDragSelection.ts","../src/hooks/useCellSelection.ts"],"sourcesContent":["import { useState } from \"react\";\nimport { CellIdentifier } from \"../types\";\n\nexport const useMouseDragSelection = (\n toggleCellSelection: (cell: CellIdentifier, ctrlKey: boolean, shiftKey: boolean, newSelection: boolean) => void\n) => {\n const [isDragging, setIsDragging] = useState(false);\n\n const handleMouseDown = (cell: CellIdentifier, event: React.MouseEvent) => {\n setIsDragging(true);\n toggleCellSelection(cell, event.ctrlKey || event.metaKey, event.shiftKey, true);\n };\n\n const handleMouseEnter = (cell: CellIdentifier, event: React.MouseEvent) => {\n if (isDragging) {\n toggleCellSelection(cell, event.ctrlKey || event.metaKey, event.shiftKey, false);\n }\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n };\n\n return {\n handleMouseDown,\n handleMouseEnter,\n handleMouseUp,\n };\n};\n","import { useState } from \"react\";\nimport { CellIdentifier, SelectionState } from \"../types\";\nimport { useMouseDragSelection } from \"./useMouseDragSelection\";\n\nconst getCellKey = (cell: Omit<CellIdentifier, \"id\">): string => {\n return `${cell.row}-${cell.col}`;\n};\n\nexport const useGridCellSelection = () => {\n const [selectionState, setSelectionState] = useState<SelectionState>({\n selectedCells: new Set(),\n });\n\n const toggleCellSelection = (cell: CellIdentifier, ctrlKey = false, shiftKey = false, newSelection = false) => {\n setSelectionState((prevState) => {\n const selectedCells = new Set(prevState.selectedCells);\n const cellKey = getCellKey(cell);\n\n if (prevState.startCell && !newSelection) {\n handleRangeSelection(selectedCells, prevState.startCell, cell);\n } else if ((shiftKey || ctrlKey) && newSelection) {\n handleSingleOrMultipleSelection(selectedCells, cellKey);\n } else {\n selectedCells.clear();\n selectedCells.add(cellKey);\n }\n\n return {\n ...prevState,\n selectedCells,\n startCell: newSelection ? cell : prevState.startCell,\n };\n });\n };\n\n const isCellSelected = (cell: CellIdentifier) => {\n return selectionState.selectedCells.has(getCellKey(cell));\n };\n\n const { handleMouseDown, handleMouseEnter, handleMouseUp } = useMouseDragSelection(toggleCellSelection);\n\n return {\n selectedCells: selectionState.selectedCells,\n isCellSelected,\n handleMouseDown,\n handleMouseEnter,\n handleMouseUp,\n };\n};\n\n// New helper functions\nfunction handleRangeSelection(selectedCells: Set<string>, startCell: CellIdentifier, endCell: CellIdentifier) {\n const action = selectedCells.has(getCellKey(startCell)) ? \"add\" : \"delete\";\n const [startRow, startCol] = [startCell.row, startCell.col];\n const [endRow, endCol] = [endCell.row, endCell.col];\n\n const minRow = Math.min(startRow, endRow);\n const maxRow = Math.max(startRow, endRow);\n const minCol = Math.min(startCol, endCol);\n const maxCol = Math.max(startCol, endCol);\n\n for (let row = minRow; row <= maxRow; row++) {\n for (let col = minCol; col <= maxCol; col++) {\n selectedCells[action](getCellKey({ row, col }));\n }\n }\n}\n\nfunction handleSingleOrMultipleSelection(selectedCells: Set<string>, cellKey: string) {\n if (selectedCells.has(cellKey)) {\n selectedCells.delete(cellKey);\n } else {\n selectedCells.add(cellKey);\n }\n}\n"],"names":["useState"],"mappings":"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"}
|
package/dist/main.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
import "./index.css";
|
package/package.json
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
{
|
2
|
+
"name": "grid-cell-selection",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "A React hook for grid cell selection",
|
5
|
+
"main": "dist/index.js",
|
6
|
+
"module": "dist/index.esm.js",
|
7
|
+
"types": "dist/index.d.ts",
|
8
|
+
"files": [
|
9
|
+
"dist"
|
10
|
+
],
|
11
|
+
"scripts": {
|
12
|
+
"dev": "vite",
|
13
|
+
"build": "rollup -c && tsc --emitDeclarationOnly",
|
14
|
+
"lint": "eslint .",
|
15
|
+
"preview": "vite preview",
|
16
|
+
"prepublishOnly": "npm run build"
|
17
|
+
},
|
18
|
+
"dependencies": {
|
19
|
+
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
20
|
+
"react-dom": "^18.3.1"
|
21
|
+
},
|
22
|
+
"peerDependencies": {
|
23
|
+
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
24
|
+
},
|
25
|
+
"devDependencies": {
|
26
|
+
"@eslint/js": "^9.11.1",
|
27
|
+
"@types/react": "^18.0.0",
|
28
|
+
"@types/react-dom": "^18.3.0",
|
29
|
+
"@vitejs/plugin-react": "^4.3.2",
|
30
|
+
"eslint": "^9.11.1",
|
31
|
+
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
32
|
+
"eslint-plugin-react-refresh": "^0.4.12",
|
33
|
+
"globals": "^15.9.0",
|
34
|
+
"rollup": "^2.79.1",
|
35
|
+
"rollup-plugin-typescript2": "^0.31.2",
|
36
|
+
"typescript": "^4.9.5",
|
37
|
+
"typescript-eslint": "^8.7.0",
|
38
|
+
"vite": "^5.4.8"
|
39
|
+
},
|
40
|
+
"keywords": [
|
41
|
+
"react",
|
42
|
+
"hook",
|
43
|
+
"grid",
|
44
|
+
"cell",
|
45
|
+
"selection"
|
46
|
+
],
|
47
|
+
"author": "Atticus Thomson",
|
48
|
+
"license": "MIT",
|
49
|
+
"repository": {
|
50
|
+
"type": "git",
|
51
|
+
"url": "https://github.com/attithom/grid-cell-selection.git"
|
52
|
+
}
|
53
|
+
}
|