GraphiQL v6#4228
Draft
trevor-scheer wants to merge 39 commits into
Draft
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: eb46e2f The changes in this PR will be included in the next version bump. This PR includes changesets to release 7 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
## Summary `tokens.css` scopes the v6 OKLCH cascade to `[data-theme='light']` / `[data-theme='dark']` selectors, but `setTheme` was only writing `graphiql-light` / `graphiql-dark` classes onto `<body>`. With no `data-theme` attribute set, v6 components fell through to the OS `prefers-color-scheme` media-query fallback regardless of the in-app toggle. This PR mirrors the active theme onto `document.documentElement` as `data-theme` so the selectors actually match; the existing body classes are preserved for any consumer CSS that depends on them. ## Test plan - [ ] Open the [deploy preview](https://deploy-preview-4293--graphiql-test.netlify.app). With the GraphiQL theme dropdown set to System, confirm `<html>` has no `data-theme` attribute and v6 chrome follows your OS preference. - [ ] Toggle the theme to Light; confirm `<html>` gains `data-theme="light"` and v6 components (`TopBar`, `StatusBar`, `ActivityRail`, etc., once those PRs land) all switch to light tokens. - [ ] Toggle the theme to Dark; confirm `<html>` gains `data-theme="dark"` and v6 components switch to dark tokens. - [ ] Toggle back to System; confirm `data-theme` is removed and the v6 components revert to following the OS preference. Refs: #4219
## Summary This PR introduces the top bar that anchors the new GraphiQL v6 layout. It renders the brand, an endpoint URL display, a command palette button, and a primary Run button across the top of the app. The endpoint URL and command palette are intentional placeholders; their behavior will fill in once the transport and command palette work land. ## Test plan - [x] Open the [deploy preview](https://deploy-preview-4288--graphiql-test.netlify.app). Confirm the top bar spans the full width above the editor/sidebar split, showing the brand, endpoint URL placeholder, command palette button, and Run button. - [x] In the deploy preview, type a query and click Run. Confirm the button disables for the duration of the fetch and re-enables once results arrive. - [x] In the deploy preview, open the settings dialog and toggle dark/light theme. Confirm the top bar reads from the active tokens in both modes. - [x] Tab through the bar with the keyboard. Confirm the Run button is reachable and activates with Space or Enter. Refs: #4219
## Summary This PR adds a 24px footer pinned to the bottom of the GraphiQL app. It shows the connection status (with a small dot indicator), schema type count, plugin count, the document encoding, and the language label. The outer container becomes a flex column with a new `graphiql-body` wrapper for the sidebar-plus-main row, which keeps the status bar fixed beneath a scrolling content area. ## Test plan - [x] Open the [deploy preview](https://deploy-preview-4289--graphiql-test.netlify.app). Confirm the status bar appears at the bottom of the app and reads "Disconnected" with a red dot before any schema loads. - [x] In the deploy preview, the default endpoint should load a schema; confirm the status flips to "Connected" with a green dot, and a schema type count appears. - [x] Resize the browser window narrow; confirm the status bar stays pinned at the bottom and the content area above scrolls independently. - [x] Open the settings dialog and toggle dark/light theme; confirm the bar's chrome follows the active theme. Refs: #4219
## Summary This PR replaces the v5 sidebar icon strip with a new `ActivityRail` that renders registered plugins as a flat list with the settings gear pinned at the bottom. An `ActivityBar` wrapper in the `graphiql` package owns the resize sync and the settings/theme dialogs that previously lived inside the old `Sidebar`. There are no plugin API changes; registered plugins continue to render through the existing `plugins` array. ## Test plan - [x] Open the [deploy preview](https://deploy-preview-4290--graphiql-test.netlify.app). Confirm the activity rail renders along the left edge with each plugin's icon and the settings gear at the bottom. - [x] Click between plugin icons; confirm the active plugin shows the accent indicator and the panel content swaps. - [x] Click the settings gear; confirm the settings dialog opens. - [x] Drag the divider between the panel and the editor area; confirm the rail stays put and the side panel resizes. - [x] Toggle dark/light theme via the settings dialog; confirm the rail reads from the active tokens in both modes. Refs: #4219
## Summary This PR adds a `SidePanel` that hosts the active plugin's content next to the new activity rail. The panel renders nothing when no plugin is active, and remains user-resizable via the existing drag handle. Together with the activity rail change, it completes the left-side navigation chrome for the v6 layout. ## Test plan - [x] Open the [deploy preview](https://deploy-preview-4291--graphiql-test.netlify.app). With no plugin active, confirm the side panel area is collapsed and the editor takes the full width. - [x] Click a plugin icon in the activity rail; confirm the side panel opens with that plugin's content. - [x] Drag the divider between the panel and the editor; confirm the panel resizes smoothly and the width persists when you switch between plugins. - [x] Click the active plugin's icon a second time; confirm the panel closes. - [x] Toggle dark/light theme via the settings dialog; confirm the panel chrome reads from the active tokens. Refs: #4219
## Summary This PR restyles the editor tab strip for v6 and introduces dirty-state and save affordances. Each tab now shows an accent dot when its query differs from the last saved snapshot, and hovering a tab reveals a close button. A new save action, bound to `Cmd-S` / `Ctrl-S`, snapshots the active tab's query, and the right side of the strip gains prettify, copy, and save buttons that surface the existing actions inline. A note on save: today `saveQuery()` just updates the `lastSavedQuery` snapshot to clear the dirty dot. Tab content already auto-persists to localStorage, so save isn't writing anything new. The hook is in place so collections (planned as a follow-up package) can give save real semantics, snapshotting the active tab into the current collection entry. Until that lands, the indicator is a cosmetic baseline. ## Test plan - [x] Open the [deploy preview](https://deploy-preview-4292--graphiql-test.netlify.app) with at least two tabs. Edit the query in one tab and confirm the accent dot appears next to its label. - [x] Press `Cmd-S` (macOS) or `Ctrl-S` (Windows/Linux); confirm the dot disappears. - [x] Click the Save button in the tab strip's right-side action area; confirm the dot also clears. - [x] Hover over a dirty tab; confirm the close button appears and the dirty dot shifts left so it doesn't overlap the close icon. - [x] Close an inactive tab via the close button; confirm the active tab stays active. Close the active tab; confirm focus moves to an adjacent tab. - [x] Drag tabs to reorder them; confirm the dirty state follows the correct tab. - [x] Tab through the strip with the keyboard; confirm both tab labels and the right-side action buttons are reachable in a logical order. Refs: #4219
## Summary - Migrate `@graphiql/plugin-doc-explorer` CSS from v5 HSL tokens to v6 OKLCH tokens. - Use `PanelHeader` for the panel header. - Type names: `--accent-orange`. Field and enum names: `--accent-green-light`. Argument names: `--accent-purple`. ## Test plan - [x] Open the Docs panel in the example app; confirm type/field colors match the v6 palette and navigation (back button, search) still works. - [x] Check the `DocExplorer` Storybook stories: schema overview, type detail variants (object, enum, input), field detail, and token colors story. - [x] Verify the search overlay still expands over the header title (focus the search icon while on a nested type page). Refs: #4219
## Summary - Rewrite `MONACO_THEME_DATA` in `constants.ts`: both `graphiql-DARK` and `graphiql-LIGHT` now cover all GraphQL token types (keywords, types, fields, `$variables`, `@directives`, strings, numbers, operators, comments) using the v6 accent palette. - Editor surface colors (suggest widget, hover widget, quick input) move from the old pink `--color-primary` to `--accent-green`. - `editor.css`: swaps `hsl(var(--color-primary))` for `oklch(var(--accent-green))` in the `.highlight` and `input:focus-visible` rules. - Adds `monaco-themes.test.ts` to pin token rule shapes for both themes. ## Test plan - [x] Open the editor, write a query with keywords, type names, variables, directives, strings, and a comment; confirm syntax colors match the v6 palette (see the changeset for the token reference). - [x] Toggle the theme via the settings dropdown; confirm Monaco switches from dark to light and back, with distinct and correct syntax colors in each. - [x] Verify the autocomplete suggestion widget, hover widget, and quick-input palette use the green accent instead of pink. - [x] Open the editor with the system set to light mode and no pinned theme; confirm Monaco uses the light palette. Refs: #4219
## Summary
- Replaces the `examples/monaco-graphql-react-vite` build target with a
minimal fixture under
`packages/monaco-graphql/__fixtures__/bundle-test/` that imports only
`monaco-graphql`'s public API and wires graphql + json workers. No
React, no example-app baggage, no TypeScript language support.
- Replaces the previous `execa`-driven `yarn workspace ... build`
shell-out with Vite's programmatic `build()` API. Drops `write: false`,
`minify: false`, `target: 'esnext'`, `reportCompressedSize: false`, and
`treeshake: false` since the assertion only cares about the chunk file
list, not the bundle contents or size.
- Adds an explicit negative regex assertion against
`/typescript|tsMode|tsWorker|ts\.worker|cssMode|css\.worker|htmlMode|html\.worker/i`,
so the test's intent ("don't bundle unwanted Monaco language modules")
is readable from the assertion, not just the snapshot.
- Removes the now-unused `execa` devDependency.
- Local test runtime drops from ~8.5s to ~2.3s. CI runtime is ~32s,
dominated by Rollup traversing monaco-editor's module graph; the new
minimal-fixture surface and dropped transforms don't change that floor.
Vitest timeout set to 60s (~28s headroom).
## Test plan
- [x] Run `yarn workspace monaco-graphql test` and confirm both tests
pass in under 5s locally.
- [x] Confirm the snapshot lists only editor core, graphql, and json
chunks (no TypeScript, CSS, or HTML language service modules).
- [x] Sanity-check the negative assertion by manually adding a
TypeScript worker import to the fixture, rerunning the test, and
confirming it fails with the explicit message before reverting.
## Summary `KeycapHint` callers now use semantic names (`MODIFIER.Meta`, etc.) and the component renders the right glyph or text per OS. `MODIFIER.Meta` becomes `⌘` on macOS and `Ctrl` on other platforms; `Ctrl`/`Alt`/`Shift` become Mac glyphs (`⌃`/`⌥`/`⇧`) on macOS and plain text elsewhere. `Enter` always renders as `⏎`. ## Test plan - [ ] Open Storybook `Primitives/KeycapHint` on macOS: chips render as ⌘/⏎. - [ ] In Chrome devtools, override the user agent to a Windows or Linux UA and reload Storybook: same stories render as Ctrl/⏎. - [ ] Confirm the run-shortcut chip and command-palette chip in the top bar follow the same OS detection.
## Summary - `PanelHeader` for the docs panel becomes a fixed eyebrow label, `Schema Explorer`. The type name moves into a new breadcrumb row below the header. - New `SchemaDocumentation` root view: two eyebrow sections (`ROOT TYPES` and `ALL SCHEMA TYPES · N`) replace the old accordion. Root operation rows show a `MethodPill` and target type name. All-types rows show a kind badge (`TYPE`, `SCALAR`, `ENUM`, `INPUT`, `INTERFACE`, `UNION`) and type name in mono. - New `Breadcrumb` row: mono font, depth segments color-coded as `--accent-blue` / `--accent-green-light` / `--fg-strong`, chevron separators; clicking a segment navigates back to that depth. - New `SearchRow` content-area component: inline `Search schema` input with keycap hint; listbox renders as a floating popover in the content area, replacing the old absolutely-positioned search overlay. - New `TypeCard`: `TYPE` badge (mono, uppercase, accent-blue tinted), type name in mono, description, and an `implements X · Y` row with `--accent-orange` links. - New `FieldsList`: collapsible `FIELDS · N` header, mono rows with field name in `--accent-green-light`, colon in `--fg-muted`, return type in `--accent-orange`, optional description in `--fg-subtle`, and a 2px `--accent-blue` left border on the active row. Horizontal padding bumped to 16px across all content sections for breathing room. - `TypeDocumentation` gains a `hideHeader` prop so it can suppress its own description / implements / fields block when `TypeCard` + `FieldsList` render those above. ## Test plan - [ ] Open the Docs panel. Confirm the header shows `SCHEMA EXPLORER` with no extra buttons, a search input, and two eyebrow sections: `ROOT TYPES` and `ALL SCHEMA TYPES · N`. - [ ] Confirm each root operation row shows its `MethodPill` (`QRY`/`MUT`/`SUB`), operation label, and target type name. Click a row and confirm it navigates into the type detail. - [ ] In `ALL SCHEMA TYPES`, confirm each row shows a kind badge and mono type name. Click a row and confirm navigation. - [ ] Confirm the breadcrumb row appears below the header when inside a type, with color-coded segments. Click an intermediate segment and confirm it navigates back. - [ ] Confirm `TypeCard` shows the kind badge, name, description, and `implements` list for an object type that implements interfaces. - [ ] Confirm `FieldsList` shows mono rows with green field names and orange return types; click a field row and confirm it navigates in. - [ ] Type in the inline search row and confirm the listbox popover appears with results. - [ ] Toggle light / dark theme; confirm root view and type-detail both render correctly. - [ ] Navigate to an enum type and confirm enum values still render below. Refs: #4219
## Summary - Migrate `@graphiql/plugin-history` CSS to OKLCH tokens. - New row layout: status dot, mono query name, variables snippet below, action buttons on the right. - Replace the bespoke header div with `PanelHeader`; subtitle carries the ⌥-click hint. - Storybook stories: `Empty`, `FewRows`, `ManyRows`, `Mixed`, and individual item variants. ## Test plan - [x] Open the History panel; confirm the header reads "History" with the subtitle. - [x] Run a query; verify the row appears with a green status dot, mono query name, and a variable snippet if variables were provided. - [x] Click a history row; confirm the query loads into the editor. - [ ] ⌥-click a row (diff behavior) and confirm it still works. - [x] Click "Clear"; confirm rows are removed and the button shows "Cleared" briefly. - [x] Open Storybook under "Plugins/History"; verify all stories render correctly. Refs: #4219
## Summary - Show a `MethodPill` (`QRY`/`MUT`/`SUB`) per History row in place of the green status dot. - `QueryStoreItem` gains an optional `operation` field, populated at write time from the parsed query. - The Clear button drops the green-on-success state; rows disappearing is the feedback. ## Test plan - Open the History panel, run a query/mutation/subscription, and confirm each row shows the right pill. - Click "Clear"; rows are removed without any color flash on the button. - Open Storybook under "Plugins/History"; check the updated `Mixed` story. Refs: #4219
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.