Skip to content

Commit

Permalink
feat: add @graphiql/react package (#2370)
Browse files Browse the repository at this point in the history
* upgrade eslint-plugin-react

* add @graphiql/react package with context provider

* replace docs state with context provider from @graphiql/react

* add changesets

* add type annotation for variable

Co-authored-by: Laurin Quast <[email protected]>

* build @graphiql/react before graphiql

* make package public and add github links

* don't reset state if it doesn't change

* correct type annotation

* fix doc explorer tests by adding context provider

* fix typedoc

* make explorer context nullable

* promote to minor change

Co-authored-by: Laurin Quast <[email protected]>
  • Loading branch information
thomasheyenbrock and n1ru4l authored May 13, 2022
1 parent c5696df commit 7f695b1
Show file tree
Hide file tree
Showing 22 changed files with 789 additions and 290 deletions.
5 changes: 5 additions & 0 deletions .changeset/slimy-tips-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'graphiql': minor
---

Include the context provider for the explorer from `@graphiql/react` and replace the local state for the nav stack of the docs with methods provided by hooks from `@graphiql/react`.
5 changes: 5 additions & 0 deletions .changeset/slow-sloths-suffer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphiql/react': patch
---

Add a context with provider component and hooks that manages the state related to the docs/explorer.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"npm": "please_use_yarn_instead"
},
"scripts": {
"build": "yarn tsc --clean && yarn tsc",
"build": "yarn workspace @graphiql/react run build && yarn tsc --clean && yarn tsc",
"build-bundles": "yarn prebuild-bundles && yarn workspace graphiql run build-bundles",
"build-bundles-clean": "rimraf '{packages,examples,plugins}/**/{bundle,cdn,webpack}' && yarn workspace graphiql run build-bundles-clean",
"build-clean": "wsrun build-clean",
Expand Down Expand Up @@ -96,6 +96,7 @@
"@types/jest": "^26.0.22",
"@types/node": "^14.14.22",
"@types/prettier": "^2.0.0",
"@types/react": "^17.0.37",
"@types/set-value": "^4.0.1",
"@types/theme-ui": "^0.3.1",
"@types/ws": "^7.4.0",
Expand All @@ -117,7 +118,7 @@
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-jest": "^23.8.2",
"eslint-plugin-prefer-object-spread": "1.2.1",
"eslint-plugin-react": "7.19.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^3.0.0",
"execa": "^6.0.0",
"express": "^4.17.1",
Expand Down
3 changes: 3 additions & 0 deletions packages/graphiql-react/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": ["plugin:react/jsx-runtime"]
}
27 changes: 27 additions & 0 deletions packages/graphiql-react/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
types
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?


35 changes: 35 additions & 0 deletions packages/graphiql-react/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "@graphiql/react",
"version": "0.0.0",
"repository": {
"type": "git",
"url": "https://github.com/graphql/graphiql",
"directory": "packages/graphiql-react"
},
"homepage": "http://github.com/graphql/graphiql/tree/master/packages/graphiql-react#readme",
"bugs": {
"url": "https://github.com/graphql/graphiql/issues?q=issue+label:graphiql-react"
},
"license": "MIT",
"main": "dist/index.cjs.js",
"module": "dist/index.es.js",
"types": "types/index.d.ts",
"scripts": {
"dev": "vite",
"build": "tsc && rimraf tsc && vite build",
"preview": "vite preview"
},
"peerDependencies": {
"graphql": "^15.5.0 || ^16.0.0",
"react": "^16.8.0 | ^17.0.0 | ^18.0.0",
"react-dom": "^16.8.0 | ^17.0.0 | ^18.0.0"
},
"devDependencies": {
"@vitejs/plugin-react": "^1.3.0",
"graphql": "^16.4.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"typescript": "^4.6.3",
"vite": "^2.9.5"
}
}
93 changes: 93 additions & 0 deletions packages/graphiql-react/src/explorer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import type {
GraphQLArgument,
GraphQLField,
GraphQLInputField,
GraphQLNamedType,
} from 'graphql';
import {
createContext,
ReactNode,
useCallback,
useContext,
useState,
} from 'react';

export type ExplorerFieldDef =
| GraphQLField<{}, {}, {}>
| GraphQLInputField
| GraphQLArgument;

export type ExplorerNavStackItem = {
name: string;
title?: string;
search?: string;
def?: GraphQLNamedType | ExplorerFieldDef;
};

// There's always at least one item in the nav stack
export type ExplorerNavStack = [
ExplorerNavStackItem,
...ExplorerNavStackItem[]
];

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

export type ExplorerContextType = {
explorerNavStack: ExplorerNavStack;
push(item: ExplorerNavStackItem): void;
pop(): void;
reset(): void;
showSearch(search: string): void;
};

export const ExplorerContext = createContext<ExplorerContextType | null>(null);

export function ExplorerContextProvider(props: { children: ReactNode }) {
const [state, setState] = useState<ExplorerNavStack>([initialNavStackItem]);

const push = useCallback((item: ExplorerNavStackItem) => {
setState(currentState => {
const lastItem = currentState[currentState.length - 1];
return lastItem.def === item.def
? // Avoid pushing duplicate items
currentState
: [...currentState, item];
});
}, []);

const pop = useCallback(() => {
setState(currentState =>
currentState.length > 1
? (currentState.slice(0, -1) as ExplorerNavStack)
: currentState,
);
}, []);

const reset = useCallback(() => {
setState(currentState =>
currentState.length === 1 ? currentState : [initialNavStackItem],
);
}, []);

const showSearch = useCallback((search: string) => {
setState(currentState => {
const lastItem = currentState[currentState.length - 1];
const allButLastItem = currentState.slice(0, -1) as ExplorerNavStack;
return [...allButLastItem, { ...lastItem, search }] as ExplorerNavStack;
});
}, []);

return (
<ExplorerContext.Provider
value={{ explorerNavStack: state, push, pop, reset, showSearch }}>
{props.children}
</ExplorerContext.Provider>
);
}

export function useExplorerNavStack() {
return useContext(ExplorerContext);
}
20 changes: 20 additions & 0 deletions packages/graphiql-react/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
ExplorerContext,
ExplorerContextProvider,
useExplorerNavStack,
} from './explorer';
import type {
ExplorerContextType,
ExplorerFieldDef,
ExplorerNavStack,
ExplorerNavStackItem,
} from './explorer';

export { ExplorerContext, ExplorerContextProvider, useExplorerNavStack };

export type {
ExplorerContextType,
ExplorerFieldDef,
ExplorerNavStack,
ExplorerNavStackItem,
};
1 change: 1 addition & 0 deletions packages/graphiql-react/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// / <reference types="vite/client" />
23 changes: 23 additions & 0 deletions packages/graphiql-react/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"declaration": true,
"declarationDir": "types",
"outDir": "tsc"
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
8 changes: 8 additions & 0 deletions packages/graphiql-react/tsconfig.node.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"composite": true,
"module": "esnext",
"moduleResolution": "node"
},
"include": ["vite.config.ts"]
}
16 changes: 16 additions & 0 deletions packages/graphiql-react/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
plugins: [react()],
build: {
lib: {
entry: 'src/index.ts',
fileName: 'index',
formats: ['cjs', 'es'],
},
rollupOptions: {
external: ['react', 'react-dom'],
},
},
});
1 change: 1 addition & 0 deletions packages/graphiql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"webpack": "webpack --config resources/webpack.config.js"
},
"dependencies": {
"@graphiql/react": "^0.0.0",
"@graphiql/toolkit": "^0.4.5",
"codemirror": "^5.65.3",
"codemirror-graphql": "^1.3.0",
Expand Down
Loading

0 comments on commit 7f695b1

Please sign in to comment.