import React, { FC, Fragment } from "react"; import { isInterfaceType, isObjectType, isInputObjectType, isUnionType, isEnumType, GraphQLField, GraphQLInputField, GraphQLNamedType, GraphQLArgument, GraphQLEnumValue, GraphQLObjectType, } from "graphql"; import styled from "styled-components"; import { InlineCodeHighlight } from "../../../components"; import { Type } from "./Type"; interface FieldProps { node?: GraphQLNamedType; setType: (type: GraphQLNamedType) => void; } export const Fields: FC = ({ node, setType }) => { if (!node) { return null; } const isDeprecated = ( field: GraphQLField | GraphQLEnumValue ) => field.isDeprecated ? ( {`Deprecated: ${field.deprecationReason}`} ) : null; const getDefaultValue = (field: GraphQLInputField | GraphQLArgument) => field.defaultValue !== undefined || null ? ( {` = `} ) : null; const getDescription = ( field: | GraphQLField | GraphQLArgument | GraphQLInputField | GraphQLEnumValue | GraphQLObjectType ) => field.description ? ( {`"${field.description}"`} ) : null; if (isObjectType(node) || isInterfaceType(node)) { const fields = node.getFields(); const keys = Object.keys(fields); return ( <> {keys.map((field, i) => { const args = fields[field].args; const hasArgumentLevelDescription = args.some( (arg) => arg.description ); const hasFieldLevelDescription = !!fields[field].description; return (
{getDescription(fields[field])}
{fields[field].name} {args.length > 0 ? "(" : null} {args.length > 0 ? ( <> {args.map((arg, idx) => ( {getDescription(arg)} {arg.name} {getDefaultValue(arg)} {idx !== args.length - 1 && } ))} ) : null}
{args.length ? ")" : null} {isDeprecated(fields[field])}
); })} ); } if (isInputObjectType(node)) { const fields = node.getFields(); const keys = Object.keys(fields); return ( <> {keys.map((field, i) => { return ( {getDescription(fields[field])} {fields[field].name} {getDefaultValue(fields[field])} ); })} ); } if (isUnionType(node)) { const types = node.getTypes(); return ( <> {types.map((type, i) => { return ( {getDescription(type)} ); })} ); } if (isEnumType(node)) { const types = node.getValues(); return ( <> {types.map((type, i) => { return ( {getDescription(type)} {type.value} {isDeprecated(type)} ); })} ); } return null; }; const Description = styled.code` color: ${(p) => p.theme.colors.syntax.string}; `; const FieldWrapper = styled.div` position: relative; display: flex; align-items: baseline; font-size: ${(p) => p.theme.fontSizes.body.l}; line-height: ${(p) => p.theme.lineHeights.body.l}; padding: ${(p) => p.theme.space[3]}; color: ${(p) => p.theme.colors.text.base}; white-space: nowrap; &:last-child { border: none; } & + & { padding-top: 0; } &[data-multiline="true"] { flex-direction: column; & > ${Description} { margin-bottom: ${(p) => p.theme.space[2]}; } } `; const Separator = styled.span` &::before { content: ${({ content }: { content: string }) => `"${content}"`}; display: inline-block; color: ${(p) => p.theme.colors.text.base}; margin-right: ${(p) => p.theme.space[2]}; } `; const Name = styled.span` color: ${(p) => p.theme.colors.syntax.property}; `; const Deprecated = styled.code` display: inline-block; color: ${(p) => p.theme.colors.syntax.invalid}; margin-left: ${(p) => p.theme.space[2]}; `; const Default = styled.code` display: inline-block; color: ${(p) => p.theme.colors.syntax.description}; margin-left: ${(p) => p.theme.space[2]}; `; const ArgWrapper = styled.div` display: flex; &[data-multiline="true"] { flex-direction: column; & > code { padding-left: ${(p) => p.theme.space[3]}; } } `;