Issue#3150 - Esc and click outside is working to close searchbox (#3168)
* Issue#3150 - Esc and clickOutside will close Searchbox * Font size, margin + 'esc' only Font size changed to theme specific, have a handsome margin to the top right of search box for text "Esc to cancel". Passing 'esc' only to escape.
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useRef, useState } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
@ -13,6 +13,7 @@ import { SelectableItem } from '@/ui/layout/selectable-list/components/Selectabl
|
|||||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
|
import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
|
||||||
|
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||||
import { Avatar } from '@/users/components/Avatar';
|
import { Avatar } from '@/users/components/Avatar';
|
||||||
@ -61,6 +62,16 @@ export const StyledInput = styled.input`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const StyledCancelText = styled.span`
|
||||||
|
color: ${({ theme }) => theme.font.color.tertiary};
|
||||||
|
font-size: ${({ theme }) => theme.font.size.sm};
|
||||||
|
margin-right: 12px;
|
||||||
|
margin-top: 6px;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
`;
|
||||||
|
|
||||||
export const StyledList = styled.div`
|
export const StyledList = styled.div`
|
||||||
background: ${({ theme }) => theme.background.secondary};
|
background: ${({ theme }) => theme.background.secondary};
|
||||||
height: 400px;
|
height: 400px;
|
||||||
@ -86,7 +97,8 @@ export const StyledEmpty = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const CommandMenu = () => {
|
export const CommandMenu = () => {
|
||||||
const { toggleCommandMenu, onItemClick } = useCommandMenu();
|
const { toggleCommandMenu, onItemClick, closeCommandMenu } = useCommandMenu();
|
||||||
|
const commandMenuRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const openActivityRightDrawer = useOpenActivityRightDrawer();
|
const openActivityRightDrawer = useOpenActivityRightDrawer();
|
||||||
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
|
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
|
||||||
@ -109,6 +121,15 @@ export const CommandMenu = () => {
|
|||||||
[toggleCommandMenu, setSearch],
|
[toggleCommandMenu, setSearch],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useScopedHotkeys(
|
||||||
|
'esc',
|
||||||
|
() => {
|
||||||
|
closeCommandMenu();
|
||||||
|
},
|
||||||
|
AppHotkeyScope.CommandMenuOpen,
|
||||||
|
[closeCommandMenu],
|
||||||
|
);
|
||||||
|
|
||||||
const { records: people } = useFindManyRecords<Person>({
|
const { records: people } = useFindManyRecords<Person>({
|
||||||
skip: !isCommandMenuOpened,
|
skip: !isCommandMenuOpened,
|
||||||
objectNameSingular: 'person',
|
objectNameSingular: 'person',
|
||||||
@ -208,6 +229,11 @@ export const CommandMenu = () => {
|
|||||||
: true) && cmd.type === CommandType.Create,
|
: true) && cmd.type === CommandType.Create,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useListenClickOutside({
|
||||||
|
refs: [commandMenuRef],
|
||||||
|
callback: closeCommandMenu,
|
||||||
|
});
|
||||||
|
|
||||||
const selectableItemIds = matchingCreateCommand
|
const selectableItemIds = matchingCreateCommand
|
||||||
.map((cmd) => cmd.id)
|
.map((cmd) => cmd.id)
|
||||||
.concat(matchingNavigateCommand.map((cmd) => cmd.id))
|
.concat(matchingNavigateCommand.map((cmd) => cmd.id))
|
||||||
@ -218,12 +244,13 @@ export const CommandMenu = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isCommandMenuOpened && (
|
{isCommandMenuOpened && (
|
||||||
<StyledDialog>
|
<StyledDialog ref={commandMenuRef}>
|
||||||
<StyledInput
|
<StyledInput
|
||||||
value={search}
|
value={search}
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
onChange={handleSearchChange}
|
onChange={handleSearchChange}
|
||||||
/>
|
/>
|
||||||
|
<StyledCancelText>Esc to cancel</StyledCancelText>
|
||||||
<StyledList>
|
<StyledList>
|
||||||
<ScrollWrapper>
|
<ScrollWrapper>
|
||||||
<StyledInnerList>
|
<StyledInnerList>
|
||||||
|
|||||||
@ -15,6 +15,7 @@ const isCustomScopesEqual = (
|
|||||||
) => {
|
) => {
|
||||||
return (
|
return (
|
||||||
customScopesA?.commandMenu === customScopesB?.commandMenu &&
|
customScopesA?.commandMenu === customScopesB?.commandMenu &&
|
||||||
|
customScopesA?.commandMenuOpen === customScopesB?.commandMenuOpen &&
|
||||||
customScopesA?.goto === customScopesB?.goto &&
|
customScopesA?.goto === customScopesB?.goto &&
|
||||||
customScopesA?.keyboardShortcutMenu === customScopesB?.keyboardShortcutMenu
|
customScopesA?.keyboardShortcutMenu === customScopesB?.keyboardShortcutMenu
|
||||||
);
|
);
|
||||||
@ -54,6 +55,7 @@ export const useSetHotkeyScope = () =>
|
|||||||
scope: hotkeyScopeToSet,
|
scope: hotkeyScopeToSet,
|
||||||
customScopes: {
|
customScopes: {
|
||||||
commandMenu: customScopes?.commandMenu ?? true,
|
commandMenu: customScopes?.commandMenu ?? true,
|
||||||
|
commandMenuOpen: customScopes?.commandMenuOpen ?? true,
|
||||||
goto: customScopes?.goto ?? false,
|
goto: customScopes?.goto ?? false,
|
||||||
keyboardShortcutMenu: customScopes?.keyboardShortcutMenu ?? false,
|
keyboardShortcutMenu: customScopes?.keyboardShortcutMenu ?? false,
|
||||||
},
|
},
|
||||||
@ -65,6 +67,10 @@ export const useSetHotkeyScope = () =>
|
|||||||
scopesToSet.push(AppHotkeyScope.CommandMenu);
|
scopesToSet.push(AppHotkeyScope.CommandMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newHotkeyScope.customScopes?.commandMenuOpen) {
|
||||||
|
scopesToSet.push(AppHotkeyScope.CommandMenuOpen);
|
||||||
|
}
|
||||||
|
|
||||||
if (newHotkeyScope?.customScopes?.goto) {
|
if (newHotkeyScope?.customScopes?.goto) {
|
||||||
scopesToSet.push(AppHotkeyScope.Goto);
|
scopesToSet.push(AppHotkeyScope.Goto);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,5 +2,6 @@ export enum AppHotkeyScope {
|
|||||||
App = 'app',
|
App = 'app',
|
||||||
Goto = 'goto',
|
Goto = 'goto',
|
||||||
CommandMenu = 'command-menu',
|
CommandMenu = 'command-menu',
|
||||||
|
CommandMenuOpen = 'command-menu-open',
|
||||||
KeyboardShortcutMenu = 'keyboard-shortcut-menu',
|
KeyboardShortcutMenu = 'keyboard-shortcut-menu',
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
export type CustomHotkeyScopes = {
|
export type CustomHotkeyScopes = {
|
||||||
goto?: boolean;
|
goto?: boolean;
|
||||||
commandMenu?: boolean;
|
commandMenu?: boolean;
|
||||||
|
commandMenuOpen?: boolean;
|
||||||
keyboardShortcutMenu?: boolean;
|
keyboardShortcutMenu?: boolean;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user