From 8c7bea54970fc633d5efbf2940801131a39a4cc9 Mon Sep 17 00:00:00 2001 From: Matthew Holloway Date: Tue, 29 Nov 2022 18:55:52 +1300 Subject: [PATCH 1/5] Fix casing for case-sensitive filesystems --- packages/showcase/pages/gmail.tsx | 2 +- packages/showcase/pages/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/showcase/pages/gmail.tsx b/packages/showcase/pages/gmail.tsx index e42062c..73f1b46 100644 --- a/packages/showcase/pages/gmail.tsx +++ b/packages/showcase/pages/gmail.tsx @@ -2,7 +2,7 @@ import clsx from "clsx"; import { CursorProps, NodeApi, NodeRendererProps, Tree } from "react-arborist"; import { gmailData, GmailItem } from "../data/gmail"; import * as icons from "react-icons/md"; -import styles from "../styles/gmail.module.css"; +import styles from "../styles/Gmail.module.css"; import { FillFlexParent } from "../components/fill-flex-parent"; import { SiGmail } from "react-icons/si"; import { BsTree } from "react-icons/bs"; diff --git a/packages/showcase/pages/index.tsx b/packages/showcase/pages/index.tsx index 8885a1e..cfaae9e 100644 --- a/packages/showcase/pages/index.tsx +++ b/packages/showcase/pages/index.tsx @@ -2,7 +2,7 @@ import type { NextPage } from "next"; import Image from "next/image"; import Head from "next/head"; import Link from "next/link"; -import styles from "../styles/home.module.css"; +import styles from "../styles/Home.module.css"; const Home: NextPage = () => { return ( From 8ac86f565471dad7328a77df17a09d7471c6bfce Mon Sep 17 00:00:00 2001 From: Matthew Holloway Date: Tue, 6 Dec 2022 09:06:01 +1300 Subject: [PATCH 2/5] Configurable keybindings --- README.md | 3 + .../src/components/default-container.tsx | 200 +++------------- .../react-arborist/src/interfaces/commands.ts | 216 ++++++++++++++++++ .../src/interfaces/keybindings.ts | 35 +++ .../react-arborist/src/interfaces/tree-api.ts | 5 + .../react-arborist/src/types/keybindings.ts | 8 + .../react-arborist/src/types/tree-props.ts | 4 + 7 files changed, 300 insertions(+), 171 deletions(-) create mode 100644 packages/react-arborist/src/interfaces/commands.ts create mode 100644 packages/react-arborist/src/interfaces/keybindings.ts create mode 100644 packages/react-arborist/src/types/keybindings.ts diff --git a/README.md b/README.md index aacdf58..9ac8864 100644 --- a/README.md +++ b/README.md @@ -314,6 +314,9 @@ interface TreeProps { searchTerm?: string; searchMatch?: (node: NodeApi, searchTerm: string) => boolean; + /* Keybindings */ + keybindings?: Keybinding; + /* Extra */ className?: string | undefined; rowClassName?: string | undefined; diff --git a/packages/react-arborist/src/components/default-container.tsx b/packages/react-arborist/src/components/default-container.tsx index 70b8a30..4f11d9b 100644 --- a/packages/react-arborist/src/components/default-container.tsx +++ b/packages/react-arborist/src/components/default-container.tsx @@ -1,12 +1,13 @@ import { FixedSizeList } from "react-window"; import { useDataUpdates, useTreeApi } from "../context"; -import { focusNextElement, focusPrevElement } from "../utils"; import { ListOuterElement } from "./list-outer-element"; import { ListInnerElement } from "./list-inner-element"; import { RowContainer } from "./row-container"; - -let focusSearchTerm = ""; -let timeoutId: any = null; +import { SearchForNode } from "../interfaces/commands"; +import { + parseKeybindings, + filterFalseyToString, +} from "../interfaces/keybindings"; /** * All these keyboard shortcuts seem like they should be configurable. @@ -41,177 +42,34 @@ export function DefaultContainer() { if (tree.isEditing) { return; } - if (e.key === "Backspace") { - if (!tree.props.onDelete) return; - const ids = Array.from(tree.selectedIds); - if (ids.length > 1) { - let nextFocus = tree.mostRecentNode; - while (nextFocus && nextFocus.isSelected) { - nextFocus = nextFocus.nextSibling; - } - if (!nextFocus) nextFocus = tree.lastNode; - tree.focus(nextFocus, { scroll: false }); - tree.delete(Array.from(ids)); - } else { - const node = tree.focusedNode; - if (node) { - const sib = node.nextSibling; - const parent = node.parent; - tree.focus(sib || parent, { scroll: false }); - tree.delete(node); - } - } - return; - } - if (e.key === "Tab" && !e.shiftKey) { - e.preventDefault(); - focusNextElement(e.currentTarget); - return; - } - if (e.key === "Tab" && e.shiftKey) { - e.preventDefault(); - focusPrevElement(e.currentTarget); - return; - } - if (e.key === "ArrowDown") { - e.preventDefault(); - const next = tree.nextNode; - if (e.metaKey) { - tree.select(tree.focusedNode); - tree.activate(tree.focusedNode); - return; - } else if (!e.shiftKey || tree.props.disableMultiSelection) { - tree.focus(next); - return; - } else { - if (!next) return; - const current = tree.focusedNode; - if (!current) { - tree.focus(tree.firstNode); - } else if (current.isSelected) { - tree.selectContiguous(next); - } else { - tree.selectMulti(next); - } - return; - } - } - if (e.key === "ArrowUp") { - e.preventDefault(); - const prev = tree.prevNode; - if (!e.shiftKey || tree.props.disableMultiSelection) { - tree.focus(prev); - return; - } else { - if (!prev) return; - const current = tree.focusedNode; - if (!current) { - tree.focus(tree.lastNode); // ? - } else if (current.isSelected) { - tree.selectContiguous(prev); - } else { - tree.selectMulti(prev); - } - return; - } - } - if (e.key === "ArrowRight") { - const node = tree.focusedNode; - if (!node) return; - if (node.isInternal && node.isOpen) { - tree.focus(tree.nextNode); - } else if (node.isInternal) tree.open(node.id); - return; - } - if (e.key === "ArrowLeft") { - const node = tree.focusedNode; - if (!node || node.isRoot) return; - if (node.isInternal && node.isOpen) tree.close(node.id); - else if (!node.parent?.isRoot) { - tree.focus(node.parent); - } - return; - } - if (e.key === "a" && e.metaKey) { - e.preventDefault(); - tree.selectAll(); - return; - } - if (e.key === "a" && !e.metaKey) { - if (!tree.props.onCreate) return; - tree.createLeaf(); - return; - } - if (e.key === "A" && !e.metaKey) { - if (!tree.props.onCreate) return; - tree.createInternal(); - return; - } - if (e.key === "Home") { - // add shift keys - e.preventDefault(); - tree.focus(tree.firstNode); - return; - } - if (e.key === "End") { - // add shift keys + const keybinding = tree.keybinding; + + const keysToControls = parseKeybindings(keybinding); + + const currentKeys = [ + e.key, + e.shiftKey ? "shift" : false, + e.metaKey ? "meta" : false, + ].filter(filterFalseyToString); + + const matches = keysToControls.filter((keysToControl) => { + const keys = keysToControl[0]; + return ( + keys.length === currentKeys.length && + keys.every((key) => currentKeys.includes(key)) + ); + }); + + if (matches.length > 0) { e.preventDefault(); - tree.focus(tree.lastNode); - return; - } - if (e.key === "Enter") { - if (!tree.props.onRename) return; - setTimeout(() => { - if (tree.focusedNode) tree.edit(tree.focusedNode); + matches.forEach((match) => { + const control = match[1]; + control(tree, e); }); - return; + } else { + SearchForNode(tree, e); } - if (e.key === " ") { - e.preventDefault(); - const node = tree.focusedNode; - if (!node) return; - if (node.isLeaf) { - node.select(); - node.activate(); - } else { - node.toggle(); - } - return; - } - if (e.key === "*") { - const node = tree.focusedNode; - if (!node) return; - tree.openSiblings(node); - return; - } - if (e.key === "PageUp") { - e.preventDefault(); - tree.pageUp(); - return; - } - if (e.key === "PageDown") { - e.preventDefault(); - tree.pageDown(); - } - - // If they type a sequence of characters - // collect them. Reset them after a timeout. - // Use it to search the tree for a node, then focus it. - // Clean this up a bit later - clearTimeout(timeoutId); - focusSearchTerm += e.key; - timeoutId = setTimeout(() => { - focusSearchTerm = ""; - }, 600); - const node = tree.visibleNodes.find((n) => { - // @ts-ignore - const name = n.data.name; - if (typeof name === "string") { - return name.toLowerCase().startsWith(focusSearchTerm); - } else return false; - }); - if (node) tree.focus(node.id); }} > ( + tree: TreeApi, + e?: KeyboardEvent +) => void; + +const Delete: Command = (tree) => { + if (!tree.props.onDelete) return; + const ids = Array.from(tree.selectedIds); + if (ids.length > 1) { + let nextFocus = tree.mostRecentNode; + while (nextFocus && nextFocus.isSelected) { + nextFocus = nextFocus.nextSibling; + } + if (!nextFocus) nextFocus = tree.lastNode; + tree.focus(nextFocus, { scroll: false }); + tree.delete(Array.from(ids)); + } else { + const node = tree.focusedNode; + if (node) { + const sib = node.nextSibling; + const parent = node.parent; + tree.focus(sib || parent, { scroll: false }); + tree.delete(node); + } + } +}; + +const FocusOutsideNext: Command = (_, e) => { + if (!e) throw Error(`Required keyboard event`); + focusNextElement(e.currentTarget); +}; + +const FocusOutsidePrev: Command = (_, e) => { + if (!e) throw Error(`Required keyboard event`); + focusPrevElement(e.currentTarget); +}; + +const SelectAndActivate: Command = (tree) => { + tree.select(tree.focusedNode); + tree.activate(tree.focusedNode); +}; + +const FocusNext: Command = (tree) => { + const next = tree.nextNode; + tree.focus(next); +}; + +const FocusFirst: Command = (tree) => { + tree.focus(tree.firstNode); +}; + +const FocusPrev: Command = (tree) => { + tree.focus(tree.prevNode); +}; + +const Prev: Command = (tree) => { + const prev = tree.prevNode; + if (!prev) return; + if (tree.props.disableMultiSelection) { + tree.focus(prev); + return; + } + const current = tree.focusedNode; + if (!current) { + tree.focus(tree.lastNode); // ? + } else if (current.isSelected) { + tree.selectContiguous(prev); + } else { + tree.selectMulti(prev); + } +}; + +const FocusLast: Command = (tree) => { + tree.focus(tree.lastNode); +}; + +const Next: Command = (tree) => { + const next = tree.nextNode; + if (tree.props.disableMultiSelection) { + tree.focus(next); + return; + } + + const current = tree.focusedNode; + if (!current) { + tree.focus(tree.firstNode); + } else if (current.isSelected) { + tree.selectContiguous(next); + } else { + tree.selectMulti(next); + } +}; + +const Right: Command = (tree) => { + const node = tree.focusedNode; + if (!node) return; + if (node.isInternal && node.isOpen) { + tree.focus(tree.nextNode); + } else if (node.isInternal) { + tree.open(node.id); + } +}; + +const Left: Command = (tree) => { + const node = tree.focusedNode; + if (!node || node.isRoot) return; + if (node.isInternal && node.isOpen) { + tree.close(node.id); + } else if (!node.parent?.isRoot) { + tree.focus(node.parent); + } +}; + +const SelectAll: Command = (tree) => { + tree.selectAll(); +}; + +const CreateLeaf: Command = (tree) => { + if (!tree.props.onCreate) return; + tree.createLeaf(); +}; + +const CreateInternal: Command = (tree) => { + if (!tree.props.onCreate) return; + tree.createInternal(); +}; + +const Rename: Command = (tree) => { + if (!tree.props.onRename) return; + setTimeout(() => { + if (tree.focusedNode) tree.edit(tree.focusedNode); + }); +}; + +const SelectOrToggle: Command = (tree) => { + const node = tree.focusedNode; + if (!node) return; + if (node.isLeaf) { + node.select(); + node.activate(); + } else { + node.toggle(); + } +}; + +const OpenSiblings: Command = (tree) => { + const node = tree.focusedNode; + if (!node) return; + tree.openSiblings(node); +}; + +const PageUp: Command = (tree) => { + tree.pageUp(); +}; + +const PageDown: Command = (tree) => { + tree.pageDown(); +}; + +export const commands = { + Delete, + SelectAndActivate, + FocusOutsideNext, + FocusOutsidePrev, + FocusNext, + FocusPrev, + FocusFirst, + FocusLast, + Next, + Prev, + Right, + Left, + SelectAll, + CreateLeaf, + CreateInternal, + Rename, + SelectOrToggle, + OpenSiblings, + PageUp, + PageDown, +} as const; + +export const SearchForNode = (() => { + // variables for the closure + let focusSearchTerm = ""; + let timeoutId: NodeJS.Timeout | null = null; + + return ( + tree: TreeApi, + e: KeyboardEvent + ) => { + // If they type a sequence of characters + // collect them. Reset them after a timeout. + // Use it to search the tree for a node, then focus it. + // Clean this up a bit later + if (timeoutId) { + clearTimeout(timeoutId); + } + focusSearchTerm += e.key; + timeoutId = setTimeout(() => { + focusSearchTerm = ""; + }, 600); + const node = tree.visibleNodes.find((n) => { + // @ts-ignore + const name = n.data.name; + if (typeof name === "string") { + return name.toLowerCase().startsWith(focusSearchTerm); + } else return false; + }); + if (node) tree.focus(node.id); + }; +})(); diff --git a/packages/react-arborist/src/interfaces/keybindings.ts b/packages/react-arborist/src/interfaces/keybindings.ts new file mode 100644 index 0000000..c5a12cc --- /dev/null +++ b/packages/react-arborist/src/interfaces/keybindings.ts @@ -0,0 +1,35 @@ +import { commands, Command } from "./commands"; + +export type Keybinding = Record; + +export const DEFAULT_KEYBINDING: Keybinding = { + Backspace: "Delete", + Tab: "FocusOutsideNext", + "Tab+shift": "FocusOutsidePrev", + "ArrowDown+meta": "SelectAndActivate", + ArrowDown: "Next", + ArrowUp: "Prev", + ArrowRight: "Right", + ArrowLeft: "Left", + "a+meta": "SelectAll", + a: "CreateLeaf", + A: "CreateInternal", + Home: "FocusFirst", + End: "FocusLast", + Enter: "Rename", + " ": "SelectOrToggle", + "*": "OpenSiblings", + PageUp: "PageUp", + PageDown: "PageDown", +}; + +export const filterFalseyToString = (key: unknown): key is string => !!key; + +type KeysToControl = [string[], Command]; + +export const parseKeybindings = (keybinding: Keybinding): KeysToControl[] => + Object.keys(keybinding).reduce((acc, key) => { + const keys = key.split(/[ +]/g).filter(filterFalseyToString); + acc.push([keys, commands[keybinding[key]]]); + return acc; + }, [] as KeysToControl[]); diff --git a/packages/react-arborist/src/interfaces/tree-api.ts b/packages/react-arborist/src/interfaces/tree-api.ts index 10c3cda..2ad2f90 100644 --- a/packages/react-arborist/src/interfaces/tree-api.ts +++ b/packages/react-arborist/src/interfaces/tree-api.ts @@ -21,6 +21,7 @@ import { Cursor } from "../dnd/compute-drop"; import { Store } from "redux"; import { createList } from "../data/create-list"; import { createIndex } from "../data/create-index"; +import { DEFAULT_KEYBINDING, Keybinding } from "./keybindings"; const { safeRun, identify, identifyNull } = utils; export class TreeApi { @@ -555,6 +556,10 @@ export class TreeApi { return id === this.state.nodes.drag.idWillReceiveDrop; } + get keybinding(): Keybinding { + return this.props.keybindings || DEFAULT_KEYBINDING; + } + /* Tree Event Handlers */ onFocus() { diff --git a/packages/react-arborist/src/types/keybindings.ts b/packages/react-arborist/src/types/keybindings.ts new file mode 100644 index 0000000..2db2e95 --- /dev/null +++ b/packages/react-arborist/src/types/keybindings.ts @@ -0,0 +1,8 @@ +import { TreeApi } from "../interfaces/tree-api"; + +export type BindingFunctions = Pick, "create">; + +export type Keybindings = Record< + string, + keyof BindingFunctions +>; diff --git a/packages/react-arborist/src/types/tree-props.ts b/packages/react-arborist/src/types/tree-props.ts index 1e3e2ce..165cb30 100644 --- a/packages/react-arborist/src/types/tree-props.ts +++ b/packages/react-arborist/src/types/tree-props.ts @@ -5,6 +5,7 @@ import { ElementType, MouseEventHandler } from "react"; import { ListOnScrollProps } from "react-window"; import { NodeApi } from "../interfaces/node-api"; import { OpenMap, OpenSlice } from "../state/open-slice"; +import { Keybinding } from "../interfaces/keybindings"; export interface TreeProps { /* Data Options */ @@ -63,6 +64,9 @@ export interface TreeProps { className?: string | undefined; rowClassName?: string | undefined; + /* Keybindings */ + keybindings?: Keybinding; + dndRootElement?: globalThis.Node | null; onClick?: MouseEventHandler; onContextMenu?: MouseEventHandler; From 2a4179cfc4fb2b3498660e1dfd2964dc560fc27d Mon Sep 17 00:00:00 2001 From: Matthew Holloway Date: Tue, 6 Dec 2022 09:33:17 +1300 Subject: [PATCH 3/5] Keybindings plural to keybinding --- README.md | 4 ++-- .../react-arborist/src/components/default-container.tsx | 6 +++--- packages/react-arborist/src/index.ts | 1 + .../src/interfaces/{keybindings.ts => keybinding.ts} | 2 +- packages/react-arborist/src/interfaces/tree-api.ts | 4 ++-- packages/react-arborist/src/types/tree-props.ts | 6 +++--- 6 files changed, 12 insertions(+), 11 deletions(-) rename packages/react-arborist/src/interfaces/{keybindings.ts => keybinding.ts} (92%) diff --git a/README.md b/README.md index 9ac8864..3e2d7ab 100644 --- a/README.md +++ b/README.md @@ -314,8 +314,8 @@ interface TreeProps { searchTerm?: string; searchMatch?: (node: NodeApi, searchTerm: string) => boolean; - /* Keybindings */ - keybindings?: Keybinding; + /* Keybinding */ + keybinding?: Keybinding; /* Extra */ className?: string | undefined; diff --git a/packages/react-arborist/src/components/default-container.tsx b/packages/react-arborist/src/components/default-container.tsx index 4f11d9b..2399aed 100644 --- a/packages/react-arborist/src/components/default-container.tsx +++ b/packages/react-arborist/src/components/default-container.tsx @@ -5,9 +5,9 @@ import { ListInnerElement } from "./list-inner-element"; import { RowContainer } from "./row-container"; import { SearchForNode } from "../interfaces/commands"; import { - parseKeybindings, + parseKeybinding, filterFalseyToString, -} from "../interfaces/keybindings"; +} from "../interfaces/keybinding"; /** * All these keyboard shortcuts seem like they should be configurable. @@ -45,7 +45,7 @@ export function DefaultContainer() { const keybinding = tree.keybinding; - const keysToControls = parseKeybindings(keybinding); + const keysToControls = parseKeybinding(keybinding); const currentKeys = [ e.key, diff --git a/packages/react-arborist/src/index.ts b/packages/react-arborist/src/index.ts index 854860f..5428819 100644 --- a/packages/react-arborist/src/index.ts +++ b/packages/react-arborist/src/index.ts @@ -7,3 +7,4 @@ export * from "./interfaces/node-api"; export * from "./interfaces/tree-api"; export * from "./data/simple-tree"; export * from "./hooks/use-simple-tree"; +export { DEFAULT_KEYBINDING } from "./interfaces/keybinding"; diff --git a/packages/react-arborist/src/interfaces/keybindings.ts b/packages/react-arborist/src/interfaces/keybinding.ts similarity index 92% rename from packages/react-arborist/src/interfaces/keybindings.ts rename to packages/react-arborist/src/interfaces/keybinding.ts index c5a12cc..52ce9b9 100644 --- a/packages/react-arborist/src/interfaces/keybindings.ts +++ b/packages/react-arborist/src/interfaces/keybinding.ts @@ -27,7 +27,7 @@ export const filterFalseyToString = (key: unknown): key is string => !!key; type KeysToControl = [string[], Command]; -export const parseKeybindings = (keybinding: Keybinding): KeysToControl[] => +export const parseKeybinding = (keybinding: Keybinding): KeysToControl[] => Object.keys(keybinding).reduce((acc, key) => { const keys = key.split(/[ +]/g).filter(filterFalseyToString); acc.push([keys, commands[keybinding[key]]]); diff --git a/packages/react-arborist/src/interfaces/tree-api.ts b/packages/react-arborist/src/interfaces/tree-api.ts index 2ad2f90..808346c 100644 --- a/packages/react-arborist/src/interfaces/tree-api.ts +++ b/packages/react-arborist/src/interfaces/tree-api.ts @@ -21,7 +21,7 @@ import { Cursor } from "../dnd/compute-drop"; import { Store } from "redux"; import { createList } from "../data/create-list"; import { createIndex } from "../data/create-index"; -import { DEFAULT_KEYBINDING, Keybinding } from "./keybindings"; +import { DEFAULT_KEYBINDING, Keybinding } from "./keybinding"; const { safeRun, identify, identifyNull } = utils; export class TreeApi { @@ -557,7 +557,7 @@ export class TreeApi { } get keybinding(): Keybinding { - return this.props.keybindings || DEFAULT_KEYBINDING; + return this.props.keybinding || DEFAULT_KEYBINDING; } /* Tree Event Handlers */ diff --git a/packages/react-arborist/src/types/tree-props.ts b/packages/react-arborist/src/types/tree-props.ts index 165cb30..04d690a 100644 --- a/packages/react-arborist/src/types/tree-props.ts +++ b/packages/react-arborist/src/types/tree-props.ts @@ -5,7 +5,7 @@ import { ElementType, MouseEventHandler } from "react"; import { ListOnScrollProps } from "react-window"; import { NodeApi } from "../interfaces/node-api"; import { OpenMap, OpenSlice } from "../state/open-slice"; -import { Keybinding } from "../interfaces/keybindings"; +import { Keybinding } from "../interfaces/keybinding"; export interface TreeProps { /* Data Options */ @@ -64,8 +64,8 @@ export interface TreeProps { className?: string | undefined; rowClassName?: string | undefined; - /* Keybindings */ - keybindings?: Keybinding; + /* Keybinding */ + keybinding?: Keybinding; dndRootElement?: globalThis.Node | null; onClick?: MouseEventHandler; From 9f9b0793378f75332f27fd2ad513fcc306e12480 Mon Sep 17 00:00:00 2001 From: Matthew Holloway Date: Tue, 6 Dec 2022 10:27:54 +1300 Subject: [PATCH 4/5] Case-insensitive keybinding keys --- packages/react-arborist/src/components/default-container.tsx | 2 +- packages/react-arborist/src/interfaces/keybinding.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-arborist/src/components/default-container.tsx b/packages/react-arborist/src/components/default-container.tsx index 2399aed..7701909 100644 --- a/packages/react-arborist/src/components/default-container.tsx +++ b/packages/react-arborist/src/components/default-container.tsx @@ -48,7 +48,7 @@ export function DefaultContainer() { const keysToControls = parseKeybinding(keybinding); const currentKeys = [ - e.key, + e.key.toLowerCase(), e.shiftKey ? "shift" : false, e.metaKey ? "meta" : false, ].filter(filterFalseyToString); diff --git a/packages/react-arborist/src/interfaces/keybinding.ts b/packages/react-arborist/src/interfaces/keybinding.ts index 52ce9b9..c4231db 100644 --- a/packages/react-arborist/src/interfaces/keybinding.ts +++ b/packages/react-arborist/src/interfaces/keybinding.ts @@ -29,7 +29,7 @@ type KeysToControl = [string[], Command]; export const parseKeybinding = (keybinding: Keybinding): KeysToControl[] => Object.keys(keybinding).reduce((acc, key) => { - const keys = key.split(/[ +]/g).filter(filterFalseyToString); + const keys = key.toLowerCase().split(/[ +]/g).filter(filterFalseyToString); acc.push([keys, commands[keybinding[key]]]); return acc; }, [] as KeysToControl[]); From ad2e6666cd30e68fd67b08ae73a1190918466dab Mon Sep 17 00:00:00 2001 From: Matthew Holloway Date: Tue, 6 Dec 2022 13:38:21 +1300 Subject: [PATCH 5/5] Removing unnecessary file --- packages/react-arborist/src/types/keybindings.ts | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 packages/react-arborist/src/types/keybindings.ts diff --git a/packages/react-arborist/src/types/keybindings.ts b/packages/react-arborist/src/types/keybindings.ts deleted file mode 100644 index 2db2e95..0000000 --- a/packages/react-arborist/src/types/keybindings.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { TreeApi } from "../interfaces/tree-api"; - -export type BindingFunctions = Pick, "create">; - -export type Keybindings = Record< - string, - keyof BindingFunctions ->;