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

[redesign] move docs components to @graphiql/react #2582

Merged
merged 8 commits into from
Jul 25, 2022
5 changes: 0 additions & 5 deletions .changeset/fifty-elephants-divide.md

This file was deleted.

7 changes: 6 additions & 1 deletion .changeset/five-pillows-fail.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@
'@graphiql/react': minor
---

Add editor components and implement styles for the new GraphiQL design
Add new components:
- UI components (`Dropdown`, `Spinner`, `UnStyledButton` and lots of icon components)
- Editor components (`QueryEditor`, `VariableEditor`, `HeaderEditor` and `ResponseEditor`)
- Toolbar components (`ExecuteButton` and `ToolbarButton`)
- Docs components (`Argument`, `DefaultValue`, `Directive`, `FieldLink` and `TypeLink`)
- `History` component
5 changes: 0 additions & 5 deletions .changeset/fluffy-pianos-mix.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/long-gorillas-act.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/mean-chefs-happen.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/nice-garlics-help.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/perfect-flowers-hunt.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/serious-actors-accept.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/smooth-countries-shout.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { GraphQLNamedType, GraphQLType } from 'graphql';

import { ExplorerContextType, ExplorerNavStackItem } from '../../context';

export function mockExplorerContextValue(
navStackItem: ExplorerNavStackItem,
): ExplorerContextType {
return {
explorerNavStack: [navStackItem],
hide() {},
isVisible: true,
pop() {},
push() {},
reset() {},
show() {},
showSearch() {},
};
}

export function unwrapType(type: GraphQLType): GraphQLNamedType {
return 'ofType' in type ? unwrapType(type.ofType) : type;
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
/**
* Copyright (c) 2021 GraphQL Contributors.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import { ExplorerContext } from '@graphiql/react';
import {
// @ts-expect-error
fireEvent,
render,
} from '@testing-library/react';
import { GraphQLNonNull, GraphQLList, GraphQLString } from 'graphql';
import React, { ComponentProps } from 'react';
import { ComponentProps } from 'react';

import TypeLink from '../TypeLink';
import { ExplorerContext } from '../../context';
import { TypeLink } from '../type-link';
import { mockExplorerContextValue, unwrapType } from './test-utils';

const nonNullType = new GraphQLNonNull(GraphQLString);
Expand All @@ -30,9 +23,11 @@ function TypeLinkWithContext(props: ComponentProps<typeof TypeLink>) {
<TypeLink {...props} />
{/* Print the top of the current nav stack for test assertions */}
<ExplorerContext.Consumer>
{({ explorerNavStack }) => (
{context => (
<span data-testid="nav-stack">
{JSON.stringify(explorerNavStack[explorerNavStack.length + 1])}
{JSON.stringify(
context!.explorerNavStack[context!.explorerNavStack.length + 1],
)}
</span>
)}
</ExplorerContext.Consumer>
Expand All @@ -45,7 +40,6 @@ describe('TypeLink', () => {
const { container } = render(<TypeLinkWithContext type={GraphQLString} />);
expect(container).toHaveTextContent('String');
expect(container.querySelectorAll('a')).toHaveLength(1);
expect(container.querySelector('a')).toHaveClass('type-name');
});
it('should render a non-null type', () => {
const { container } = render(<TypeLinkWithContext type={nonNullType} />);
Expand Down
22 changes: 22 additions & 0 deletions packages/graphiql-react/src/explorer/components/argument.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.graphiql-doc-explorer-argument {
& > * + * {
margin-top: var(--px-12);
}
}

.graphiql-doc-explorer-argument-name {
color: var(--color-purple);
}

.graphiql-doc-explorer-argument-deprecation {
background-color: var(--color-orche-background);
border: 1px solid var(--color-orche);
border-radius: var(--border-radius-4);
color: var(--color-orche);
padding: var(--px-8);
}

.graphiql-doc-explorer-argument-deprecation-label {
font-size: var(--font-size-hint);
font-weight: var(--font-weight-medium);
}
45 changes: 45 additions & 0 deletions packages/graphiql-react/src/explorer/components/argument.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { GraphQLArgument } from 'graphql';

import { DefaultValue } from './default-value';
import { TypeLink } from './type-link';

import './argument.css';
import { MarkdownContent } from '../../ui';

type ArgumentProps = {
arg: GraphQLArgument;
showDefaultValue?: boolean;
inline?: boolean;
};

export function Argument({ arg, showDefaultValue, inline }: ArgumentProps) {
const definition = (
<span>
<span className="graphiql-doc-explorer-argument-name">{arg.name}</span>
{': '}
<TypeLink type={arg.type} />
{showDefaultValue !== false && <DefaultValue field={arg} />}
</span>
);
if (inline) {
return definition;
}
return (
<div className="graphiql-doc-explorer-argument">
{definition}
{arg.description ? (
<MarkdownContent type="description">{arg.description}</MarkdownContent>
) : null}
{arg.deprecationReason ? (
<div className="graphiql-doc-explorer-argument-deprecation">
<div className="graphiql-doc-explorer-argument-deprecation-label">
Deprecated
</div>
<MarkdownContent type="deprecation">
{arg.deprecationReason}
</MarkdownContent>
</div>
) : null}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.graphiql-doc-explorer-default-value {
color: var(--color-green);
}
34 changes: 34 additions & 0 deletions packages/graphiql-react/src/explorer/components/default-value.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { astFromValue, print, ValueNode } from 'graphql';

import { ExplorerFieldDef } from '../context';

import './default-value.css';

const printDefault = (ast?: ValueNode | null): string => {
if (!ast) {
return '';
}
return print(ast);
};

type DefaultValueProps = {
field: ExplorerFieldDef;
};

export function DefaultValue({ field }: DefaultValueProps) {
if (!('defaultValue' in field) || field.defaultValue === undefined) {
return null;
}
const ast = astFromValue(field.defaultValue, field.type);
if (!ast) {
return null;
}
return (
<>
{' = '}
<span className="graphiql-doc-explorer-default-value">
{printDefault(ast)}
</span>
</>
);
}
3 changes: 3 additions & 0 deletions packages/graphiql-react/src/explorer/components/directive.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.graphiql-doc-explorer-directive {
color: var(--color-purple);
}
15 changes: 15 additions & 0 deletions packages/graphiql-react/src/explorer/components/directive.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { DirectiveNode } from 'graphql';

import './directive.css';

type DirectiveProps = {
directive: DirectiveNode;
};

export function Directive({ directive }: DirectiveProps) {
return (
<span className="graphiql-doc-explorer-directive">
@{directive.name.value}
</span>
);
}
12 changes: 12 additions & 0 deletions packages/graphiql-react/src/explorer/components/field-link.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.graphiql-doc-explorer-field-name {
color: var(--color-blue);
text-decoration: none;

&:hover {
text-decoration: underline;
}

&:focus {
outline: var(--color-blue) auto 1px;
}
}
23 changes: 23 additions & 0 deletions packages/graphiql-react/src/explorer/components/field-link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ExplorerFieldDef, useExplorerContext } from '../context';

import './field-link.css';

type FieldLinkProps = {
field: ExplorerFieldDef;
};

export function FieldLink(props: FieldLinkProps) {
const { push } = useExplorerContext({ nonNull: true });

return (
<a
className="graphiql-doc-explorer-field-name"
onClick={event => {
event.preventDefault();
push({ name: props.field.name, def: props.field });
}}
href="#">
{props.field.name}
</a>
);
}
12 changes: 12 additions & 0 deletions packages/graphiql-react/src/explorer/components/type-link.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.graphiql-doc-explorer-type-name {
color: var(--color-orche);
text-decoration: none;

&:hover {
text-decoration: underline;
}

&:focus {
outline: var(--color-orche) auto 1px;
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
/**
* Copyright (c) 2021 GraphQL Contributors.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import { useExplorerContext } from '@graphiql/react';
import { GraphQLType, isListType, isNonNullType } from 'graphql';
import React from 'react';

import { useExplorerContext } from '../context';

import './type-link.css';

type TypeLinkProps = {
type: GraphQLType;
};

export default function TypeLink(props: TypeLinkProps) {
export function TypeLink(props: TypeLinkProps) {
const { push } = useExplorerContext({ nonNull: true, caller: TypeLink });

if (!props.type) {
Expand All @@ -37,7 +32,7 @@ export default function TypeLink(props: TypeLinkProps) {
}
return (
<a
className="type-name"
className="graphiql-doc-explorer-type-name"
onClick={event => {
event.preventDefault();
push({ name: type.name, def: type });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import {
useRef,
useState,
} from 'react';
import { useSchemaContext } from './schema';
import { useSchemaContext } from '../schema';

import { useStorageContext } from './storage';
import { createContextHook, createNullableContext } from './utility/context';
import { useStorageContext } from '../storage';
import { createContextHook, createNullableContext } from '../utility/context';

export type ExplorerFieldDef =
| GraphQLField<{}, {}, {}>
Expand All @@ -37,7 +37,7 @@ export type ExplorerNavStack = [

const initialNavStackItem: ExplorerNavStackItem = {
name: 'Schema',
title: 'Documentation Explorer',
title: 'Docs',
};

export type ExplorerContextType = {
Expand Down
17 changes: 17 additions & 0 deletions packages/graphiql-react/src/explorer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export { Argument } from './components/argument';
export { DefaultValue } from './components/default-value';
export { Directive } from './components/directive';
export { FieldLink } from './components/field-link';
export { TypeLink } from './components/type-link';
export {
ExplorerContext,
ExplorerContextProvider,
useExplorerContext,
} from './context';

export type {
ExplorerContextType,
ExplorerFieldDef,
ExplorerNavStack,
ExplorerNavStackItem,
} from './context';
6 changes: 5 additions & 1 deletion packages/graphiql-react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@ export {
useExecutionContext,
} from './execution';
export {
Argument,
DefaultValue,
Directive,
ExplorerContext,
ExplorerContextProvider,
FieldLink,
TypeLink,
useExplorerContext,
} from './explorer';
export {
Expand Down Expand Up @@ -70,4 +75,3 @@ export type { SchemaContextType } from './schema';
export type { StorageContextType } from './storage';

import './style/root.css';
import './style/markdown.css';
Loading