Skip to content

Commit d97bcff

Browse files
authored
Merge pull request #13906 from ethereum/marquee-tooltips
Marquee tooltips
2 parents 360c0f9 + 0617db6 commit d97bcff

File tree

2 files changed

+63
-29
lines changed

2 files changed

+63
-29
lines changed

src/components/Homepage/ValuesMarquee.tsx

Lines changed: 60 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { forwardRef, useEffect, useRef, useState } from "react"
12
import { FaCheck } from "react-icons/fa"
23

34
import Tooltip from "@/components/Tooltip"
@@ -18,6 +19,7 @@ type ItemProps = React.HTMLAttributes<HTMLButtonElement> & {
1819
explanation: string[]
1920
separatorClass: string
2021
icon?: React.ReactNode
22+
container?: HTMLElement | null
2123
}
2224

2325
const Item = ({
@@ -26,9 +28,11 @@ const Item = ({
2628
explanation,
2729
separatorClass,
2830
icon,
31+
container,
2932
}: ItemProps) => (
3033
<>
3134
<Tooltip
35+
container={container}
3236
content={
3337
<>
3438
<h3 className="text-md uppercase text-body-medium">{children}</h3>
@@ -63,38 +67,60 @@ type RowProps = React.HTMLAttributes<HTMLDivElement> & {
6367
toRight?: boolean
6468
}
6569

66-
const Row = ({ className, children, toRight }: RowProps) => {
67-
const { prefersReducedMotion } = usePrefersReducedMotion()
68-
const fadeEdges = {
69-
mask: `linear-gradient(to right, transparent 1rem, white 15%, white 85%, transparent calc(100% - 1rem))`,
70-
}
70+
const Row = forwardRef<HTMLDivElement, RowProps>(
71+
({ className, children, toRight }, ref) => {
72+
const { prefersReducedMotion } = usePrefersReducedMotion()
73+
const fadeEdges = {
74+
mask: `linear-gradient(to right, transparent 1rem, white 15%, white 85%, transparent calc(100% - 1rem))`,
75+
}
7176

72-
return (
73-
<div className={cn("group", className)}>
74-
<div
75-
className="flex max-w-full overflow-hidden motion-reduce:overflow-auto"
76-
style={prefersReducedMotion ? {} : fadeEdges}
77-
>
78-
{Array(prefersReducedMotion ? 1 : 3)
79-
.fill(0)
80-
.map((_, idx) => (
81-
<div
82-
key={idx}
83-
className={cn(
84-
"group-hover:animate-pause flex min-w-fit items-center space-x-10 p-6 motion-reduce:w-full motion-reduce:animate-none motion-reduce:justify-center",
85-
toRight ? "animate-scroll-right" : "animate-scroll-left"
86-
)}
87-
>
88-
{children}
89-
</div>
90-
))}
77+
return (
78+
<div ref={ref} className={cn("group", className)}>
79+
<div
80+
className="flex max-w-full overflow-hidden motion-reduce:overflow-auto"
81+
style={prefersReducedMotion ? {} : fadeEdges}
82+
>
83+
{Array(prefersReducedMotion ? 1 : 3)
84+
.fill(0)
85+
.map((_, idx) => (
86+
<div
87+
key={idx}
88+
className={cn(
89+
"group-hover:animate-pause flex min-w-fit items-center space-x-10 p-6 motion-reduce:w-full motion-reduce:animate-none motion-reduce:justify-center",
90+
toRight ? "animate-scroll-right" : "animate-scroll-left"
91+
)}
92+
>
93+
{children}
94+
</div>
95+
))}
96+
</div>
9197
</div>
92-
</div>
93-
)
94-
}
98+
)
99+
}
100+
)
101+
Row.displayName = "Row"
95102

96103
const ValuesMarquee = () => {
97104
const { t, pairings } = useValuesMarquee()
105+
const containerFirstRef = useRef<HTMLDivElement>(null)
106+
const containerSecondRef = useRef<HTMLDivElement>(null)
107+
108+
const [containerFirst, setContainerFirst] = useState<HTMLDivElement | null>(
109+
null
110+
)
111+
const [containerSecond, setContainerSecond] = useState<HTMLDivElement | null>(
112+
null
113+
)
114+
115+
useEffect(() => {
116+
if (containerFirstRef.current) {
117+
setContainerFirst(containerFirstRef.current)
118+
}
119+
if (containerSecondRef.current) {
120+
setContainerSecond(containerSecondRef.current)
121+
}
122+
}, [])
123+
98124
return (
99125
<Section id="values" className="!my-64">
100126
<SectionContent className="flex flex-col items-center text-center">
@@ -107,11 +133,15 @@ const ValuesMarquee = () => {
107133
</p>
108134
</SectionContent>
109135
<div className="relative mt-19 overflow-hidden max-2xl:-mx-4 2xl:rounded-2xl">
110-
<Row className="border-b border-background bg-blue-50 dark:bg-blue-600">
136+
<Row
137+
ref={containerFirstRef}
138+
className="border-b border-background bg-blue-50 dark:bg-blue-600"
139+
>
111140
{pairings.map(({ ethereum: { label, content } }) => (
112141
<Item
113142
key={label}
114143
explanation={content}
144+
container={containerFirst}
115145
separatorClass="bg-accent-a"
116146
className="group/item bg-blue-100 text-blue-600 hover:bg-blue-600 hover:text-white dark:hover:bg-blue-700"
117147
icon={
@@ -123,12 +153,14 @@ const ValuesMarquee = () => {
123153
))}
124154
</Row>
125155
<Row
156+
ref={containerSecondRef}
126157
className="border-t border-background bg-gray-50 dark:bg-gray-800"
127158
toRight
128159
>
129160
{pairings.map(({ legacy: { label, content } }) => (
130161
<Item
131162
key={label}
163+
container={containerSecond}
132164
explanation={content}
133165
className="bg-gray-200/20 text-body-medium hover:bg-gray-600 hover:text-white dark:bg-gray-950 dark:text-body"
134166
separatorClass="bg-gray-200 dark:bg-gray-950"

src/components/Tooltip/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ export type TooltipProps = ComponentProps<typeof Popover> & {
1717
content: ReactNode
1818
children?: ReactNode
1919
onBeforeOpen?: () => void
20+
container?: HTMLElement | null
2021
}
2122

2223
const Tooltip = ({
2324
content,
2425
children,
2526
onBeforeOpen,
27+
container,
2628
...props
2729
}: TooltipProps) => {
2830
const { isOpen, onOpen, onClose } = useDisclosure()
@@ -88,7 +90,7 @@ const Tooltip = ({
8890
<Trigger className="focus-visible:rounded-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-hover">
8991
{children}
9092
</Trigger>
91-
<Portal>
93+
<Portal container={container}>
9294
<Content
9395
side="top"
9496
sideOffset={2}

0 commit comments

Comments
 (0)