Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v4] Remove query, variables, headers and response props in <GraphiQL />, <GraphiQLProvider /> and <EditorContextProvider /> #3735

Draft
wants to merge 3 commits into
base: graphiql-v4
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/nasty-cows-train.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@graphiql/react': major
'graphiql': major
---

- Remove `query`, `variables`, `headers`, and `response` props in `<GraphiQL />`, `<GraphiQLProvider />`, and `<EditorContextProvider />`

- Remove `useSynchronizeValue` hook
69 changes: 28 additions & 41 deletions packages/graphiql-react/src/editor/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import { useStorageContext } from '../storage';
import { createContextHook, createNullableContext } from '../utility/context';
import { STORAGE_KEY as STORAGE_KEY_HEADERS } from './header-editor';
import { useSynchronizeValue } from './hooks';
import { STORAGE_KEY_QUERY } from './query-editor';
import {
createTab,
Expand Down Expand Up @@ -181,13 +180,6 @@
* `FragmentDefinitionNode` objects.
*/
externalFragments?: string | FragmentDefinitionNode[];
/**
* This prop can be used to set the contents of the headers editor. Every
* time this prop changes, the contents of the headers editor are replaced.
* Note that the editor contents can be changed in between these updates by
* typing in the editor.
*/
headers?: string;
/**
* This prop can be used to define the default set of tabs, with their
* queries, variables, and headers. It will be used as default only if
Expand Down Expand Up @@ -221,20 +213,6 @@
* @param tabState The tabs state after it has been updated.
*/
onTabChange?(tabState: TabsState): void;
/**
* This prop can be used to set the contents of the query editor. Every time
* this prop changes, the contents of the query editor are replaced. Note
* that the editor contents can be changed in between these updates by typing
* in the editor.
*/
query?: string;
/**
* This prop can be used to set the contents of the response editor. Every
* time this prop changes, the contents of the response editor are replaced.
* Note that the editor contents can change in between these updates by
* executing queries that will show a response.
*/
response?: string;
/**
* This prop toggles if the contents of the headers editor are persisted in
* storage.
Expand All @@ -247,21 +225,37 @@
* that are specified in the GraphQL spec).
*/
validationRules?: ValidationRule[];
/**
* This prop can be used to set the contents of the variables editor. Every
* time this prop changes, the contents of the variables editor are replaced.
* Note that the editor contents can be changed in between these updates by
* typing in the editor.
*/
variables?: string;

/**
* Headers to be set when opening a new tab
*/
defaultHeaders?: string;
};

export function EditorContextProvider(props: EditorContextProviderProps) {
// @ts-expect-error -- Prop is removed
if (props.query) {
throw new TypeError(

Check warning on line 237 in packages/graphiql-react/src/editor/context.tsx

View check run for this annotation

Codecov / codecov/patch

packages/graphiql-react/src/editor/context.tsx#L237

Added line #L237 was not covered by tests
'`query` was removed. Use `queryEditor.setValue(query)` instead.',
);
}
// @ts-expect-error -- Prop is removed
if (props.variables) {
throw new TypeError(

Check warning on line 243 in packages/graphiql-react/src/editor/context.tsx

View check run for this annotation

Codecov / codecov/patch

packages/graphiql-react/src/editor/context.tsx#L243

Added line #L243 was not covered by tests
'`variables` was removed. Use `variableEditor.setValue(variables)` instead.',
);
}
// @ts-expect-error -- Prop is removed
if (props.headers) {
throw new TypeError(

Check warning on line 249 in packages/graphiql-react/src/editor/context.tsx

View check run for this annotation

Codecov / codecov/patch

packages/graphiql-react/src/editor/context.tsx#L249

Added line #L249 was not covered by tests
'`headers` was removed. Use `headerEditor.setValue(headers)` instead.',
);
}
// @ts-expect-error -- Prop is removed
if (props.response) {
throw new TypeError(

Check warning on line 255 in packages/graphiql-react/src/editor/context.tsx

View check run for this annotation

Codecov / codecov/patch

packages/graphiql-react/src/editor/context.tsx#L255

Added line #L255 was not covered by tests
'`response` was removed. Use `responseEditor.setValue(response)` instead.',
);
}
const storage = useStorageContext();
const [headerEditor, setHeaderEditor] = useState<CodeMirrorEditor | null>(
null,
Expand All @@ -284,11 +278,6 @@
},
);

useSynchronizeValue(headerEditor, props.headers);
useSynchronizeValue(queryEditor, props.query);
useSynchronizeValue(responseEditor, props.response);
useSynchronizeValue(variableEditor, props.variables);

const storeTabs = useStoreTabs({
storage,
shouldPersistHeaders,
Expand All @@ -297,11 +286,9 @@
// We store this in state but never update it. By passing a function we only
// need to compute it lazily during the initial render.
const [initialState] = useState(() => {
const query = props.query ?? storage?.get(STORAGE_KEY_QUERY) ?? null;
const variables =
props.variables ?? storage?.get(STORAGE_KEY_VARIABLES) ?? null;
const headers = props.headers ?? storage?.get(STORAGE_KEY_HEADERS) ?? null;
const response = props.response ?? '';
const query = storage?.get(STORAGE_KEY_QUERY) ?? null;
const variables = storage?.get(STORAGE_KEY_VARIABLES) ?? null;
const headers = storage?.get(STORAGE_KEY_HEADERS) ?? null;

const tabState = getDefaultTabState({
query,
Expand All @@ -322,7 +309,7 @@
'',
variables: variables ?? '',
headers: headers ?? props.defaultHeaders ?? '',
response,
response: '',
tabState,
};
});
Expand Down
11 changes: 0 additions & 11 deletions packages/graphiql-react/src/editor/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,6 @@ import { onHasCompletion } from './completion';
import { useEditorContext } from './context';
import { CodeMirrorEditor } from './types';

export function useSynchronizeValue(
editor: CodeMirrorEditor | null,
value: string | undefined,
) {
useEffect(() => {
if (editor && typeof value === 'string' && value !== editor.getValue()) {
editor.setValue(value);
}
}, [editor, value]);
}

export function useSynchronizeOption<K extends keyof EditorConfiguration>(
editor: CodeMirrorEditor | null,
option: K,
Expand Down
8 changes: 0 additions & 8 deletions packages/graphiql-react/src/provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export function GraphiQLProvider({
externalFragments,
fetcher,
getDefaultFieldNames,
headers,
inputValueDeprecation,
introspectionQueryName,
maxHistoryLength,
Expand All @@ -39,14 +38,11 @@ export function GraphiQLProvider({
onTogglePluginVisibility,
operationName,
plugins,
query,
response,
schema,
schemaDescription,
shouldPersistHeaders,
storage,
validationRules,
variables,
visiblePlugin,
}: GraphiQLProviderProps) {
return (
Expand All @@ -57,14 +53,10 @@ export function GraphiQLProvider({
defaultHeaders={defaultHeaders}
defaultTabs={defaultTabs}
externalFragments={externalFragments}
headers={headers}
onEditOperationName={onEditOperationName}
onTabChange={onTabChange}
query={query}
response={response}
shouldPersistHeaders={shouldPersistHeaders}
validationRules={validationRules}
variables={variables}
>
<SchemaContextProvider
dangerouslyAssumeSchemaIsValid={dangerouslyAssumeSchemaIsValid}
Expand Down
8 changes: 3 additions & 5 deletions packages/graphiql/cypress/e2e/headers.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@ const DEFAULT_HEADERS = '{"foo":2}';
describe('Headers', () => {
describe('`defaultHeaders`', () => {
it('should have default headers while open new tabs', () => {
cy.visit(
`/?query={test}&defaultHeaders=${DEFAULT_HEADERS}&defaultQuery=`,
);
cy.visit(`/?query={test}&defaultHeaders=${DEFAULT_HEADERS}`);
cy.assertHasValues({ query: '{test}', headersString: DEFAULT_HEADERS });
cy.get('.graphiql-tab-add').click();
cy.assertHasValues({ query: '', headersString: DEFAULT_HEADERS });
cy.get('.graphiql-tab-add').click();
cy.assertHasValues({ query: '', headersString: DEFAULT_HEADERS });
});

it('in case `headers` and `defaultHeaders` are set, `headers` should be on 1st tab and `defaultHeaders` for other opened tabs', () => {
it('if `headers` and `defaultHeaders` are set, `headers` should be on 1st tab and `defaultHeaders` for other opened tabs', () => {
const HEADERS = '{"bar":true}';
cy.visit(
`/?query={test}&defaultHeaders=${DEFAULT_HEADERS}&headers=${HEADERS}&defaultQuery=`,
`/?query={test}&defaultHeaders=${DEFAULT_HEADERS}&headers=${HEADERS}`,
);
cy.assertHasValues({ query: '{test}', headersString: HEADERS });
cy.get('.graphiql-tab-add').click();
Expand Down
2 changes: 1 addition & 1 deletion packages/graphiql/cypress/e2e/tabs.cy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
describe('Tabs', () => {
it('Should store editor contents when switching between tabs', () => {
cy.visit('/?defaultQuery=&query=');
cy.visit('/?query=');

// Assert that tab visible when there's only one session
cy.get('.graphiql-tab-button').eq(0).should('exist');
Expand Down
6 changes: 2 additions & 4 deletions packages/graphiql/resources/renderExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,8 @@ root.render(
url: getSchemaUrl(),
subscriptionUrl: 'ws://localhost:8081/subscriptions',
}),
query: parameters.query,
variables: parameters.variables,
headers: parameters.headers,
defaultQuery: parameters.query,
// variables: parameters.variables,
defaultHeaders: parameters.defaultHeaders,
onEditQuery,
onEditVariables,
Expand All @@ -101,7 +100,6 @@ root.render(
parameters.onPrettifyQuery === 'true' ? onPrettifyQuery : undefined,
onTabChange,
forcedTheme: parameters.forcedTheme,
defaultQuery: parameters.defaultQuery,
defaultTheme: parameters.defaultTheme,
}),
);
8 changes: 0 additions & 8 deletions packages/graphiql/src/components/GraphiQL.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ export function GraphiQL({
externalFragments,
fetcher,
getDefaultFieldNames,
headers,
inputValueDeprecation,
introspectionQueryName,
maxHistoryLength,
Expand All @@ -109,14 +108,11 @@ export function GraphiQL({
onTogglePluginVisibility,
operationName,
plugins,
query,
response,
schema,
schemaDescription,
shouldPersistHeaders,
storage,
validationRules,
variables,
visiblePlugin,
defaultHeaders,
...props
Expand Down Expand Up @@ -148,7 +144,6 @@ export function GraphiQL({
defaultTabs={defaultTabs}
externalFragments={externalFragments}
fetcher={fetcher}
headers={headers}
inputValueDeprecation={inputValueDeprecation}
introspectionQueryName={introspectionQueryName}
maxHistoryLength={maxHistoryLength}
Expand All @@ -159,14 +154,11 @@ export function GraphiQL({
plugins={plugins}
visiblePlugin={visiblePlugin}
operationName={operationName}
query={query}
response={response}
schema={schema}
schemaDescription={schemaDescription}
shouldPersistHeaders={shouldPersistHeaders}
storage={storage}
validationRules={validationRules}
variables={variables}
>
<GraphiQLInterface
confirmCloseTab={confirmCloseTab}
Expand Down
Loading