Skip to content

Commit f9780bd

Browse files
authored
graphiql 5: Use an additional Alt key for focus doc explorer search input instead of Cmd/Ctrl+K because monaco-editor has a built-in shortcut for Cmd/Ctrl+K (#4007)
* upd * upd snapshots lines since graphql description was changed * upd * upd * upd * upd * upd * upd * upd * polish * polish * polish
1 parent 7792dc9 commit f9780bd

File tree

15 files changed

+115
-78
lines changed

15 files changed

+115
-78
lines changed

.changeset/four-carrots-leave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@graphiql/plugin-doc-explorer': patch
3+
---
4+
5+
Use an additional `Alt` key for focus doc explorer search input instead of `Cmd/Ctrl+K` because monaco-editor has a built-in shortcut for `Cmd/Ctrl+K`

packages/graphiql-plugin-doc-explorer/src/components/doc-explorer.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
&:not(:focus-within) [role='combobox'] {
4040
height: 24px;
41-
width: 5ch;
41+
width: 6.5ch;
4242
}
4343

4444
& [role='combobox']:focus {

packages/graphiql-plugin-doc-explorer/src/components/search.tsx

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,6 @@ export const Search: FC = () => {
4545
debouncedGetSearchResults(searchValue);
4646
}, [debouncedGetSearchResults, searchValue]);
4747

48-
useEffect(() => {
49-
function handleKeyDown(event: KeyboardEvent) {
50-
if (event.metaKey && event.key === 'k') {
51-
inputRef.current.focus();
52-
}
53-
}
54-
55-
window.addEventListener('keydown', handleKeyDown);
56-
return () => window.removeEventListener('keydown', handleKeyDown);
57-
}, []);
58-
5948
const navItem = explorerNavStack.at(-1)!;
6049

6150
const onSelect = (def: TypeMatch | FieldMatch | null) => {
@@ -97,7 +86,7 @@ export const Search: FC = () => {
9786
autoComplete="off"
9887
onChange={event => setSearchValue(event.target.value)}
9988
placeholder={formatShortcutForOS(
100-
KEY_MAP.searchInDocs.key.replace('-', ' '),
89+
formatShortcutForOS(KEY_MAP.searchInDocs.key).replaceAll('-', ' '),
10190
)}
10291
ref={inputRef}
10392
value={searchValue}

packages/graphiql-plugin-doc-explorer/src/context.ts renamed to packages/graphiql-plugin-doc-explorer/src/context.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,27 @@ import {
2020
useGraphiQL,
2121
pick,
2222
createBoundedUseStore,
23+
GraphiQLPlugin,
24+
DocsFilledIcon,
25+
DocsIcon,
26+
isMacOs,
2327
} from '@graphiql/react';
2428
import { createStore } from 'zustand';
2529
import { getSchemaReference } from './schema-reference';
30+
import { DocExplorer } from './components';
31+
32+
export const DOC_EXPLORER_PLUGIN: GraphiQLPlugin = {
33+
title: 'Documentation Explorer',
34+
icon: function Icon() {
35+
const visiblePlugin = useGraphiQL(state => state.visiblePlugin);
36+
return visiblePlugin === DOC_EXPLORER_PLUGIN ? (
37+
<DocsFilledIcon />
38+
) : (
39+
<DocsIcon />
40+
);
41+
},
42+
content: DocExplorer,
43+
};
2644

2745
export type DocExplorerFieldDef =
2846
| GraphQLField<unknown, unknown>
@@ -275,6 +293,38 @@ export const DocExplorerStore: FC<{
275293
}
276294
}, [schema, validationErrors]);
277295

296+
useEffect(() => {
297+
function handleKeyDown(event: KeyboardEvent) {
298+
const shouldFocusInput =
299+
// Use an additional `Alt` key instead of `Cmd/Ctrl+K` because monaco-editor has a built-in
300+
// shortcut for `Cmd/Ctrl+K`
301+
event.altKey &&
302+
event[isMacOs ? 'metaKey' : 'ctrlKey'] &&
303+
// Using `event.code` because `event.key` will trigger different character
304+
// in English `˚` and in French `È`
305+
event.code === 'KeyK';
306+
if (!shouldFocusInput) {
307+
return;
308+
}
309+
const button = document.querySelector<HTMLButtonElement>(
310+
'.graphiql-sidebar button[aria-label="Show Documentation Explorer"]',
311+
);
312+
button?.click();
313+
// Execute on next tick when doc explorer is opened and input exists in DOM
314+
requestAnimationFrame(() => {
315+
const el = document.querySelector<HTMLDivElement>(
316+
'.graphiql-doc-explorer-search-input',
317+
);
318+
el?.click();
319+
});
320+
}
321+
322+
window.addEventListener('keydown', handleKeyDown);
323+
return () => {
324+
window.removeEventListener('keydown', handleKeyDown);
325+
};
326+
}, []);
327+
278328
return children as ReactElement;
279329
};
280330

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export * from './components';
2+
3+
export {
4+
DocExplorerStore,
5+
useDocExplorer,
6+
useDocExplorerActions,
7+
DOC_EXPLORER_PLUGIN,
8+
} from './context';
9+
10+
export type {
11+
DocExplorerFieldDef,
12+
DocExplorerNavStack,
13+
DocExplorerNavStackItem,
14+
} from './context';

packages/graphiql-plugin-doc-explorer/src/index.tsx

Lines changed: 0 additions & 34 deletions
This file was deleted.

packages/graphiql-plugin-doc-explorer/vite.config.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default defineConfig({
3636
minify: false,
3737
sourcemap: true,
3838
lib: {
39-
entry: 'src/index.tsx',
39+
entry: 'src/index.ts',
4040
fileName(_format, entryName) {
4141
const filePath = entryName.replace(/\.svg$/, '');
4242
return `${filePath}.js`;

packages/graphiql-react/src/components/response-editor.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,16 @@ export const ResponseEditor: FC<ResponseEditorProps> = ({
8787
$model,
8888
position,
8989
) => {
90-
if ($model.uri !== model.uri) {
90+
const sameModel = $model.uri === model.uri;
91+
if (!sameModel) {
9192
return null; // Ignore for other editors
9293
}
9394
const wordAtPosition = $model.getWordAtPosition(position);
9495
if (!wordAtPosition?.word.startsWith('/')) {
9596
return null;
9697
}
97-
if (!ImagePreview.shouldRender(wordAtPosition.word)) {
98+
const shouldRender = ImagePreview.shouldRender(wordAtPosition.word);
99+
if (!shouldRender) {
98100
return null;
99101
}
100102

@@ -138,8 +140,9 @@ export const ResponseEditor: FC<ResponseEditorProps> = ({
138140
],
139141
};
140142
};
143+
const languageId = model.getLanguageId();
141144
const disposables = [
142-
languages.registerHoverProvider(model.getLanguageId(), { provideHover }),
145+
languages.registerHoverProvider(languageId, { provideHover }),
143146
editor.addAction({ ...KEY_BINDINGS.runQuery, run }),
144147
editor,
145148
model,

packages/graphiql-react/src/constants.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { parse, print } from 'graphql';
44
import { KeyCode, KeyMod, Uri, languages } from './monaco-editor';
55
import { EditorSlice } from './stores';
66

7-
const isMacOs =
7+
export const isMacOs =
88
typeof navigator !== 'undefined' && navigator.userAgent.includes('Mac');
99

1010
export function formatShortcutForOS(key: string, replaced = '⌘') {
@@ -38,7 +38,7 @@ export const KEY_MAP = Object.freeze({
3838
key: 'Ctrl-F',
3939
},
4040
searchInDocs: {
41-
key: 'Ctrl-K',
41+
key: 'Ctrl-Alt-K',
4242
},
4343
});
4444

@@ -75,7 +75,7 @@ export const DEFAULT_QUERY = `# Welcome to GraphiQL
7575
7676
`;
7777

78-
export const KEY_BINDINGS = Object.freeze({
78+
export const KEY_BINDINGS = {
7979
prettify: {
8080
id: 'graphql-prettify',
8181
label: 'Prettify Editors',
@@ -100,7 +100,7 @@ export const KEY_BINDINGS = Object.freeze({
100100
contextMenuGroupId: 'graphql',
101101
keybindings: KEY_MAP.copyQuery.keybindings,
102102
},
103-
});
103+
} as const;
104104

105105
export const QUERY_URI = Uri.file('query.graphql');
106106
export const VARIABLE_URI = Uri.file('variable.json');

packages/graphiql-react/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ export * from './components';
99

1010
export type { EditorProps, SchemaReference, AllSlices } from './types';
1111
export type { GraphiQLPlugin } from './stores/plugin';
12-
export { KEY_MAP, formatShortcutForOS } from './constants';
12+
export { KEY_MAP, formatShortcutForOS, isMacOs } from './constants';

0 commit comments

Comments
 (0)