diff --git a/.changeset/add-on-prettify-callback.md b/.changeset/add-on-prettify-callback.md new file mode 100644 index 00000000000..40640e5571c --- /dev/null +++ b/.changeset/add-on-prettify-callback.md @@ -0,0 +1,6 @@ +--- +"@graphiql/react": minor +"graphiql": minor +--- + +Add support for `onPrettifyQuery` callback to enable customised query formatting diff --git a/.changeset/breezy-chicken-crash.md b/.changeset/breezy-chicken-crash.md new file mode 100644 index 00000000000..1a3bff1737e --- /dev/null +++ b/.changeset/breezy-chicken-crash.md @@ -0,0 +1,12 @@ +--- +'@graphiql/plugin-code-exporter': major +--- + +`style.css` import was changed + +## Migration + +```diff +-import '@graphiql/plugin-code-exporter/dist/style.css'; ++import '@graphiql/plugin-code-exporter/style.css'; +``` diff --git a/.changeset/few-steaks-clap.md b/.changeset/few-steaks-clap.md new file mode 100644 index 00000000000..7eff915641d --- /dev/null +++ b/.changeset/few-steaks-clap.md @@ -0,0 +1,5 @@ +--- +'graphiql': major +--- + +show tabs even there is only 1 tab diff --git a/.changeset/flat-lies-heal.md b/.changeset/flat-lies-heal.md new file mode 100644 index 00000000000..dfe39818386 --- /dev/null +++ b/.changeset/flat-lies-heal.md @@ -0,0 +1,7 @@ +--- +'@graphiql/react': minor +'@graphiql/plugin-explorer': minor +'@graphiql/plugin-code-exporter': minor +--- + +generate types with `vite-plugin-dts` diff --git a/.changeset/gentle-bugs-mix.md b/.changeset/gentle-bugs-mix.md new file mode 100644 index 00000000000..9bb1ae56ab2 --- /dev/null +++ b/.changeset/gentle-bugs-mix.md @@ -0,0 +1,19 @@ +--- +'graphiql': major +--- + +remove default export + +## Migration + +### Before + +```jsx +import GraphiQL from 'graphiql' +``` + +### After + +```jsx +import { GraphiQL } from 'graphiql' +``` diff --git a/.changeset/good-vans-refuse.md b/.changeset/good-vans-refuse.md new file mode 100644 index 00000000000..906325035d5 --- /dev/null +++ b/.changeset/good-vans-refuse.md @@ -0,0 +1,12 @@ +--- +'@graphiql/react': minor +--- + +`style.css` import was changed + +## Migration + +```diff +-import '@graphiql/react/dist/style.css'; ++import '@graphiql/react/style.css'; +``` diff --git a/.changeset/green-pugs-worry.md b/.changeset/green-pugs-worry.md new file mode 100644 index 00000000000..4342a6bc271 --- /dev/null +++ b/.changeset/green-pugs-worry.md @@ -0,0 +1,5 @@ +--- +'graphiql': major +--- + +remove `disableTabs` option diff --git a/.changeset/healthy-onions-bake.md b/.changeset/healthy-onions-bake.md new file mode 100644 index 00000000000..37a059e690e --- /dev/null +++ b/.changeset/healthy-onions-bake.md @@ -0,0 +1,5 @@ +--- +'@graphiql/plugin-explorer': patch +--- + +improve explorer styles diff --git a/.changeset/hungry-spiders-cheat.md b/.changeset/hungry-spiders-cheat.md new file mode 100644 index 00000000000..2f22a97f550 --- /dev/null +++ b/.changeset/hungry-spiders-cheat.md @@ -0,0 +1,5 @@ +--- +'graphiql': major +--- + +remove `data-testid="graphiql-container"` diff --git a/.changeset/metal-glasses-bow.md b/.changeset/metal-glasses-bow.md new file mode 100644 index 00000000000..48c99bbf5c7 --- /dev/null +++ b/.changeset/metal-glasses-bow.md @@ -0,0 +1,5 @@ +--- +'graphiql': patch +--- + +update graphql to `16.9.0` and use vite `define` configuration to remove development code from cdn bundle diff --git a/.changeset/nine-meals-happen.md b/.changeset/nine-meals-happen.md new file mode 100644 index 00000000000..34b1551d197 --- /dev/null +++ b/.changeset/nine-meals-happen.md @@ -0,0 +1,6 @@ +--- +'@graphiql/plugin-code-exporter': patch +'@graphiql/plugin-explorer': patch +--- + +fix types incorrect types entry diff --git a/.changeset/old-zebras-knock.md b/.changeset/old-zebras-knock.md new file mode 100644 index 00000000000..a0109290d2e --- /dev/null +++ b/.changeset/old-zebras-knock.md @@ -0,0 +1,5 @@ +--- +'graphiql': minor +--- + +remove `.graphiql-session` class diff --git a/.changeset/olive-mice-hide.md b/.changeset/olive-mice-hide.md new file mode 100644 index 00000000000..2606c7cae1c --- /dev/null +++ b/.changeset/olive-mice-hide.md @@ -0,0 +1,6 @@ +--- +'graphiql': patch +'@graphiql/react': patch +--- + +Respect Markdown format: ignore single newline diff --git a/.changeset/orange-rivers-draw.md b/.changeset/orange-rivers-draw.md new file mode 100644 index 00000000000..f87e0f7e852 --- /dev/null +++ b/.changeset/orange-rivers-draw.md @@ -0,0 +1,9 @@ +--- +'@graphiql/plugin-code-exporter': patch +'@graphiql/plugin-explorer': patch +'@graphiql/react': patch +--- + +use `vite build --watch` instead of `vite` for `dev` script because we don't need development server for them + +do not use `vite-plugin-dts` when generating umd build diff --git a/.changeset/pink-moose-shake.md b/.changeset/pink-moose-shake.md new file mode 100644 index 00000000000..59273f6196b --- /dev/null +++ b/.changeset/pink-moose-shake.md @@ -0,0 +1,5 @@ +--- +'graphiql': patch +--- + +use `position: absolute` for `.graphiql-logo` class diff --git a/.changeset/poor-ghosts-jump.md b/.changeset/poor-ghosts-jump.md new file mode 100644 index 00000000000..79d454d52a5 --- /dev/null +++ b/.changeset/poor-ghosts-jump.md @@ -0,0 +1,13 @@ +--- +'@graphiql/plugin-explorer': major +--- + +`style.css` import was changed + +## Migration + +```diff +-import '@graphiql/plugin-explorer/dist/style.css'; ++import '@graphiql/plugin-explorer/style.css'; +``` + diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 00000000000..4220dda8dcc --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,51 @@ +{ + "mode": "pre", + "tag": "alpha", + "initialVersions": { + "cm6-graphql": "0.0.15", + "codemirror-graphql": "2.0.13", + "graphiql": "3.4.0", + "@graphiql/plugin-code-exporter": "3.0.5", + "@graphiql/plugin-explorer": "3.1.1", + "@graphiql/react": "0.23.0", + "@graphiql/toolkit": "0.9.2", + "graphql-language-service": "5.2.2", + "graphql-language-service-cli": "3.4.2", + "graphql-language-service-server": "2.13.2", + "monaco-graphql": "1.5.3", + "vscode-graphql": "0.11.2", + "vscode-graphql-execution": "0.2.6", + "vscode-graphql-syntax": "1.3.6", + "example-graphiql-webpack": "0.0.0", + "example-monaco-graphql-nextjs": "0.0.0", + "example-monaco-graphql-react-vite": "0.0.0", + "example-monaco-graphql-webpack": "0.0.0" + }, + "changesets": [ + "add-on-prettify-callback", + "breezy-chicken-crash", + "few-steaks-clap", + "flat-lies-heal", + "gentle-bugs-mix", + "good-vans-refuse", + "green-pugs-worry", + "healthy-onions-bake", + "hungry-spiders-cheat", + "metal-glasses-bow", + "nine-meals-happen", + "old-zebras-knock", + "olive-mice-hide", + "orange-rivers-draw", + "pink-moose-shake", + "poor-ghosts-jump", + "red-papayas-fly", + "rich-jobs-kick", + "serious-forks-sip", + "spotty-bulldogs-confess", + "strong-ears-bake", + "thick-adults-leave", + "thirty-spoons-call", + "weak-dancers-jog", + "wicked-seas-laugh" + ] +} diff --git a/.changeset/red-papayas-fly.md b/.changeset/red-papayas-fly.md new file mode 100644 index 00000000000..2d02218e3b5 --- /dev/null +++ b/.changeset/red-papayas-fly.md @@ -0,0 +1,6 @@ +--- +'@graphiql/react': patch +'graphiql': patch +--- + +replace `overflow-y: scroll` with `overflow-y: auto` diff --git a/.changeset/rich-jobs-kick.md b/.changeset/rich-jobs-kick.md new file mode 100644 index 00000000000..602fd4c63c3 --- /dev/null +++ b/.changeset/rich-jobs-kick.md @@ -0,0 +1,21 @@ +--- +'graphiql': major +--- + +changed exports + +```diff +-graphiql/graphiql.css ++graphiql/style.css +``` + +changed cdn paths, `dist/index.umd.js` and `dist/style.css` are minified + +```diff +-https://unpkg.com/graphiql/graphiql.js +-https://unpkg.com/graphiql/graphiql.min.js ++https://unpkg.com/graphiql/dist/index.umd.js +-https://unpkg.com/graphiql/graphiql.css +-https://unpkg.com/graphiql/graphiql.min.css ++https://unpkg.com/graphiql/dist/style.css +``` diff --git a/.changeset/serious-forks-sip.md b/.changeset/serious-forks-sip.md new file mode 100644 index 00000000000..e7c0353f66f --- /dev/null +++ b/.changeset/serious-forks-sip.md @@ -0,0 +1,6 @@ +--- +'@graphiql/react': patch +'graphiql': patch +--- + +rollback `position: absolute` style for `.graphiql-logo` because tabs will behind logo diff --git a/.changeset/spotty-bulldogs-confess.md b/.changeset/spotty-bulldogs-confess.md new file mode 100644 index 00000000000..eed64fbd7f1 --- /dev/null +++ b/.changeset/spotty-bulldogs-confess.md @@ -0,0 +1,7 @@ +--- +'@graphiql/react': patch +'graphiql': patch +--- + +- prefer `location` over `window.location` +- prefer `navigator` over `window.navigator` diff --git a/.changeset/strong-ears-bake.md b/.changeset/strong-ears-bake.md new file mode 100644 index 00000000000..45ac76e3ebd --- /dev/null +++ b/.changeset/strong-ears-bake.md @@ -0,0 +1,5 @@ +--- +'graphiql': patch +--- + +use `right: var(--px-16)` instead of `right: 0` for `.graphiql-logo` diff --git a/.changeset/thick-adults-leave.md b/.changeset/thick-adults-leave.md new file mode 100644 index 00000000000..f18738c9905 --- /dev/null +++ b/.changeset/thick-adults-leave.md @@ -0,0 +1,5 @@ +--- +'@graphiql/react': minor +--- + +remove `createComponentGroup` utility in favour `Object.assign` diff --git a/.changeset/thirty-spoons-call.md b/.changeset/thirty-spoons-call.md new file mode 100644 index 00000000000..4853b541b98 --- /dev/null +++ b/.changeset/thirty-spoons-call.md @@ -0,0 +1,8 @@ +--- +"graphiql": major +"@graphiql/react": minor +--- + +- new looks of tabs + +- fix `disableTabs` when `Add tab` button is still shown diff --git a/.changeset/weak-dancers-jog.md b/.changeset/weak-dancers-jog.md new file mode 100644 index 00000000000..8b78fe25302 --- /dev/null +++ b/.changeset/weak-dancers-jog.md @@ -0,0 +1,79 @@ +--- +'graphiql': major +--- + +Remove `toolbar.additionalContent` and `toolbar.additionalComponent` props in favor of `GraphiQL.Toolbar` render props. + +## Migration from `toolbar.additionalContent` + +### Before + +```jsx +My button }} /> +``` + +### After + +```jsx + + + {({ merge, prettify, copy }) => ( + <> + {prettify} + {merge} + {copy} + + + )} + + +``` + +## Migration from `toolbar.additionalComponent` + +### Before + +```jsx +My button; + }, + }} +/> +``` + +### After + +```jsx + + + {({ merge, prettify, copy }) => ( + <> + {prettify} + {merge} + {copy} + + + )} + + +``` + +--- + +Additionally, you can sort default toolbar buttons in different order or remove unneeded buttons for you: + +```jsx + + + {({ prettify, copy }) => ( + <> + {copy /* Copy button will be first instead of default last */} + {/* Merge button is removed from toolbar */} + {prettify} + + )} + + +``` diff --git a/.changeset/wicked-seas-laugh.md b/.changeset/wicked-seas-laugh.md new file mode 100644 index 00000000000..3162059dcaf --- /dev/null +++ b/.changeset/wicked-seas-laugh.md @@ -0,0 +1,5 @@ +--- +'graphiql': patch +--- + +replace `Tooltip`s in tabs with html `title="..."` attribute diff --git a/.eslintrc.js b/.eslintrc.js index 9c60692380e..b83237de399 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -129,6 +129,16 @@ module.exports = { property: 'localStorage', message: 'Use `localStorage` instead', }, + { + object: 'window', + property: 'location', + message: 'Use `location` instead', + }, + { + object: 'window', + property: 'navigator', + message: 'Use `navigator` instead', + }, ], 'no-return-assign': 'error', 'no-return-await': 'error', @@ -389,7 +399,7 @@ module.exports = { projectService: { allowDefaultProject: [ 'examples/monaco-graphql-react-vite/vite.config.ts', - 'packages/{graphiql,graphiql-plugin-explorer,graphiql-plugin-code-exporter}/vite.config.mts', + 'packages/graphiql/vite.config.mts', 'packages/{codemirror-graphql,graphiql-toolkit,graphql-language-service-cli,graphql-language-service,monaco-graphql,vscode-graphql-syntax,graphiql}/vitest.config.mts', 'packages/cm6-graphql/__tests__/test.spec.ts', diff --git a/.github/workflows/pr-graphql-compat-check.yml b/.github/workflows/pr-graphql-compat-check.yml index da0c1c2098c..ec380cb83ed 100644 --- a/.github/workflows/pr-graphql-compat-check.yml +++ b/.github/workflows/pr-graphql-compat-check.yml @@ -4,8 +4,7 @@ on: # only on merge to main. # it's rare that this workflow would # show us an error, but when it does it's important! - branches: - - main + branches: [main, graphiql-v4] # don't run this regression suite if we don't need to paths-ignore: - '**.md' diff --git a/docs/migration/graphiql-4.0.0.md b/docs/migration/graphiql-4.0.0.md index 09439975d21..780ff6b0208 100644 --- a/docs/migration/graphiql-4.0.0.md +++ b/docs/migration/graphiql-4.0.0.md @@ -2,30 +2,149 @@ ## `graphiql` changes +- New looks of tabs - Drop CommonJS build output - Drop support React 16/17 - Support React 19 -- ⚠️ UMD CDN build `index.umd.js` is deprecated. Migrate to ESM-based CDN. +- Changed umd CDN paths, `dist/index.umd.js` and `dist/style.css` are minified + ```diff + -https://unpkg.com/graphiql/graphiql.js + -https://unpkg.com/graphiql/graphiql.min.js + +https://unpkg.com/graphiql/dist/index.umd.js + -https://unpkg.com/graphiql/graphiql.css + -https://unpkg.com/graphiql/graphiql.min.css + +https://unpkg.com/graphiql/dist/style.css + ``` +- ⚠️ UMD CDN build `index.umd.js` is deprecated. Migrate to ESM-based CDN +- Add support for `onPrettifyQuery` callback to enable customized query formatting +- Show tabs even there is only one tab +- Remove default export + ```diff + -import GraphiQL from 'graphiql' + +import { GraphiQL } from 'graphiql' + ``` +- Remove `disableTabs` option +- Respect a Markdown format - ignore single newline +- Replace `Tooltip`s in tabs with html `title="..."` attribute +- Style import was changed + ```diff + -graphiql/graphiql.css + +graphiql/style.css + ``` +- Remove `toolbar.additionalContent` and `toolbar.additionalComponent` props in favor of `GraphiQL.Toolbar` render props + + ### Migration from `toolbar.additionalContent` + + #### Before + + ```jsx + My button }} /> + ``` + + #### After + + ```jsx + + + {({ merge, prettify, copy }) => ( + <> + {prettify} + {merge} + {copy} + + + )} + + + ``` + + ### Migration from `toolbar.additionalComponent` + + #### Before + + ```jsx + My button; + }, + }} + /> + ``` + + #### After + + ```jsx + + + {({ merge, prettify, copy }) => ( + <> + {prettify} + {merge} + {copy} + + + )} + + + ``` + + *** + + Additionally, you can sort default toolbar buttons in different order or remove unneeded buttons for you: + + ```jsx + + + {({ prettify, copy }) => ( + <> + {copy /* Copy button will be first instead of default last */} + {/* Merge button is removed from toolbar */} + {prettify} + + )} + + + ``` ## `@graphiql/react` changes +- New looks of tabs - Drop CommonJS build output - Drop support React 16/17 - Support React 19 - Update `@radix-ui` and `@headlessui/react` dependencies +- Add support for `onPrettifyQuery` callback to enable customized query formatting +- `style.css` import was changed + ```diff + -import '@graphiql/react/dist/style.css'; + +import '@graphiql/react/style.css'; + ``` +- Respect a Markdown format - ignore single newline ## `@graphiql/plugin-code-exporter` changes - Drop CommonJS build output - Drop support React 16/17 - Support React 19 -- ⚠️ UMD CDN build `index.umd.js` is deprecated. Migrate to ESM-based CDN. +- ⚠️ UMD CDN build `index.umd.js` is deprecated. Migrate to ESM-based CDN - [Updated CDN ESM-based example](../../packages/graphiql-plugin-code-exporter/example/index.html) +- `style.css` import was changed + ```diff + -import '@graphiql/plugin-code-exporter/dist/style.css'; + +import '@graphiql/plugin-code-exporter/style.css'; + ``` ## `@graphiql/plugin-explorer` changes - Drop CommonJS build output - Drop support React 16/17 - Support React 19 -- ⚠️ UMD CDN build `index.umd.js` is deprecated. Migrate to ESM-based CDN. +- ⚠️ UMD CDN build `index.umd.js` is deprecated. Migrate to ESM-based CDN - [Updated CDN ESM-based example](../../packages/graphiql-plugin-explorer/example/index.html) +- Improve explorer styles +- `style.css` import was changed + ```diff + -import '@graphiql/plugin-explorer/dist/style.css'; + +import '@graphiql/plugin-explorer/style.css'; + ``` diff --git a/examples/graphiql-create-react-app/package.json b/examples/graphiql-create-react-app/package.json index e2c9baefb7a..6a2438460a2 100644 --- a/examples/graphiql-create-react-app/package.json +++ b/examples/graphiql-create-react-app/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "private": true, "dependencies": { - "graphiql": "^3.4.0", + "graphiql": "^3.4.1", "graphql": "^16.9.0", "react": "^19.1.0", "react-dom": "^19.1.0", diff --git a/examples/graphiql-create-react-app/src/App.jsx b/examples/graphiql-create-react-app/src/App.jsx index 9175fb03fee..ba2d6b6fb2e 100644 --- a/examples/graphiql-create-react-app/src/App.jsx +++ b/examples/graphiql-create-react-app/src/App.jsx @@ -1,5 +1,5 @@ import { GraphiQL } from 'graphiql'; -import 'graphiql/graphiql.css'; +import 'graphiql/style.css'; const fetcher = async graphQLParams => { const response = await fetch( diff --git a/examples/graphiql-webpack/public/logo.svg b/examples/graphiql-webpack/public/logo.svg index 43e513e06ca..8b265562b12 100644 --- a/examples/graphiql-webpack/public/logo.svg +++ b/examples/graphiql-webpack/public/logo.svg @@ -1,27 +1,15 @@ - + + + - - + - + - diff --git a/examples/graphiql-webpack/src/index.jsx b/examples/graphiql-webpack/src/index.jsx index ea0adb4c667..7b6f678fa04 100644 --- a/examples/graphiql-webpack/src/index.jsx +++ b/examples/graphiql-webpack/src/index.jsx @@ -5,9 +5,9 @@ import { GraphiQL } from 'graphiql'; import { explorerPlugin } from '@graphiql/plugin-explorer'; import { getSnippets } from './snippets'; import { codeExporterPlugin } from '@graphiql/plugin-code-exporter'; -import 'graphiql/graphiql.css'; -import '@graphiql/plugin-explorer/dist/style.css'; -import '@graphiql/plugin-code-exporter/dist/style.css'; +import 'graphiql/style.css'; +import '@graphiql/plugin-explorer/style.css'; +import '@graphiql/plugin-code-exporter/style.css'; import { createGraphiQLFetcher } from '@graphiql/toolkit'; import { useStorageContext } from '@graphiql/react'; diff --git a/examples/monaco-graphql-webpack/webpack.config.js b/examples/monaco-graphql-webpack/webpack.config.js index 577f2b1f5c2..019b0e0ac21 100644 --- a/examples/monaco-graphql-webpack/webpack.config.js +++ b/examples/monaco-graphql-webpack/webpack.config.js @@ -47,7 +47,7 @@ const resultConfig = { plugins: [ // in order to prevent async modules for CDN builds // until we can guarantee it will work with the CDN properly - // and so that graphiql.min.js can retain parity + // and so that `index.umd.js` can retain parity new HtmlWebpackPlugin({ template: relPath('src/index.html.ejs'), filename: 'index.html', diff --git a/functions/graphql.ts b/functions/graphql.ts index 935f056e26f..2788d0b9188 100644 --- a/functions/graphql.ts +++ b/functions/graphql.ts @@ -10,8 +10,8 @@ import type { HandlerContext as NetlifyHandlerContext, } from '@netlify/functions'; -import schema from '../packages/graphiql/test/schema'; -import { customExecute } from '../packages/graphiql/test/execute'; +import { schema } from '../packages/graphiql/test/schema.js'; +import { customExecute } from '../packages/graphiql/test/execute.js'; /** * Handler options when using the netlify adapter diff --git a/package.json b/package.json index 039c952b2ed..3f0dfe41a27 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,8 @@ "gen-agenda": "wgutils agenda gen" }, "dependencies": { + "identity-obj-proxy": "^3.0.0", + "babel-plugin-macros": "^3.1.0", "graphql-http": "^1.22.1", "@babel/cli": "^7.21.0", "@babel/core": "^7.21.0", @@ -104,7 +106,6 @@ "@typescript-eslint/eslint-plugin": "^8.31.0", "@typescript-eslint/parser": "^8.31.0", "babel-jest": "^29.4.3", - "babel-plugin-macros": "^3.1.0", "babel-plugin-transform-import-meta": "^2.2.1", "concurrently": "^7.0.0", "copy": "^0.3.2", @@ -122,7 +123,6 @@ "eslint-plugin-sonarjs": "^3.0.2", "eslint-plugin-unicorn": "^56.0.0", "execa": "^7.1.1", - "identity-obj-proxy": "^3.0.0", "fetch-mock": "6.5.2", "husky": "^4.2.3", "jest": "^27.5.1", diff --git a/packages/graphiql-plugin-code-exporter/CHANGELOG.md b/packages/graphiql-plugin-code-exporter/CHANGELOG.md index e4acbf292d9..7ac8389de9b 100644 --- a/packages/graphiql-plugin-code-exporter/CHANGELOG.md +++ b/packages/graphiql-plugin-code-exporter/CHANGELOG.md @@ -1,5 +1,37 @@ # @graphiql/plugin-code-exporter +## 4.0.0-alpha.1 + +### Patch Changes + +- [#3740](https://github.com/graphql/graphiql/pull/3740) [`3c12ce0`](https://github.com/graphql/graphiql/commit/3c12ce01eb3b2ec9a317a2fea2bb92602b748a8b) Thanks [@dimaMachina](https://github.com/dimaMachina)! - fix types incorrect types entry + +## 4.0.0-alpha.0 + +### Major Changes + +- [#3709](https://github.com/graphql/graphiql/pull/3709) [`9baf1f0`](https://github.com/graphql/graphiql/commit/9baf1f0fc9f32404fbb8bf57b3d1c2c2c8778ddb) Thanks [@dimaMachina](https://github.com/dimaMachina)! - `style.css` import was changed + + ## Migration + + ```diff + -import '@graphiql/plugin-code-exporter/dist/style.css'; + +import '@graphiql/plugin-code-exporter/style.css'; + ``` + +### Minor Changes + +- [#3702](https://github.com/graphql/graphiql/pull/3702) [`00415d2`](https://github.com/graphql/graphiql/commit/00415d2940c4d76a4a9e683e9fa0504ba97dd627) Thanks [@dimaMachina](https://github.com/dimaMachina)! - generate types with `vite-plugin-dts` + +### Patch Changes + +- [#3705](https://github.com/graphql/graphiql/pull/3705) [`8ff87d7`](https://github.com/graphql/graphiql/commit/8ff87d7b6b3d5d12b539612a39ca3abf7e631106) Thanks [@dimaMachina](https://github.com/dimaMachina)! - use `vite build --watch` instead of `vite` for `dev` script because we don't need development server for them + + do not use `vite-plugin-dts` when generating umd build + +- Updated dependencies [[`00415d2`](https://github.com/graphql/graphiql/commit/00415d2940c4d76a4a9e683e9fa0504ba97dd627), [`9baf1f0`](https://github.com/graphql/graphiql/commit/9baf1f0fc9f32404fbb8bf57b3d1c2c2c8778ddb), [`8ff87d7`](https://github.com/graphql/graphiql/commit/8ff87d7b6b3d5d12b539612a39ca3abf7e631106), [`82bc961`](https://github.com/graphql/graphiql/commit/82bc961a33c4e9da29dffb4a603035a4909f49ad), [`3c1a345`](https://github.com/graphql/graphiql/commit/3c1a345acd9bf07b45bc230009cb57c51c425673)]: + - @graphiql/react@1.0.0-alpha.0 + ## 3.1.5 ### Patch Changes diff --git a/packages/graphiql-plugin-code-exporter/README.md b/packages/graphiql-plugin-code-exporter/README.md index 51f0c0eb9fb..56c683531e3 100644 --- a/packages/graphiql-plugin-code-exporter/README.md +++ b/packages/graphiql-plugin-code-exporter/README.md @@ -28,8 +28,8 @@ Example integration: import { GraphiQL } from 'graphiql'; import { createGraphiQLFetcher } from '@graphiql/toolkit'; import { codeExporterPlugin } from '@graphiql/plugin-code-exporter'; -import 'graphiql/graphiql.css'; -import '@graphiql/plugin-code-exporter/dist/style.css'; +import 'graphiql/style.css'; +import '@graphiql/plugin-code-exporter/style.css'; const fetcher = createGraphiQLFetcher({ url: 'https://countries.trevorblades.com', diff --git a/packages/graphiql-plugin-code-exporter/package.json b/packages/graphiql-plugin-code-exporter/package.json index e0eecbe45dd..c775e92fd80 100644 --- a/packages/graphiql-plugin-code-exporter/package.json +++ b/packages/graphiql-plugin-code-exporter/package.json @@ -1,6 +1,6 @@ { "name": "@graphiql/plugin-code-exporter", - "version": "3.1.5", + "version": "4.0.0-alpha.1", "sideEffects": false, "repository": { "type": "git", @@ -8,8 +8,7 @@ "directory": "packages/graphiql-plugin-code-exporter" }, "author": "LekoArts", - "main": "dist/index.js", - "types": "types/index.d.ts", + "types": "dist/index.d.ts", "license": "MIT", "keywords": [ "react", @@ -19,32 +18,40 @@ "explorer" ], "files": [ - "dist", - "src", - "types" + "dist" ], + "exports": { + "./package.json": "./package.json", + "./style.css": "./dist/style.css", + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, "scripts": { - "prebuild": "rimraf dist types", - "dev": "vite", - "build": "tsc --emitDeclarationOnly && node resources/copy-types.mjs && vite build && UMD=true vite build", - "preview": "vite preview" + "dev": "vite build --watch", + "build": "vite build && UMD=true vite build", + "prebuild": "yarn types:check", + "postbuild": "cp src/graphiql-code-exporter.d.ts dist/graphiql-code-exporter.d.ts", + "types:check": "tsc --noEmit" }, "dependencies": { "graphiql-code-exporter": "^3.0.3" }, "peerDependencies": { - "@graphiql/react": "^0.29.0", - "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0", + "@graphiql/react": "^1.0.0-alpha.0", + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0-alpha.2", "react": "^18 || ^19", "react-dom": "^18 || ^19" }, "devDependencies": { - "@graphiql/react": "^0.29.0", + "@graphiql/react": "^1.0.0-alpha.3", "@vitejs/plugin-react": "^4.4.1", "graphql": "^16.9.0", "react": "^19.1.0", "react-dom": "^19.1.0", "typescript": "^4.6.3", - "vite": "^6.3.3" + "vite": "^6.3.3", + "vite-plugin-dts": "^4.0.1" } } diff --git a/packages/graphiql-plugin-code-exporter/resources/copy-types.mjs b/packages/graphiql-plugin-code-exporter/resources/copy-types.mjs deleted file mode 100644 index 45e621b507b..00000000000 --- a/packages/graphiql-plugin-code-exporter/resources/copy-types.mjs +++ /dev/null @@ -1,11 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import { fileURLToPath } from 'url'; - -const __filename = fileURLToPath(import.meta.url); -const base = path.resolve(path.dirname(__filename), '..'); - -fs.copyFileSync( - path.resolve(base, 'src', 'graphiql-code-exporter.d.ts'), - path.resolve(base, 'types', 'graphiql-code-exporter.d.ts'), -); diff --git a/packages/graphiql-plugin-code-exporter/src/index.css b/packages/graphiql-plugin-code-exporter/src/index.css index 716d01d954c..16af4b1b6f9 100644 --- a/packages/graphiql-plugin-code-exporter/src/index.css +++ b/packages/graphiql-plugin-code-exporter/src/index.css @@ -133,7 +133,7 @@ } & .CodeMirror { box-shadow: var(--popover-box-shadow); - border-radius: calc(var(--border-radius-12)); + border-radius: var(--border-radius-12); padding: var(--px-16); } } diff --git a/packages/graphiql-plugin-code-exporter/tsconfig.json b/packages/graphiql-plugin-code-exporter/tsconfig.json index 8ad4d4a311c..2dd9b41294b 100644 --- a/packages/graphiql-plugin-code-exporter/tsconfig.json +++ b/packages/graphiql-plugin-code-exporter/tsconfig.json @@ -14,9 +14,6 @@ "resolveJsonModule": true, "isolatedModules": true, "declaration": true, - "declarationDir": "types", "jsx": "react" - }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] + } } diff --git a/packages/graphiql-plugin-code-exporter/tsconfig.node.json b/packages/graphiql-plugin-code-exporter/tsconfig.node.json deleted file mode 100644 index 9d31e2aed93..00000000000 --- a/packages/graphiql-plugin-code-exporter/tsconfig.node.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "module": "ESNext", - "moduleResolution": "Node", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/packages/graphiql-plugin-code-exporter/vite.config.mts b/packages/graphiql-plugin-code-exporter/vite.config.mts index a6b7327d4bd..627e266b78f 100644 --- a/packages/graphiql-plugin-code-exporter/vite.config.mts +++ b/packages/graphiql-plugin-code-exporter/vite.config.mts @@ -1,16 +1,22 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import packageJSON from './package.json'; +import dts from 'vite-plugin-dts'; const IS_UMD = process.env.UMD === 'true'; export default defineConfig({ - plugins: [react({ jsxRuntime: 'classic' })], + plugins: [ + react({ jsxRuntime: 'classic' }), + !IS_UMD && dts({ include: ['src/**'] }), + ], css: { transformer: 'lightningcss', }, build: { - minify: IS_UMD ? 'esbuild' : false, + minify: IS_UMD + ? 'terser' // produce better bundle size than esbuild + : false, // avoid clean cjs/es builds emptyOutDir: !IS_UMD, lib: { @@ -28,7 +34,6 @@ export default defineConfig({ ...(IS_UMD ? [] : Object.keys(packageJSON.dependencies)), ], output: { - chunkFileNames: '[name].[format].js', globals: { '@graphiql/react': 'GraphiQL.React', graphql: 'GraphiQL.GraphQL', @@ -37,9 +42,5 @@ export default defineConfig({ }, }, }, - commonjsOptions: { - esmExternals: true, - requireReturnsDefault: 'auto', - }, }, }); diff --git a/packages/graphiql-plugin-explorer/CHANGELOG.md b/packages/graphiql-plugin-explorer/CHANGELOG.md index 9d64d6f730e..86bd789f48e 100644 --- a/packages/graphiql-plugin-explorer/CHANGELOG.md +++ b/packages/graphiql-plugin-explorer/CHANGELOG.md @@ -1,5 +1,43 @@ # @graphiql/plugin-explorer +## 4.0.0-alpha.2 + +### Patch Changes + +- [#3740](https://github.com/graphql/graphiql/pull/3740) [`3c12ce0`](https://github.com/graphql/graphiql/commit/3c12ce01eb3b2ec9a317a2fea2bb92602b748a8b) Thanks [@dimaMachina](https://github.com/dimaMachina)! - fix types incorrect types entry + +## 4.0.0-alpha.1 + +### Patch Changes + +- [#3738](https://github.com/graphql/graphiql/pull/3738) [`eaa415c`](https://github.com/graphql/graphiql/commit/eaa415cce5c3baecea76068c02953884eec5ba2e) Thanks [@dimaMachina](https://github.com/dimaMachina)! - improve explorer styles + +## 4.0.0-alpha.0 + +### Major Changes + +- [#3709](https://github.com/graphql/graphiql/pull/3709) [`9baf1f0`](https://github.com/graphql/graphiql/commit/9baf1f0fc9f32404fbb8bf57b3d1c2c2c8778ddb) Thanks [@dimaMachina](https://github.com/dimaMachina)! - `style.css` import was changed + + ## Migration + + ```diff + -import '@graphiql/plugin-explorer/dist/style.css'; + +import '@graphiql/plugin-explorer/style.css'; + ``` + +### Minor Changes + +- [#3702](https://github.com/graphql/graphiql/pull/3702) [`00415d2`](https://github.com/graphql/graphiql/commit/00415d2940c4d76a4a9e683e9fa0504ba97dd627) Thanks [@dimaMachina](https://github.com/dimaMachina)! - generate types with `vite-plugin-dts` + +### Patch Changes + +- [#3705](https://github.com/graphql/graphiql/pull/3705) [`8ff87d7`](https://github.com/graphql/graphiql/commit/8ff87d7b6b3d5d12b539612a39ca3abf7e631106) Thanks [@dimaMachina](https://github.com/dimaMachina)! - use `vite build --watch` instead of `vite` for `dev` script because we don't need development server for them + + do not use `vite-plugin-dts` when generating umd build + +- Updated dependencies [[`00415d2`](https://github.com/graphql/graphiql/commit/00415d2940c4d76a4a9e683e9fa0504ba97dd627), [`9baf1f0`](https://github.com/graphql/graphiql/commit/9baf1f0fc9f32404fbb8bf57b3d1c2c2c8778ddb), [`8ff87d7`](https://github.com/graphql/graphiql/commit/8ff87d7b6b3d5d12b539612a39ca3abf7e631106), [`82bc961`](https://github.com/graphql/graphiql/commit/82bc961a33c4e9da29dffb4a603035a4909f49ad), [`3c1a345`](https://github.com/graphql/graphiql/commit/3c1a345acd9bf07b45bc230009cb57c51c425673)]: + - @graphiql/react@1.0.0-alpha.0 + ## 3.2.6 ### Patch Changes diff --git a/packages/graphiql-plugin-explorer/README.md b/packages/graphiql-plugin-explorer/README.md index 1b2f33eee3e..ea75f273f10 100644 --- a/packages/graphiql-plugin-explorer/README.md +++ b/packages/graphiql-plugin-explorer/README.md @@ -24,7 +24,7 @@ import { GraphiQL } from 'graphiql'; import { createGraphiQLFetcher } from '@graphiql/toolkit'; import { explorerPlugin } from '@graphiql/plugin-explorer'; import 'graphiql/style.css'; -import '@graphiql/plugin-explorer/dist/style.css'; +import '@graphiql/plugin-explorer/style.css'; const fetcher = createGraphiQLFetcher({ url: 'https://swapi-graphql.netlify.app/.netlify/functions/index', diff --git a/packages/graphiql-plugin-explorer/package.json b/packages/graphiql-plugin-explorer/package.json index 099d6a29d8f..748ebe64586 100644 --- a/packages/graphiql-plugin-explorer/package.json +++ b/packages/graphiql-plugin-explorer/package.json @@ -1,14 +1,13 @@ { "name": "@graphiql/plugin-explorer", - "version": "3.2.6", + "version": "4.0.0-alpha.2", "sideEffects": false, "repository": { "type": "git", "url": "https://github.com/graphql/graphiql", "directory": "packages/graphiql-plugin-explorer" }, - "main": "dist/index.js", - "types": "types/index.d.ts", + "types": "dist/index.d.ts", "license": "MIT", "keywords": [ "react", @@ -18,33 +17,41 @@ "explorer" ], "files": [ - "dist", - "src", - "types" + "dist" ], + "exports": { + "./package.json": "./package.json", + "./style.css": "./dist/style.css", + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, "scripts": { - "prebuild": "rimraf dist types", - "dev": "vite", - "build": "tsc --emitDeclarationOnly && node resources/copy-types.mjs && vite build && UMD=true vite build", - "preview": "vite preview" + "dev": "vite build --watch", + "build": "vite build && UMD=true vite build", + "postbuild": "cp src/graphiql-explorer.d.ts dist/graphiql-explorer.d.ts", + "prebuild": "yarn types:check", + "types:check": "tsc --noEmit" }, "dependencies": { "graphiql-explorer": "^0.9.0" }, "peerDependencies": { - "@graphiql/react": "^0.29.0", - "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0", + "@graphiql/react": "^1.0.0-alpha.0", + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0-alpha.2", "react": "^18 || ^19", "react-dom": "^18 || ^19" }, "devDependencies": { - "@graphiql/react": "^0.29.0", + "@graphiql/react": "^1.0.0-alpha.3", "@vitejs/plugin-react": "^4.4.1", "graphql": "^16.9.0", "react": "^19.1.0", "react-dom": "^19.1.0", "typescript": "^4.6.3", "vite": "^6.3.3", - "vite-plugin-svgr": "^4.3.0" + "vite-plugin-svgr": "^4.3.0", + "vite-plugin-dts": "^4.0.1" } } diff --git a/packages/graphiql-plugin-explorer/resources/copy-types.mjs b/packages/graphiql-plugin-explorer/resources/copy-types.mjs deleted file mode 100644 index 8f6175f68c7..00000000000 --- a/packages/graphiql-plugin-explorer/resources/copy-types.mjs +++ /dev/null @@ -1,11 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import { fileURLToPath } from 'url'; - -const __filename = fileURLToPath(import.meta.url); -const base = path.resolve(path.dirname(__filename), '..'); - -fs.copyFileSync( - path.resolve(base, 'src', 'graphiql-explorer.d.ts'), - path.resolve(base, 'types', 'graphiql-explorer.d.ts'), -); diff --git a/packages/graphiql-plugin-explorer/src/icons/folder-plus.svg b/packages/graphiql-plugin-explorer/src/icons/folder-plus.svg index d6714651b81..0e5550c87d8 100644 --- a/packages/graphiql-plugin-explorer/src/icons/folder-plus.svg +++ b/packages/graphiql-plugin-explorer/src/icons/folder-plus.svg @@ -13,8 +13,6 @@ /> div { + overflow: auto !important; /* override overflow: scroll */ +} + .graphiql-explorer-root input { background: unset; } @@ -44,16 +48,23 @@ padding: var(--px-4) var(--px-6); } -.graphiql-operation-title-bar .toolbar-button { - line-height: 0; - margin-left: var(--px-8); - color: hsla(var(--color-neutral), var(--alpha-secondary, 0.6)); - font-size: var(--font-size-h3); - vertical-align: middle; +.toolbar-button { + all: unset; + cursor: pointer; + line-height: 0 !important; + margin-left: var(--px-6); + color: hsl(var(--color-primary)); + font-size: var(--font-size-h3) !important; +} + +.graphiql-explorer-slug .toolbar-button, +.graphiql-explorer-graphql-arguments .toolbar-button { + font-size: inherit !important; } .graphiql-explorer-graphql-arguments input { line-height: 0; + min-width: 2rem; } .graphiql-explorer-actions { diff --git a/packages/graphiql-plugin-explorer/tsconfig.json b/packages/graphiql-plugin-explorer/tsconfig.json index 8ad4d4a311c..2dd9b41294b 100644 --- a/packages/graphiql-plugin-explorer/tsconfig.json +++ b/packages/graphiql-plugin-explorer/tsconfig.json @@ -14,9 +14,6 @@ "resolveJsonModule": true, "isolatedModules": true, "declaration": true, - "declarationDir": "types", "jsx": "react" - }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] + } } diff --git a/packages/graphiql-plugin-explorer/tsconfig.node.json b/packages/graphiql-plugin-explorer/tsconfig.node.json deleted file mode 100644 index 9d31e2aed93..00000000000 --- a/packages/graphiql-plugin-explorer/tsconfig.node.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "module": "ESNext", - "moduleResolution": "Node", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/packages/graphiql-plugin-explorer/vite.config.mts b/packages/graphiql-plugin-explorer/vite.config.mts index f636de5fade..aa65e0ba7f0 100644 --- a/packages/graphiql-plugin-explorer/vite.config.mts +++ b/packages/graphiql-plugin-explorer/vite.config.mts @@ -1,6 +1,7 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import svgr from 'vite-plugin-svgr'; +import dts from 'vite-plugin-dts'; import packageJSON from './package.json'; const IS_UMD = process.env.UMD === 'true'; @@ -9,17 +10,19 @@ export default defineConfig({ plugins: [ react({ jsxRuntime: 'classic' }), svgr({ - exportAsDefault: true, svgrOptions: { titleProp: true, }, }), + !IS_UMD && [dts({ include: ['src/**'] })], ], css: { transformer: 'lightningcss', }, build: { - minify: IS_UMD ? 'esbuild' : false, + minify: IS_UMD + ? 'terser' // produce better bundle size than esbuild + : false, // avoid clean cjs/es builds emptyOutDir: !IS_UMD, lib: { diff --git a/packages/graphiql-react/CHANGELOG.md b/packages/graphiql-react/CHANGELOG.md index f7042df3357..d0b32d05b1f 100644 --- a/packages/graphiql-react/CHANGELOG.md +++ b/packages/graphiql-react/CHANGELOG.md @@ -1,5 +1,61 @@ # @graphiql/react +## 1.0.0-alpha.4 + +### Minor Changes + +- [#3733](https://github.com/graphql/graphiql/pull/3733) [`8dbddb5`](https://github.com/graphql/graphiql/commit/8dbddb50273720d76f895af6b783b04204c68e03) Thanks [@dimaMachina](https://github.com/dimaMachina)! - Add support for `onPrettifyQuery` callback to enable customised query formatting + +## 1.0.0-alpha.3 + +### Patch Changes + +- [#3414](https://github.com/graphql/graphiql/pull/3414) [`f8b719f`](https://github.com/graphql/graphiql/commit/f8b719f215a79038d1b2a54ddfef461fd849a912) Thanks [@leonardehrenfried](https://github.com/leonardehrenfried)! - Respect Markdown format: ignore single newline + +- [#3730](https://github.com/graphql/graphiql/pull/3730) [`360a038`](https://github.com/graphql/graphiql/commit/360a0385d4ef0105beb8e76044a78f5cd43c9448) Thanks [@dimaMachina](https://github.com/dimaMachina)! - rollback `position: absolute` style for `.graphiql-logo` because tabs will behind logo + +## 1.0.0-alpha.2 + +### Patch Changes + +- [#3720](https://github.com/graphql/graphiql/pull/3720) [`79f3abf`](https://github.com/graphql/graphiql/commit/79f3abf9b697c448442e32eb5a21b7ff720bc242) Thanks [@dimaMachina](https://github.com/dimaMachina)! - replace `overflow-y: scroll` with `overflow-y: auto` + +## 1.0.0-alpha.1 + +### Minor Changes + +- [#3717](https://github.com/graphql/graphiql/pull/3717) [`bf0c4e7`](https://github.com/graphql/graphiql/commit/bf0c4e7236f4a68448063aa0c6a4ed439e869a9f) Thanks [@dimaMachina](https://github.com/dimaMachina)! - remove `createComponentGroup` utility in favour `Object.assign` + +## 1.0.0-alpha.0 + +### Major Changes + +- [#3709](https://github.com/graphql/graphiql/pull/3709) [`9baf1f0`](https://github.com/graphql/graphiql/commit/9baf1f0fc9f32404fbb8bf57b3d1c2c2c8778ddb) Thanks [@dimaMachina](https://github.com/dimaMachina)! - `style.css` import was changed + + ## Migration + + ```diff + -import '@graphiql/react/dist/style.css'; + +import '@graphiql/react/style.css'; + ``` + +### Minor Changes + +- [#3702](https://github.com/graphql/graphiql/pull/3702) [`00415d2`](https://github.com/graphql/graphiql/commit/00415d2940c4d76a4a9e683e9fa0504ba97dd627) Thanks [@dimaMachina](https://github.com/dimaMachina)! - generate types with `vite-plugin-dts` + +- [#3644](https://github.com/graphql/graphiql/pull/3644) [`3c1a345`](https://github.com/graphql/graphiql/commit/3c1a345acd9bf07b45bc230009cb57c51c425673) Thanks [@dimaMachina](https://github.com/dimaMachina)! - - new looks of tabs + + - fix `disableTabs` when `Add tab` button is still shown + +### Patch Changes + +- [#3705](https://github.com/graphql/graphiql/pull/3705) [`8ff87d7`](https://github.com/graphql/graphiql/commit/8ff87d7b6b3d5d12b539612a39ca3abf7e631106) Thanks [@dimaMachina](https://github.com/dimaMachina)! - use `vite build --watch` instead of `vite` for `dev` script because we don't need development server for them + + do not use `vite-plugin-dts` when generating umd build + +- [#3692](https://github.com/graphql/graphiql/pull/3692) [`82bc961`](https://github.com/graphql/graphiql/commit/82bc961a33c4e9da29dffb4a603035a4909f49ad) Thanks [@dimaMachina](https://github.com/dimaMachina)! - - prefer `location` over `window.location` + - prefer `navigator` over `window.navigator` + ## 0.29.0 ### Minor Changes diff --git a/packages/graphiql-react/README.md b/packages/graphiql-react/README.md index 54ac1e2615e..77b90db13c2 100644 --- a/packages/graphiql-react/README.md +++ b/packages/graphiql-react/README.md @@ -61,7 +61,7 @@ function MyGraphQLIDE() { ``` The package also ships the necessary CSS that all its UI components need. You -can import them from `@graphiql/react/dist/style.css`. +can import them from `@graphiql/react/style.css`. > **Note**: In order for these styles to apply, the UI components need to be > rendered inside an element that has a class name `graphiql-container`. diff --git a/packages/graphiql-react/package.json b/packages/graphiql-react/package.json index 6a9c28077cb..c49cb0d5b73 100644 --- a/packages/graphiql-react/package.json +++ b/packages/graphiql-react/package.json @@ -1,9 +1,7 @@ { "name": "@graphiql/react", - "version": "0.29.0", - "sideEffects": [ - "*.css" - ], + "version": "1.0.0-alpha.4", + "sideEffects": false, "repository": { "type": "git", "url": "https://github.com/graphql/graphiql", @@ -16,13 +14,12 @@ "license": "MIT", "exports": { "./package.json": "./package.json", + "./style.css": "./dist/style.css", + "./font/*": "./font/*", ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" - }, - "./font/roboto.css": "./font/roboto.css", - "./font/fira-code.css": "./font/fira-code.css", - "./dist/style.css": "./dist/style.css" + } }, "types": "dist/index.d.ts", "keywords": [ diff --git a/packages/graphiql-react/src/editor/common.ts b/packages/graphiql-react/src/editor/common.ts index a4ea9fd2bbc..7b5673c4306 100644 --- a/packages/graphiql-react/src/editor/common.ts +++ b/packages/graphiql-react/src/editor/common.ts @@ -27,10 +27,10 @@ export async function importCodeMirror( addons: Promise[], options?: { useCommonAddons?: boolean }, ) { - const CodeMirror = await import('codemirror').then(c => + const CodeMirror = await import('codemirror').then(mod => // Depending on bundler and settings the dynamic import either returns a // function (e.g., parcel) or an object containing a `default` property - typeof c === 'function' ? c : c.default, + typeof mod === 'function' ? mod : mod.default, ); await Promise.all( options?.useCommonAddons === false diff --git a/packages/graphiql-react/src/editor/components/image-preview.tsx b/packages/graphiql-react/src/editor/components/image-preview.tsx index 4a2b65dfc16..f21f6aa5ef5 100644 --- a/packages/graphiql-react/src/editor/components/image-preview.tsx +++ b/packages/graphiql-react/src/editor/components/image-preview.tsx @@ -76,11 +76,8 @@ function tokenToURL(token: Token) { const value = token.string.slice(1).slice(0, -1).trim(); try { - const { location } = window; return new URL(value, location.protocol + '//' + location.host); - } catch { - return; - } + } catch {} } function isImageURL(url: URL) { diff --git a/packages/graphiql-react/src/editor/hooks.ts b/packages/graphiql-react/src/editor/hooks.ts index 2292c7db615..52c1f68b27d 100644 --- a/packages/graphiql-react/src/editor/hooks.ts +++ b/packages/graphiql-react/src/editor/hooks.ts @@ -1,4 +1,9 @@ -import { fillLeafs, GetDefaultFieldNamesFn, mergeAst } from '@graphiql/toolkit'; +import { + fillLeafs, + GetDefaultFieldNamesFn, + mergeAst, + MaybePromise, +} from '@graphiql/toolkit'; import type { EditorChange, EditorConfiguration } from 'codemirror'; import type { SchemaReference } from 'codemirror-graphql/utils/SchemaReference'; import copyToClipboard from 'copy-to-clipboard'; @@ -32,9 +37,7 @@ export function useSynchronizeOption( value: EditorConfiguration[K], ) { useEffect(() => { - if (editor) { - editor.setOption(option, value); - } + editor?.setOption(option, value); }, [editor, option, value]); } @@ -214,19 +217,36 @@ export function useMergeQuery({ caller }: UseMergeQueryArgs = {}) { }; } -type UsePrettifyEditorsArgs = { +export type UsePrettifyEditorsArgs = { /** * This is only meant to be used internally in `@graphiql/react`. */ caller?: Function; + /** + * Invoked when the prettify callback is invoked. + * @param query The current value of the query editor. + * @default + * import { parse, print } from 'graphql' + * + * (query) => print(parse(query)) + * @returns The formatted query. + */ + onPrettifyQuery?: (query: string) => MaybePromise; }; -export function usePrettifyEditors({ caller }: UsePrettifyEditorsArgs = {}) { +function DEFAULT_PRETTIFY_QUERY(query: string): string { + return print(parse(query)); +} + +export function usePrettifyEditors({ + caller, + onPrettifyQuery = DEFAULT_PRETTIFY_QUERY, +}: UsePrettifyEditorsArgs = {}) { const { queryEditor, headerEditor, variableEditor } = useEditorContext({ nonNull: true, caller: caller || _usePrettifyEditors, }); - return () => { + return async () => { if (variableEditor) { const variableEditorContent = variableEditor.getValue(); try { @@ -262,10 +282,13 @@ export function usePrettifyEditors({ caller }: UsePrettifyEditorsArgs = {}) { if (queryEditor) { const editorContent = queryEditor.getValue(); - const prettifiedEditorContent = print(parse(editorContent)); - - if (prettifiedEditorContent !== editorContent) { - queryEditor.setValue(prettifiedEditorContent); + try { + const prettifiedEditorContent = await onPrettifyQuery(editorContent); + if (prettifiedEditorContent !== editorContent) { + queryEditor.setValue(prettifiedEditorContent); + } + } catch { + /* Parsing query failed, skip prettification */ } } }; @@ -344,12 +367,10 @@ export function useAutoCompleteLeafs({ } // https://react.dev/learn/you-might-not-need-an-effect - export const useEditorState = (editor: 'query' | 'variable' | 'header') => { - 'use no memo'; // eslint-disable-line react-hooks/react-compiler -- TODO: check why query builder update only 1st field https://github.com/graphql/graphiql/issues/3836 - const context = useEditorContext({ - nonNull: true, - }); + // eslint-disable-next-line react-hooks/react-compiler -- TODO: check why query builder update only 1st field https://github.com/graphql/graphiql/issues/3836 + 'use no memo'; + const context = useEditorContext({ nonNull: true }); const editorInstance = context[`${editor}Editor` as const]; let valueString = ''; diff --git a/packages/graphiql-react/src/editor/query-editor.ts b/packages/graphiql-react/src/editor/query-editor.ts index 97f056d6a1f..1e3d97cc1ff 100644 --- a/packages/graphiql-react/src/editor/query-editor.ts +++ b/packages/graphiql-react/src/editor/query-editor.ts @@ -34,6 +34,7 @@ import { useCompletion, useCopyQuery, UseCopyQueryArgs, + UsePrettifyEditorsArgs, useKeyMap, useMergeQuery, usePrettifyEditors, @@ -47,7 +48,8 @@ import { import { normalizeWhitespace } from './whitespace'; export type UseQueryEditorArgs = WriteableEditorProps & - Pick & { + Pick & + Pick & { /** * Invoked when a reference to the GraphQL schema (type or field) is clicked * as part of the editor or one of its tooltips. @@ -120,6 +122,7 @@ export function useQueryEditor( onClickReference, onCopyQuery, onEdit, + onPrettifyQuery, readOnly = false, }: UseQueryEditorArgs = {}, caller?: Function, @@ -147,7 +150,10 @@ export function useQueryEditor( const plugin = usePluginContext(); const copy = useCopyQuery({ caller: caller || _useQueryEditor, onCopyQuery }); const merge = useMergeQuery({ caller: caller || _useQueryEditor }); - const prettify = usePrettifyEditors({ caller: caller || _useQueryEditor }); + const prettify = usePrettifyEditors({ + caller: caller || _useQueryEditor, + onPrettifyQuery, + }); const ref = useRef(null); const codeMirrorRef = useRef(undefined); diff --git a/packages/graphiql-react/src/markdown.ts b/packages/graphiql-react/src/markdown.ts index e8d24628cff..c1fe6a36465 100644 --- a/packages/graphiql-react/src/markdown.ts +++ b/packages/graphiql-react/src/markdown.ts @@ -3,6 +3,8 @@ import MarkdownIt from 'markdown-it'; export const markdown = new MarkdownIt({ - breaks: true, + // we don't want to convert \n to
because in markdown a single newline is not a line break + // https://github.com/graphql/graphiql/issues/3155 + breaks: false, linkify: true, }); diff --git a/packages/graphiql-react/src/style/root.css b/packages/graphiql-react/src/style/root.css index 5f18fa336c6..8c8dbcfa09f 100644 --- a/packages/graphiql-react/src/style/root.css +++ b/packages/graphiql-react/src/style/root.css @@ -68,7 +68,7 @@ /* Layout */ --sidebar-width: 60px; --toolbar-width: 40px; - --session-header-height: 51px; + --session-header-height: 38.5px; } @media (prefers-color-scheme: dark) { diff --git a/packages/graphiql-react/src/toolbar/menu.tsx b/packages/graphiql-react/src/toolbar/menu.tsx index 1874679cbfc..7f8a6a9d154 100644 --- a/packages/graphiql-react/src/toolbar/menu.tsx +++ b/packages/graphiql-react/src/toolbar/menu.tsx @@ -1,7 +1,6 @@ import { ReactNode } from 'react'; import { clsx } from 'clsx'; import { DropdownMenu, Tooltip } from '../ui'; -import { createComponentGroup } from '../utility/component-group'; import './menu.css'; import { DropdownMenuProps } from '@radix-ui/react-dropdown-menu'; @@ -38,6 +37,6 @@ const ToolbarMenuRoot = ({ ); }; -export const ToolbarMenu = createComponentGroup(ToolbarMenuRoot, { +export const ToolbarMenu = Object.assign(ToolbarMenuRoot, { Item: DropdownMenu.Item, }); diff --git a/packages/graphiql-react/src/ui/dialog.tsx b/packages/graphiql-react/src/ui/dialog.tsx index 50c54bdb0c4..7ec068fe0cb 100644 --- a/packages/graphiql-react/src/ui/dialog.tsx +++ b/packages/graphiql-react/src/ui/dialog.tsx @@ -1,7 +1,6 @@ import { clsx } from 'clsx'; import { forwardRef, ReactElement, JSX } from 'react'; import { CloseIcon } from '../icons'; -import { createComponentGroup } from '../utility/component-group'; import { UnStyledButton } from './button'; import * as D from '@radix-ui/react-dialog'; import { Root as VisuallyHidden } from '@radix-ui/react-visually-hidden'; @@ -40,7 +39,7 @@ export function DialogRoot({ ); } -export const Dialog = createComponentGroup(DialogRoot, { +export const Dialog = Object.assign(DialogRoot, { Close: DialogClose, Title: D.Title, Trigger: D.Trigger, diff --git a/packages/graphiql-react/src/ui/dropdown.css b/packages/graphiql-react/src/ui/dropdown.css index 5f7b9186ee2..09f4c57524e 100644 --- a/packages/graphiql-react/src/ui/dropdown.css +++ b/packages/graphiql-react/src/ui/dropdown.css @@ -12,7 +12,7 @@ calc(var(--radix-dropdown-menu-content-available-height) - 10px), 400px ); - overflow-y: scroll; + overflow-y: auto; } .graphiql-dropdown-item { diff --git a/packages/graphiql-react/src/ui/dropdown.tsx b/packages/graphiql-react/src/ui/dropdown.tsx index 5009c102da4..4d39e706fbc 100644 --- a/packages/graphiql-react/src/ui/dropdown.tsx +++ b/packages/graphiql-react/src/ui/dropdown.tsx @@ -1,6 +1,5 @@ import { ComponentProps, forwardRef, ReactElement } from 'react'; import { clsx } from 'clsx'; -import { createComponentGroup } from '../utility/component-group'; import { Trigger, Portal, @@ -53,7 +52,7 @@ const Item = ({ className, children, ...props }: DropdownMenuItemProps) => ( ); -export const DropdownMenu = createComponentGroup(Root, { +export const DropdownMenu = Object.assign(Root, { Button, Item, Content, diff --git a/packages/graphiql-react/src/ui/tabs.css b/packages/graphiql-react/src/ui/tabs.css index d3ddb46e7e8..66cd5b73361 100644 --- a/packages/graphiql-react/src/ui/tabs.css +++ b/packages/graphiql-react/src/ui/tabs.css @@ -1,46 +1,84 @@ .graphiql-tabs { + --bg: hsl(var(--color-base)); + display: flex; align-items: center; - overflow-x: auto; - padding: var(--px-12); + gap: var(--px-8); + /* reset browser defaults */ + padding: 0; + margin: 0; + list-style: none; +} - & > :not(:first-child) { - margin-left: var(--px-12); - } +/* trick to shrink multiple tabs, instead of overflow container */ +.graphiql-tabs, +.graphiql-tab { + min-width: 0; } .graphiql-tab { - align-items: stretch; - border-radius: var(--border-radius-8); - color: hsla(var(--color-neutral), var(--alpha-secondary)); + border-radius: var(--border-radius-8) var(--border-radius-8) 0 0; + background: hsla(var(--color-neutral), var(--alpha-background-light)); + position: relative; display: flex; + max-width: 140px; - & > button.graphiql-tab-close { - visibility: hidden; - } - &.graphiql-tab-active > button.graphiql-tab-close, - &:hover > button.graphiql-tab-close, - &:focus-within > button.graphiql-tab-close { - visibility: unset; + /* disable shrinking while changing the operation name */ + &:not(:focus-within) { + transform: none !important; } + &:hover, + &:focus-within, &.graphiql-tab-active { - background-color: hsla(var(--color-neutral), var(--alpha-background-heavy)); - color: hsla(var(--color-neutral), 1); + background: var(--bg); + color: hsl(var(--color-neutral)); + + .graphiql-tab-close { + display: block; + } } -} -button.graphiql-tab-button { - padding: var(--px-4) 0 var(--px-4) var(--px-8); -} + .graphiql-tab-button { + border-radius: var(--border-radius-8) var(--border-radius-8) 0 0; + overflow: hidden; + text-overflow: ellipsis; + padding: var(--px-4) 28px var(--px-4) var(--px-8); -button.graphiql-tab-close { - align-items: center; - display: flex; - padding: var(--px-4) var(--px-8); + &:hover { + background: none; + } + } + + .graphiql-tab-close { + position: absolute; + right: min(var(--px-4), 5%); + top: 50%; + transform: translateY(-50%); + display: none; + background: var(--bg); + box-shadow: -10px 0 10px 0 var(--bg); + padding: var(--px-6); + line-height: 0; + + & > svg { + height: var(--px-8); + width: var(--px-8); + } + + &:hover { + background: var(--bg); + color: hsl(var(--color-neutral)); + overflow: hidden; /* bg in `:before` will not overflow from radius area */ - & > svg { - height: var(--px-8); - width: var(--px-8); + /* trick to add 2nd bg with opacity */ + &:before { + content: ''; + position: absolute; + inset: 0; + z-index: -1; + background: hsla(var(--color-neutral), 0.3); + } + } } } diff --git a/packages/graphiql-react/src/ui/tabs.tsx b/packages/graphiql-react/src/ui/tabs.tsx index a0a2c7dd920..331c0f5fa61 100644 --- a/packages/graphiql-react/src/ui/tabs.tsx +++ b/packages/graphiql-react/src/ui/tabs.tsx @@ -2,9 +2,7 @@ import { forwardRef, ReactNode, JSX } from 'react'; import { clsx } from 'clsx'; import { Reorder } from 'framer-motion'; import { CloseIcon } from '../icons'; -import { createComponentGroup } from '../utility/component-group'; import { UnStyledButton } from './button'; -import { Tooltip } from './tooltip'; import './tabs.css'; @@ -21,7 +19,7 @@ const TabRoot = forwardRef( {...props} ref={ref} value={value} - aria-selected={isActive ? 'true' : undefined} + aria-selected={isActive} role="tab" className={clsx( 'graphiql-tab', @@ -38,36 +36,34 @@ TabRoot.displayName = 'Tab'; const TabButton = forwardRef< HTMLButtonElement, JSX.IntrinsicElements['button'] ->((props, ref) => ( +>(({ children, className, ...props }, ref) => ( - {props.children} + {children} )); TabButton.displayName = 'Tab.Button'; const TabClose = forwardRef( (props, ref) => ( - - - - - + + + ), ); TabClose.displayName = 'Tab.Close'; -export const Tab = createComponentGroup(TabRoot, { +export const Tab = Object.assign(TabRoot, { Button: TabButton, Close: TabClose, }); diff --git a/packages/graphiql-react/src/ui/tooltip.tsx b/packages/graphiql-react/src/ui/tooltip.tsx index 6284780c580..125d7c10db6 100644 --- a/packages/graphiql-react/src/ui/tooltip.tsx +++ b/packages/graphiql-react/src/ui/tooltip.tsx @@ -1,6 +1,5 @@ import { FC, ReactNode } from 'react'; import * as T from '@radix-ui/react-tooltip'; -import { createComponentGroup } from '../utility/component-group'; import './tooltip.css'; export const TooltipRoot: FC = ({ @@ -27,6 +26,6 @@ export const TooltipRoot: FC = ({ ); }; -export const Tooltip = createComponentGroup(TooltipRoot, { +export const Tooltip = Object.assign(TooltipRoot, { Provider: T.Provider, }); diff --git a/packages/graphiql-react/src/utility/component-group.ts b/packages/graphiql-react/src/utility/component-group.ts deleted file mode 100644 index 71e67ac3c32..00000000000 --- a/packages/graphiql-react/src/utility/component-group.ts +++ /dev/null @@ -1,15 +0,0 @@ -'use no memo'; - -import { JSXElementConstructor } from 'react'; - -export const createComponentGroup = < - Root extends JSXElementConstructor, - Children extends { [key: string]: JSXElementConstructor }, ->( - root: Root, - children: Children, -): Root & Children => - Object.entries(children).reduce((r, [key, value]) => { - r[key] = value; - return r; - }, root); diff --git a/packages/graphiql-react/tsconfig.json b/packages/graphiql-react/tsconfig.json index 3d58136542f..d1c216fef77 100644 --- a/packages/graphiql-react/tsconfig.json +++ b/packages/graphiql-react/tsconfig.json @@ -15,7 +15,6 @@ "isolatedModules": true, "jsx": "react-jsx", "declaration": true, - "declarationDir": "types", "types": ["vitest/globals", "@testing-library/jest-dom"] } } diff --git a/packages/graphiql/CHANGELOG.md b/packages/graphiql/CHANGELOG.md index 02fc07ad16c..978db1997f6 100644 --- a/packages/graphiql/CHANGELOG.md +++ b/packages/graphiql/CHANGELOG.md @@ -1,5 +1,192 @@ # Change Log +## 4.0.0-alpha.5 + +### Minor Changes + +- [#3733](https://github.com/graphql/graphiql/pull/3733) [`8dbddb5`](https://github.com/graphql/graphiql/commit/8dbddb50273720d76f895af6b783b04204c68e03) Thanks [@dimaMachina](https://github.com/dimaMachina)! - Add support for `onPrettifyQuery` callback to enable customised query formatting + +### Patch Changes + +- Updated dependencies [[`8dbddb5`](https://github.com/graphql/graphiql/commit/8dbddb50273720d76f895af6b783b04204c68e03)]: + - @graphiql/react@1.0.0-alpha.4 + +## 4.0.0-alpha.4 + +### Minor Changes + +- [#3728](https://github.com/graphql/graphiql/pull/3728) [`a1a5208`](https://github.com/graphql/graphiql/commit/a1a5208aeebe4ff622e83cd355f8b4e9b7fa011c) Thanks [@dimaMachina](https://github.com/dimaMachina)! - remove `.graphiql-session` class + +### Patch Changes + +- [#3414](https://github.com/graphql/graphiql/pull/3414) [`f8b719f`](https://github.com/graphql/graphiql/commit/f8b719f215a79038d1b2a54ddfef461fd849a912) Thanks [@leonardehrenfried](https://github.com/leonardehrenfried)! - Respect Markdown format: ignore single newline + +- [#3730](https://github.com/graphql/graphiql/pull/3730) [`360a038`](https://github.com/graphql/graphiql/commit/360a0385d4ef0105beb8e76044a78f5cd43c9448) Thanks [@dimaMachina](https://github.com/dimaMachina)! - rollback `position: absolute` style for `.graphiql-logo` because tabs will behind logo + +- [#3726](https://github.com/graphql/graphiql/pull/3726) [`196e9a0`](https://github.com/graphql/graphiql/commit/196e9a081ffc0df16a5537c8ec0fb622fc3ba0b0) Thanks [@dimaMachina](https://github.com/dimaMachina)! - use `right: var(--px-16)` instead of `right: 0` for `.graphiql-logo` + +- Updated dependencies [[`f8b719f`](https://github.com/graphql/graphiql/commit/f8b719f215a79038d1b2a54ddfef461fd849a912), [`360a038`](https://github.com/graphql/graphiql/commit/360a0385d4ef0105beb8e76044a78f5cd43c9448)]: + - @graphiql/react@1.0.0-alpha.3 + +## 4.0.0-alpha.3 + +### Patch Changes + +- [#3720](https://github.com/graphql/graphiql/pull/3720) [`79f3abf`](https://github.com/graphql/graphiql/commit/79f3abf9b697c448442e32eb5a21b7ff720bc242) Thanks [@dimaMachina](https://github.com/dimaMachina)! - replace `overflow-y: scroll` with `overflow-y: auto` + +- [#3720](https://github.com/graphql/graphiql/pull/3720) [`79f3abf`](https://github.com/graphql/graphiql/commit/79f3abf9b697c448442e32eb5a21b7ff720bc242) Thanks [@dimaMachina](https://github.com/dimaMachina)! - replace `Tooltip`s in tabs with html `title="..."` attribute + +- Updated dependencies [[`79f3abf`](https://github.com/graphql/graphiql/commit/79f3abf9b697c448442e32eb5a21b7ff720bc242)]: + - @graphiql/react@1.0.0-alpha.2 + +## 4.0.0-alpha.2 + +### Patch Changes + +- [#3716](https://github.com/graphql/graphiql/pull/3716) [`cc2808f`](https://github.com/graphql/graphiql/commit/cc2808f9b0d9ac0f98603299ec67e2a659cbfcd7) Thanks [@dimaMachina](https://github.com/dimaMachina)! - use `position: absolute` for `.graphiql-logo` class + +- Updated dependencies [[`bf0c4e7`](https://github.com/graphql/graphiql/commit/bf0c4e7236f4a68448063aa0c6a4ed439e869a9f)]: + - @graphiql/react@1.0.0-alpha.1 + +## 4.0.0-alpha.1 + +### Major Changes + +- [#3713](https://github.com/graphql/graphiql/pull/3713) [`27bbc51`](https://github.com/graphql/graphiql/commit/27bbc51a69504ffa9c6efbb17f112668f38fe52d) Thanks [@dimaMachina](https://github.com/dimaMachina)! - show tabs even there is only 1 tab + +- [#3707](https://github.com/graphql/graphiql/pull/3707) [`3c901c1`](https://github.com/graphql/graphiql/commit/3c901c104123750f45bcd64ade5b0ab9706d3146) Thanks [@dimaMachina](https://github.com/dimaMachina)! - Remove `toolbar.additionalContent` and `toolbar.additionalComponent` props in favor of `GraphiQL.Toolbar` render props. + + ## Migration from `toolbar.additionalContent` + + #### Before + + ```jsx + My button }} /> + ``` + + #### After + + ```jsx + + + {({ merge, prettify, copy }) => ( + <> + {prettify} + {merge} + {copy} + + + )} + + + ``` + + ### Migration from `toolbar.additionalComponent` + + #### Before + + ```jsx + My button; + }, + }} + /> + ``` + + #### After + + ```jsx + + + {({ merge, prettify, copy }) => ( + <> + {prettify} + {merge} + {copy} + + + )} + + + ``` + + *** + + Additionally, you can sort default toolbar buttons in different order or remove unneeded buttons for you: + + ```jsx + + + {({ prettify, copy }) => ( + <> + {copy /* Copy button will be first instead of default last */} + {/* Merge button is removed from toolbar */} + {prettify} + + )} + + + ``` + +## 4.0.0-alpha.0 + +### Major Changes + +- [#3706](https://github.com/graphql/graphiql/pull/3706) [`343dd59`](https://github.com/graphql/graphiql/commit/343dd599ee10b0670cd7ab4dfaa65344f0d48c84) Thanks [@dimaMachina](https://github.com/dimaMachina)! - remove default export + + ## Migration + + ### Before + + ```jsx + import GraphiQL from 'graphiql'; + ``` + + ### After + + ```jsx + import { GraphiQL } from 'graphiql'; + ``` + +- [#3687](https://github.com/graphql/graphiql/pull/3687) [`09e7004`](https://github.com/graphql/graphiql/commit/09e700403beb6c7290d165df33a2455ac2196971) Thanks [@dimaMachina](https://github.com/dimaMachina)! - remove `disableTabs` option + +- [#3688](https://github.com/graphql/graphiql/pull/3688) [`0fdd9b9`](https://github.com/graphql/graphiql/commit/0fdd9b9f32513d96281f577a5d9bd2fefb5f05d4) Thanks [@dimaMachina](https://github.com/dimaMachina)! - remove `data-testid="graphiql-container"` + +- [#3679](https://github.com/graphql/graphiql/pull/3679) [`5d90e0e`](https://github.com/graphql/graphiql/commit/5d90e0eed58214c5926e6e0edb196971b15b1121) Thanks [@dimaMachina](https://github.com/dimaMachina)! - migrate from `webpack` to `vite` + + changed exports + + ```diff + -graphiql/graphiql.css + +graphiql/style.css + ``` + + changed cdn paths, `dist/index.umd.js` and `dist/style.css` are minified + + ```diff + -https://unpkg.com/graphiql/graphiql.js + -https://unpkg.com/graphiql/graphiql.min.js + +https://unpkg.com/graphiql/dist/index.umd.js + -https://unpkg.com/graphiql/graphiql.css + -https://unpkg.com/graphiql/graphiql.min.css + +https://unpkg.com/graphiql/dist/style.css + ``` + +- [#3644](https://github.com/graphql/graphiql/pull/3644) [`3c1a345`](https://github.com/graphql/graphiql/commit/3c1a345acd9bf07b45bc230009cb57c51c425673) Thanks [@dimaMachina](https://github.com/dimaMachina)! - - new looks of tabs + + - fix `disableTabs` when `Add tab` button is still shown + +### Patch Changes + +- [#3683](https://github.com/graphql/graphiql/pull/3683) [`8efb873`](https://github.com/graphql/graphiql/commit/8efb873458489ce3497d917bcafd4ad8dfcbe6c8) Thanks [@dimaMachina](https://github.com/dimaMachina)! - update graphql to `16.9.0` and use vite `define` configuration to remove development code from cdn bundle + +- [#3692](https://github.com/graphql/graphiql/pull/3692) [`82bc961`](https://github.com/graphql/graphiql/commit/82bc961a33c4e9da29dffb4a603035a4909f49ad) Thanks [@dimaMachina](https://github.com/dimaMachina)! - - prefer `location` over `window.location` + - prefer `navigator` over `window.navigator` +- Updated dependencies [[`00415d2`](https://github.com/graphql/graphiql/commit/00415d2940c4d76a4a9e683e9fa0504ba97dd627), [`9baf1f0`](https://github.com/graphql/graphiql/commit/9baf1f0fc9f32404fbb8bf57b3d1c2c2c8778ddb), [`8ff87d7`](https://github.com/graphql/graphiql/commit/8ff87d7b6b3d5d12b539612a39ca3abf7e631106), [`82bc961`](https://github.com/graphql/graphiql/commit/82bc961a33c4e9da29dffb4a603035a4909f49ad), [`3c1a345`](https://github.com/graphql/graphiql/commit/3c1a345acd9bf07b45bc230009cb57c51c425673)]: + - @graphiql/react@1.0.0-alpha.0 + ## 3.9.0 ### Minor Changes diff --git a/packages/graphiql/cypress/e2e/errors.cy.ts b/packages/graphiql/cypress/e2e/errors.cy.ts index a6613665f19..b46511b3a8d 100644 --- a/packages/graphiql/cypress/e2e/errors.cy.ts +++ b/packages/graphiql/cypress/e2e/errors.cy.ts @@ -39,7 +39,7 @@ describe('Errors', () => { cy.visit('/'); /** * We can't use `cy.assertQueryResult` here because the stack contains line - * and column numbers of the `graphiql.min.js` bundle which are not stable. + * and column numbers of the `index.umd.js` bundle which are not stable. */ cy.get('section.result-window').should(element => { expect(element.get(0).innerText).to.contain( diff --git a/packages/graphiql/cypress/e2e/incremental-delivery.cy.ts b/packages/graphiql/cypress/e2e/incremental-delivery.cy.ts index d10273434b2..00e46ff0312 100644 --- a/packages/graphiql/cypress/e2e/incremental-delivery.cy.ts +++ b/packages/graphiql/cypress/e2e/incremental-delivery.cy.ts @@ -106,7 +106,7 @@ describeOrSkip('IncrementalDelivery support via fetcher', () => { This tests that; 1. user ({name}) => { name } 2. user ({age}) => { name, age } - 3. user.friends.0 ({name}) => { name, age, friends: [{name}] } <- can sometimes happen before 4, due the the promise race + 3. user.friends.0 ({name}) => { name, age, friends: [{name}] } <- can sometimes happen before 4, due to the promise race 4. user.friends.0 ({age}) => { name, age, friends: [{name, age}] } This shows us that we can deep merge defers, deep merge streams, and also deep merge defers inside streams diff --git a/packages/graphiql/cypress/e2e/prettify.cy.ts b/packages/graphiql/cypress/e2e/prettify.cy.ts index 6e2224f28dc..ba8e3e16ada 100644 --- a/packages/graphiql/cypress/e2e/prettify.cy.ts +++ b/packages/graphiql/cypress/e2e/prettify.cy.ts @@ -1,4 +1,5 @@ import { version } from 'graphql'; + let describeOrSkip = describe.skip; // hard to account for the extra \n between 15/16 so these only run for 16 for now @@ -25,6 +26,26 @@ const brokenQuery = 'longDescriptionType {id}}'; const brokenVariables = '"a": 1}'; describeOrSkip('GraphiQL Prettify', () => { + describe('onPrettifyQuery', () => { + const rawQuery = '{ test\n\nid }'; + const resultQuery = '{ test id }'; + + it('should work while click on prettify button', () => { + cy.visit(`/?query=${rawQuery}&onPrettifyQuery=true`); + cy.clickPrettify(); + cy.assertHasValues({ query: resultQuery }); + }); + + it('should work while click on key map short cut', () => { + cy.visit(`/?query=${rawQuery}&onPrettifyQuery=true`); + cy.get('.graphiql-query-editor textarea').type('{shift}{ctrl}P', { + force: true, + }); + cy.get('.graphiql-query-editor textarea').type('{esc}'); + cy.assertHasValues({ query: resultQuery }); + }); + }); + it('Regular prettification', () => { cy.visitWithOp({ query: uglyQuery, variablesString: uglyVariables }); diff --git a/packages/graphiql/cypress/e2e/tabs.cy.ts b/packages/graphiql/cypress/e2e/tabs.cy.ts index 43df5a2db4c..c3dac4a5705 100644 --- a/packages/graphiql/cypress/e2e/tabs.cy.ts +++ b/packages/graphiql/cypress/e2e/tabs.cy.ts @@ -2,8 +2,8 @@ describe('Tabs', () => { it('Should store editor contents when switching between tabs', () => { cy.visit('/?defaultQuery=&query='); - // Assert that no tab visible when there's only one session - cy.get('#graphiql-session-tab-0').should('not.exist'); + // Assert that tab visible when there's only one session + cy.get('.graphiql-tab-button').eq(0).should('exist'); // Enter a query without operation name cy.get('.graphiql-query-editor textarea').type('{id', { force: true }); @@ -18,7 +18,7 @@ describe('Tabs', () => { cy.get('.graphiql-query-editor textarea').type('query Foo {image', { force: true, }); - cy.get('#graphiql-session-tab-1').should('have.text', 'Foo'); + cy.get('.graphiql-tab-button').eq(1).should('have.text', 'Foo'); // Enter variables cy.get('.graphiql-editor-tool textarea') @@ -35,11 +35,11 @@ describe('Tabs', () => { cy.clickExecuteQuery(); // Switch back to the first tab - cy.get('#graphiql-session-tab-0').click(); + cy.get('.graphiql-tab-button').eq(0).click(); // Assert tab titles - cy.get('#graphiql-session-tab-0').should('have.text', ''); - cy.get('#graphiql-session-tab-1').should('have.text', 'Foo'); + cy.get('.graphiql-tab-button').eq(0).should('have.text', ''); + cy.get('.graphiql-tab-button').eq(1).should('have.text', 'Foo'); // Assert editor values cy.assertHasValues({ @@ -50,11 +50,11 @@ describe('Tabs', () => { }); // Switch back to the second tab - cy.get('#graphiql-session-tab-1').click(); + cy.get('.graphiql-tab-button').eq(1).click(); // Assert tab titles - cy.get('#graphiql-session-tab-0').should('have.text', ''); - cy.get('#graphiql-session-tab-1').should('have.text', 'Foo'); + cy.get('.graphiql-tab-button').eq(0).should('have.text', ''); + cy.get('.graphiql-tab-button').eq(1).should('have.text', 'Foo'); // Assert editor values cy.assertHasValues({ @@ -65,10 +65,10 @@ describe('Tabs', () => { }); // Close tab - cy.get('#graphiql-session-tab-1 + .graphiql-tab-close').click(); + cy.get('.graphiql-tab-button + .graphiql-tab-close').eq(1).click(); - // Assert that no tab visible when there's only one session - cy.get('#graphiql-session-tab-0').should('not.exist'); + // Assert that tab close button not visible when there is only 1 tab + cy.get('.graphiql-tab-button + .graphiql-tab-close').should('not.exist'); // Assert editor values cy.assertHasValues({ @@ -99,7 +99,7 @@ describe('Tabs', () => { cy.get('.graphiql-tab-button + .graphiql-tab-close').eq(1).click(); - cy.get('.graphiql-tab-button').should('have.length', 0); + cy.get('.graphiql-tab-button').should('have.length', 1); }); }); }); diff --git a/packages/graphiql/cypress/support/commands.ts b/packages/graphiql/cypress/support/commands.ts index 411033d2fcc..4e34051cab5 100644 --- a/packages/graphiql/cypress/support/commands.ts +++ b/packages/graphiql/cypress/support/commands.ts @@ -1,12 +1,10 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** +/** + * This example commands.ts shows you how to create various custom commands and + * overwrite existing commands. + * + * For more comprehensive examples of custom commands, please read more here: + * https://on.cypress.io/custom-commands + */ /// @@ -26,7 +24,7 @@ declare namespace Cypress { interface Chainable { /** - * Custom command to select DOM element by data-cy attribute. + * Custom command to select a DOM element by `data-cy` attribute. * @example cy.dataCy('greeting') */ dataCy(value: string): Chainable; @@ -56,11 +54,15 @@ Cypress.Commands.add('dataCy', value => { // @ts-expect-error -- fixme Cypress.Commands.add('clickExecuteQuery', () => { + // Check CodeMirror was initialized + cy.get('.graphiql-query-editor .CodeMirror-scroll').should('exist'); return cy.get('.graphiql-execute-button').click(); }); // @ts-expect-error -- fixme Cypress.Commands.add('clickPrettify', () => { + // Check CodeMirror was initialized + cy.get('.graphiql-query-editor .CodeMirror-scroll').should('exist'); return cy.get('[aria-label="Prettify query (Shift-Ctrl-P)"]').click(); }); @@ -139,11 +141,11 @@ function codeWithLineNumbers(code: string): string { .join('\n'); } -function normalize(str: string) { +function normalize(str: string): string { return str.replaceAll('​', ''); } -function normalizeWhitespace(str: string) { +function normalizeWhitespace(str: string): string { return str.replaceAll('\xA0', ' '); } diff --git a/packages/graphiql/package.json b/packages/graphiql/package.json index 9c586302f69..d44ccb16e63 100644 --- a/packages/graphiql/package.json +++ b/packages/graphiql/package.json @@ -1,6 +1,6 @@ { "name": "graphiql", - "version": "3.9.0", + "version": "4.0.0-alpha.5", "sideEffects": false, "description": "An graphical interactive in-browser GraphQL IDE.", "contributors": [ @@ -41,7 +41,7 @@ "prebuild": "yarn types:check", "types:check": "tsc --noEmit", "build": "vite build && UMD=true vite build", - "cypress-open": "yarn dev 'cypress open'", + "cypress-open": "yarn dev 'cypress open --browser electron'", "dev": "concurrently 'cross-env PORT=8080 node test/e2e-server' vite", "e2e": "yarn e2e-server 'cypress run'", "e2e-server": "start-server-and-test 'cross-env PORT=8080 node test/e2e-server' 'http-get://localhost:8080/graphql?query={test { id }}'", @@ -50,7 +50,7 @@ }, "dependencies": { "react-compiler-runtime": "19.1.0-rc.1", - "@graphiql/react": "^0.29.0" + "@graphiql/react": "^1.0.0-alpha.4" }, "peerDependencies": { "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0", @@ -69,8 +69,8 @@ "cross-env": "^7.0.2", "cypress": "^13.13.2", "express": "^4.20.0", - "graphql": "^16.9.0", - "graphql-http": "^1.22.1", + "graphql": "^16.11.0", + "graphql-helix": "^1.13.0", "graphql-subscriptions": "^2.0.0", "react": "^19.1.0", "react-dom": "^19.1.0", diff --git a/packages/graphiql/resources/logo.svg b/packages/graphiql/resources/logo.svg index 43e513e06ca..e50db408fa2 100644 --- a/packages/graphiql/resources/logo.svg +++ b/packages/graphiql/resources/logo.svg @@ -1,27 +1,15 @@ - + + + - - + - + - diff --git a/packages/graphiql/src/GraphiQL.spec.tsx b/packages/graphiql/src/GraphiQL.spec.tsx index eb363ff13a3..5d8f1fd8e38 100644 --- a/packages/graphiql/src/GraphiQL.spec.tsx +++ b/packages/graphiql/src/GraphiQL.spec.tsx @@ -415,13 +415,13 @@ describe('GraphiQL', () => { }); describe('Tabs', () => { - it('show tabs if there are more than one', async () => { + it('show tabs', async () => { const { container } = render(); await waitFor(() => { expect( container.querySelectorAll('.graphiql-tabs .graphiql-tab'), - ).toHaveLength(0); + ).toHaveLength(1); }); act(() => { @@ -497,7 +497,7 @@ describe('GraphiQL', () => { await waitFor(() => { expect( container.querySelectorAll('.graphiql-tabs .graphiql-tab'), - ).toHaveLength(0); + ).toHaveLength(1); expect( container.querySelectorAll('.graphiql-tab .graphiql-tab-close'), ).toHaveLength(0); @@ -604,28 +604,6 @@ describe('GraphiQL', () => { expect(getByText('My Exported Type Logo')).toBeInTheDocument(); }); }); - - it('can be overridden using a named component', async () => { - const WrappedLogo = () => { - return ( -
- My Named Component Logo -
- ); - }; - WrappedLogo.displayName = 'GraphiQLLogo'; - - const { container, getByText } = render( - - - , - ); - - await waitFor(() => { - expect(container.querySelector('.test-wrapper')).toBeInTheDocument(); - expect(getByText('My Named Component Logo')).toBeInTheDocument(); - }); - }); }); describe('GraphiQL.Toolbar', () => { @@ -633,7 +611,7 @@ describe('GraphiQL', () => { const { container } = render( - + {() => } , ); @@ -646,35 +624,6 @@ describe('GraphiQL', () => { ).toHaveLength(1); }); }); - - it('can be overridden using a named component', async () => { - const WrappedToolbar = () => { - return ( -
- - - - , -
- ); - }; - WrappedToolbar.displayName = 'GraphiQLToolbar'; - - const { container } = render( - - - , - ); - - await waitFor(() => { - expect(container.querySelector('.test-wrapper')).toBeInTheDocument(); - expect( - container.querySelectorAll( - '[role="toolbar"] .graphiql-toolbar-button', - ), - ).toHaveLength(1); - }); - }); }); describe('GraphiQL.Footer', () => { @@ -693,33 +642,6 @@ describe('GraphiQL', () => { ).toHaveLength(1); }); }); - - it('can be overridden using a named component', async () => { - const WrappedFooter = () => { - return ( -
- - - - , -
- ); - }; - WrappedFooter.displayName = 'GraphiQLFooter'; - - const { container } = render( - - - , - ); - - await waitFor(() => { - expect(container.querySelector('.test-wrapper')).toBeInTheDocument(); - expect( - container.querySelectorAll('.graphiql-footer button'), - ).toHaveLength(1); - }); - }); }); }); }); diff --git a/packages/graphiql/src/GraphiQL.tsx b/packages/graphiql/src/GraphiQL.tsx index 4927bc94087..8178050c367 100644 --- a/packages/graphiql/src/GraphiQL.tsx +++ b/packages/graphiql/src/GraphiQL.tsx @@ -6,14 +6,20 @@ */ import type { - ComponentType, MouseEventHandler, PropsWithChildren, ReactNode, ReactElement, - JSXElementConstructor, + JSX, +} from 'react'; +import { + Fragment, + useState, + useEffect, + version, + Children, + cloneElement, } from 'react'; -import { Fragment, useState, useEffect, version, Children } from 'react'; import { Button, ButtonGroup, @@ -71,20 +77,6 @@ if (majorVersion < 16) { ); } -export type GraphiQLToolbarConfig = { - /** - * This content will be rendered after the built-in buttons of the toolbar. - * Note that this will not apply if you provide a completely custom toolbar - * (by passing `GraphiQL.Toolbar` as child to the `GraphiQL` component). - */ - additionalContent?: ReactNode; - - /** - * same as above, except a component with access to context - */ - additionalComponent?: JSXElementConstructor; -}; - /** * API docs for this live here: * @@ -135,7 +127,18 @@ export function GraphiQL({ 'The `GraphiQL` component requires a `fetcher` function to be passed as prop.', ); } - + // @ts-expect-error -- Prop is removed + if (props.toolbar?.additionalContent) { + throw new TypeError( + '`toolbar.additionalContent` was removed. Use render props on `GraphiQL.Toolbar` component instead.', + ); + } + // @ts-expect-error -- Prop is removed + if (props.toolbar?.additionalComponent) { + throw new TypeError( + '`toolbar.additionalComponent` was removed. Use render props on `GraphiQL.Toolbar` component instead.', + ); + } return ( @@ -187,7 +189,7 @@ type AddSuffix, Suffix extends string> = { export type GraphiQLInterfaceProps = WriteableEditorProps & AddSuffix, 'Query'> & - Pick & + Pick & AddSuffix, 'Variables'> & AddSuffix, 'Headers'> & Pick & { @@ -207,18 +209,12 @@ export type GraphiQLInterfaceProps = WriteableEditorProps & * @default true */ isHeadersEditorEnabled?: boolean; - /** - * An object that allows configuration of the toolbar next to the query - * editor. - */ - toolbar?: GraphiQLToolbarConfig; /** * Indicates if settings for persisting headers should appear in the * settings modal. */ showPersistHeadersSettings?: boolean; defaultTheme?: Theme; - disableTabs?: boolean; /** * `forcedTheme` allows enforcement of a specific theme for GraphiQL. * This is useful when you want to make sure that GraphiQL is always @@ -254,11 +250,6 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) { props.forcedTheme && THEMES.includes(props.forcedTheme) ? props.forcedTheme : undefined; - - const copy = useCopyQuery({ onCopyQuery: props.onCopyQuery }); - const merge = useMergeQuery(); - const prettify = usePrettifyEditors(); - const { theme, setTheme } = useTheme(props.defaultTheme); useEffect(() => { @@ -332,37 +323,39 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) { 'success' | 'error' | null >(null); - const children = Children.toArray(props.children); - - const logo = children.find(child => - isChildComponentType(child, GraphiQL.Logo), - ) || ; - - const toolbar = children.find(child => - isChildComponentType(child, GraphiQL.Toolbar), - ) || ( - <> - - - - - - - {props.toolbar?.additionalContent} - {props.toolbar?.additionalComponent && ( - - )} - - ); - - const footer = children.find(child => - isChildComponentType(child, GraphiQL.Footer), + const { logo, toolbar, footer } = Children.toArray(props.children).reduce<{ + logo?: ReactNode; + toolbar?: ReactNode; + footer?: ReactNode; + }>( + (acc, curr) => { + switch (getChildComponentType(curr)) { + case GraphiQL.Logo: + acc.logo = curr; + break; + case GraphiQL.Toolbar: + // @ts-expect-error -- fix type error + acc.toolbar = cloneElement(curr, { + onCopyQuery: props.onCopyQuery, + onPrettifyQuery: props.onPrettifyQuery, + }); + break; + case GraphiQL.Footer: + acc.footer = curr; + break; + } + return acc; + }, + { + logo: , + toolbar: ( +