Skip to content

Commit 7fb5ac3

Browse files
authored
graphiql 5: fix GraphiQL 5 feedback (#4026)
* fix GraphiQL 5 feedback * add deprecated.ts * add more deprecated * useExecutionContext * usePluginContext * useSchemaContext * useStorageContext * useHistoryContext * useExplorerContext * upd readme * upd readme * upd readme * polish * mention never rerender * upd * upd * fix toolbar * toolbar changes * upd * upd * upd * upd * fix graphiql footer overflow * add changeset * add changeset * prettier
1 parent 6a50740 commit 7fb5ac3

File tree

21 files changed

+211
-75
lines changed

21 files changed

+211
-75
lines changed

.changeset/tender-years-destroy.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@graphiql/plugin-doc-explorer': minor
3+
'@graphiql/plugin-history': minor
4+
'@graphiql/react': minor
5+
'graphiql': minor
6+
---
7+
8+
- deprecate `useExplorerContext`, `useHistoryContext`, `usePrettifyEditors`, `useCopyQuery`, `useMergeQuery`, `useExecutionContext`, `usePluginContext`, `useSchemaContext`, `useStorageContext` hooks
9+
- fix response editor overflow on `<GraphiQL.Footer />`
10+
- export `GraphiQLProps` type
11+
- allow `children: ReactNode` for `<GraphiQL.Toolbar />`
12+
- change `ToolbarMenu` component:
13+
- The `label` and `className` props were removed
14+
- The `button` prop should now be a button element
15+
- document `useGraphiQL` and `useGraphiQLActions` hooks in `@graphiql/react` README.md
16+
- rename `useThemeStore` to `useTheme`

docs/migration/graphiql-5.0.0.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,25 @@
1818
- `keyMap`. To use Vim or Emacs keybindings in Monaco, you can use community plugins. Monaco Vim: https://github.com/brijeshb42/monaco-vim. Monaco Emacs: https://github.com/aioutecism/monaco-emacs
1919
- `readOnly`
2020
- `validationRules`. Use custom GraphQL worker, see https://github.com/graphql/graphiql/tree/main/packages/monaco-graphql#custom-webworker-for-passing-non-static-config-to-worker.'
21+
22+
## `@graphiql/react`
23+
24+
The `ToolbarMenu` component has changed.
25+
26+
- The `label` and `className` props were removed
27+
- The `button` prop should now be a button element
28+
29+
```jsx
30+
<ToolbarMenu
31+
label="Options"
32+
button={
33+
<ToolbarButton label="Options">
34+
<SettingsIcon className="graphiql-toolbar-icon" aria-hidden="true" />
35+
</ToolbarButton>
36+
}
37+
>
38+
<ToolbarMenu.Item onSelect={() => console.log('Clicked!')}>
39+
Test
40+
</ToolbarMenu.Item>
41+
</ToolbarMenu>
42+
```
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { useDocExplorer, useDocExplorerActions } from './context';
2+
3+
/**
4+
* @deprecated Use `useDocExplorerActions` and `useDocExplorer` hooks instead.
5+
*/
6+
export function useExplorerContext() {
7+
const actions = useDocExplorerActions();
8+
const explorerNavStack = useDocExplorer();
9+
return {
10+
...actions,
11+
explorerNavStack,
12+
};
13+
}

packages/graphiql-plugin-doc-explorer/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ export type {
1212
DocExplorerNavStack,
1313
DocExplorerNavStackItem,
1414
} from './context';
15+
export * from './deprecated';
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { useHistory, useHistoryActions } from './context';
2+
3+
/**
4+
* @deprecated Use `useHistoryActions` and `useHistory` hooks instead.
5+
*/
6+
export function useHistoryContext() {
7+
const actions = useHistoryActions();
8+
const items = useHistory();
9+
return { ...actions, items };
10+
}

packages/graphiql-plugin-history/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ export const HISTORY_PLUGIN: GraphiQLPlugin = {
1212
export { History };
1313

1414
export { HistoryStore, useHistory, useHistoryActions } from './context';
15+
export * from './deprecated';

packages/graphiql-react/README.md

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,31 +74,54 @@ text. If you want to use the default fonts you can load them using these files:
7474
- `@graphiql/react/font/roboto.css`
7575
- `@graphiql/react/font/fira-code.css`.
7676

77-
You can of course use any other method to load these fonts (for example loading
77+
You can, of course, use any other method to load these fonts (for example, loading
7878
them from Google Fonts).
7979

8080
Further details on how to use `@graphiql/react` can be found in the reference
8181
implementation of a GraphQL IDE - Graph*i*QL - in the
8282
[`graphiql` package](https://github.com/graphql/graphiql/blob/main/packages/graphiql/src/components/GraphiQL.tsx).
8383

84-
## Available stores
84+
## Available Stores
8585

86-
There are multiple stores that own different parts of the state that make up a
87-
complete GraphQL IDE. For each store there is a component
88-
(`<name>Store`) that makes sure the store is initialized and managed
89-
properly. These components contains all the logic related to state management.
86+
GraphiQL uses a set of state management stores, each responsible for a specific part of the IDE's
87+
behavior. These stores contain all logic related to state management and can be accessed via custom
88+
React hooks.
9089

91-
In addition, for each store, there is also a hook that
92-
allows you to consume its current value:
90+
### Core Hooks
9391

94-
- `useStorage`: Provides a storage API that can be used to persist state in
95-
the browser (by default using `localStorage`)
96-
- `useEditorStore`: Manages all the editors and tabs
97-
- `useSchemaStore`: Fetches, validates and stores the GraphQL schema
98-
- `useExecutionStore`: Executes GraphQL requests
92+
- **`useStorage`**: Provides a storage API that can be used to persist state in the browser (by default using `localStorage`).
93+
- **`useTheme`**: Manages the current theme and provides a method to update it.
94+
- **`useGraphiQL`**: Access the current state.
95+
- **`useGraphiQLActions`**: Trigger actions that mutate the state. This hook **never** rerenders.
9996

100-
All context properties are documented using JSDoc comments. If you're using an
101-
IDE like VSCode for development these descriptions will show up in auto-complete
97+
The `useGraphiQLActions` hook **exposes all actions** across store slices.
98+
The `useGraphiQL` hook **provides access to the following store slices**:
99+
100+
| Store Slice | Responsibilities |
101+
| ----------- | -------------------------------------------------------------------------------- |
102+
| `editor` | Manages **query**, **variables**, **headers**, and **response** editors and tabs |
103+
| `execution` | Handles the execution of GraphQL requests |
104+
| `plugin` | Manages plugins and the currently active plugin |
105+
| `schema` | Fetches, validates, and stores the GraphQL schema |
106+
107+
### Usage Example
108+
109+
```js
110+
import { useGraphiQL, useGraphiQLActions, useTheme } from '@graphiql/react';
111+
112+
// Get an action to fetch the schema
113+
const { introspect } = useGraphiQLActions();
114+
115+
// Get the current theme and a method to change it
116+
const { theme, setTheme } = useTheme();
117+
118+
// Or use a selector to access specific parts of the state
119+
const schema = useGraphiQL(state => state.schema);
120+
const currentTheme = useTheme(state => state.theme);
121+
```
122+
123+
All store properties are documented using TSDoc comments. If you're using an
124+
IDE like VSCode for development, these descriptions will show up in auto-complete
102125
tooltips. All these descriptions can also be found in the
103126
[API Docs](https://graphiql-test.netlify.app/typedoc/modules/graphiql_react.html).
104127

packages/graphiql-react/src/components/toolbar-menu/index.css

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/graphiql-react/src/components/toolbar-menu/index.tsx

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,19 @@
11
import type { FC, ReactNode } from 'react';
2-
import { cn } from '../../utility';
3-
import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';
2+
import { Trigger, type DropdownMenuProps } from '@radix-ui/react-dropdown-menu';
43
import { DropdownMenu } from '../dropdown-menu';
5-
import { Tooltip } from '../tooltip';
6-
import './index.css';
74

8-
interface ToolbarMenuProps {
5+
interface ToolbarMenuProps extends DropdownMenuProps {
96
button: ReactNode;
10-
label: string;
117
}
128

13-
const ToolbarMenuRoot: FC<
14-
ToolbarMenuProps & {
15-
children: ReactNode;
16-
className?: string;
17-
} & DropdownMenuProps
18-
> = ({ button, children, label, ...props }) => {
9+
const ToolbarMenuRoot: FC<ToolbarMenuProps> = ({
10+
button,
11+
children,
12+
...props
13+
}) => {
1914
return (
2015
<DropdownMenu {...props}>
21-
<Tooltip label={label}>
22-
<DropdownMenu.Button
23-
className={cn(
24-
'graphiql-un-styled graphiql-toolbar-menu',
25-
props.className,
26-
)}
27-
aria-label={label}
28-
>
29-
{button}
30-
</DropdownMenu.Button>
31-
</Tooltip>
16+
<Trigger asChild>{button}</Trigger>
3217
<DropdownMenu.Content>{children}</DropdownMenu.Content>
3318
</DropdownMenu>
3419
);
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* eslint-disable unicorn/prefer-export-from */
2+
import { useGraphiQL, useGraphiQLActions } from './components';
3+
import { pick } from './utility';
4+
import { useStorage } from './stores';
5+
6+
/**
7+
* @deprecated Use `const { prettifyEditors } = useGraphiQLActions()` instead.
8+
*/
9+
export function usePrettifyEditors() {
10+
const { prettifyEditors } = useGraphiQLActions();
11+
return prettifyEditors;
12+
}
13+
14+
/**
15+
* @deprecated Use `const { copyQuery } = useGraphiQLActions()` instead.
16+
*/
17+
export function useCopyQuery() {
18+
const { copyQuery } = useGraphiQLActions();
19+
return copyQuery;
20+
}
21+
22+
/**
23+
* @deprecated Use `const { mergeQuery } = useGraphiQLActions()` instead.
24+
*/
25+
export function useMergeQuery() {
26+
const { mergeQuery } = useGraphiQLActions();
27+
return mergeQuery;
28+
}
29+
30+
/**
31+
* @deprecated Use `useGraphiQLActions` and `useGraphiQL` hooks instead.
32+
*/
33+
export function useExecutionContext() {
34+
const { run, stop } = useGraphiQLActions();
35+
const values = useGraphiQL(state => ({
36+
isFetching: state.isIntrospecting,
37+
isSubscribed: Boolean(state.subscription),
38+
operationName: state.operationName,
39+
}));
40+
return {
41+
run,
42+
stop,
43+
...values,
44+
};
45+
}
46+
47+
/**
48+
* @deprecated Use `useGraphiQLActions` and `useGraphiQL` hooks instead.
49+
*/
50+
export function usePluginContext() {
51+
const { setVisiblePlugin } = useGraphiQLActions();
52+
const values = useGraphiQL(pick('plugins', 'visiblePlugin'));
53+
return {
54+
setVisiblePlugin,
55+
...values,
56+
};
57+
}
58+
59+
/**
60+
* @deprecated Use `useGraphiQLActions` and `useGraphiQL` hooks instead.
61+
*/
62+
export function useSchemaContext() {
63+
const { introspect } = useGraphiQLActions();
64+
const values = useGraphiQL(
65+
pick('fetchError', 'isFetching', 'schema', 'validationErrors'),
66+
);
67+
return {
68+
introspect,
69+
...values,
70+
};
71+
}
72+
73+
/**
74+
* @deprecated Use `const storage = useStorage()` instead.
75+
*/
76+
export const useStorageContext = useStorage;

0 commit comments

Comments
 (0)