Skip to content

Commit 04614ae

Browse files
authored
getMouseArgsForPosition ref API (#961)
* getMouseArgsForPosition * fix types * fix undefined * update testing lib * document and add story for getMouseArgsForPosition
1 parent c194e02 commit 04614ae

File tree

4 files changed

+114
-12
lines changed

4 files changed

+114
-12
lines changed

packages/core/API.md

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,16 @@ Details of each property can be found by clicking on it.
4545

4646
## Ref Methods
4747

48-
| Name | Description |
49-
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
50-
| [appendRow](#appendrow) | Append a row to the data grid. |
51-
| [emit](#emit) | Used to emit commands normally emitted by keyboard shortcuts. |
52-
| [focus](#focus) | Focuses the data grid. |
53-
| [getBounds](#getbounds) | Gets the current screen-space bounds of a desired cell. |
54-
| [remeasureColumns](#remeasureColumns) | Causes the columns in the selection to have their natural sizes recomputed and re-emitted as a resize event. |
55-
| [scrollTo](#scrollto) | Tells the data-grid to scroll to a particular location. |
56-
| [updateCells](#updatecells) | Invalidates the rendering of a list of passed cells. |
48+
| Name | Description |
49+
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
50+
| [appendRow](#appendrow) | Append a row to the data grid. |
51+
| [emit](#emit) | Used to emit commands normally emitted by keyboard shortcuts. |
52+
| [focus](#focus) | Focuses the data grid. |
53+
| [getBounds](#getbounds) | Gets the current screen-space bounds of a desired cell. |
54+
| [remeasureColumns](#remeasurecolumns) | Causes the columns in the selection to have their natural sizes recomputed and re-emitted as a resize event. |
55+
| [scrollTo](#scrollto) | Tells the data-grid to scroll to a particular location. |
56+
| [updateCells](#updatecells) | Invalidates the rendering of a list of passed cells. |
57+
| [getMouseArgsForPosition](#getmouseargsforposition) | Gets the mouse args from pointer event position. |
5758

5859
## Required Props
5960

@@ -460,6 +461,20 @@ Emits the event into the data grid as if the user had pressed the keyboard short
460461

461462
---
462463

464+
## getMouseArgsForPosition
465+
466+
```ts
467+
getMouseArgsForPosition: (
468+
posX: number,
469+
posY: number,
470+
ev?: MouseEvent | TouchEvent
471+
) => GridMouseEventArgs | undefined;
472+
```
473+
474+
Returns grid coordinates and context for a pointer event position. Useful for handling interactions outside of built-in callbacks.
475+
476+
---
477+
463478
## columns
464479

465480
```ts

packages/core/src/data-editor/data-editor.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,10 @@ export interface DataEditorRef {
722722
* Causes the columns in the selection to have their natural size recomputed and re-emitted as a resize event.
723723
*/
724724
remeasureColumns: (cols: CompactSelection) => void;
725+
/**
726+
* Gets the mouse args from pointer event position.
727+
*/
728+
getMouseArgsForPosition: (posX: number, posY: number, ev?: MouseEvent | TouchEvent) => GridMouseEventArgs | undefined
725729
}
726730

727731
const loadingCell: GridCell = {
@@ -1334,7 +1338,7 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
13341338
let result = getCellContent([outerCol, row]);
13351339
if (rowMarkerOffset !== 0 && result.span !== undefined) {
13361340
result = {
1337-
...result, // FIXME: Mutate
1341+
...result,
13381342
span: [result.span[0] + rowMarkerOffset, result.span[1] + rowMarkerOffset],
13391343
};
13401344
}
@@ -1364,7 +1368,6 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
13641368
let result = getGroupDetails?.(group) ?? { name: group };
13651369
if (onGroupHeaderRenamed !== undefined && group !== "") {
13661370
result = {
1367-
// FIXME: Mutate
13681371
icon: result.icon,
13691372
name: result.name,
13701373
overrideTheme: result.overrideTheme,
@@ -2415,7 +2418,7 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
24152418
const onMouseMoveImpl = React.useCallback(
24162419
(args: GridMouseEventArgs) => {
24172420
const a: GridMouseEventArgs = {
2418-
...args, // FIXME: Mutate
2421+
...args,
24192422
location: [args.location[0] - rowMarkerOffset, args.location[1]] as any,
24202423
};
24212424
onMouseMove?.(a);
@@ -3922,6 +3925,21 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
39223925
void normalSizeColumn(col + rowMarkerOffset);
39233926
}
39243927
},
3928+
getMouseArgsForPosition: (posX: number, posY: number, ev?: MouseEvent | TouchEvent): GridMouseEventArgs | undefined => {
3929+
if (gridRef?.current === null) {
3930+
return undefined;
3931+
}
3932+
3933+
const args = gridRef.current.getMouseArgsForPosition(posX, posY, ev);
3934+
if (args === undefined) {
3935+
return undefined;
3936+
}
3937+
3938+
return {
3939+
...args,
3940+
location: [args.location[0] - rowMarkerOffset, args.location[1]] as any,
3941+
};
3942+
}
39253943
}),
39263944
[appendRow, normalSizeColumn, scrollRef, onCopy, onKeyDown, onPasteInternal, rowMarkerOffset, scrollTo]
39273945
);
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React from "react";
2+
import type { DataEditorRef } from "../../data-editor/data-editor.js";
3+
import { DataEditorAll as DataEditor } from "../../data-editor-all.js";
4+
import {
5+
BeautifulWrapper,
6+
Description,
7+
PropName,
8+
useMockDataGenerator,
9+
defaultProps,
10+
} from "../../data-editor/stories/utils.js";
11+
import { SimpleThemeWrapper } from "../../stories/story-utils.js";
12+
13+
export default {
14+
title: "Glide-Data-Grid/DataEditor Demos",
15+
decorators: [
16+
(Story: React.ComponentType) => (
17+
<SimpleThemeWrapper>
18+
<Story />
19+
</SimpleThemeWrapper>
20+
),
21+
],
22+
};
23+
24+
export const GetMouseArgsForPosition: React.VFC = () => {
25+
const { cols, getCellContent } = useMockDataGenerator(6);
26+
const ref = React.useRef<DataEditorRef>(null);
27+
const [info, setInfo] = React.useState<string>("Move the mouse over the grid");
28+
29+
const onMouseMove = React.useCallback((ev: React.MouseEvent<HTMLDivElement>) => {
30+
const args = ref.current?.getMouseArgsForPosition(ev.clientX, ev.clientY, ev);
31+
if (args === undefined) {
32+
setInfo("Outside grid");
33+
} else if (args.kind === "cell") {
34+
setInfo(`Cell ${args.location[0]}, ${args.location[1]}`);
35+
} else {
36+
setInfo(args.kind);
37+
}
38+
}, []);
39+
40+
return (
41+
<BeautifulWrapper
42+
title="getMouseArgsForPosition"
43+
description={
44+
<Description>
45+
Use <PropName>getMouseArgsForPosition</PropName> to translate
46+
pointer coordinates into grid locations.
47+
</Description>
48+
}>
49+
<div onMouseMove={onMouseMove}>
50+
<DataEditor
51+
{...defaultProps}
52+
ref={ref}
53+
columns={cols}
54+
getCellContent={getCellContent}
55+
rows={1000}
56+
/>
57+
</div>
58+
<div style={{ marginTop: 8 }}>{info}</div>
59+
</BeautifulWrapper>
60+
);
61+
};

packages/core/src/internal/data-grid/data-grid.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ export interface DataGridRef {
320320
focus: () => void;
321321
getBounds: (col?: number, row?: number) => Rectangle | undefined;
322322
damage: (cells: DamageUpdateList) => void;
323+
getMouseArgsForPosition: (posX: number, posY: number, ev?: MouseEvent | TouchEvent) => GridMouseEventArgs | undefined;
323324
}
324325

325326
const getRowData = (cell: InnerGridCell, getCellRenderer?: GetCellRendererCallback) => {
@@ -1715,6 +1716,13 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
17151716
return getBoundsForItem(canvasRef.current, col ?? 0, row ?? -1);
17161717
},
17171718
damage,
1719+
getMouseArgsForPosition: (posX: number, posY: number, ev?: MouseEvent | TouchEvent) => {
1720+
if (canvasRef === undefined || canvasRef.current === null) {
1721+
return undefined;
1722+
}
1723+
1724+
return getMouseArgsForPosition(canvasRef.current, posX, posY, ev);
1725+
}
17181726
}),
17191727
[canvasRef, damage, getBoundsForItem]
17201728
);

0 commit comments

Comments
 (0)