Skip to content

Commit 06a0b5a

Browse files
authored
Update some design elements based on latest orbit designs (#1349)
1 parent 2761ff3 commit 06a0b5a

22 files changed

+249
-75
lines changed

.changeset/moody-grapes-play.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"apollo-client-devtools": patch
3+
---
4+
5+
Fix some design issues to match latest design implementation

package-lock.json

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"@radix-ui/react-tabs": "^1.0.2",
4747
"@radix-ui/react-tooltip": "^1.0.7",
4848
"@xstate/fsm": "^2.1.0",
49+
"class-variance-authority": "^0.7.0",
4950
"clsx": "^2.1.0",
5051
"framer-motion": "^11.0.3",
5152
"graphql": "^16.0.0",
@@ -58,6 +59,7 @@
5859
"react-json-tree": "^0.18.0",
5960
"react-resizable-panels": "^1.0.0",
6061
"react-syntax-highlighter": "^15.5.0",
62+
"tailwind-merge": "^2.3.0",
6163
"zen-observable": "^0.10.0"
6264
},
6365
"devDependencies": {

src/application/App.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const ALERT_CONFIGS = {
6565
<Button
6666
size="xs"
6767
variant="hidden"
68-
icon={IconSync}
68+
icon={<IconSync />}
6969
onClick={() => panelWindow.send({ type: "retryConnection" })}
7070
>
7171
Retry connection
@@ -175,22 +175,25 @@ export const App = () => {
175175

176176
<ButtonGroup className="ml-auto flex-1 justify-end">
177177
<Tooltip content="Report an issue">
178-
<Button variant="hidden" size="sm" asChild>
179-
<GitHubIssueLink labels={[LABELS.bug]} body={ISSUE_BODY}>
180-
<IconGitHubSolid aria-hidden="true" className="w-4" />
181-
</GitHubIssueLink>
178+
<Button
179+
aria-label="Report an issue"
180+
variant="hidden"
181+
size="sm"
182+
icon={<IconGitHubSolid />}
183+
asChild
184+
>
185+
<GitHubIssueLink labels={[LABELS.bug]} body={ISSUE_BODY} />
182186
</Button>
183187
</Tooltip>
184188

185189
<Tooltip content="Settings">
186190
<Button
191+
aria-label="Settings"
187192
size="sm"
188193
variant="hidden"
189194
onClick={() => setSettingsOpen(true)}
190-
>
191-
<IconSettings aria-hidden="true" className="w-4" />
192-
<span className="sr-only">Settings</span>
193-
</Button>
195+
icon={<IconSettings />}
196+
/>
194197
</Tooltip>
195198
</ButtonGroup>
196199
<SettingsModal open={settingsOpen} onOpen={setSettingsOpen} />

src/application/components/Button.tsx

Lines changed: 111 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,118 @@
1-
import type { ComponentPropsWithoutRef, ElementType } from "react";
2-
import { forwardRef } from "react";
3-
import { clsx } from "clsx";
1+
import type { ComponentPropsWithoutRef, ReactElement } from "react";
2+
import { cloneElement, forwardRef, isValidElement } from "react";
43
import { Slot, Slottable } from "@radix-ui/react-slot";
54
import type { AsChildProps } from "../types/props";
5+
import { cva, type VariantProps } from "class-variance-authority";
6+
import { twMerge } from "tailwind-merge";
7+
import type { OmitNull } from "../types/utils";
68

79
type NativeButtonProps = ComponentPropsWithoutRef<"button">;
810

9-
type ButtonSize = "md" | "sm" | "xs";
11+
type ButtonProps = AsChildProps<NativeButtonProps> &
12+
Variants & {
13+
className?: string;
14+
icon?: ReactElement<{ "aria-hidden": boolean; className?: string }>;
15+
};
1016

11-
type ButtonProps = AsChildProps<NativeButtonProps> & {
12-
className?: string;
13-
icon?: ElementType;
14-
variant: "primary" | "secondary" | "hidden";
15-
size: ButtonSize;
16-
};
17+
type Variants = OmitNull<Required<VariantProps<typeof button>>>;
1718

18-
const ICON_SIZES = {
19-
xs: "w-3",
20-
sm: "w-4",
21-
md: "w-4",
22-
} satisfies Record<ButtonSize, string>;
19+
const button = cva(
20+
[
21+
"flex",
22+
"items-center",
23+
"flex",
24+
"gap-2",
25+
"outline-none",
26+
"focus:ring-3",
27+
"focus:ring-offset-3",
28+
"focus:ring-offset-primary",
29+
"focus:dark:ring-offset-primary-dark",
30+
"focus:ring-focused",
31+
"focus:dark:ring-focused-dark",
32+
"disabled:bg-button-disabled",
33+
"disabled:dark:bg-button-disabled-dark",
34+
"disabled:text-disabled",
35+
"disabled:dark:text-disabled-dark",
36+
"disabled:cursor-not-allowed",
37+
"transition-colors",
38+
"duration-200",
39+
],
40+
{
41+
variants: {
42+
variant: {
43+
hidden: [
44+
"text-primary",
45+
"dark:text-primary-dark",
46+
"hover:bg-button-secondaryHover",
47+
"hover:dark:bg-button-secondaryHover-dark",
48+
"active:bg-button-secondarySelected",
49+
"active:dark:bg-button-secondarySelected-dark",
50+
],
51+
primary: [
52+
"text-white",
53+
"bg-button-primary",
54+
"dark:bg-button-primary-dark",
55+
"hover:bg-button-primaryHover",
56+
"hover:dark:bg-button-primaryHover-dark",
57+
"active:bg-selected",
58+
"active:dark:bg-selected-dark",
59+
],
60+
secondary: [
61+
"text-primary",
62+
"dark:text-primary-dark",
63+
"border",
64+
"bg-button-secondary",
65+
"dark:bg-button-secondary-dark",
66+
"border-primary",
67+
"dark:border-primary-dark",
68+
"hover:bg-button-secondaryHover",
69+
"hover:dark:bg-button-secondaryHover-dark",
70+
"active:bg-selected",
71+
"active:dark:bg-selected-dark",
72+
],
73+
},
74+
size: {
75+
xs: [
76+
"p-2",
77+
"rounded",
78+
"text-sm",
79+
"font-semibold",
80+
"has-[>svg:only-child]:p-1.5",
81+
],
82+
sm: [
83+
"py-2",
84+
"px-3",
85+
"rounded",
86+
"text-sm",
87+
"font-semibold",
88+
"has-[>svg:only-child]:p-2",
89+
],
90+
md: [
91+
"py-2",
92+
"px-3",
93+
"rounded-lg",
94+
"text-md",
95+
"font-semibold",
96+
"has-[>svg:only-child]:p-3",
97+
],
98+
},
99+
},
100+
}
101+
);
102+
103+
const iconSize = cva([], {
104+
variants: {
105+
size: {
106+
xs: ["w-3"],
107+
sm: ["w-4"],
108+
md: ["w-4"],
109+
},
110+
},
111+
});
23112

24113
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
25114
function Button(
26-
{ asChild, className, children, variant, size, icon: Icon, ...props },
115+
{ asChild, className, children, variant, size, icon, ...props },
27116
ref
28117
) {
29118
const Component = asChild ? Slot : "button";
@@ -32,25 +121,13 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
32121
<Component
33122
{...props}
34123
ref={ref}
35-
className={clsx(
36-
className,
37-
"flex items-center gap-2 outline-none",
38-
"focus:ring-3 focus:ring-offset-3 focus:ring-offset-primary focus:dark:ring-offset-primary-dark focus:ring-focused focus:dark:ring-focused-dark",
39-
"disabled:bg-button-disabled disabled:dark:bg-button-disabled-dark disabled:text-disabled disabled:dark:text-disabled-dark disabled:cursor-not-allowed",
40-
{
41-
"py-2 px-3 rounded-lg text-md font-semibold": size === "md",
42-
"py-2 px-3 rounded text-sm font-semibold": size === "sm",
43-
"p-2 rounded text-sm font-semibold": size === "xs",
44-
"text-white bg-button-primary dark:bg-button-primary-dark hover:bg-button-primaryHover hover:dark:bg-button-primaryHover-dark active:bg-selected active:dark:bg-selected-dark":
45-
variant === "primary",
46-
"text-primary dark:text-primary-dark border bg-button-secondary dark:bg-button-secondary-dark border-primary dark:border-primary-dark hover:bg-button-secondaryHover hover:dark:bg-button-secondaryHover-dark active:bg-selected active:dark:bg-selected-dark":
47-
variant === "secondary",
48-
"text-primary dark:text-primary-dark hover:bg-button-secondaryHover hover:dark:bg-button-secondaryHover-dark active:bg-selected active:dark:bg-selected-dark":
49-
variant === "hidden",
50-
}
51-
)}
124+
className={twMerge(button({ variant, size }), className)}
52125
>
53-
{Icon && <Icon className={ICON_SIZES[size]} />}
126+
{isValidElement(icon) &&
127+
cloneElement(icon, {
128+
"aria-hidden": true,
129+
className: twMerge(iconSize({ size }), icon.props.className),
130+
})}
54131
<Slottable>{children}</Slottable>
55132
</Component>
56133
);

src/application/components/Cache/sidebar/EntityList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export function EntityList({
2828
key={cacheId}
2929
onClick={() => setCacheId(cacheId)}
3030
selected={cacheId === selectedCacheId}
31-
className="font-code h-8 text-sm"
31+
className="font-code"
3232
>
3333
{searchTerm ? (
3434
<HighlightMatch searchTerm={searchTerm} value={cacheId} />

src/application/components/CopyButton.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { ComponentPropsWithoutRef } from "react";
2-
import clsx from "clsx";
32
import CopyToClipboard from "react-copy-to-clipboard";
43
import { Button } from "./Button";
54
import IconCopy from "@apollo/icons/default/IconCopy.svg";
@@ -20,14 +19,14 @@ export function CopyButton({
2019
}: CopyButtonProps) {
2120
return (
2221
<CopyToClipboard text={text}>
23-
<Button {...rest} className={className} size={size} variant="hidden">
24-
<IconCopy
25-
className={clsx({
26-
"h-4": size === "sm" || size === "md",
27-
"h-2": size === "xs",
28-
})}
29-
/>
30-
</Button>
22+
<Button
23+
{...rest}
24+
aria-label="Copy"
25+
className={className}
26+
size={size}
27+
variant="hidden"
28+
icon={<IconCopy />}
29+
/>
3130
</CopyToClipboard>
3231
);
3332
}

src/application/components/GitHubIssueLink.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ interface GitHubIssueLinkProps {
88
body?: string;
99
labels?: string[];
1010
repository?: "apollo-client" | "apollo-client-devtools";
11-
children: ReactNode;
11+
children?: ReactNode;
1212
}
1313

1414
const WHITESPACE = /\s/g;

src/application/components/Layouts/SettingsModal.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Button } from "../Button";
12
import { Modal } from "../Modal";
23

34
declare const VERSION: string;
@@ -25,6 +26,11 @@ export function SettingsModal({
2526
{VERSION}
2627
</a>
2728
</Modal.Body>
29+
<Modal.Footer>
30+
<Button variant="primary" size="md" onClick={() => onOpen(false)}>
31+
Close
32+
</Button>
33+
</Modal.Footer>
2834
</Modal>
2935
);
3036
}

src/application/components/List.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
import type { ComponentPropsWithoutRef } from "react";
22
import clsx from "clsx";
33

4-
type ListProps = ComponentPropsWithoutRef<"div">;
4+
type ListProps = ComponentPropsWithoutRef<"ul">;
55

66
export function List({ className, ...props }: ListProps) {
7-
return <div {...props} className={clsx(className, "overflow-y-auto")} />;
7+
return (
8+
<ul
9+
{...props}
10+
className={clsx(
11+
className,
12+
"overflow-y-auto flex flex-col gap-2 list-none"
13+
)}
14+
/>
15+
);
816
}

0 commit comments

Comments
 (0)