|
| 1 | +import 'graphiql/style.css'; |
| 2 | +import '@graphiql/plugin-explorer/style.css'; |
| 3 | +import { GraphiQL, GraphiQLProps } from 'graphiql'; |
| 4 | +import { DocumentNode, Kind, parse } from 'graphql'; |
1 | 5 | import { explorerPlugin } from '@graphiql/plugin-explorer';
|
2 |
| -import '@graphiql/plugin-explorer/dist/style.css'; |
3 |
| -import { GraphiQL, GraphiQLInterface, GraphiQLProps, GraphiQLProvider } from 'graphiql'; |
4 | 6 | import { Fetcher, FetcherOpts, FetcherParams } from '@graphiql/toolkit';
|
5 | 7 | import { LoadFromUrlOptions, SubscriptionProtocol, UrlLoader } from '@graphql-tools/url-loader';
|
6 |
| -import 'graphiql/graphiql.css'; |
7 |
| -import { DocumentNode, Kind, parse } from 'graphql'; |
8 | 8 | import 'json-bigint-patch';
|
9 |
| -import React, { useMemo, useState } from 'react'; |
10 |
| -import { useUrlSearchParams } from 'use-url-search-params'; |
| 9 | +import React, { useMemo } from 'react'; |
11 | 10 | import { YogaLogo } from './YogaLogo';
|
12 | 11 | import './styles.css';
|
13 | 12 |
|
@@ -43,6 +42,19 @@ export type YogaGraphiQLProps = Partial<GraphiQLProps> &
|
43 | 42 | * Extra headers you always want to pass with users' headers input
|
44 | 43 | */
|
45 | 44 | additionalHeaders?: LoadFromUrlOptions['headers'];
|
| 45 | + |
| 46 | + /** |
| 47 | + * @deprecated Use `initialQuery` instead. |
| 48 | + */ |
| 49 | + query?: GraphiQLProps['initialQuery']; |
| 50 | + /** |
| 51 | + * @deprecated Use `initialHeaders` instead. |
| 52 | + */ |
| 53 | + headers?: GraphiQLProps['initialHeaders']; |
| 54 | + /** |
| 55 | + * @deprecated Use `initialVariables` instead. |
| 56 | + */ |
| 57 | + variables?: GraphiQLProps['initialVariables']; |
46 | 58 | };
|
47 | 59 |
|
48 | 60 | export function YogaGraphiQL(props: YogaGraphiQLProps): React.ReactElement {
|
@@ -81,10 +93,6 @@ export function YogaGraphiQL(props: YogaGraphiQLProps): React.ReactElement {
|
81 | 93 |
|
82 | 94 | const endpoint = new URL(props.endpoint ?? location.pathname, location.href).toString();
|
83 | 95 |
|
84 |
| - const type = { |
85 |
| - query: String, |
86 |
| - }; |
87 |
| - |
88 | 96 | const urlLoader = useMemo(() => new UrlLoader(), []);
|
89 | 97 |
|
90 | 98 | const fetcher = useMemo(() => {
|
@@ -126,81 +134,71 @@ export function YogaGraphiQL(props: YogaGraphiQLProps): React.ReactElement {
|
126 | 134 | };
|
127 | 135 | }, [urlLoader, endpoint, props.fetcher]) as Fetcher;
|
128 | 136 |
|
129 |
| - const [params, setParams] = useUrlSearchParams( |
130 |
| - { |
131 |
| - query: props.defaultQuery || initialQuery, |
132 |
| - }, |
133 |
| - type, |
134 |
| - false, |
135 |
| - ); |
136 |
| - |
137 |
| - const [query, setQuery] = useState(params['query']?.toString()); |
138 | 137 | const explorer = explorerPlugin({
|
139 | 138 | showAttribution: true,
|
140 | 139 | });
|
141 | 140 |
|
142 |
| - if (props.query && !props.onEditQuery) { |
143 |
| - // eslint-disable-next-line no-console |
144 |
| - console.warn( |
145 |
| - 'If you provide `query` prop, you should also provide `onEditQuery` prop to handle query changes.', |
146 |
| - ); |
147 |
| - } |
| 141 | + const currentUrl = new URL(location.href); |
| 142 | + const initialQueryFromUrl = currentUrl.searchParams.get('query') || props.query || initialQuery; |
| 143 | + |
| 144 | + const { |
| 145 | + query: deprecatedInitialQuery = initialQueryFromUrl, |
| 146 | + headers: deprecatedInitialHeaders, |
| 147 | + variables: deprecatedInitialVariables, |
| 148 | + ...otherProps |
| 149 | + } = props; |
148 | 150 |
|
149 | 151 | return (
|
150 | 152 | <div className="graphiql-container">
|
151 |
| - <GraphiQLProvider |
| 153 | + <GraphiQL |
152 | 154 | // default values that can be override by props
|
153 | 155 | shouldPersistHeaders
|
154 | 156 | plugins={[explorer]}
|
155 | 157 | schemaDescription={true}
|
156 | 158 | inputValueDeprecation={true}
|
157 |
| - query={query} |
158 |
| - {...props} |
| 159 | + isHeadersEditorEnabled |
| 160 | + defaultEditorToolsVisibility |
| 161 | + initialQuery={deprecatedInitialQuery} |
| 162 | + defaultHeaders={deprecatedInitialHeaders} |
| 163 | + initialVariables={deprecatedInitialVariables} |
| 164 | + onEditQuery={(query, ast) => { |
| 165 | + currentUrl.searchParams.set('query', query); |
| 166 | + history.replaceState({}, '', currentUrl); |
| 167 | + props.onEditQuery?.(query, ast); |
| 168 | + }} |
| 169 | + {...otherProps} |
159 | 170 | fetcher={fetcher}
|
160 | 171 | >
|
161 |
| - <GraphiQLInterface |
162 |
| - isHeadersEditorEnabled |
163 |
| - defaultEditorToolsVisibility |
164 |
| - {...props} |
165 |
| - onEditQuery={(query, ast) => { |
166 |
| - setParams({ |
167 |
| - query, |
168 |
| - }); |
169 |
| - setQuery(query); |
170 |
| - props.onEditQuery?.(query, ast); |
171 |
| - }} |
172 |
| - > |
173 |
| - <GraphiQL.Logo> |
174 |
| - <div style={{ display: 'flex', alignItems: 'center' }}> |
175 |
| - {typeof props?.logo === 'string' ? ( |
176 |
| - // if the logo is a string, then it's coming when rendering graphiql as a static page (see render-graphiql) |
177 |
| - <div |
178 |
| - style={{ width: 40, display: 'flex' }} |
179 |
| - dangerouslySetInnerHTML={{ __html: props.logo }} |
180 |
| - /> |
181 |
| - ) : ( |
182 |
| - // otherwise, it's used inside react and we can render it as a component |
183 |
| - <div style={{ width: 40, display: 'flex' }}>{props?.logo || <YogaLogo />}</div> |
184 |
| - )} |
185 |
| - {typeof props?.title === 'string' ? ( |
186 |
| - // if the title is a string, then it's coming when rendering graphiql as a static page (see render-graphiql) |
187 |
| - <span dangerouslySetInnerHTML={{ __html: props.title }} /> |
188 |
| - ) : ( |
189 |
| - // otherwise, it's used inside react and we can render it as a component |
190 |
| - <span> |
191 |
| - {props?.title || ( |
192 |
| - <> |
193 |
| - Yoga Graph |
194 |
| - <em>i</em> |
195 |
| - QL |
196 |
| - </> |
197 |
| - )} |
198 |
| - </span> |
199 |
| - )} |
200 |
| - </div> |
201 |
| - </GraphiQL.Logo> |
202 |
| - </GraphiQLInterface> |
203 |
| - </GraphiQLProvider> |
| 172 | + <GraphiQL.Logo> |
| 173 | + <div style={{ display: 'flex', alignItems: 'center' }}> |
| 174 | + {typeof props?.logo === 'string' ? ( |
| 175 | + // if the logo is a string, then it's coming when rendering graphiql as a static page (see render-graphiql) |
| 176 | + <div |
| 177 | + style={{ width: 40, display: 'flex' }} |
| 178 | + dangerouslySetInnerHTML={{ __html: props.logo }} |
| 179 | + /> |
| 180 | + ) : ( |
| 181 | + // otherwise, it's used inside react and we can render it as a component |
| 182 | + <div style={{ width: 40, display: 'flex' }}>{props?.logo || <YogaLogo />}</div> |
| 183 | + )} |
| 184 | + {typeof props?.title === 'string' ? ( |
| 185 | + // if the title is a string, then it's coming when rendering graphiql as a static page (see render-graphiql) |
| 186 | + <span dangerouslySetInnerHTML={{ __html: props.title }} /> |
| 187 | + ) : ( |
| 188 | + // otherwise, it's used inside react and we can render it as a component |
| 189 | + <span> |
| 190 | + {props?.title || ( |
| 191 | + <> |
| 192 | + Yoga Graph |
| 193 | + <em>i</em> |
| 194 | + QL |
| 195 | + </> |
| 196 | + )} |
| 197 | + </span> |
| 198 | + )} |
| 199 | + </div> |
| 200 | + </GraphiQL.Logo> |
| 201 | + </GraphiQL> |
204 | 202 | </div>
|
205 | 203 | );
|
206 | 204 | }
|
0 commit comments