Skip to content

Commit 7ef3f1e

Browse files
committed
#638 Select multiple cells by dragging
1 parent b2481fd commit 7ef3f1e

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

browser/data-browser/src/components/TableEditor/Cell.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export function Cell({
4545
const ref = useRef<HTMLDivElement>(null);
4646

4747
const {
48+
mouseDown,
4849
selectedRow,
4950
selectedColumn,
5051
multiSelectCornerRow,
@@ -57,15 +58,29 @@ export function Cell({
5758
setCursorMode,
5859
registerEventListener,
5960
disabledKeyboardInteractions,
61+
setMouseDown,
6062
} = useTableEditorContext();
6163

6264
const isActive = rowIndex === selectedRow && columnIndex === selectedColumn;
6365
const isActiveCorner =
6466
rowIndex === multiSelectCornerRow &&
6567
columnIndex === multiSelectCornerColumn;
6668

67-
const handleClick = useCallback(
69+
const handleMouseUp = useCallback(() => {
70+
setMouseDown(false);
71+
}, []);
72+
73+
const handleMouseEnter = useCallback(() => {
74+
if (mouseDown) {
75+
setMultiSelectCorner(rowIndex, columnIndex);
76+
setCursorMode(CursorMode.MultiSelect);
77+
}
78+
}, [mouseDown, rowIndex, columnIndex]);
79+
80+
const handleMouseDown = useCallback(
6881
(e: React.MouseEvent<HTMLDivElement>) => {
82+
setMouseDown(true);
83+
6984
// When Shift is pressed, enter multi-select mode
7085
if (e.shiftKey) {
7186
e.stopPropagation();
@@ -90,6 +105,8 @@ export function Cell({
90105

91106
if (isActive && columnIndex !== 0) {
92107
// Enter edit mode when clicking on a higlighted cell, except when it's the index column.
108+
setMultiSelectCorner(undefined, undefined);
109+
93110
return setCursorMode(CursorMode.Edit);
94111
}
95112

@@ -155,10 +172,12 @@ export function Cell({
155172
disabled={disabled}
156173
role={role ?? 'gridcell'}
157174
className={className}
158-
onClick={handleClick}
159175
allowUserSelect={cursorMode === CursorMode.Edit}
160176
align={align}
161177
tabIndex={isActive ? 0 : -1}
178+
onMouseDown={handleMouseDown}
179+
onMouseUp={handleMouseUp}
180+
onMouseEnter={handleMouseEnter}
162181
>
163182
{children}
164183
</CellWrapper>

browser/data-browser/src/components/TableEditor/TableEditorContext.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ function emptySetState<T>(_: T | ((__: T) => T)): undefined {
2828
}
2929

3030
export interface TableEditorContext {
31+
mouseDown: boolean;
32+
setMouseDown: React.Dispatch<React.SetStateAction<boolean>>;
3133
tableRef: React.MutableRefObject<HTMLDivElement | null>;
3234
disabledKeyboardInteractions: Set<KeyboardInteraction>;
3335
setDisabledKeyboardInteractions: React.Dispatch<
@@ -62,6 +64,8 @@ export interface TableEditorContext {
6264
}
6365

6466
const initial = {
67+
mouseDown: false,
68+
setMouseDown: emptySetState,
6569
tableRef: { current: null },
6670
disabledKeyboardInteractions: new Set<KeyboardInteraction>(),
6771
setDisabledKeyboardInteractions: emptySetState,
@@ -92,6 +96,7 @@ const TableEditorContext = React.createContext<TableEditorContext>(initial);
9296
export function TableEditorContextProvider({
9397
children,
9498
}: React.PropsWithChildren<unknown>): JSX.Element {
99+
const [mouseDown, setMouseDown] = useState(false);
95100
const tableRef = useRef<HTMLDivElement | null>(null);
96101
const listRef = useRef<FixedSizeList>(null);
97102
const [eventManager] = useState(
@@ -159,6 +164,8 @@ export function TableEditorContextProvider({
159164

160165
const context = useMemo(
161166
() => ({
167+
mouseDown,
168+
setMouseDown,
162169
tableRef,
163170
disabledKeyboardInteractions,
164171
setDisabledKeyboardInteractions,
@@ -195,6 +202,7 @@ export function TableEditorContextProvider({
195202
isDragging,
196203
cursorMode,
197204
emitInteractionsFired,
205+
mouseDown,
198206
],
199207
);
200208

0 commit comments

Comments
 (0)