Skip to content

Commit 2bfbb06

Browse files
authored
add scroll-x to graphiql tabs area (#3936)
* add scroll-x to graphiql tabs area * add scroll-x to graphiql tabs area * upd * prettier * fix tests
1 parent 5985e13 commit 2bfbb06

File tree

5 files changed

+152
-132
lines changed

5 files changed

+152
-132
lines changed

.changeset/early-camels-protect.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@graphiql/react': patch
3+
'graphiql': patch
4+
---
5+
6+
add scroll-x to graphiql tabs area

packages/graphiql-react/src/ui/tabs.css

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@
88
padding: 0;
99
margin: 0;
1010
list-style: none;
11+
overflow: auto;
12+
border-top-left-radius: var(--border-radius-8);
13+
}
14+
15+
/* Hide scrollbar */
16+
.no-scrollbar {
17+
scrollbar-width: none; /* Firefox */
18+
-ms-overflow-style: none; /* IE and Edge */
19+
20+
&::-webkit-scrollbar {
21+
@apply x:hidden; /* Chrome, Safari and Opera */
22+
}
1123
}
1224

1325
/* trick to shrink multiple tabs, instead of overflow container */
@@ -21,7 +33,7 @@
2133
background: hsla(var(--color-neutral), var(--alpha-background-light));
2234
position: relative;
2335
display: flex;
24-
max-width: 140px;
36+
flex-shrink: 0;
2537

2638
/* disable shrinking while changing the operation name */
2739
&:not(:focus-within) {
@@ -41,8 +53,6 @@
4153

4254
.graphiql-tab-button {
4355
border-radius: var(--border-radius-8) var(--border-radius-8) 0 0;
44-
overflow: hidden;
45-
text-overflow: ellipsis;
4656
padding: var(--px-4) 28px var(--px-4) var(--px-8);
4757

4858
&:hover {
@@ -57,7 +67,6 @@
5767
transform: translateY(-50%);
5868
display: none;
5969
background: var(--bg);
60-
box-shadow: -10px 0 10px 0 var(--bg);
6170
padding: var(--px-6);
6271
line-height: 0;
6372

packages/graphiql-react/src/utility/resize.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ export function useDragResize({
196196
direction === 'horizontal' ? 'clientWidth' : 'clientHeight';
197197

198198
function handleMouseDown(downEvent: MouseEvent) {
199+
const isClickOnCurrentElement =
200+
downEvent.target === downEvent.currentTarget;
201+
if (!isClickOnCurrentElement) {
202+
return;
203+
}
204+
199205
downEvent.preventDefault();
200206

201207
// Distance between the start of the drag bar and the exact point where

packages/graphiql/src/GraphiQL.spec.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ describe('GraphiQL', () => {
306306

307307
await waitFor(() => {
308308
// 700 / (900 - 700) = 3.5
309-
expect(editors.parentElement!.style.flex).toEqual('3.5');
309+
expect(editors.style.flex).toEqual('3.5');
310310
});
311311

312312
clientWidthSpy.mockRestore();
@@ -351,10 +351,9 @@ describe('GraphiQL', () => {
351351

352352
await waitFor(() => {
353353
// 797 / (1200 - 797) = 1.977667493796526
354-
expect(
355-
container.querySelector('.graphiql-plugin')!.parentElement!.style
356-
.flex,
357-
).toBe('1.977667493796526');
354+
expect(container.querySelector('.graphiql-plugin')!.style.flex).toBe(
355+
'1.977667493796526',
356+
);
358357
});
359358

360359
clientWidthSpy.mockRestore();

packages/graphiql/src/GraphiQL.tsx

Lines changed: 123 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -519,15 +519,14 @@ export const GraphiQLInterface: FC<GraphiQLInterfaceProps> = props => {
519519
<div className="graphiql-main">
520520
<div
521521
ref={pluginResize.firstRef}
522+
className="graphiql-plugin"
522523
style={{
523524
// Make sure the container shrinks when containing long
524525
// non-breaking texts
525526
minWidth: '200px',
526527
}}
527528
>
528-
<div className="graphiql-plugin">
529-
{PluginContent ? <PluginContent /> : null}
530-
</div>
529+
{PluginContent ? <PluginContent /> : null}
531530
</div>
532531
{pluginContext?.visiblePlugin && (
533532
<div
@@ -541,6 +540,7 @@ export const GraphiQLInterface: FC<GraphiQLInterfaceProps> = props => {
541540
values={editorContext.tabs}
542541
onReorder={handleReorder}
543542
aria-label="Select active operation"
543+
className="no-scrollbar"
544544
>
545545
{editorContext.tabs.map((tab, index, tabs) => (
546546
<Tab
@@ -577,141 +577,136 @@ export const GraphiQLInterface: FC<GraphiQLInterfaceProps> = props => {
577577
id="graphiql-session" // used by aria-controls="graphiql-session"
578578
aria-labelledby={`${TAB_CLASS_PREFIX}${editorContext.activeTabIndex}`}
579579
>
580-
<div ref={editorResize.firstRef}>
581-
<div className="graphiql-editors">
582-
<div ref={editorToolsResize.firstRef}>
583-
<section
584-
className="graphiql-query-editor"
585-
aria-label="Query Editor"
586-
>
587-
<QueryEditor
588-
editorTheme={props.editorTheme}
589-
keyMap={props.keyMap}
590-
onClickReference={onClickReference}
591-
onCopyQuery={props.onCopyQuery}
592-
onPrettifyQuery={props.onPrettifyQuery}
593-
onEdit={props.onEditQuery}
594-
readOnly={props.readOnly}
595-
/>
596-
<div
597-
className="graphiql-toolbar"
598-
role="toolbar"
599-
aria-label="Editor Commands"
600-
>
601-
<ExecuteButton />
602-
{toolbar}
603-
</div>
604-
</section>
580+
<div className="graphiql-editors" ref={editorResize.firstRef}>
581+
<section
582+
className="graphiql-query-editor"
583+
aria-label="Query Editor"
584+
ref={editorToolsResize.firstRef}
585+
>
586+
<QueryEditor
587+
editorTheme={props.editorTheme}
588+
keyMap={props.keyMap}
589+
onClickReference={onClickReference}
590+
onCopyQuery={props.onCopyQuery}
591+
onPrettifyQuery={props.onPrettifyQuery}
592+
onEdit={props.onEditQuery}
593+
readOnly={props.readOnly}
594+
/>
595+
<div
596+
className="graphiql-toolbar"
597+
role="toolbar"
598+
aria-label="Editor Commands"
599+
>
600+
<ExecuteButton />
601+
{toolbar}
605602
</div>
603+
</section>
606604

607-
<div ref={editorToolsResize.dragBarRef}>
608-
<div className="graphiql-editor-tools">
609-
<UnStyledButton
610-
type="button"
611-
className={cn(
612-
activeSecondaryEditor === 'variables' &&
613-
editorToolsResize.hiddenElement !== 'second' &&
614-
'active',
615-
)}
616-
onClick={handleToolsTabClick}
617-
data-name="variables"
618-
>
619-
Variables
620-
</UnStyledButton>
621-
{isHeadersEditorEnabled && (
622-
<UnStyledButton
623-
type="button"
624-
className={cn(
625-
activeSecondaryEditor === 'headers' &&
626-
editorToolsResize.hiddenElement !== 'second' &&
627-
'active',
628-
)}
629-
onClick={handleToolsTabClick}
630-
data-name="headers"
631-
>
632-
Headers
633-
</UnStyledButton>
605+
<div
606+
ref={editorToolsResize.dragBarRef}
607+
className="graphiql-editor-tools"
608+
>
609+
<UnStyledButton
610+
type="button"
611+
className={cn(
612+
activeSecondaryEditor === 'variables' &&
613+
editorToolsResize.hiddenElement !== 'second' &&
614+
'active',
615+
)}
616+
onClick={handleToolsTabClick}
617+
data-name="variables"
618+
>
619+
Variables
620+
</UnStyledButton>
621+
{isHeadersEditorEnabled && (
622+
<UnStyledButton
623+
type="button"
624+
className={cn(
625+
activeSecondaryEditor === 'headers' &&
626+
editorToolsResize.hiddenElement !== 'second' &&
627+
'active',
634628
)}
629+
onClick={handleToolsTabClick}
630+
data-name="headers"
631+
>
632+
Headers
633+
</UnStyledButton>
634+
)}
635635

636-
<Tooltip
637-
label={
638-
editorToolsResize.hiddenElement === 'second'
639-
? 'Show editor tools'
640-
: 'Hide editor tools'
641-
}
642-
>
643-
<UnStyledButton
644-
type="button"
645-
onClick={toggleEditorTools}
646-
aria-label={
647-
editorToolsResize.hiddenElement === 'second'
648-
? 'Show editor tools'
649-
: 'Hide editor tools'
650-
}
651-
className="graphiql-toggle-editor-tools"
652-
>
653-
{editorToolsResize.hiddenElement === 'second' ? (
654-
<ChevronUpIcon
655-
className="graphiql-chevron-icon"
656-
aria-hidden="true"
657-
/>
658-
) : (
659-
<ChevronDownIcon
660-
className="graphiql-chevron-icon"
661-
aria-hidden="true"
662-
/>
663-
)}
664-
</UnStyledButton>
665-
</Tooltip>
666-
</div>
667-
</div>
668-
669-
<div ref={editorToolsResize.secondRef}>
670-
<section
671-
className="graphiql-editor-tool"
636+
<Tooltip
637+
label={
638+
editorToolsResize.hiddenElement === 'second'
639+
? 'Show editor tools'
640+
: 'Hide editor tools'
641+
}
642+
>
643+
<UnStyledButton
644+
type="button"
645+
onClick={toggleEditorTools}
672646
aria-label={
673-
activeSecondaryEditor === 'variables'
674-
? 'Variables'
675-
: 'Headers'
647+
editorToolsResize.hiddenElement === 'second'
648+
? 'Show editor tools'
649+
: 'Hide editor tools'
676650
}
651+
className="graphiql-toggle-editor-tools"
677652
>
678-
<VariableEditor
679-
editorTheme={props.editorTheme}
680-
isHidden={activeSecondaryEditor !== 'variables'}
681-
keyMap={props.keyMap}
682-
onEdit={props.onEditVariables}
683-
onClickReference={onClickReference}
684-
readOnly={props.readOnly}
685-
/>
686-
{isHeadersEditorEnabled && (
687-
<HeaderEditor
688-
editorTheme={props.editorTheme}
689-
isHidden={activeSecondaryEditor !== 'headers'}
690-
keyMap={props.keyMap}
691-
onEdit={props.onEditHeaders}
692-
readOnly={props.readOnly}
653+
{editorToolsResize.hiddenElement === 'second' ? (
654+
<ChevronUpIcon
655+
className="graphiql-chevron-icon"
656+
aria-hidden="true"
657+
/>
658+
) : (
659+
<ChevronDownIcon
660+
className="graphiql-chevron-icon"
661+
aria-hidden="true"
693662
/>
694663
)}
695-
</section>
696-
</div>
664+
</UnStyledButton>
665+
</Tooltip>
697666
</div>
667+
668+
<section
669+
className="graphiql-editor-tool"
670+
aria-label={
671+
activeSecondaryEditor === 'variables'
672+
? 'Variables'
673+
: 'Headers'
674+
}
675+
ref={editorToolsResize.secondRef}
676+
>
677+
<VariableEditor
678+
editorTheme={props.editorTheme}
679+
isHidden={activeSecondaryEditor !== 'variables'}
680+
keyMap={props.keyMap}
681+
onEdit={props.onEditVariables}
682+
onClickReference={onClickReference}
683+
readOnly={props.readOnly}
684+
/>
685+
{isHeadersEditorEnabled && (
686+
<HeaderEditor
687+
editorTheme={props.editorTheme}
688+
isHidden={activeSecondaryEditor !== 'headers'}
689+
keyMap={props.keyMap}
690+
onEdit={props.onEditHeaders}
691+
readOnly={props.readOnly}
692+
/>
693+
)}
694+
</section>
698695
</div>
699696

700697
<div
701698
className="graphiql-horizontal-drag-bar"
702699
ref={editorResize.dragBarRef}
703700
/>
704701

705-
<div ref={editorResize.secondRef}>
706-
<div className="graphiql-response">
707-
{executionContext.isFetching ? <Spinner /> : null}
708-
<ResponseEditor
709-
editorTheme={props.editorTheme}
710-
responseTooltip={props.responseTooltip}
711-
keyMap={props.keyMap}
712-
/>
713-
{footer}
714-
</div>
702+
<div className="graphiql-response" ref={editorResize.secondRef}>
703+
{executionContext.isFetching ? <Spinner /> : null}
704+
<ResponseEditor
705+
editorTheme={props.editorTheme}
706+
responseTooltip={props.responseTooltip}
707+
keyMap={props.keyMap}
708+
/>
709+
{footer}
715710
</div>
716711
</div>
717712
</div>
@@ -727,7 +722,7 @@ export const GraphiQLInterface: FC<GraphiQLInterfaceProps> = props => {
727722
<Dialog.Close />
728723
</div>
729724
<div className="graphiql-dialog-section">
730-
<ShortKeys keyMap={props.keyMap || 'sublime'} />
725+
<ShortKeys keyMap={props.keyMap} />
731726
</div>
732727
</Dialog>
733728
<Dialog
@@ -856,7 +851,12 @@ const SHORT_KEYS = Object.entries({
856851
'Re-fetch schema using introspection': ['Ctrl', 'Shift', 'R'],
857852
});
858853

859-
const ShortKeys: FC<{ keyMap: string }> = ({ keyMap }) => {
854+
interface ShortKeysProps {
855+
/** @default 'sublime' */
856+
keyMap?: string;
857+
}
858+
859+
const ShortKeys: FC<ShortKeysProps> = ({ keyMap = 'sublime' }) => {
860860
return (
861861
<div>
862862
<table className="graphiql-table">

0 commit comments

Comments
 (0)