Skip to content

Commit b93c5cb

Browse files
authored
Merge pull request #13836 from ethereum/internet-is-changing
Homepage: add "values" section with marquee
2 parents a54ce13 + 8dc29d7 commit b93c5cb

File tree

12 files changed

+391
-19
lines changed

12 files changed

+391
-19
lines changed

src/components/BannerGrid/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ export const BannerGridCell = ({ children }: ChildOnlyProp) => {
3636
className={cn(
3737
"px-0 py-8 md:px-12",
3838
"flex-col",
39-
"border-t border-t-search-background",
40-
"md:border-s md:border-s-search-background",
39+
"border-t-search-background border-t",
40+
"md:border-s-search-background md:border-s",
4141
"first:border-t-0",
4242
"lg:[&:first-child]:border-s-0",
43-
"md:[&:nth-child(-n+2)]:border-t-0 lg:[&:nth-child(-n+2)]:border-t lg:[&:nth-child(-n+2)]:border-t-search-background",
44-
"md:[&:nth-child(2n+1)]:border-s-0 lg:[&:nth-child(2n+1)]:border-s lg:[&:nth-child(2n+1)]:border-s-search-background",
43+
"lg:[&:nth-child(-n+2)]:border-t-search-background md:[&:nth-child(-n+2)]:border-t-0 lg:[&:nth-child(-n+2)]:border-t",
44+
"lg:[&:nth-child(2n+1)]:border-s-search-background md:[&:nth-child(2n+1)]:border-s-0 lg:[&:nth-child(2n+1)]:border-s",
4545
"lg:[&:nth-child(-n+3)]:justify-start lg:[&:nth-child(-n+3)]:border-t-0 lg:[&:nth-child(-n+3)]:pt-0",
4646
"lg:[&:nth-child(3n+1)]:border-s-0 lg:[&:nth-child(3n+1)]:ps-0",
4747
"lg:[&:nth-child(n+4)]:justify-start lg:[&:nth-child(n+4)]:pb-0"

src/components/Hero/HomeHero/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const HomeHero = ({ heroImg, className }: HomeHeroProps) => {
2626
<Morpher />
2727
<div className="flex flex-col items-center gap-y-5 lg:max-w-2xl">
2828
<h1 className="font-black">{t("page-index:page-index-title")}</h1>
29-
<p className="max-w-96 text-body-medium">
29+
<p className="max-w-96 text-md text-body-medium lg:text-lg">
3030
{t("page-index:page-index-description")}
3131
</p>
3232
</div>
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
import { forwardRef, useEffect, useRef, useState } from "react"
2+
import { FaCheck } from "react-icons/fa"
3+
import { MdClose } from "react-icons/md"
4+
5+
import EthGlyphSolid from "@/components/icons/eth-glyph-solid.svg"
6+
import Tooltip from "@/components/Tooltip"
7+
8+
import { cn } from "@/lib/utils/cn"
9+
import { isMobile } from "@/lib/utils/isMobile"
10+
import { trackCustomEvent } from "@/lib/utils/matomo"
11+
12+
import { type Pairing, useValuesMarquee } from "../Homepage/useValuesMarquee"
13+
import { Stack } from "../ui/flex"
14+
import {
15+
Section,
16+
SectionContent,
17+
SectionHeader,
18+
SectionTag,
19+
} from "../ui/section"
20+
21+
import { usePrefersReducedMotion } from "@/hooks/usePrefersReducedMotion"
22+
23+
type ItemProps = React.HTMLAttributes<HTMLButtonElement> & {
24+
pairing: Pairing
25+
separatorClass: string
26+
container?: HTMLElement | null
27+
label: string
28+
}
29+
30+
const Item = ({
31+
children,
32+
className,
33+
pairing,
34+
separatorClass,
35+
container,
36+
label,
37+
}: ItemProps) => (
38+
<>
39+
<Tooltip
40+
container={container}
41+
onBeforeOpen={() => {
42+
trackCustomEvent({
43+
eventCategory: "Homepage",
44+
eventAction: "internet_changing",
45+
eventName: label,
46+
})
47+
}}
48+
content={
49+
<Stack>
50+
<h3 className="text-md text-body-medium dark:text-gray-300">
51+
{label}
52+
</h3>
53+
<div className="flex flex-col gap-4">
54+
<div className="flex gap-2 text-body-medium">
55+
<div className="p-1 text-lg">
56+
<MdClose />
57+
</div>
58+
<div>
59+
{pairing.legacy.content.map((line) => (
60+
<p key={line} className="text-sm">
61+
{line}
62+
</p>
63+
))}
64+
</div>
65+
</div>
66+
<div className="flex gap-2 text-body">
67+
<div className="p-1 text-lg">
68+
<EthGlyphSolid />
69+
</div>
70+
<div className="flex flex-col gap-2">
71+
{pairing.ethereum.content.map((line) => (
72+
<p key={line} className="text-sm">
73+
{line}
74+
</p>
75+
))}
76+
</div>
77+
</div>
78+
</div>
79+
</Stack>
80+
}
81+
>
82+
<div
83+
className={cn(
84+
"flex flex-nowrap items-center text-nowrap rounded-full px-4 py-1 font-bold uppercase",
85+
className
86+
)}
87+
>
88+
{children}
89+
</div>
90+
</Tooltip>
91+
<div
92+
className={cn(
93+
"h-1.5 min-w-1.5 rounded-full motion-reduce:last:hidden",
94+
separatorClass
95+
)}
96+
/>
97+
</>
98+
)
99+
100+
type RowProps = React.HTMLAttributes<HTMLDivElement> & {
101+
toRight?: boolean
102+
}
103+
104+
const Row = forwardRef<HTMLDivElement, RowProps>(
105+
({ className, children, toRight }, ref) => {
106+
const { prefersReducedMotion } = usePrefersReducedMotion()
107+
const fadeEdges = {
108+
mask: `linear-gradient(to right, transparent 1rem, white 15%, white 85%, transparent calc(100% - 1rem))`,
109+
}
110+
111+
return (
112+
<div ref={ref} className={cn("group", className)}>
113+
<div
114+
className="flex max-w-full overflow-hidden motion-reduce:overflow-auto"
115+
style={prefersReducedMotion ? {} : fadeEdges}
116+
>
117+
{Array(prefersReducedMotion ? 1 : 3)
118+
.fill(0)
119+
.map((_, idx) => (
120+
<div
121+
key={idx}
122+
className={cn(
123+
"flex min-w-fit items-center space-x-10 px-6 py-8 motion-reduce:w-full motion-reduce:animate-none motion-reduce:justify-center",
124+
isMobile()
125+
? "group-has-[button:hover]:animate-pause"
126+
: "group-hover:animate-pause",
127+
toRight ? "animate-scroll-right" : "animate-scroll-left"
128+
)}
129+
>
130+
{children}
131+
</div>
132+
))}
133+
</div>
134+
</div>
135+
)
136+
}
137+
)
138+
Row.displayName = "Row"
139+
140+
const ValuesMarquee = () => {
141+
const { t, pairings } = useValuesMarquee()
142+
const containerFirstRef = useRef<HTMLDivElement>(null)
143+
const containerSecondRef = useRef<HTMLDivElement>(null)
144+
145+
const [containerFirst, setContainerFirst] = useState<HTMLDivElement | null>(
146+
null
147+
)
148+
const [containerSecond, setContainerSecond] = useState<HTMLDivElement | null>(
149+
null
150+
)
151+
152+
useEffect(() => {
153+
if (containerFirstRef.current) {
154+
setContainerFirst(containerFirstRef.current)
155+
}
156+
if (containerSecondRef.current) {
157+
setContainerSecond(containerSecondRef.current)
158+
}
159+
}, [])
160+
161+
return (
162+
<Section id="values" className="!sm:my-64 !my-48 scroll-m-48">
163+
<SectionContent className="flex flex-col items-center text-center">
164+
<SectionTag>{t("page-index:page-index-values-tag")}</SectionTag>
165+
<SectionHeader>
166+
{t("page-index:page-index-values-header")}
167+
</SectionHeader>
168+
<p className="text-lg text-body-medium">
169+
{t("page-index:page-index-values-description")}
170+
</p>
171+
</SectionContent>
172+
<div className="relative mt-19 overflow-hidden max-2xl:-mx-4 2xl:rounded-2xl">
173+
<Row
174+
ref={containerFirstRef}
175+
className="border-b border-background bg-blue-50 dark:bg-blue-600"
176+
>
177+
{pairings.map((pairing) => (
178+
<Item
179+
key={pairing.ethereum.label}
180+
label={pairing.ethereum.label}
181+
container={containerFirst}
182+
pairing={pairing}
183+
separatorClass="bg-accent-a"
184+
className="group/item bg-blue-100 text-blue-600 hover:bg-blue-600 hover:text-white dark:hover:bg-blue-700"
185+
>
186+
<FaCheck className="me-1 text-success group-hover/item:text-white" />
187+
{pairing.ethereum.label}
188+
</Item>
189+
))}
190+
</Row>
191+
192+
<Row
193+
ref={containerSecondRef}
194+
className="border-t border-background bg-gray-50 dark:bg-gray-800"
195+
toRight
196+
>
197+
{pairings.map((pairing) => (
198+
<Item
199+
key={pairing.legacy.label}
200+
label={pairing.legacy.label}
201+
container={containerSecond}
202+
pairing={pairing}
203+
className="bg-gray-200/20 text-body-medium hover:bg-gray-600 hover:text-white dark:bg-gray-950 dark:text-body"
204+
separatorClass="bg-gray-200 dark:bg-gray-950"
205+
>
206+
{pairing.legacy.label}
207+
</Item>
208+
))}
209+
</Row>
210+
211+
<div className="absolute start-[50%] top-[50%] flex -translate-x-[50%] -translate-y-[50%] items-center overflow-hidden rounded-lg text-sm font-bold">
212+
<p className="bg-gray-50 px-4 py-1 text-body-medium dark:bg-gray-800 dark:text-gray-200">
213+
{t("page-index-values-legacy")}
214+
</p>
215+
216+
<div
217+
className={cn(
218+
"border-t-[15px] border-t-blue-50 dark:border-t-blue-600",
219+
"border-r-8 border-r-blue-50 dark:border-r-blue-600",
220+
"border-b-[15px] border-b-gray-50 dark:border-b-gray-800",
221+
"border-l-8 border-l-gray-50 dark:border-l-gray-800"
222+
)}
223+
/>
224+
225+
<p className="bg-blue-50 px-4 py-1 text-accent-a dark:bg-blue-600 dark:text-white">
226+
{t("common:ethereum")}
227+
</p>
228+
</div>
229+
</div>
230+
</Section>
231+
)
232+
}
233+
234+
export default ValuesMarquee
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { useTranslation } from "next-i18next"
2+
3+
type Item = {
4+
label: string
5+
content: string[]
6+
}
7+
8+
export type Pairing = {
9+
legacy: Item
10+
ethereum: Item
11+
}
12+
13+
export const useValuesMarquee = () => {
14+
const { t } = useTranslation("page-index")
15+
const pairings: Pairing[] = [
16+
{
17+
legacy: {
18+
label: t("page-index-values-ownership-legacy-label"),
19+
content: [
20+
t("page-index-values-ownership-legacy-content-0"),
21+
t("page-index-values-ownership-legacy-content-1"),
22+
],
23+
},
24+
ethereum: {
25+
label: t("page-index-values-ownership-ethereum-label"),
26+
content: [t("page-index-values-ownership-ethereum-content-0")],
27+
},
28+
},
29+
{
30+
legacy: {
31+
label: t("page-index-values-fairness-legacy-label"),
32+
content: [t("page-index-values-fairness-legacy-content-0")],
33+
},
34+
ethereum: {
35+
label: t("page-index-values-fairness-ethereum-label"),
36+
content: [t("page-index-values-fairness-ethereum-content-0")],
37+
},
38+
},
39+
{
40+
legacy: {
41+
label: t("page-index-values-privacy-legacy-label"),
42+
content: [
43+
t("page-index-values-privacy-legacy-content-0"),
44+
t("page-index-values-privacy-legacy-content-1"),
45+
],
46+
},
47+
ethereum: {
48+
label: t("page-index-values-privacy-ethereum-label"),
49+
content: [t("page-index-values-privacy-ethereum-content-0")],
50+
},
51+
},
52+
{
53+
legacy: {
54+
label: t("page-index-values-integration-legacy-label"),
55+
content: [t("page-index-values-integration-legacy-content-0")],
56+
},
57+
ethereum: {
58+
label: t("page-index-values-integration-ethereum-label"),
59+
content: [t("page-index-values-integration-ethereum-content-0")],
60+
},
61+
},
62+
{
63+
legacy: {
64+
label: t("page-index-values-decentralization-legacy-label"),
65+
content: [t("page-index-values-decentralization-legacy-content-0")],
66+
},
67+
ethereum: {
68+
label: t("page-index-values-decentralization-ethereum-label"),
69+
content: [t("page-index-values-decentralization-ethereum-content-0")],
70+
},
71+
},
72+
{
73+
legacy: {
74+
label: t("page-index-values-censorship-legacy-label"),
75+
content: [t("page-index-values-censorship-legacy-content-0")],
76+
},
77+
ethereum: {
78+
label: t("page-index-values-censorship-ethereum-label"),
79+
content: [
80+
t("page-index-values-censorship-ethereum-content-0"),
81+
t("page-index-values-censorship-ethereum-content-1"),
82+
],
83+
},
84+
},
85+
{
86+
legacy: {
87+
label: t("page-index-values-open-legacy-label"),
88+
content: [t("page-index-values-open-legacy-content-0")],
89+
},
90+
ethereum: {
91+
label: t("page-index-values-open-ethereum-label"),
92+
content: [t("page-index-values-open-ethereum-content-0")],
93+
},
94+
},
95+
]
96+
97+
return { t, pairings }
98+
}

0 commit comments

Comments
 (0)