Skip to content

Commit

Permalink
Make header menus touch accessible
Browse files Browse the repository at this point in the history
  • Loading branch information
jassmith committed Mar 15, 2022
1 parent e70fafd commit 8dc6d55
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 23 deletions.
49 changes: 33 additions & 16 deletions packages/core/src/data-editor/data-editor.tsx
Expand Up @@ -838,7 +838,11 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
const isSelected = selectedRows.hasIndex(row);

const lastHighlighted = lastSelectedRowRef.current;
if (args.shiftKey && lastHighlighted !== undefined && selectedRows.hasIndex(lastHighlighted)) {
if (
(args.shiftKey || args.isLongTouch === true) &&
lastHighlighted !== undefined &&
selectedRows.hasIndex(lastHighlighted)
) {
const newSlice: Slice = [Math.min(lastHighlighted, row), Math.max(lastHighlighted, row) + 1];

if (isMultiKey || rowSelectionMode === "multi") {
Expand Down Expand Up @@ -869,7 +873,11 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
const startedFromLastSticky =
lastRowSticky && gridSelection !== undefined && gridSelection.cell[1] === rows;

if (args.shiftKey && gridSelection !== undefined && !startedFromLastSticky) {
if (
(args.shiftKey || args.isLongTouch === true) &&
gridSelection !== undefined &&
!startedFromLastSticky
) {
if (isLastStickyRow) {
// If we're making a selection and shift click in to the last sticky row,
// just drop the event. Don't kill the selection.
Expand Down Expand Up @@ -923,7 +931,11 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
focus();
} else {
const lastCol = lastSelectedColRef.current;
if (args.shiftKey && lastCol !== undefined && selectedColumns.hasIndex(lastCol)) {
if (
(args.shiftKey || args.isLongTouch === true) &&
lastCol !== undefined &&
selectedColumns.hasIndex(lastCol)
) {
const newSlice: Slice = [Math.min(lastCol, col), Math.max(lastCol, col) + 1];

if (isMultiKey) {
Expand Down Expand Up @@ -1015,16 +1027,10 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
);

const lastMouseDownCellLocation = React.useRef<[number, number]>();
const touchDownArgs = React.useRef({
visibleRegion,
startTime: 0,
});
const touchDownArgs = React.useRef(visibleRegion);
const onMouseDown = React.useCallback(
(args: GridMouseEventArgs) => {
touchDownArgs.current = {
visibleRegion: visibleRegionRef.current,
startTime: Date.now(),
};
touchDownArgs.current = visibleRegionRef.current;
if (args.button !== 0) {
return;
}
Expand Down Expand Up @@ -1097,15 +1103,25 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr

if (args.isTouch) {
const vr = visibleRegionRef.current;
const touchVr = touchDownArgs.current.visibleRegion;
const touchVr = touchDownArgs.current;
if (vr.x !== touchVr.x || vr.y !== touchVr.y) {
// we scrolled, abort
return;
}
if (touchDownArgs.current.startTime > 0 && Date.now() - touchDownArgs.current.startTime > 500) {
args = {
...args,
shiftKey: true,
// take care of context menus first if long pressed item is already selected
if (args.isLongTouch === true) {
if (args.kind === "cell" && gridSelection?.cell[0] === col && gridSelection?.cell[1] === row) {
onCellContextMenu?.([args.location[0] - rowMarkerOffset, args.location[1]], {
...args,
preventDefault,
});
return;
} else if (args.kind === "header" && selectedColumns.hasIndex(col)) {
onHeaderContextMenu?.(args.location[0] - rowMarkerOffset, { ...args, preventDefault });
return;
} else if (args.kind === "group-header") {
onGroupHeaderContextMenu?.(args.location[0] - rowMarkerOffset, { ...args, preventDefault });
return;
}
}
if (args.kind === "cell") {
Expand Down Expand Up @@ -1159,6 +1175,7 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
onHeaderContextMenu,
reselect,
rowMarkerOffset,
selectedColumns,
]
);

Expand Down
19 changes: 13 additions & 6 deletions packages/core/src/data-grid/data-grid-render.tsx
Expand Up @@ -585,7 +585,8 @@ function drawHeader(
hasSelectedCell: boolean,
hoverAmount: number,
spriteManager: SpriteManager,
drawHeaderCallback: DrawHeaderCallback | undefined
drawHeaderCallback: DrawHeaderCallback | undefined,
touchMode: boolean
) {
const menuBounds = getHeaderMenuBounds(x, y, width, height);
if (drawHeaderCallback !== undefined) {
Expand All @@ -609,6 +610,8 @@ function drawHeader(
const xPad = 8;
const fillStyle = selected ? theme.textHeaderSelected : theme.textHeader;

const shouldDrawMenu = c.hasMenu === true && (isHovered || (touchMode && selected));

let drawX = x + xPad;
if (c.icon !== undefined) {
let variant: SpriteVariant = selected ? "selected" : "normal";
Expand All @@ -632,7 +635,7 @@ function drawHeader(
drawX += 26;
}

if (isHovered && c.hasMenu === true && width > 35) {
if (shouldDrawMenu && c.hasMenu === true && width > 35) {
const fadeWidth = 35;
const fadeStart = width - fadeWidth;
const fadeEnd = width - fadeWidth * 0.7;
Expand All @@ -653,7 +656,7 @@ function drawHeader(
}
ctx.fillText(c.title, drawX, y + height / 2 + 1);

if (isHovered && c.hasMenu === true) {
if (shouldDrawMenu && c.hasMenu === true) {
ctx.beginPath();
const triangleX = menuBounds.x + menuBounds.width / 2 - 5.5;
const triangleY = menuBounds.y + menuBounds.height / 2 - 3;
Expand Down Expand Up @@ -700,7 +703,8 @@ function drawGridHeaders(
verticalBorder: (col: number) => boolean,
getGroupDetails: GroupDetailsCallback,
damage: CellList | undefined,
drawHeaderCallback: DrawHeaderCallback | undefined
drawHeaderCallback: DrawHeaderCallback | undefined,
touchMode: boolean
) {
const totalHeaderHeight = headerHeight + groupHeaderHeight;
if (totalHeaderHeight <= 0) return;
Expand Down Expand Up @@ -781,7 +785,8 @@ function drawGridHeaders(
hasSelectedCell,
hover,
spriteManager,
drawHeaderCallback
drawHeaderCallback,
touchMode
);
ctx.restore();
});
Expand Down Expand Up @@ -1472,6 +1477,7 @@ export function drawGrid(
hoverInfo: HoverInfo | undefined,
spriteManager: SpriteManager,
scrolling: boolean,
touchMode: boolean,
enqueue: (item: Item) => void
) {
if (width === 0 || height === 0) return;
Expand Down Expand Up @@ -1553,7 +1559,8 @@ export function drawGrid(
verticalBorder,
getGroupDetails,
damage,
drawHeaderCallback
drawHeaderCallback,
touchMode
);

drawGridLines(
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/data-grid/data-grid-types.ts
Expand Up @@ -26,6 +26,7 @@ interface BaseGridMouseEventArgs {
readonly ctrlKey: boolean;
readonly metaKey: boolean;
readonly isTouch: boolean;
readonly isLongTouch?: boolean;
readonly isEdge: boolean;
readonly button: number;
}
Expand Down
28 changes: 27 additions & 1 deletion packages/core/src/data-grid/data-grid.tsx
Expand Up @@ -203,6 +203,10 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
const [hoveredOnEdge, setHoveredOnEdge] = React.useState<boolean>();
const overlayRef = React.useRef<HTMLCanvasElement | null>(null);

const [lastWasTouch, setLastWasTouch] = React.useState(false);
const lastWasTouchRef = React.useRef(lastWasTouch);
lastWasTouchRef.current = lastWasTouch;

const spriteManager = React.useMemo(() => new SpriteManager(headerIcons), [headerIcons]);
const totalHeaderHeight = enableGroups ? groupHeaderHeight + headerHeight : headerHeight;

Expand Down Expand Up @@ -535,6 +539,7 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
hoverInfoRef.current,
spriteManager,
scrolling,
lastWasTouch,
enqueueRef.current
);
}, [
Expand Down Expand Up @@ -570,6 +575,7 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
imageLoader,
spriteManager,
scrolling,
lastWasTouch,
]);

canBlit.current = canBlit.current !== undefined;
Expand All @@ -587,6 +593,7 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
verticalBorder,
getCellContent,
selectedRows,
lastWasTouch,
selectedColumns,
selectedCell,
dragAndDropState,
Expand Down Expand Up @@ -714,6 +721,7 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
[columns, getBoundsForItem, hoveredOnEdge, isDragging, isResizing]
);

const downTime = React.useRef(0);
const onMouseDownImpl = React.useCallback(
(ev: MouseEvent | TouchEvent) => {
const canvas = ref.current;
Expand All @@ -737,6 +745,13 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,

const args = getMouseArgsForPosition(canvas, clientX, clientY, ev);

if (args.isTouch) {
downTime.current = Date.now();
}
if (lastWasTouchRef.current !== args.isTouch) {
setLastWasTouch(args.isTouch);
}

if (args.kind === "header" && isOverHeaderMenu(canvas, args.location[0], clientX, clientY) !== undefined) {
return;
} else if (args.kind === "group-header") {
Expand Down Expand Up @@ -775,7 +790,18 @@ const DataGrid: React.ForwardRefRenderFunction<DataGridRef, DataGridProps> = (p,
clientY = ev.changedTouches[0].clientY;
}

const args = getMouseArgsForPosition(canvas, clientX, clientY, ev);
let args = getMouseArgsForPosition(canvas, clientX, clientY, ev);

if (args.isTouch && downTime.current !== 0 && Date.now() - downTime.current > 500) {
args = {
...args,
isLongTouch: true,
};
}

if (lastWasTouchRef.current !== args.isTouch) {
setLastWasTouch(args.isTouch);
}

if (!isOutside && ev.cancelable) {
ev.preventDefault();
Expand Down

0 comments on commit 8dc6d55

Please sign in to comment.