Skip to content

Commit 8b927d9

Browse files
committed
Make the step transition nice
1 parent a4b08a9 commit 8b927d9

File tree

2 files changed

+128
-46
lines changed

2 files changed

+128
-46
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.wires {
2+
& rect,
3+
& path {
4+
transition:
5+
fill 1s linear,
6+
stroke 1s linear,
7+
opacity 1s linear;
8+
}
9+
}

src/components/index-page/what-is-graphql/wires.tsx

Lines changed: 119 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,23 @@ import {
1515

1616
import QueryMdx from "./api-gateway-query.mdx"
1717
import clsx from "clsx"
18-
import { ComponentPropsWithoutRef, ReactNode, useReducer } from "react"
18+
import {
19+
ComponentPropsWithoutRef,
20+
ReactNode,
21+
useEffect,
22+
useReducer,
23+
useRef,
24+
} from "react"
25+
26+
import classes from "./wires.module.css"
1927

20-
function ClientEdges({ highlighted }: { highlighted?: number }) {
28+
function ClientEdges({
29+
highlightedEdge,
30+
highlightedVisible,
31+
}: {
32+
highlightedEdge?: number
33+
highlightedVisible: boolean
34+
}) {
2135
const paths = [
2236
"M514.5 220H424.5V76H72",
2337
"M446 220H424.5V112H144",
@@ -33,25 +47,38 @@ function ClientEdges({ highlighted }: { highlighted?: number }) {
3347
return (
3448
<>
3549
{moveHighlightedToTop(
36-
highlighted,
50+
highlightedEdge,
3751
paths.map((path, index) => (
38-
<path
39-
key={index}
40-
d={path}
41-
stroke={
42-
highlighted === index
43-
? `url(#paint_lr_dark_linear_671_9150)`
44-
: `url(#paint_lr_light_linear_671_9150)`
45-
}
46-
strokeWidth={highlighted === index ? "2" : "1"}
47-
/>
52+
<>
53+
<path
54+
key={index}
55+
d={path}
56+
stroke="url(#paint_lr_light_linear_671_9150)"
57+
strokeWidth="1"
58+
/>
59+
{highlightedEdge === index && (
60+
<path
61+
key={index + "h"}
62+
d={path}
63+
stroke="url(#paint_lr_dark_linear_671_9150)"
64+
strokeWidth="2"
65+
className={highlightedVisible ? "opacity-100" : "opacity-0"}
66+
/>
67+
)}
68+
</>
4869
)),
4970
)}
5071
</>
5172
)
5273
}
5374

54-
function ServerEdges({ highlighted }: { highlighted: number[] }) {
75+
function ServerEdges({
76+
highlighted,
77+
highlightedVisible,
78+
}: {
79+
highlighted: number[]
80+
highlightedVisible: boolean
81+
}) {
5582
const paths = [
5683
"M696 159.5H811.5V75H1176",
5784
"M696 175.5L833.5 175.5V112H1104.5",
@@ -69,18 +96,27 @@ function ServerEdges({ highlighted }: { highlighted: number[] }) {
6996
{paths.map((d, index) => {
7097
const isHighlighted = highlighted?.includes(index)
7198
return (
72-
<path
73-
key={index}
74-
d={d}
75-
strokeWidth={isHighlighted ? 2 : 1}
76-
className={clsx(
77-
isHighlighted
78-
? index % 2
79-
? "stroke-[url(#paint_sr_pri_highlight_linear_671_9150)] motion-reduce:stroke-[url(#paint_sr_pri_highlight_linear_static_671_9150)]"
80-
: "stroke-[url(#paint_sr_sec_highlight_linear_671_9150)] motion-reduce:stroke-[url(#paint_sr_sec_highlight_linear_static_671_9150)]"
81-
: "stroke-[url(#paint_sr_light_linear_671_9150)]",
99+
<>
100+
<path
101+
key={index}
102+
d={d}
103+
strokeWidth={1}
104+
className="stroke-[url(#paint_sr_light_linear_671_9150)]"
105+
/>
106+
{isHighlighted && (
107+
<path
108+
key={index + "h"}
109+
d={d}
110+
strokeWidth={2}
111+
className={clsx(
112+
highlightedVisible ? "opacity-100" : "opacity-0",
113+
index % 2
114+
? "stroke-[url(#paint_sr_pri_highlight_linear_671_9150)] motion-reduce:stroke-[url(#paint_sr_pri_highlight_linear_static_671_9150)]"
115+
: "stroke-[url(#paint_sr_sec_highlight_linear_671_9150)] motion-reduce:stroke-[url(#paint_sr_sec_highlight_linear_static_671_9150)]",
116+
)}
117+
/>
82118
)}
83-
/>
119+
</>
84120
)
85121
})}
86122
</>
@@ -89,7 +125,6 @@ function ServerEdges({ highlighted }: { highlighted: number[] }) {
89125

90126
function Box({
91127
transform,
92-
fill = "hsl(var(--color-neu-100))",
93128
children,
94129
className,
95130
}: {
@@ -102,11 +137,11 @@ function Box({
102137
<g
103138
transform={transform}
104139
className={clsx(
105-
"[&>path]:translate-x-4 [&>path]:translate-y-4 [:where(&>path:not([fill]))]:fill-neu-600",
140+
"fill-neu-100 [&>path]:translate-x-4 [&>path]:translate-y-4 [:where(&>path:not([fill]))]:fill-neu-600",
106141
className,
107142
)}
108143
>
109-
<rect width="56" height="56" fill={fill} />
144+
<rect width="56" height="56" />
110145
{children}
111146
</g>
112147
)
@@ -142,7 +177,7 @@ function ClientBoxes({ highlighted }: { highlighted?: number }) {
142177
}
143178
className={
144179
isHighlighted
145-
? "[&_path]:fill-neu-800 dark:[&_path]:fill-neu-0"
180+
? "[&_path]:fill-neu-800 dark:[&_path]:fill-neu-0 dark:[&_rect]:fill-neu-400"
146181
: undefined
147182
}
148183
>
@@ -177,18 +212,11 @@ function ServerBoxes({ highlighted }: { highlighted: number[] }) {
177212
<Box
178213
key={index}
179214
transform={transform}
180-
fill={
181-
isHighlighted
182-
? index % 2
183-
? "hsl(var(--color-pri-lighter))"
184-
: "hsl(var(--color-sec-light))"
185-
: "hsl(var(--color-neu-100))"
186-
}
187215
className={
188216
isHighlighted
189217
? index % 2
190-
? "dark:[&_path]:fill-pri-lighter [&_rect]:fill-pri-darker"
191-
: "dark:[&_path]:fill-sec-lighter [&_rect]:fill-sec-darker"
218+
? "fill-pri-lighter [&_path]:fill-pri-darker dark:[&_path]:fill-pri-lighter dark:[&_rect]:fill-pri-darker"
219+
: "fill-sec-light [&_path]:fill-sec-darker dark:[&_path]:fill-sec-lighter dark:[&_rect]:fill-sec-darker"
192220
: undefined
193221
}
194222
>
@@ -200,7 +228,6 @@ function ServerBoxes({ highlighted }: { highlighted: number[] }) {
200228
)
201229
}
202230

203-
// SVG gradients and definitions
204231
function SVGDefinitions() {
205232
return (
206233
<defs>
@@ -222,8 +249,40 @@ function SVGDefinitions() {
222249
className="dark:[stop-color:hsl(var(--color-neu-100))]"
223250
/>
224251
</linearGradient>
252+
<linearGradient id="paint_lr_dark_linear_671_9150">
253+
<stop
254+
stopColor="hsl(var(--color-neu-300))"
255+
className="dark:[stop-color:hsl(var(--color-neu-200))]"
256+
>
257+
<animate
258+
attributeName="offset"
259+
values="-2.562;1.438;-2.562"
260+
dur="10s"
261+
repeatCount="indefinite"
262+
/>
263+
</stop>
264+
<stop stopColor="hsl(var(--color-neu-700))">
265+
<animate
266+
attributeName="offset"
267+
values="-1.562;2.438;-1.562"
268+
dur="10s"
269+
repeatCount="indefinite"
270+
/>
271+
</stop>
272+
<stop
273+
stopColor="hsl(var(--color-neu-300))"
274+
className="dark:[stop-color:hsl(var(--color-neu-200))]"
275+
>
276+
<animate
277+
attributeName="offset"
278+
values="-0.562;3.438;-0.562"
279+
dur="10s"
280+
repeatCount="indefinite"
281+
/>
282+
</stop>
283+
</linearGradient>
225284
<linearGradient
226-
id="paint_lr_dark_linear_671_9150"
285+
id="paint_lr_dark_linear_static_671_9150"
227286
x1="446"
228287
y1="-17.6347"
229288
x2="204.096"
@@ -369,13 +428,26 @@ const components = {
369428
}
370429

371430
export function Wires({ className }: { className?: string }) {
372-
const STEPS = 3
373-
const [step, inc] = useReducer(x => (x + 1) % STEPS, 1)
431+
const STEPS = 2
432+
const [step, inc] = useReducer(x => (x + 1) % STEPS, 0)
374433

375-
// TODO: Increment from 0 to 1 and 1 to 2 on `repeatEvent` in client and server edges.
434+
const ref = useRef<SVGSVGElement>(null)
435+
436+
useEffect(() => {
437+
const animate = document.querySelector(
438+
"#paint_sr_pri_highlight_linear_671_9150 animate",
439+
)
376440

441+
if (animate && animate instanceof SVGAnimateElement) {
442+
animate.addEventListener("repeatEvent", inc)
443+
}
444+
445+
return () => animate?.removeEventListener("repeatEvent", inc)
446+
}, [])
447+
448+
// TODO: Increment from 0 to 1 and 1 to 2 on `repeatEvent` in client and server edges.
377449
return (
378-
<div className={clsx(className, "relative")}>
450+
<div className={clsx(className, "relative", classes.wires)}>
379451
<svg
380452
id="what-is-graphql--wires"
381453
width="1248"
@@ -385,10 +457,11 @@ export function Wires({ className }: { className?: string }) {
385457
xmlns="http://www.w3.org/2000/svg"
386458
aria-label="GraphQL allows you to build API Gateways to bring data from multiple sources to your clients in a single query"
387459
className="relative h-auto w-full"
460+
ref={ref}
388461
>
389-
<ClientEdges highlighted={step === 0 ? 0 : undefined} />
462+
<ClientEdges highlightedEdge={0} highlightedVisible={step === 0} />
390463
<ClientBoxes highlighted={step === 0 ? 0 : undefined} />
391-
<ServerEdges highlighted={step === 1 ? [1, 6] : []} />
464+
<ServerEdges highlighted={[1, 6]} highlightedVisible={step === 1} />
392465
<ServerBoxes highlighted={step === 1 ? [1, 6] : []} />
393466
<SVGDefinitions />
394467
</svg>

0 commit comments

Comments
 (0)