Repository navigation
GraphiQL v6 - #4228
Draft
trevor-scheer wants to merge 206 commits into
Draft
GraphiQL v6#4228trevor-scheer wants to merge 206 commits into
trevor-scheer wants to merge 206 commits into
Conversation
## Summary - Swap the vestigial `graphiql-5` reference in `.github/workflows/release.yml` for `graphiql-6` so the changesets-action runs on pushes to the integration branch. - Enter changesets pre-mode with the `alpha` tag so merges aggregate into `6.0.0-alpha.N` prereleases. - Add a changeset that seeds the alpha release line by bumping `graphiql` to v6. No functional change — subsequent alphas accumulate the redesign work. ## Test plan - [ ] On merge: changesets-action opens a "Version Packages (alpha)" PR bumping `graphiql` to `6.0.0-alpha.0`. - [ ] Merging the version PR publishes `graphiql@6.0.0-alpha.0` to npm with the `alpha` dist-tag. Refs: #4219
🦋 Changeset detectedLatest commit: 93c9f9c The changes in this PR will be included in the next version bump. This PR includes changesets to release 16 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Contributor
|
The latest changes of this PR are not available as canary, since there are no linked |
## Summary - Introduce a new `packages/graphiql-react/src/style/tokens.css` with the v6 OKLCH-based design token system. Both dark and light palettes ship together. - Light theme activates explicitly via `data-theme="light"` or automatically via `prefers-color-scheme: light` when no theme is pinned. Dark remains the default. - Existing v5 HSL variables are unchanged; nothing in `@graphiql/react` references the new tokens yet. - Future PRs will restyle components to consume the new tokens and shim the v5 variables. Refs: #4219
## Summary Storybook gives us a fast feedback loop for iterating on the look of the app and individual components — flipping themes/density/font-size without spinning up the full GraphiQL shell. - Bootstrap Storybook 10 in `@graphiql/react`. Stories colocated as `<component>.stories.tsx`; ships one starter (`Spinner`) to validate the pipeline. - A global decorator wraps every story in `.graphiql-container` with `data-theme` / `data-density` / `data-font-size` attributes, toggleable from the Storybook toolbar. - Move `Uri`, `KeyMod`, `KeyCode`, and `Range` out of the `utility` barrel into direct imports from `utility/monaco-ssr`. The barrel was bundling two unrelated concerns — lightweight UI helpers (`cn`, `pick`, etc.) and heavy Monaco re-exports — so any story reaching for `cn` transitively pulled Monaco's ESM bundle, which doesn't initialize cleanly inside Storybook's preview iframe. Splitting them keeps UI primitives lightweight. ## Run locally From the repo root: ``` yarn storybook # dev server on http://localhost:6006 yarn build-storybook # static build under packages/graphiql-react/storybook-static ``` Refs: #4219
## Summary Component a11y is covered by Storybook + axe; this is the full-app counterpart. `cypress-axe` runs axe at four checkpoints during a normal session (initial render, after running a query, with the docs panel open, with the history panel open) and gates PRs against a committed baseline. `cypress/.a11y-baseline.json` pins today's accepted violations — color-contrast in several spots, a couple of nested-interactive cases, link-in-text-block in the docs panel. CI fails on net-new only. The spec lives alongside the existing Cypress suite, so it runs as part of the normal `yarn e2e` flow. `cypress.config.ts` gets a small `writeBaseline` Node task so the spec can persist baseline updates from inside the browser. ## Refresh baseline ``` yarn workspace graphiql test:a11y:update ``` Refs: #4219
) ## Summary Component-level a11y for v6. `@storybook/addon-a11y` surfaces axe results next to each story while you're working on it; `@storybook/addon-vitest` folds those same checks into the existing Vitest suite so they run as part of `yarn test` in CI. The model is per-story `parameters.a11y.test`: - `'error'` (default) — axe violations fail the test - `'todo'` — warn only, for stories with known issues we plan to fix - `'off'` — skip a11y for the story `vitest.config.mts` is split into two projects: - `unit` — existing jsdom suite, unchanged behavior - `storybook` — Vitest browser mode (Playwright Chromium), picks up `.stories.*` files The PR CI workflow gets one new step: `yarn playwright install --with-deps chromium` ahead of `yarn test`. ## Run locally ``` yarn workspace @graphiql/react test # both projects yarn workspace @graphiql/react vitest run --project=unit # unit only yarn workspace @graphiql/react vitest run --project=storybook ``` The Storybook a11y panel surfaces the same axe results live during `yarn workspace @graphiql/react storybook`. Refs: #4219
## Summary - Migrate `Button`, `UnStyledButton`, `ToolbarButton`, and `ExecuteButton` CSS to v6 OKLCH tokens. - Add `variant?: 'default' | 'primary'` to `Button`; `primary` renders the Run-button style. - Switch `:focus` to `:focus-visible` on interactive states so the focus ring no longer fires on mouse click. Aligns with [MDN `:focus-visible`](https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible) and WCAG 2.4.7 (Focus Visible). - Import `clsx` directly in `button` and `toolbar-button`, following the leaf-module pattern from #4272. A follow-up PR will convert remaining callers and remove the `cn` re-export. - Add Storybook stories: `Primitives/Button` (Default, Primary, Success, Error, Disabled) and `Primitives/ToolbarButton` (Default). ## Test plan - [x] Open Storybook `Primitives/Button` and verify each variant matches the design. - [x] Tab into the buttons, then mouse-click them. Focus ring appears on Tab only, not on click. - [x] Open `Primitives/ToolbarButton`. Hover the icon button; a v6 tooltip appears. - [x] Run `yarn dev:graphiql`. The Run button and toolbar buttons match the new design. Refs: #4219
The optional-features list links to `#custom-save-handlers`, but that section was replaced by [Saving with your own plugin](https://github.com/graphql/graphiql/blob/d3f2e0ff74e4a2b3c39d590c4e431fca1ccada79/docs/migration/graphiql-6.0.0.md#saving-with-your-own-plugin). It also still describes host and plugin save hooks. Point the link at the existing section and describe the single registered custom save handler.
The license check follows the root `cspell` range through current registry metadata, where a newly published dictionary now reports WTFPL. The lockfile still installs the earlier MIT-licensed dictionary, so this unrelated registry change is failing the v6 PR checks. `cspell` is only used for linting. Moving it to `devDependencies` keeps the installed version and the CI spell check the same, while the license check's existing `dev: false` setting continues to check the published workspace packages without scanning this development tool.
The v6 packages still build with `babel-plugin-react-compiler@19.1.0-rc.3` and publish a dependency on the matching prerelease runtime. This replaces both with the stable `1.0.0` release before v6 is finalized. The build continues to target React 18, and each compiled published package keeps `react-compiler-runtime` as a direct dependency. This follows [React's guidance for compiled libraries that support React 18](https://react.dev/reference/react-compiler/compiling-libraries). The version change also covers the E2E app's compiler so its build uses the same release as the published packages.
The v6 branch still builds with a July 2026 `@typescript/native-preview` release. TypeScript 7.0.2 is now stable and ships its native compiler as `tsc`. This replaces the preview with a TypeScript 7 npm alias and updates the build scripts to use `tsc`. TypeScript 7 doesn't yet expose a stable programmatic API, so packages that use `svelte2tsx`, declaration bundlers, or other API consumers continue to install TypeScript 5 directly. That includes packages which previously inherited TypeScript 5 from the workspace root. [TypeScript's migration guidance](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/#running-side-by-side-with-typescript-60) describes the side-by-side arrangement.
The v6 packages already advertise GraphQL 17 in their peer ranges, but most of the workspace still develops against GraphQL 16. The existing [PR job](https://github.com/graphql/graphiql/blob/7a85b593/.github/workflows/pr.yml#L86-L105) exercises only four language-service test files with GraphQL 17, so we aren't building the UI and toolkit against that advertised major. This uses GraphQL 17 for the published packages and browser E2E app, updates `graphql-ws` to a version whose peer range includes 17, and runs the full build and test suite under GraphQL 16 in a compatibility job. It also reads GraphQL 17's new SDL default representation when generating variable JSON schemas and resolves one declaration format consistently across project references. The first commit handles source compatibility, the second changes the development baseline and CI job, and the third limits the declaration-resolution setting to the four affected packages. This is stacked on #4624, which provides the stable TypeScript 7 compiler needed for this build. A few older packages (`graphql-helix`, `graphql-config`, `subscriptions-transport-ws`, and `graphiql-code-exporter`) still declare peer ranges ending before GraphQL 17. The E2E server already used GraphQL 17 before this PR.
The language server uses `@astrojs/compiler` to parse Astro frontmatter before finding GraphQL tags. This updates it from 2 to 4. While checking the existing Astro fixture, I found that the reported query line was one line early: the parser disabled positions even though the range mapper reads the frontmatter position. This lets the compiler provide positions and asserts the query's source line in that fixture.
`@graphiql/react` uses Motion's `Reorder` components for tabs. This updates `framer-motion` to v14 and records the dependency change in the v6 release notes. [Motion's upgrade guide](https://motion.dev/docs/react-upgrade-guide) reports no breaking React API changes in v14; its peer range still covers React 18 and 19.
`pnpm/action-setup@v4` uses the deprecated Node 20 action runtime. This updates every workflow reference to v6, which uses Node 24.
Several user-facing dialogs provide a title but no `Dialog.Description`. Radix reports this during tests, and assistive technology receives no concise explanation of what each dialog is for. This adds screen-reader descriptions to Settings and the collection form dialogs. The conflict and destructive replacement dialogs already had visible explanatory text, so this makes that text the Radix description rather than duplicating it. The generic portal tests now include the description required by the dialog contract as well.
The GraphiQL 6 test and build logs currently include a line for every Zustand mock creation, Monaco worker request, and successful React Compiler transform. The language service CLI test also prints the three error stacks that it intentionally triggers, while the execute button stories pass GraphQL ASTs through Storybook args and produce cyclic-value warnings. This removes the routine messages while preserving React Compiler skip and failure reporting. The CLI test now stubs and asserts each expected stderr write and failure exit independently. The execute button stories parse their operations inside `render`, leaving their serializable args available to Storybook controls without passing cyclic AST location data through the args channel. The first commit removes the unconditional logs. The second commit keeps intentionally failing test output and cyclic story data out of the logs.
Since v3, the `graphql-language-service` package has exposed a `graphql` executable that only prints a migration notice directing users to `graphql-language-service-cli`: https://github.com/graphql/graphiql/blob/c1fe2ca802fb39fc37e662c5f85cd83ab13a2b7b/packages/graphql-language-service/src/temp-bin.ts#L10-L34 The workspace manifest points that executable at build output, so pnpm tries to link `dist/temp-bin.js` before it exists and reports a missing-bin warning for every workspace consumer during installation. This removes the deprecated `bin` entry and its warning-only source as part of the v6 major release. The README migration note remains and still directs CLI users to `graphql-language-service-cli` and `graphql-lsp`. To verify the install behavior, run `pnpm install --frozen-lockfile` in a fresh checkout. To inspect the published contents after building, run `npm pack --dry-run --json` from `packages/graphql-language-service`; neither the package metadata nor file list should contain the old executable.
Downstream jobs restore the build job’s Turbo cache, but Cypress currently runs a full build and then invokes `pnpm e2e`, which requests the GraphiQL build again. Lint also waits for and runs the build even though `oxlint` only reads source files, and each Turbo invocation replays cached task output. This has Cypress materialize only the `graphiql-e2e...` build graph once before calling the package-level E2E runner, lets lint run independently without Turbo, and uses `--output-logs=new-only` for Turbo-backed workflow commands. The canary job still materializes the full build output before publishing.
The repo runs Vitest 4 while Vite is already on 8. This updates Vitest and its browser, worker, and canvas helpers to versions that support Vitest 5. The Storybook Vitest addon moves to 10.6.1 because 10.6.0 only accepts Vitest 4 as a peer. The first local parallel test run passed its assertions but hit an intermittent Monaco mock worker teardown error; a focused run and a second full run completed without it. No published package dependency or API changes.
Cypress 16 deprecates its bundled Electron browser, but our E2E scripts still default to Electron and CI carries an Electron-only GPU workaround. This runs source, built, interactive, and accessibility Cypress commands in Chrome, removes the GPU workaround, and updates `cypress-real-events` to 1.15.1 (the release whose peer range includes Cypress 16). The latest `cypress-axe` package still only declares support through Cypress 15. Upstream merged [Cypress 16 support](component-driven/cypress-axe#193), but [its release pipeline is currently blocking publication](component-driven/cypress-axe#194), so this leaves 1.7.0 in place instead of pinning Cypress backward or depending on an unreleased commit.
Vite 8 currently warns for SVGs transformed by `vite-plugin-svgr` 4 because the plugin calls the deprecated `transformWithEsbuild` API. Vitest also warns while loading the two ESM configuration files that still refer to the CommonJS-only `__dirname` global. This updates both SVG plugin consumers to 5.2.0, whose Rolldown path uses `transformWithOxc`, and resolves both test aliases relative to `import.meta.dirname`. I kept the other dependency deprecations and peer compatibility warnings out of this change.
`@types/dotenv` is a deprecated stub package; `dotenv@10.0.0` already declares its own `types/index.d.ts`. `sane@2.0.0` is also deprecated and remained in `codemirror-graphql` after the watch script that imported it was removed in 2021: 5f49f27 This removes both development dependencies and prunes their orphaned lockfile entries. In particular, removing `sane` drops its old Watchman, `fsevents@1`, and micromatch dependency tree. Neither change affects published runtime dependencies, so there is no changeset.
The GraphQL 16 compatibility install reports peer failures from two direct dependencies of `example-graphiql-webpack`: `ajv-formats` receives AJV 6 instead of its AJV 8 peer, and `worker-loader@2` only supports Webpack 3 and 4 while the example uses Webpack 5. Neither package is imported or configured. `worker-loader` is left over from the example’s Webpack 4 setup, and `ajv-formats` was added as a speculative `copy-webpack-plugin` workaround. Removing both declarations also prunes the obsolete Webpack 4 loader dependency chain from the lockfile.
Fresh installs currently warn about three deprecated Babel proposal plugins and `@babel/polyfill`. The proposal syntax has been part of the language for years, and Babel maintains equivalent transform plugins for these configurations. This replaces the proposal plugins with their transform equivalents in the root and both Webpack example configurations. It also removes the unused root `@babel/polyfill` dependency and stops loading it from `graphql-language-service-cli`. The CLI already compiles to ES2018, and its `yargs` dependency requires Node 10 or newer, where the Promise and async runtime features used by the compiled output are native. Adding `core-js` and `regenerator-runtime` to every CLI invocation would not provide a required compatibility path. The lockfile no longer contains `@babel/polyfill`, its `core-js` 2 dependency, or the superseded proposal plugins. The first commit is the mechanical plugin migration; the second removes the CLI polyfill and includes its patch changeset.
`@graphiql/toolkit` installs deprecated `subscriptions-transport-ws` only so two tests can construct or mock its client. The runtime compatibility path is already structural: it calls `legacyWsClient.request(...)` and subscribes to the returned observable without importing the package: https://github.com/graphql/graphiql/blob/c1fe2ca802fb39fc37e662c5f85cd83ab13a2b7b/packages/graphiql-toolkit/src/create-fetcher/lib.ts#L299-L311 This replaces the package fixtures with structural clients and exercises the legacy observable through request, subscription, result delivery, completion, and unsubscribe. Removing the package also exposed that its declarations had implicitly supplied Node types used by toolkit source and tests, so this declares `@types/node` directly and includes it in the toolkit TypeScript configuration. The public `legacyWsClient` option, implementation, and documentation remain unchanged. This is development/test dependency cleanup, so there is no changeset.
`eslint-plugin-react-hooks` is loaded as an Oxlint JS plugin, but pnpm also auto-installs its ESLint peer and the lockfile still selects the unsupported ESLint 9 release. This emits a deprecation warning during the GraphQL 16 compatibility install even though the plugin supports ESLint 10. This constrains that auto-installed peer with a workspace override and refreshes the lockfile to ESLint 10. Keeping the constraint as an override avoids representing ESLint as a tool the repository invokes directly. A peer dependency rule would only hide the warning while leaving the unsupported package installed.
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tracking PR for the GraphiQL v6 redesign effort. This is the long-running integration branch that hosts work-in-progress against
main.Individual PRs target
graphiql-6and produce alpha releases via changesets pre-mode. When v6 is ready to ship, this branch will be merged intomain.See discussion #4219 for background and progress updates.
Closes #734 — the visual query builder ships in v6 as
@graphiql/plugin-query-builder.