Skip to content

Commit

Permalink
[redesign] move docs components to @graphiql/react (#2582)
Browse files Browse the repository at this point in the history
* move explorer context into folder

* move `TypeLink` component to `@graphiql/react`

* move `FieldLink` component to `@graphiql/react`

* move `DefaultValue` component to `@graphiql/react`

* move `Directive` component to `@graphiql/react`

* extract `MarkdownContent` component in `@gaphiql/react`

* move `Argument` component to `@graphiql/react`

* combine and extend changesets
  • Loading branch information
thomasheyenbrock committed Aug 9, 2022
1 parent e54b5c8 commit 1a06818
Show file tree
Hide file tree
Showing 42 changed files with 413 additions and 371 deletions.
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 @@ -31,9 +24,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 @@ -46,7 +41,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;
}
}
24 changes: 24 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,24 @@
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';
Loading

0 comments on commit 1a06818

Please sign in to comment.