Skip to content

Commit

Permalink
Merge pull request #59 from reg-viz/fix/shortcuts
Browse files Browse the repository at this point in the history
fix: keyboard shortcuts bug
  • Loading branch information
wadackel committed Apr 28, 2024
2 parents c6d2838 + dc719fc commit b01dfeb
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 5 deletions.
9 changes: 6 additions & 3 deletions src/components/Sidebar/internal/SidebarInner/SidebarInner.tsx
@@ -1,5 +1,6 @@
import React, { createRef, useCallback } from 'react';
import React, { useCallback, useRef } from 'react';
import { useKey } from '../../../../hooks/useKey';
import { useMergeRefs } from '../../../../hooks/useMergeRefs';
import { useEntities, useEntityFilter } from '../../../../states/entity';
import {
useSidebarEntities,
Expand Down Expand Up @@ -32,7 +33,7 @@ export const SidebarInner = ({ scrollerRef, inputRef, listRef }: Props) => {
const { toggle } = useSidebarMutators();
const sidebarEntity = useSidebarEntities();
const entity = useEntities();
const innerRef = scrollerRef || createRef();
const innerRef = useRef<HTMLDivElement>(null);

const handleChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -53,9 +54,11 @@ export const SidebarInner = ({ scrollerRef, inputRef, listRef }: Props) => {
tryNextFocus(innerRef.current);
});

const ref = useMergeRefs(innerRef, scrollerRef);

return (
<>
<div ref={innerRef} className={styles.inner} id="sidebar">
<div ref={ref} className={styles.inner} id="sidebar">
<SearchBox
inputRef={inputRef}
placeholder="Filter by file name"
Expand Down
21 changes: 19 additions & 2 deletions src/hooks/useKey.ts
@@ -1,10 +1,15 @@
import { useCallback, useEffect, useRef } from 'react';
import { tinykeys } from 'tinykeys';

const ignore = new Set(['input', 'select', 'textarea']);

export type UseKeyCallback = (e: KeyboardEvent) => void;

export const useKey = (
target: React.RefObject<HTMLElement> | null,
target:
| React.RefObject<HTMLElement>
| React.MutableRefObject<HTMLElement>
| null,
keys: string[],
callback: UseKeyCallback,
) => {
Expand All @@ -20,7 +25,19 @@ export const useKey = (
return tinykeys(
target?.current ?? window,
Object.fromEntries(
keys.map((key) => [key, (e) => callbackRef.current(e)]),
keys.map((key) => [
key,
(e) => {
const el = e.target;
if (
el instanceof HTMLElement &&
ignore.has(el.tagName.toLowerCase())
) {
return;
}
callbackRef.current(e);
},
]),
),
);
}, [target, keys]);
Expand Down
37 changes: 37 additions & 0 deletions src/hooks/useMergeRefs.ts
@@ -0,0 +1,37 @@
import { useMemo } from 'react';

type ReactRef<T> = React.Ref<T> | React.MutableRefObject<T>;

const assignRef = <T = any>(ref: ReactRef<T> | undefined, value: T) => {
if (ref == null) {
return;
}

if (typeof ref === 'function') {
ref(value);
return;
}

try {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
ref.current = value;
} catch (error) {
throw new Error(`Cannot assign value '${value}' to ref '${ref}'`);
}
};

export const useMergeRefs = <T>(...refs: (ReactRef<T> | undefined)[]) => {
return useMemo(() => {
if (refs.every((ref) => ref == null)) {
return null;
}
return (node: T) => {
refs.forEach((ref) => {
if (ref) {
assignRef(ref, node);
}
});
};
}, refs); // eslint-disable-line react-hooks/exhaustive-deps
};

0 comments on commit b01dfeb

Please sign in to comment.