Skip to content

Commit f45e26b

Browse files
v6: Remove the cn re-export from @graphiql/react (#4423)
## Summary `@graphiql/react` had a `cn` helper that was just a re-export of `clsx`, left over from before the Button/IconButton restyle. It didn't add any behavior of its own, so this removes it and has every internal usage import `clsx` directly instead: all the component files in `graphiql-react` that used `cn(...)`, plus `@graphiql/plugin-history` and the `graphiql` package, which both imported `cn` from `@graphiql/react` rather than depending on `clsx` themselves. Both packages now list `clsx` as a direct dependency. Since `cn` was exported from `@graphiql/react`'s public entry point, dropping it is a breaking change for 6.0.0. Added a changeset with a major bump and a short note in the v6 migration guide pointing anyone using `cn` at `clsx`. Refs: #4228
1 parent 8a2577f commit f45e26b

21 files changed

Lines changed: 69 additions & 42 deletions

File tree

.changeset/remove-cn-reexport.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@graphiql/react': major
3+
---
4+
5+
`cn` is no longer exported from `@graphiql/react`; import `clsx` directly.

docs/migration/graphiql-6.0.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,3 +530,4 @@ Nothing below is happening in v6. These are informal signals about where the pro
530530

531531
- **Browserslist.** v6 drops the project's custom `.browserslistrc` in favor of the single `defaults` browserslist preset (`> 0.5%, last 2 versions, Firefox ESR, not dead`). That range covers the modern browsers that support the OKLCH color functions the new token system relies on. If your previous bespoke config deliberately targeted very old browsers, they may fall outside the new range — check `defaults` against your support matrix if that matters to you.
532532
- **Monaco editor theme registration.** The built-in Monaco themes (`graphiql-DARK` and `graphiql-LIGHT`) were rewritten to use the v6 accent palette — every GraphQL token type (keywords, type names, field identifiers, variables, annotations, strings, numbers, comments) and the surrounding editor chrome (suggest widget, hover widget, quick input) now pull from the same tokens as the rest of the UI. The `editorTheme` prop on `<GraphiQL>` still takes the same `{ dark, light }` pair of Monaco theme names or definitions it always did, so a custom theme registered through that prop should continue to work unchanged. If you were depending on the specific color values baked into the previous built-in `graphiql-DARK` / `graphiql-LIGHT` themes (for a screenshot test, for example), expect those values to have shifted.
533+
- **`cn` removed from `@graphiql/react`.** The `cn` helper was just a re-export of `clsx`. It's gone now, so import `clsx` directly from the `clsx` package instead.

packages/graphiql-plugin-history/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
},
4444
"dependencies": {
4545
"@graphiql/toolkit": "^0.12.0",
46+
"clsx": "^1.2.1",
4647
"react-compiler-runtime": "19.1.0-rc.1",
4748
"zustand": "^5"
4849
},

packages/graphiql-plugin-history/src/components.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { QueryStoreItem } from '@graphiql/toolkit';
22
import { FC, MouseEventHandler, useEffect, useRef, useState } from 'react';
3+
import { clsx } from 'clsx';
34
import {
4-
cn,
55
CloseIcon,
66
PenIcon,
77
StarFilledIcon,
@@ -153,7 +153,7 @@ export const HistoryItem: FC<QueryHistoryItemProps> = props => {
153153
: null;
154154

155155
return (
156-
<li className={cn('graphiql-history-item', isEditable && 'editable')}>
156+
<li className={clsx('graphiql-history-item', isEditable && 'editable')}>
157157
{isEditable ? (
158158
<>
159159
<input
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ComponentPropsWithoutRef, forwardRef } from 'react';
2-
import { cn } from '../../utility';
2+
import { clsx } from 'clsx';
33
import './index.css';
44

55
export const ButtonGroup = forwardRef<
@@ -9,7 +9,7 @@ export const ButtonGroup = forwardRef<
99
<div
1010
{...props}
1111
ref={ref}
12-
className={cn('graphiql-button-group', props.className)}
12+
className={clsx('graphiql-button-group', props.className)}
1313
/>
1414
));
1515
ButtonGroup.displayName = 'ButtonGroup';

packages/graphiql-react/src/components/button/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ComponentPropsWithoutRef, forwardRef } from 'react';
2-
import { clsx as cn } from 'clsx';
2+
import { clsx } from 'clsx';
33
import './index.css';
44

55
type UnStyledButtonProps = ComponentPropsWithoutRef<'button'>;
@@ -11,7 +11,7 @@ export const UnStyledButton = forwardRef<
1111
<button
1212
{...props}
1313
ref={ref}
14-
className={cn('graphiql-un-styled', props.className)}
14+
className={clsx('graphiql-un-styled', props.className)}
1515
/>
1616
));
1717
UnStyledButton.displayName = 'UnStyledButton';
@@ -26,7 +26,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
2626
<button
2727
{...props}
2828
ref={ref}
29-
className={cn(
29+
className={clsx(
3030
'graphiql-button',
3131
props.variant === 'primary' && 'graphiql-button-primary',
3232
{

packages/graphiql-react/src/components/dialog/index.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { cn } from '../../utility';
1+
import { clsx } from 'clsx';
22
import { forwardRef, FC, ComponentPropsWithoutRef, RefObject } from 'react';
33
import { CloseIcon } from '../../icons';
44
import { UnStyledButton } from '../button';
@@ -17,7 +17,7 @@ const DialogClose = forwardRef<
1717
{...props}
1818
ref={ref}
1919
type="button"
20-
className={cn('graphiql-dialog-close', props.className)}
20+
className={clsx('graphiql-dialog-close', props.className)}
2121
>
2222
<VisuallyHidden>Close dialog</VisuallyHidden>
2323
<CloseIcon />
@@ -36,7 +36,11 @@ const DialogHeader = forwardRef<
3636
HTMLDivElement,
3737
ComponentPropsWithoutRef<'div'>
3838
>(({ children, className, ...props }, ref) => (
39-
<div {...props} ref={ref} className={cn('graphiql-dialog-header', className)}>
39+
<div
40+
{...props}
41+
ref={ref}
42+
className={clsx('graphiql-dialog-header', className)}
43+
>
4044
{typeof children === 'string' ? (
4145
<D.Title className="graphiql-dialog-title">{children}</D.Title>
4246
) : (
@@ -50,7 +54,11 @@ DialogHeader.displayName = 'Dialog.Header';
5054
/** The content region of a dialog, with consistent padding. */
5155
const DialogBody = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<'div'>>(
5256
({ children, className, ...props }, ref) => (
53-
<div {...props} ref={ref} className={cn('graphiql-dialog-body', className)}>
57+
<div
58+
{...props}
59+
ref={ref}
60+
className={clsx('graphiql-dialog-body', className)}
61+
>
5462
{children}
5563
</div>
5664
),
@@ -62,7 +70,11 @@ const DialogFooter = forwardRef<
6270
HTMLDivElement,
6371
ComponentPropsWithoutRef<'div'>
6472
>(({ children, className, ...props }, ref) => (
65-
<div {...props} ref={ref} className={cn('graphiql-dialog-footer', className)}>
73+
<div
74+
{...props}
75+
ref={ref}
76+
className={clsx('graphiql-dialog-footer', className)}
77+
>
6678
{children}
6779
</div>
6880
));

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ComponentProps, FC, forwardRef } from 'react';
2-
import { cn } from '../../utility';
2+
import { clsx } from 'clsx';
33
import {
44
Trigger,
55
Portal,
@@ -36,7 +36,7 @@ const Content: FC<DropdownMenuContentProps> = ({
3636
<RadixContent
3737
align={align}
3838
sideOffset={sideOffset}
39-
className={cn('graphiql-dropdown-content', className)}
39+
className={clsx('graphiql-dropdown-content', className)}
4040
{...props}
4141
>
4242
{children}
@@ -46,14 +46,14 @@ const Content: FC<DropdownMenuContentProps> = ({
4646
};
4747

4848
const Item: FC<DropdownMenuItemProps> = ({ className, children, ...props }) => (
49-
<RadixItem className={cn('graphiql-dropdown-item', className)} {...props}>
49+
<RadixItem className={clsx('graphiql-dropdown-item', className)} {...props}>
5050
{children}
5151
</RadixItem>
5252
);
5353

5454
const Separator: FC<ComponentProps<'div'>> = ({ className, ...props }) => (
5555
<RadixSeparator
56-
className={cn('graphiql-dropdown-separator', className)}
56+
className={clsx('graphiql-dropdown-separator', className)}
5757
{...props}
5858
/>
5959
);

packages/graphiql-react/src/components/markdown-content/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ComponentPropsWithoutRef, forwardRef } from 'react';
2-
import { cn, markdown } from '../../utility';
2+
import { clsx } from 'clsx';
3+
import { markdown } from '../../utility';
34
import './index.css';
45

56
interface MarkdownContentProps extends Omit<
@@ -16,7 +17,7 @@ export const MarkdownContent = forwardRef<HTMLDivElement, MarkdownContentProps>(
1617
<div
1718
{...props}
1819
ref={ref}
19-
className={cn(
20+
className={clsx(
2021
`graphiql-markdown-${type}`,
2122
onlyShowFirstChild && 'graphiql-markdown-preview',
2223
props.className,

packages/graphiql-react/src/components/operation-editor.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import {
1212
createEditor,
1313
onEditorContainerKeyDown,
1414
} from '../utility/create-editor';
15-
import { debounce, pick, cleanupDisposables, cn } from '../utility';
15+
import { clsx } from 'clsx';
16+
import { debounce, pick, cleanupDisposables } from '../utility';
1617
import { Uri, Range } from '../utility/monaco-ssr';
1718
import type { MonacoEditor, EditorProps, SchemaReference } from '../types';
1819
import {
@@ -428,7 +429,7 @@ export const OperationEditor: FC<OperationEditorProps> = ({
428429
tabIndex={0}
429430
onKeyDown={onEditorContainerKeyDown}
430431
{...props}
431-
className={cn('graphiql-editor', props.className)}
432+
className={clsx('graphiql-editor', props.className)}
432433
/>
433434
);
434435
};

0 commit comments

Comments
 (0)