Fixed global hotkey conflict in inputs (#13209)

This PR fixes a focus conflict with global hotkeys, mainly "?" that
opens the shortcut helper dialog.

This fix works but we should maybe think about a more generic approach
in another issue, like disabling global hotkeys when certain types of
components are open (input, dropdown, etc.)

Fixes https://github.com/twentyhq/twenty/issues/13197

---------

Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
This commit is contained in:
Lucas Bordeau
2025-07-15 14:18:06 +02:00
committed by GitHub
parent d916ec0af9
commit df9d2b57f9
4 changed files with 42 additions and 33 deletions

View File

@ -43,41 +43,41 @@ export const useCommandMenuHotKeys = () => {
COMMAND_MENU_COMPONENT_INSTANCE_ID,
);
useGlobalHotkeys(
'ctrl+k,meta+k',
() => {
useGlobalHotkeys({
keys: ['ctrl+k', 'meta+k'],
callback: () => {
closeKeyboardShortcutMenu();
toggleCommandMenu();
},
true,
[closeKeyboardShortcutMenu, toggleCommandMenu],
);
containsModifier: true,
dependencies: [closeKeyboardShortcutMenu, toggleCommandMenu],
});
useGlobalHotkeys(
['/'],
() => {
useGlobalHotkeys({
keys: ['/'],
callback: () => {
openRecordsSearchPage();
},
false,
[openRecordsSearchPage],
{
containsModifier: false,
dependencies: [openRecordsSearchPage],
options: {
ignoreModifiers: true,
},
);
});
useGlobalHotkeys(
['@'],
() => {
useGlobalHotkeys({
keys: ['@'],
callback: () => {
if (isAiEnabled) {
openAskAIPage();
}
},
false,
[openAskAIPage, isAiEnabled],
{
containsModifier: false,
dependencies: [openAskAIPage, isAiEnabled],
options: {
ignoreModifiers: true,
},
);
});
useHotkeysOnFocusedElement({
keys: [Key.Escape],

View File

@ -15,15 +15,15 @@ export const KeyboardShortcutMenu = () => {
);
const { closeCommandMenu } = useCommandMenu();
useGlobalHotkeys(
'shift+?,meta+?',
() => {
useGlobalHotkeys({
keys: ['shift+?', 'meta+?'],
callback: () => {
closeCommandMenu();
toggleKeyboardShortcutMenu();
},
true,
[toggleKeyboardShortcutMenu],
);
containsModifier: false,
dependencies: [toggleKeyboardShortcutMenu],
});
return (
<>{isKeyboardShortcutMenuOpened && <KeyboardShortcutMenuOpenContent />}</>

View File

@ -66,6 +66,9 @@ export const RecordTitleFullNameFieldDisplay = ({
type: FocusComponentType.OPENED_FIELD_INPUT,
instanceId: recordTitleCellId,
},
globalHotkeysConfig: {
enableGlobalHotkeysConflictingWithKeyboard: false,
},
});
openInlineCell();

View File

@ -7,13 +7,19 @@ import { isDefined } from 'twenty-shared/utils';
type UseHotkeysOptionsWithoutBuggyOptions = Omit<Options, 'enabled'>;
export const useGlobalHotkeys = (
keys: Keys,
callback: HotkeyCallback,
containsModifier: boolean,
dependencies?: unknown[],
options?: UseHotkeysOptionsWithoutBuggyOptions,
) => {
export const useGlobalHotkeys = ({
keys,
callback,
containsModifier,
dependencies,
options,
}: {
keys: Keys;
callback: HotkeyCallback;
containsModifier: boolean;
dependencies?: unknown[];
options?: UseHotkeysOptionsWithoutBuggyOptions;
}) => {
const callGlobalHotkeysCallback = useGlobalHotkeysCallback(dependencies);
const enableOnContentEditable = isDefined(options?.enableOnContentEditable)