Skip to content

Commit

Permalink
extract loading spinner to @graphiql/react (#2581)
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasheyenbrock committed Jul 27, 2022
1 parent cddd647 commit d52f346
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 54 deletions.
5 changes: 5 additions & 0 deletions .changeset/smooth-countries-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphiql/react': minor
---

Add `Spinner` component to `@graphiql/react`
1 change: 1 addition & 0 deletions packages/graphiql-react/src/ui/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './button';
export * from './dropdown';
export * from './spinner';
27 changes: 27 additions & 0 deletions packages/graphiql-react/src/ui/spinner.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.graphiql-spinner {
height: 56px;
margin: auto;
margin-top: var(--px-16);
width: 56px;

&::after {
animation: rotation 0.6s infinite linear;
border: 4px solid transparent;
border-radius: 100%;
border-top: 4px solid var(--color-neutral-40);
content: '';
display: inline-block;
height: 46px;
vertical-align: middle;
width: 46px;
}
}

@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
5 changes: 5 additions & 0 deletions packages/graphiql-react/src/ui/spinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import './spinner.css';

export function Spinner() {
return <div className="graphiql-spinner" />;
}
47 changes: 26 additions & 21 deletions packages/graphiql/__mocks__/@graphiql/react.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export {
SchemaContext,
SchemaContextProvider,
SettingsIcon,
Spinner,
StopIcon,
StorageContext,
StorageContextProvider,
Expand All @@ -52,7 +53,6 @@ export {
useMergeQuery,
usePrettifyEditors,
useSchemaContext,
useSelectHistoryItem,
useStorageContext,
} from '@graphiql/react';

Expand Down Expand Up @@ -92,15 +92,20 @@ function useMockedEditor(
onEdit?: (newValue: string) => void,
) {
const editorContext = useEditorContext({ nonNull: true });
const [code, setCode] = useState(
value ?? editorContext[NAME_TO_INITIAL_VALUE[name]],
);
const [code, setCode] = useState(() => {
const initialValueProp = NAME_TO_INITIAL_VALUE[name];
return (
value ??
(initialValueProp ? editorContext[initialValueProp] : undefined) ??
''
);
});
const ref = useRef<HTMLDivElement>(null);

const setEditor =
editorContext[`set${name.slice(0, 1).toUpperCase()}${name.slice(1)}Editor`];

const getValueRef = useRef<() => string>();
const getValueRef = useRef<() => string>(() => code);
useEffect(() => {
getValueRef.current = () => code;
}, [code]);
Expand Down Expand Up @@ -179,28 +184,28 @@ function useMockedEditor(
return ref;
}

export const useHeaderEditor: typeof _useHeaderEditor = function useHeaderEditor({
onEdit,
}) {
return useMockedEditor('header', undefined, onEdit);
export const useHeaderEditor: typeof _useHeaderEditor = function useHeaderEditor(
props,
) {
return useMockedEditor('header', undefined, props?.onEdit);
};

export const useQueryEditor: typeof _useQueryEditor = function useQueryEditor({
onEdit,
}) {
return useMockedEditor('query', undefined, onEdit);
export const useQueryEditor: typeof _useQueryEditor = function useQueryEditor(
props,
) {
return useMockedEditor('query', undefined, props?.onEdit);
};

export const useResponseEditor: typeof _useResponseEditor = function useResponseEditor({
value,
}) {
return useMockedEditor('response', value);
export const useResponseEditor: typeof _useResponseEditor = function useResponseEditor(
props,
) {
return useMockedEditor('response', props?.value);
};

export const useVariableEditor: typeof _useVariableEditor = function useVariableEditor({
onEdit,
}) {
return useMockedEditor('variable', undefined, onEdit);
export const useVariableEditor: typeof _useVariableEditor = function useVariableEditor(
props,
) {
return useMockedEditor('variable', undefined, props?.onEdit);
};

export const HeaderEditor: typeof _HeaderEditor = function HeaderEditor(props) {
Expand Down
6 changes: 3 additions & 3 deletions packages/graphiql/src/components/DocExplorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

import React, { ReactNode } from 'react';
import { Spinner, useExplorerContext, useSchemaContext } from '@graphiql/react';
import { GraphQLSchema, isType } from 'graphql';
import { useExplorerContext, useSchemaContext } from '@graphiql/react';
import React, { ReactNode } from 'react';

import FieldDoc from './DocExplorer/FieldDoc';
import SchemaDoc from './DocExplorer/SchemaDoc';
Expand Down Expand Up @@ -60,7 +60,7 @@ export function DocExplorer(props: DocExplorerProps) {
);
} else if (isFetching) {
// Schema is undefined when it is being loaded via introspection.
content = <div className="graphiql-spinner" />;
content = <Spinner />;
} else if (!schema) {
// Schema is null when it explicitly does not exist, typically due to
// an error during introspection.
Expand Down
3 changes: 2 additions & 1 deletion packages/graphiql/src/components/GraphiQL.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
ResponseEditor,
SchemaContextProvider,
SettingsIcon,
Spinner,
StorageContextProvider,
ToolbarButton,
UnStyledButton,
Expand Down Expand Up @@ -958,7 +959,7 @@ class GraphiQLWithContext extends React.Component<
<div ref={this.props.editorResize.secondRef}>
<div className="graphiql-response">
{this.props.executionContext.isFetching ? (
<div className="graphiql-spinner" />
<Spinner />
) : null}
<ResponseEditor
value={this.props.response}
Expand Down
29 changes: 0 additions & 29 deletions packages/graphiql/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -145,35 +145,6 @@
padding: var(--px-16);
}

/* Generic loading spinner */
.graphiql-container .graphiql-spinner {
height: 56px;
left: 50%;
position: relative;
top: 50%;
transform: translate(-50%, -50%);
width: 56px;
}
.graphiql-container .graphiql-spinner::after {
animation: rotation 0.6s infinite linear;
border: 4px solid transparent;
border-radius: 100%;
border-top: 4px solid var(--color-neutral-40);
content: '';
display: inline-block;
height: 46px;
vertical-align: middle;
width: 46px;
}
@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}

/* Generic drag bar for horizontal resizing */
.graphiql-container .graphiql-horizontal-drag-bar {
width: var(--px-12);
Expand Down

0 comments on commit d52f346

Please sign in to comment.