diff --git a/src/components/settings/KeyboardShortcutSetting.tsx b/src/components/settings/KeyboardShortcutSetting.tsx new file mode 100644 index 0000000..44f5067 --- /dev/null +++ b/src/components/settings/KeyboardShortcutSetting.tsx @@ -0,0 +1,58 @@ +import { Box, Button, FormControl, TextInput } from '@primer/react' +import * as React from 'react' +import { useUpdateEffect } from 'react-use' +import { friendlyFormatShortcut, noop } from 'utils/general' +import { useStateIO } from 'utils/hooks/useStateIO' +import * as keyHelper from 'utils/keyHelper' + +type Props = IO & { + label: React.ReactNode +} + +export function KeyboardShortcutSetting({ label, value, onChange }: Props) { + const $focused = useStateIO(false) + const $shortcut = useStateIO(value) + useUpdateEffect(() => $shortcut.onChange(value), [value]) + + const id = React.useMemo(() => Math.random() + '', []) + + return ( + + {label} + + $focused.onChange(true)} + onBlur={() => $focused.onChange(false)} + placeholder={$focused.value ? 'Press key combination' : 'Click here to set'} + value={friendlyFormatShortcut($shortcut.value)} + onChange={noop} + onKeyDown={e => { + switch (e.key) { + case 'Esc': + case 'Tab': + return + case 'Delete': + case 'Backspace': + // Clear shortcut with backspace + $shortcut.onChange(undefined) + return + default: + e.preventDefault() + e.stopPropagation() + } + $shortcut.onChange(keyHelper.parseEvent(e)) + }} + /> + + + + ) +} diff --git a/src/components/settings/SidebarSettings.tsx b/src/components/settings/SidebarSettings.tsx index 74e5328..3ce711c 100644 --- a/src/components/settings/SidebarSettings.tsx +++ b/src/components/settings/SidebarSettings.tsx @@ -1,10 +1,8 @@ -import { Box, Button, FormControl, TextInput } from '@primer/react' import { SimpleConfigFieldCheckbox } from 'components/settings/SimpleConfigField/Checkbox' import { useConfigs } from 'containers/ConfigsContext' import * as React from 'react' -import { friendlyFormatShortcut, noop } from 'utils/general' -import { useStateIO } from 'utils/hooks/useStateIO' -import * as keyHelper from 'utils/keyHelper' +import { subIO } from 'utils/general' +import { KeyboardShortcutSetting } from './KeyboardShortcutSetting' import { SettingsSection } from './SettingsSection' export function SidebarSettings() { @@ -12,7 +10,10 @@ export function SidebarSettings() { return ( - + ) } - -function ToggleSidebarShortcutSettings() { - const configContext = useConfigs() - const { shortcut } = configContext.value - const id = 'toggle-show-sidebar-shortcut' - - React.useEffect(() => { - useToggleShowSideBarShortcut.onChange(shortcut) - }, [shortcut]) // eslint-disable-line react-hooks/exhaustive-deps - - const useToggleShowSideBarShortcut = useStateIO(shortcut) - const { value: toggleShowSideBarShortcut } = useToggleShowSideBarShortcut - const focused = useStateIO(false) - - return ( - - Keyboard shortcut to toggle visibility - - focused.onChange(true)} - onBlur={() => focused.onChange(false)} - placeholder={focused.value ? 'Press key combination' : 'Click here to set'} - value={friendlyFormatShortcut(toggleShowSideBarShortcut)} - onChange={noop} - onKeyDown={e => { - e.preventDefault() - e.stopPropagation() - // Clear shortcut with backspace - const shortcut = e.key === 'Backspace' ? '' : keyHelper.parseEvent(e) - useToggleShowSideBarShortcut.onChange(shortcut) - }} - /> - {shortcut === toggleShowSideBarShortcut ? ( - - ) : ( - - )} - - - ) -} diff --git a/src/utils/general.ts b/src/utils/general.ts index d309e87..f95a2d0 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -2,6 +2,18 @@ import { ReactElement } from 'react' import * as ReactDOM from 'react-dom' import { is } from './is' +export function subIO(io: IO, field: K): IO { + return { + value: io.value[field], + onChange(value) { + io.onChange({ + ...io.value, + [field]: value, + }) + }, + } +} + export function pick(source: T, keys: string[]): Partial { if (keys && typeof keys === 'object') { return (Array.isArray(keys) ? keys : Object.keys(keys)).reduce((copy, key) => {