Skip to content

Commit

Permalink
move state for doc explorer visibility to explorer context in `@graph…
Browse files Browse the repository at this point in the history
…iql/react` (#2436)

* move visibility state of doc explorer to explorer context in `@graphiql/react`

* inline logic for clicking references to get to the docs

* inline onClick handlers for info tooltips and remove `onHintInformationRender` props
  • Loading branch information
thomasheyenbrock committed May 27, 2022
1 parent 89f0244 commit 3e5295f
Show file tree
Hide file tree
Showing 11 changed files with 207 additions and 219 deletions.
6 changes: 6 additions & 0 deletions .changeset/tough-jobs-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'graphiql': patch
'@graphiql/react': patch
---

Inline logic for clicking a reference to open the docs and remove the `onClickReference` and `onHintInformationRender` props of the editor components and hooks
6 changes: 6 additions & 0 deletions .changeset/warm-kings-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'graphiql': patch
'@graphiql/react': patch
---

Move visibility state for doc explorer from `graphiql` to the explorer context in `@graphiql/react`
44 changes: 33 additions & 11 deletions packages/graphiql-react/src/editor/completion.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import type { Editor, EditorChange } from 'codemirror';

import escapeHTML from 'escape-html';
import {
GraphQLNonNull,
GraphQLList,
GraphQLNonNull,
GraphQLSchema,
GraphQLType,
GraphQLField,
} from 'graphql';
import escapeHTML from 'escape-html';
import { importCodeMirror } from './common';

import { ExplorerContextType } from '../explorer';
import { markdown } from '../markdown';
import { importCodeMirror } from './common';

/**
* Render a custom UI for CodeMirror's hint which includes additional info
Expand All @@ -17,7 +18,8 @@ import { markdown } from '../markdown';
export function onHasCompletion(
_cm: Editor,
data: EditorChange | undefined,
onHintInformationRender: (el: HTMLDivElement) => void,
schema: GraphQLSchema | null | undefined,
explorer: ExplorerContextType | null,
) {
importCodeMirror([], { useCommonAddons: false }).then(CodeMirror => {
let information: HTMLDivElement | null;
Expand All @@ -36,6 +38,7 @@ export function onHasCompletion(
// highlighted typeahead option.
information = document.createElement('div');
information.className = 'CodeMirror-hint-information';
information.addEventListener('click', onClickHintInformation);
hintsUl.appendChild(information);

// This "deprecation" node will contain info about deprecated usage.
Expand All @@ -51,6 +54,12 @@ export function onHasCompletion(
(onRemoveFn = (event: Event) => {
if (event.target === hintsUl) {
hintsUl.removeEventListener('DOMNodeRemoved', onRemoveFn);
if (information) {
information.removeEventListener(
'click',
onClickHintInformation,
);
}
information = null;
deprecation = null;
onRemoveFn = null;
Expand Down Expand Up @@ -84,14 +93,27 @@ export function onHasCompletion(
} else if (deprecation) {
deprecation.style.display = 'none';
}

// Additional rendering?
if (onHintInformationRender) {
onHintInformationRender(information);
}
},
);
});

function onClickHintInformation(event: Event) {
if (
!schema ||
!explorer ||
!(event.currentTarget instanceof HTMLElement) ||
event.currentTarget.className !== 'typeName'
) {
return;
}

const typeName = event.currentTarget.innerHTML;
const type = schema.getType(typeName);
if (type) {
explorer.show();
explorer.push({ name: type.name, def: type });
}
}
}

function renderType(type: GraphQLType): string {
Expand Down
5 changes: 1 addition & 4 deletions packages/graphiql-react/src/editor/header-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { StorageContext } from '../storage';
import { commonKeys, importCodeMirror } from './common';
import { EditorContext } from './context';
import {
CompletionCallback,
EditCallback,
EmptyCallback,
useChangeHandler,
Expand All @@ -17,7 +16,6 @@ import {
export type UseHeaderEditorArgs = {
editorTheme?: string;
onEdit?: EditCallback;
onHintInformationRender?: CompletionCallback;
onPrettifyQuery?: EmptyCallback;
onMergeQuery?: EmptyCallback;
onRunQuery?: EmptyCallback;
Expand All @@ -29,7 +27,6 @@ export type UseHeaderEditorArgs = {
export function useHeaderEditor({
editorTheme = 'graphiql',
onEdit,
onHintInformationRender,
onMergeQuery,
onPrettifyQuery,
onRunQuery,
Expand Down Expand Up @@ -127,7 +124,7 @@ export function useHeaderEditor({
shouldPersistHeaders ? STORAGE_KEY : null,
);

useCompletion(headerEditor, onHintInformationRender);
useCompletion(headerEditor);

useKeyMap(headerEditor, ['Cmd-Enter', 'Ctrl-Enter'], onRunQuery);
useKeyMap(headerEditor, ['Shift-Ctrl-P'], onPrettifyQuery);
Expand Down
45 changes: 23 additions & 22 deletions packages/graphiql-react/src/editor/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { EditorChange } from 'codemirror';
import { RefObject, useContext, useEffect, useRef } from 'react';
import { ExplorerContext } from '../explorer';
import { useSchemaWithError } from '../schema';

import { StorageContext } from '../storage';
import debounce from '../utility/debounce';
Expand Down Expand Up @@ -48,33 +50,32 @@ export function useChangeHandler(
}, [callback, editor, storage, storageKey]);
}

export type CompletionCallback = (value: HTMLDivElement) => void;

export function useCompletion(
editor: CodeMirrorEditor | null,
callback: CompletionCallback | undefined,
) {
export function useCompletion(editor: CodeMirrorEditor | null) {
const { schema } = useSchemaWithError('hook', 'useCompletion');
const explorer = useContext(ExplorerContext);
useEffect(() => {
if (editor && callback) {
const handleCompletion = (
instance: CodeMirrorEditor,
changeObj?: EditorChange,
) => {
onHasCompletion(instance, changeObj, callback);
};
editor.on(
if (!editor) {
return;
}

const handleCompletion = (
instance: CodeMirrorEditor,
changeObj?: EditorChange,
) => {
onHasCompletion(instance, changeObj, schema, explorer);
};
editor.on(
// @ts-expect-error @TODO additional args for hasCompletion event
'hasCompletion',
handleCompletion,
);
return () =>
editor.off(
// @ts-expect-error @TODO additional args for hasCompletion event
'hasCompletion',
handleCompletion,
);
return () =>
editor.off(
// @ts-expect-error @TODO additional args for hasCompletion event
'hasCompletion',
handleCompletion,
);
}
}, [editor, callback]);
}, [editor, explorer, schema]);
}

export type EmptyCallback = () => void;
Expand Down
33 changes: 22 additions & 11 deletions packages/graphiql-react/src/editor/query-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import type {
import { getOperationFacts } from 'graphql-language-service';
import { MutableRefObject, useContext, useEffect, useRef } from 'react';

import { ExplorerContext } from '../explorer';
import { markdown } from '../markdown';
import { useSchemaWithError } from '../schema';
import { StorageContext } from '../storage';
import debounce from '../utility/debounce';
import { commonKeys, importCodeMirror } from './common';
import { CodeMirrorEditorWithOperationFacts, EditorContext } from './context';
import {
CompletionCallback,
EditCallback,
EmptyCallback,
useCompletion,
Expand All @@ -32,11 +32,9 @@ export type UseQueryEditorArgs = {
defaultValue?: string;
editorTheme?: string;
externalFragments?: string | FragmentDefinitionNode[];
onClickReference?: OnClickReference;
onCopyQuery?: EmptyCallback;
onEdit?: EditCallback;
onEditOperationName?: EditCallback;
onHintInformationRender?: CompletionCallback;
onPrettifyQuery?: EmptyCallback;
onMergeQuery?: EmptyCallback;
onRunQuery?: EmptyCallback;
Expand All @@ -49,11 +47,9 @@ export function useQueryEditor({
defaultValue = DEFAULT_VALUE,
editorTheme = 'graphiql',
externalFragments,
onClickReference,
onCopyQuery,
onEdit,
onEditOperationName,
onHintInformationRender,
onMergeQuery,
onPrettifyQuery,
onRunQuery,
Expand All @@ -64,6 +60,7 @@ export function useQueryEditor({
const { schema } = useSchemaWithError('hook', 'useQueryEditor');
const editorContext = useContext(EditorContext);
const storage = useContext(StorageContext);
const explorer = useContext(ExplorerContext);
const ref = useRef<HTMLDivElement>(null);
const codeMirrorRef = useRef<CodeMirrorType>();

Expand All @@ -75,10 +72,24 @@ export function useQueryEditor({

const { queryEditor, setQueryEditor, variableEditor } = editorContext;

const onClickReferenceRef = useRef<OnClickReference>();
const onClickReferenceRef = useRef<OnClickReference>(() => {});
useEffect(() => {
onClickReferenceRef.current = onClickReference;
}, [onClickReference]);
onClickReferenceRef.current = reference => {
if (!explorer) {
return;
}
explorer.show();
if (reference && reference.kind === 'Type') {
explorer.push({ name: reference.type.name, def: reference.type });
} else if (reference.kind === 'Field') {
explorer.push({ name: reference.field.name, def: reference.field });
} else if (reference.kind === 'Argument' && reference.field) {
explorer.push({ name: reference.field.name, def: reference.field });
} else if (reference.kind === 'EnumValue' && reference.type) {
explorer.push({ name: reference.type.name, def: reference.type });
}
};
}, [explorer]);

const initialValue = useRef(
value ?? storage?.get(STORAGE_KEY_QUERY) ?? defaultValue,
Expand Down Expand Up @@ -139,13 +150,13 @@ export function useQueryEditor({
schema: undefined,
renderDescription: (text: string) => markdown.render(text),
onClick: (reference: SchemaReference) => {
onClickReferenceRef.current?.(reference);
onClickReferenceRef.current(reference);
},
},
jump: {
schema: undefined,
onClick: (reference: SchemaReference) => {
onClickReferenceRef.current?.(reference);
onClickReferenceRef.current(reference);
},
},
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
Expand Down Expand Up @@ -307,7 +318,7 @@ export function useQueryEditor({

useSynchronizeValue(queryEditor, value);

useCompletion(queryEditor, onHintInformationRender);
useCompletion(queryEditor);

useKeyMap(queryEditor, ['Cmd-Enter', 'Ctrl-Enter'], onRunQuery);
useKeyMap(queryEditor, ['Shift-Ctrl-C'], onCopyQuery);
Expand Down
5 changes: 1 addition & 4 deletions packages/graphiql-react/src/editor/variable-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { StorageContext } from '../storage';
import { commonKeys, importCodeMirror } from './common';
import { EditorContext } from './context';
import {
CompletionCallback,
EditCallback,
EmptyCallback,
useChangeHandler,
Expand All @@ -18,7 +17,6 @@ import { CodeMirrorType } from './types';
export type UseVariableEditorArgs = {
editorTheme?: string;
onEdit?: EditCallback;
onHintInformationRender?: CompletionCallback;
onPrettifyQuery?: EmptyCallback;
onMergeQuery?: EmptyCallback;
onRunQuery?: EmptyCallback;
Expand All @@ -29,7 +27,6 @@ export type UseVariableEditorArgs = {
export function useVariableEditor({
editorTheme = 'graphiql',
onEdit,
onHintInformationRender,
onMergeQuery,
onPrettifyQuery,
onRunQuery,
Expand Down Expand Up @@ -137,7 +134,7 @@ export function useVariableEditor({

useChangeHandler(variableEditor, onEdit, STORAGE_KEY);

useCompletion(variableEditor, onHintInformationRender);
useCompletion(variableEditor);

useKeyMap(variableEditor, ['Cmd-Enter', 'Ctrl-Enter'], onRunQuery);
useKeyMap(variableEditor, ['Shift-Ctrl-P'], onPrettifyQuery);
Expand Down
Loading

0 comments on commit 3e5295f

Please sign in to comment.