Skip to content

Commit

Permalink
Make arrow keys work in tables, escape cancel renaming
Browse files Browse the repository at this point in the history
Issue #46
  • Loading branch information
qu1ck committed Nov 19, 2023
1 parent abac0c5 commit aa7cc40
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 20 deletions.
85 changes: 66 additions & 19 deletions src/components/tables/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,23 @@ function useTable<TData>(
return [table, columnVisibility, setColumnVisibility, columnOrder, setColumnOrder, columnSizing, sorting];
}

interface HIDEvent {
modKey: boolean,
shiftKey: boolean,
isRmb: boolean,
}

function useSelectHandler<TData>(
table: Table<TData>,
selectedReducer: TableSelectReducer,
getRowId: (row: TData) => string,
setCurrent?: (id: string) => void,
): [number, (event: React.MouseEvent<Element>, index: number, lastIndex: number) => void] {
): [number, (event: HIDEvent, index: number, lastIndex: number) => void] {
const [lastIndex, setLastIndex] = useState(-1);

const onRowClick = useCallback((event: React.MouseEvent<Element>, index: number, lastIndex: number) => {
const onRowClick = useCallback((event: HIDEvent, index: number, lastIndex: number) => {
const rows = table.getRowModel().rows;
event.preventDefault();
const modKey = eventHasModKey(event);
if (index < 0 || index >= rows.length) return;

function genIds() {
const minIndex = Math.min(index, lastIndex);
Expand All @@ -148,15 +153,15 @@ function useSelectHandler<TData>(
return ids;
}

if (event.shiftKey && modKey && lastIndex !== -1) {
if (event.shiftKey && event.modKey && lastIndex !== -1) {
const ids = genIds();
selectedReducer({ verb: "add", ids });
} else if (event.shiftKey && lastIndex !== -1) {
const ids = genIds();
selectedReducer({ verb: "set", ids });
} else if (modKey) {
} else if (event.modKey) {
selectedReducer({ verb: "toggle", ids: [getRowId(rows[index].original)] });
} else if (event.button !== 2 || !rows[index].getIsSelected()) {
} else if (!event.isRmb || !rows[index].getIsSelected()) {
selectedReducer({ verb: "set", ids: [getRowId(rows[index].original)] });
}

Expand Down Expand Up @@ -258,7 +263,7 @@ function TableRow<TData>(props: {
index: number,
start: number,
lastIndex: number,
onRowClick: (e: React.MouseEvent<Element>, i: number, li: number) => void,
onRowClick: (e: HIDEvent, i: number, li: number) => void,
onRowDoubleClick?: (row: TData) => void,
height: number,
columnSizing: ColumnSizingState,
Expand All @@ -272,17 +277,55 @@ function TableRow<TData>(props: {
}
}, [propsDblClick, row.original]);

const { onRowClick, index, lastIndex } = props;

const onMouseEvent = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
onRowClick({
modKey: eventHasModKey(e),
shiftKey: e.shiftKey,
isRmb: e.button === 2,
}, index, lastIndex);
}, [index, lastIndex, onRowClick]);

const ref = useRef<HTMLDivElement>(null);

const onKeyDown = useCallback((e: React.KeyboardEvent<HTMLDivElement>) => {
let newIndex = index;
if (e.key === "ArrowDown") {
newIndex += 1;
} else if (e.key === "ArrowUp") {
newIndex -= 1;
} else if (e.key !== "ContextMenu") {
return;
}
e.preventDefault();
if (ref.current != null) {
if (e.key === "ArrowDown" && ref.current.nextElementSibling != null) {
const element = ref.current.nextElementSibling as HTMLElement;
element.scrollIntoView({ behavior: "instant", block: "nearest" });
element.focus();
}
if (e.key === "ArrowUp" && ref.current.previousElementSibling != null) {
const element = ref.current.previousElementSibling as HTMLElement;
element.scrollIntoView({ behavior: "instant", block: "nearest" });
element.focus();
}
}
onRowClick({
modKey: eventHasModKey(e),
shiftKey: e.shiftKey,
isRmb: e.key === "ContextMenu",
}, newIndex, lastIndex);
}, [index, lastIndex, onRowClick]);

return (
<div
<div ref={ref}
className={`tr${props.selected ? " selected" : ""}`}
style={{ height: `${props.height}px`, transform: `translateY(${props.start}px)` }}
onClick={(e) => {
props.onRowClick(e, props.index, props.lastIndex);
}}
onContextMenu={(e) => {
props.onRowClick(e, props.index, props.lastIndex);
}}
onClick={onMouseEvent}
onContextMenu={onMouseEvent}
onDoubleClick={onRowDoubleClick}
onKeyDown={onKeyDown}
tabIndex={-1}
>
<MemoizedInnerRow {...props} />
Expand Down Expand Up @@ -530,7 +573,9 @@ export function EditableNameField(props: EditableNameFieldProps) {
setNewName(props.currentName);
}, [props.currentName]);

const onEnter = useCallback((event: React.KeyboardEvent<HTMLInputElement>) => {
const ref = useRef<HTMLDivElement>(null);

const onTextKeyDown = useCallback((event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === "Enter") {
props.onUpdate?.(
newName,
Expand All @@ -539,6 +584,10 @@ export function EditableNameField(props: EditableNameFieldProps) {
},
() => { setRenaming(false); });
}
if (event.key === "Escape") {
setRenaming(false);
ref.current?.focus();
}
}, [newName, props]);

useEffect(() => {
Expand All @@ -548,8 +597,6 @@ export function EditableNameField(props: EditableNameFieldProps) {
}
}, [isRenaming]);

const ref = useRef<HTMLDivElement>(null);

useEffect(() => {
if (ref.current != null) {
const row = ref.current.parentNode?.parentNode as HTMLDivElement;
Expand Down Expand Up @@ -580,7 +627,7 @@ export function EditableNameField(props: EditableNameFieldProps) {
}}
onChange={(e) => { setNewName(e.target.value); }}
onBlur={() => { setRenaming(false); }}
onKeyDown={onEnter}
onKeyDown={onTextKeyDown}
onClick={(e) => { e.stopPropagation(); }} />
: <Box pl="xs" sx={{ flexGrow: 1, textOverflow: "ellipsis", overflow: "hidden" }}>
{props.currentName}
Expand Down
2 changes: 1 addition & 1 deletion src/trutil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export function pathMapToServer(path: string, config: ServerConfig) {
return mappedPath;
}

export function eventHasModKey(event: React.MouseEvent<Element>) {
export function eventHasModKey(event: React.MouseEvent<Element> | React.KeyboardEvent<Element>) {
return (navigator.platform.startsWith("Mac") && event.metaKey) ||
(!navigator.platform.startsWith("Mac") && event.ctrlKey);
}
Expand Down

0 comments on commit aa7cc40

Please sign in to comment.