reconfigure search bar keybind

- also prevents interference with other text boxes on Esc
This commit is contained in:
maxichrome
2022-09-13 19:05:42 -05:00
parent 0d55f3c9e2
commit 40194bec47

View File

@@ -1,5 +1,5 @@
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
import { AppPropsContext, useExplorerStore, useLibraryMutation } from '@sd/client';
import { AppPropsContext, useAppProps, useExplorerStore, useLibraryMutation } from '@sd/client';
import { Dropdown } from '@sd/ui';
import clsx from 'clsx';
import {
@@ -11,7 +11,7 @@ import {
SidebarSimple,
SquaresFour
} from 'phosphor-react';
import React, { DetailedHTMLProps, HTMLAttributes, RefAttributes, useContext } from 'react';
import React, { DetailedHTMLProps, HTMLAttributes, useContext } from 'react';
import { useNavigate } from 'react-router-dom';
import { Shortcut } from '../primitive/Shortcut';
@@ -67,7 +67,7 @@ const SearchBar = React.forwardRef<HTMLInputElement, DefaultProps>((props, ref)
placeholder="Search"
className="peer w-32 h-[30px] focus:w-52 text-sm p-3 rounded-lg outline-none focus:ring-2 placeholder-gray-400 dark:placeholder-gray-450 bg-[#F6F2F6] border border-gray-50 shadow-md dark:bg-gray-600 dark:border-gray-550 focus:ring-gray-100 dark:focus:ring-gray-550 dark:focus:bg-gray-800 transition-all"
/>
<div className="space-x-1 absolute top-[2px] right-1 peer-focus:invisible">
<div className="space-x-1 absolute top-[2px] right-1 peer-focus:invisible pointer-events-none">
<Shortcut
chars={
appProps?.platform === 'macOS' || appProps?.platform === 'browser' ? '⌘L' : 'CTRL+L'
@@ -80,6 +80,8 @@ const SearchBar = React.forwardRef<HTMLInputElement, DefaultProps>((props, ref)
});
export const TopBar: React.FC<TopBarProps> = (props) => {
const appProps = useAppProps();
const { layoutMode, set, locationId, showInspector } = useExplorerStore();
const { mutate: generateThumbsForLocation } = useLibraryMutation(
'jobs.generateThumbsForLocation',
@@ -101,34 +103,65 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
const navigate = useNavigate();
//create function to focus on search box when cmd+k is pressed
const searchRef = React.useRef<HTMLInputElement>(null);
const searchBarRef = React.useRef<HTMLInputElement>(null);
const focusSearchBar = (bar: HTMLInputElement, e?: Event): boolean => {
bar.focus();
e?.preventDefault();
return false;
};
React.useEffect(() => {
const handler = (e: KeyboardEvent) => {
if (e.metaKey && e.key === 'l') {
if (searchRef.current) searchRef.current.focus();
const searchBar = searchBarRef.current;
if (searchBar === null || !searchBar) return;
const handleKeybindAction = (e: KeybindEvent) => {
if (e.detail.action === 'open_search') {
return focusSearchBar(searchBar, e);
}
};
const handleWebKeydown = (e: KeyboardEvent) => {
if (e.target === searchBar && e.key === 'Escape') {
(e.target as HTMLInputElement).blur();
e.preventDefault();
return;
}
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
if (e.key === 'Escape') {
e.target.blur();
e.preventDefault();
return;
}
} else {
if (e.key === '/') {
if (searchRef.current) searchRef.current.focus();
e.preventDefault();
return;
}
// only do this keybind check on browser to allow for native keybind functionality
// this is particularly useful for power-user niche use cases,
// like how macOS lets you redefine keybinds for apps
const isBrowser = appProps?.platform === 'browser';
// use cmd on macOS and ctrl on Windows
const hasModifier = isBrowser && navigator.platform.startsWith('Mac') ? e.metaKey : e.ctrlKey;
if (
// allow slash on all platforms
(e.key === '/' &&
!(document.activeElement instanceof HTMLInputElement) &&
!(document.activeElement instanceof HTMLTextAreaElement)) ||
// only check for cmd-l on browser
(isBrowser && hasModifier && e.key === 'l')
) {
document.dispatchEvent(
new CustomEvent('exec_keybind', { detail: { action: 'open_search' } })
);
e.preventDefault();
return;
}
};
document.addEventListener('keydown', handler);
return () => document.removeEventListener('keydown', handler);
}, []);
document.addEventListener('keydown', handleWebKeydown);
document.addEventListener('exec_keybind', handleKeybindAction);
return () => {
document.removeEventListener('keydown', handleWebKeydown);
document.removeEventListener('exec_keybind', handleKeybindAction);
};
}, [appProps?.platform]);
return (
<>
@@ -172,7 +205,7 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
/>
</Tooltip>
</div>
<SearchBar ref={searchRef} />
<SearchBar ref={searchBarRef} />
<div className="flex mx-8 space-x-2">
<Tooltip label="Major Key Alert">