Skip to content

Commit 8a4d2a3

Browse files
dondonzacao
authored andcommitted
Add extensions tab to main GraphiQL
1 parent bc6e80a commit 8a4d2a3

File tree

3 files changed

+49
-17
lines changed

3 files changed

+49
-17
lines changed

packages/graphiql-react/src/editor/hooks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export function useChangeHandler(
4141
editor: CodeMirrorEditor | null,
4242
callback: ((value: string) => void) | undefined,
4343
storageKey: string | null,
44-
tabProperty: 'variables' | 'headers',
44+
tabProperty: 'variables' | 'headers' | 'extensions',
4545
caller: Function,
4646
) {
4747
const { updateActiveTabValues } = useEditorContext({ nonNull: true, caller });

packages/graphiql-react/src/provider.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export function GraphiQLProvider({
4747
storage,
4848
validationRules,
4949
variables,
50+
extensions,
5051
visiblePlugin,
5152
}: GraphiQLProviderProps) {
5253
return (
@@ -65,6 +66,7 @@ export function GraphiQLProvider({
6566
shouldPersistHeaders={shouldPersistHeaders}
6667
validationRules={validationRules}
6768
variables={variables}
69+
extensions={extensions}
6870
>
6971
<SchemaContextProvider
7072
dangerouslyAssumeSchemaIsValid={dangerouslyAssumeSchemaIsValid}

packages/graphiql/src/components/GraphiQL.tsx

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
CopyIcon,
2525
Dialog,
2626
ExecuteButton,
27+
ExtensionEditor,
2728
GraphiQLProvider,
2829
GraphiQLProviderProps,
2930
HeaderEditor,
@@ -45,6 +46,7 @@ import {
4546
useDragResize,
4647
useEditorContext,
4748
useExecutionContext,
49+
UseExtensionEditorArgs,
4850
UseHeaderEditorArgs,
4951
useMergeQuery,
5052
usePluginContext,
@@ -120,6 +122,7 @@ export function GraphiQL({
120122
storage,
121123
validationRules,
122124
variables,
125+
extensions,
123126
visiblePlugin,
124127
defaultHeaders,
125128
...props
@@ -159,6 +162,7 @@ export function GraphiQL({
159162
storage={storage}
160163
validationRules={validationRules}
161164
variables={variables}
165+
extensions={extensions}
162166
>
163167
<GraphiQLInterface
164168
showPersistHeadersSettings={shouldPersistHeaders !== false}
@@ -181,6 +185,7 @@ export type GraphiQLInterfaceProps = WriteableEditorProps &
181185
AddSuffix<Pick<UseQueryEditorArgs, 'onEdit'>, 'Query'> &
182186
Pick<UseQueryEditorArgs, 'onCopyQuery'> &
183187
AddSuffix<Pick<UseVariableEditorArgs, 'onEdit'>, 'Variables'> &
188+
AddSuffix<Pick<UseExtensionEditorArgs, 'onEdit'>, 'Extensions'> &
184189
AddSuffix<Pick<UseHeaderEditorArgs, 'onEdit'>, 'Headers'> &
185190
Pick<UseResponseEditorArgs, 'responseTooltip'> & {
186191
children?: ReactNode;
@@ -189,11 +194,12 @@ export type GraphiQLInterfaceProps = WriteableEditorProps &
189194
* - `false` hides the editor tools
190195
* - `true` shows the editor tools
191196
* - `'variables'` specifically shows the variables editor
197+
* - `'extensions'` specifically shows the extensions editor
192198
* - `'headers'` specifically shows the headers editor
193199
* By default the editor tools are initially shown when at least one of the
194200
* editors has contents.
195201
*/
196-
defaultEditorToolsVisibility?: boolean | 'variables' | 'headers';
202+
defaultEditorToolsVisibility?: boolean | 'variables' | 'extensions' | 'headers';
197203
/**
198204
* Toggle if the headers editor should be shown inside the editor tools.
199205
* @default true
@@ -249,6 +255,7 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
249255
initiallyHidden: (() => {
250256
if (
251257
props.defaultEditorToolsVisibility === 'variables' ||
258+
props.defaultEditorToolsVisibility === 'extensions' ||
252259
props.defaultEditorToolsVisibility === 'headers'
253260
) {
254261
return;
@@ -258,7 +265,7 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
258265
return props.defaultEditorToolsVisibility ? undefined : 'second';
259266
}
260267

261-
return editorContext.initialVariables || editorContext.initialHeaders
268+
return (editorContext.initialVariables || editorContext.initialExtensions || editorContext.initialHeaders)
262269
? undefined
263270
: 'second';
264271
})(),
@@ -267,19 +274,24 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
267274
});
268275

269276
const [activeSecondaryEditor, setActiveSecondaryEditor] = useState<
270-
'variables' | 'headers'
277+
'variables' | 'extensions' | 'headers'
271278
>(() => {
272279
if (
273280
props.defaultEditorToolsVisibility === 'variables' ||
281+
props.defaultEditorToolsVisibility === 'extensions' ||
274282
props.defaultEditorToolsVisibility === 'headers'
275283
) {
276284
return props.defaultEditorToolsVisibility;
277285
}
278-
return !editorContext.initialVariables &&
279-
editorContext.initialHeaders &&
280-
isHeadersEditorEnabled
281-
? 'headers'
282-
: 'variables';
286+
287+
if (editorContext.initialVariables) {
288+
return 'variables';
289+
} if (editorContext.initialHeaders && isHeadersEditorEnabled) {
290+
return 'headers';
291+
} if (editorContext.initialExtensions) {
292+
return 'extensions';
293+
}
294+
return 'variables';
283295
});
284296
const [showDialog, setShowDialog] = useState<
285297
'settings' | 'short-keys' | null
@@ -318,6 +330,16 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
318330
isChildComponentType(child, GraphiQL.Footer),
319331
);
320332

333+
const tabName = (currentTab: String) => {
334+
if (currentTab === 'variables') {
335+
return 'Variables';
336+
} if (currentTab === 'extensions') {
337+
return 'Extensions';
338+
} if (currentTab === 'headers') {
339+
return 'Headers';
340+
}
341+
};
342+
321343
const onClickReference = useCallback(() => {
322344
if (pluginResize.hiddenElement === 'first') {
323345
pluginResize.setHiddenElement(null);
@@ -390,7 +412,7 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
390412
editorToolsResize.setHiddenElement(null);
391413
}
392414
setActiveSecondaryEditor(
393-
event.currentTarget.dataset.name as 'variables' | 'headers',
415+
event.currentTarget.dataset.name as 'variables' | 'extensions' | 'headers',
394416
);
395417
},
396418
[editorToolsResize],
@@ -618,6 +640,19 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
618640
Headers
619641
</UnStyledButton>
620642
)}
643+
<UnStyledButton
644+
type="button"
645+
className={
646+
activeSecondaryEditor === 'extensions' &&
647+
editorToolsResize.hiddenElement !== 'second'
648+
? 'active'
649+
: ''
650+
}
651+
onClick={handleToolsTabClick}
652+
data-name="extensions"
653+
>
654+
Extensions
655+
</UnStyledButton>
621656

622657
<Tooltip
623658
label={
@@ -655,11 +690,7 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
655690
<div ref={editorToolsResize.secondRef}>
656691
<section
657692
className="graphiql-editor-tool"
658-
aria-label={
659-
activeSecondaryEditor === 'variables'
660-
? 'Variables'
661-
: 'Headers'
662-
}
693+
aria-label={tabName(activeSecondaryEditor)}
663694
>
664695
<VariableEditor
665696
editorTheme={props.editorTheme}
@@ -680,8 +711,7 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
680711
)}
681712
<ExtensionEditor
682713
editorTheme={props.editorTheme}
683-
// isHidden={activeSecondaryEditor !== 'headers'}
684-
isHidden={false}
714+
isHidden={activeSecondaryEditor !== 'extensions'}
685715
keyMap={props.keyMap}
686716
onEdit={props.onEditExtensions}
687717
readOnly={props.readOnly}

0 commit comments

Comments
 (0)