/* Based on https://github.com/graphql/graphiql/blob/main/packages/graphiql/src/components/GraphiQL.tsx */ import { ChevronDownIcon, ChevronUpIcon, CopyIcon, ExecuteButton, GraphiQLProvider, HeaderEditor, MergeIcon, PlusIcon, PrettifyIcon, QueryEditor, ReloadIcon, ResponseEditor, Spinner, Tab, Tabs, ToolbarButton, Tooltip, UnStyledButton, useCopyQuery, useDragResize, useEditorContext, useExecutionContext, useMergeQuery, usePluginContext, usePrettifyEditors, useSchemaContext, useTheme, VariableEditor, } from '@graphiql/react' import { Fetcher } from '@graphiql/toolkit' import clsx from 'clsx' import { useEffect, useState } from 'react' import styles from './graphiql.module.css' export type GraphiQLProps = { fetcher: Fetcher theme?: 'dark' | 'light' accessToken?: string } const GraphiQL = ({ fetcher, theme = 'dark', accessToken }: GraphiQLProps) => { // Ensure props are correct if (typeof fetcher !== 'function') { throw new TypeError( 'The `GraphiQL` component requires a `fetcher` function to be passed as prop.' ) } return ( ) } type GraphiQLInterfaceProps = { theme: 'dark' | 'light' } export const GraphiQLInterface = ({ theme }: GraphiQLInterfaceProps) => { const editorContext = useEditorContext({ nonNull: true }) const executionContext = useExecutionContext({ nonNull: true }) const schemaContext = useSchemaContext({ nonNull: true }) const pluginContext = usePluginContext() const copy = useCopyQuery() const merge = useMergeQuery() const prettify = usePrettifyEditors() const { setTheme } = useTheme() useEffect(() => { setTheme(theme) }, [theme]) const PluginContent = pluginContext?.visiblePlugin?.content const pluginResize = useDragResize({ defaultSizeRelation: 1 / 3, direction: 'horizontal', initiallyHidden: pluginContext?.visiblePlugin ? undefined : 'second', onHiddenElementChange: (resizableElement) => { if (resizableElement === 'first') { pluginContext?.setVisiblePlugin(null) } }, sizeThresholdSecond: 200, storageKey: 'docExplorerFlex', }) const editorResize = useDragResize({ direction: 'horizontal', storageKey: 'editorFlex', }) const editorToolsResize = useDragResize({ defaultSizeRelation: 3, direction: 'vertical', initiallyHidden: (() => { return editorContext.initialVariables || editorContext.initialHeaders ? undefined : 'second' })(), sizeThresholdSecond: 60, storageKey: 'secondaryEditorFlex', }) const [activeSecondaryEditor, setActiveSecondaryEditor] = useState<'variables' | 'headers'>( () => { return !editorContext.initialVariables && editorContext.initialHeaders ? 'headers' : 'variables' } ) const toolbar = ( <> prettify()} label="Prettify query (Shift-Ctrl-P)"> merge()} label="Merge fragments into query (Shift-Ctrl-M)"> copy()} label="Copy query (Shift-Ctrl-C)"> ) const onClickReference = () => { if (pluginResize.hiddenElement === 'second') { pluginResize.setHiddenElement(null) } } const hasSingleTab = editorContext.tabs.length === 1 return (
{editorContext.tabs.length > 1 ? ( <> {editorContext.tabs.map((tab, index) => ( { executionContext.stop() editorContext.changeTab(index) }} > {tab.title} { if (editorContext.activeTabIndex === index) { executionContext.stop() } editorContext.closeTab(index) }} /> ))}
editorContext.addTab()} aria-label="Add tab" >
) : null}
{hasSingleTab ? (
editorContext.addTab()} aria-label="Add tab" >
) : null}
{toolbar}
{ if (editorToolsResize.hiddenElement === 'second') { editorToolsResize.setHiddenElement(null) } setActiveSecondaryEditor('variables') }} > Variables { if (editorToolsResize.hiddenElement === 'second') { editorToolsResize.setHiddenElement(null) } setActiveSecondaryEditor('headers') }} > Headers
{ editorToolsResize.setHiddenElement( editorToolsResize.hiddenElement === 'second' ? null : 'second' ) }} aria-label={ editorToolsResize.hiddenElement === 'second' ? 'Show editor tools' : 'Hide editor tools' } > {editorToolsResize.hiddenElement === 'second' ? (
{executionContext.isFetching ? : null}
{pluginContext?.visiblePlugin ? (
) : null}
{PluginContent ? : null}
{pluginContext?.plugins.map((plugin) => { const isVisible = plugin === pluginContext.visiblePlugin const label = `${isVisible ? 'Hide' : 'Show'} ${plugin.title}` const Icon = plugin.icon return ( { if (isVisible) { pluginContext.setVisiblePlugin(null) pluginResize.setHiddenElement('second') } else { pluginContext.setVisiblePlugin(plugin) pluginResize.setHiddenElement(null) } }} aria-label={label} > ) })}
schemaContext.introspect()} aria-label="Re-fetch GraphQL schema" >
) } export default GraphiQL