Skip to content

Commit 538cac5

Browse files
authored
Merge pull request #14684 from ethereum/cardlist-shadcn
feat: migrate CardList to tailwind
2 parents 36bb7f2 + 4ced742 commit 538cac5

File tree

6 files changed

+66
-87
lines changed

6 files changed

+66
-87
lines changed

src/components/CardList.tsx

Lines changed: 51 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,17 @@
1-
import Image, { type ImageProps } from "next/image"
1+
import TwImage, { type ImageProps } from "next/image"
22
import type { ReactNode } from "react"
3-
import {
4-
Box,
5-
type BoxProps,
6-
Flex,
7-
HStack,
8-
LinkBox,
9-
LinkOverlay,
10-
type StackProps,
11-
useColorModeValue,
12-
} from "@chakra-ui/react"
133

14-
import { BaseLink } from "@/components/Link"
4+
import { LinkBox, LinkOverlay } from "@/components/ui/link-box"
155

6+
import { cn } from "@/lib/utils/cn"
167
import { MatomoEventOptions, trackCustomEvent } from "@/lib/utils/matomo"
178
import * as url from "@/lib/utils/url"
189

10+
import { BaseLink } from "./ui/Link"
11+
1912
import { useRtlFlip } from "@/hooks/useRtlFlip"
2013

21-
export type CardListItem = {
14+
export type CardProps = {
2215
title?: ReactNode
2316
description?: ReactNode
2417
caption?: ReactNode
@@ -27,93 +20,77 @@ export type CardListItem = {
2720
image?: ImageProps["src"]
2821
imageWidth?: number
2922
alt?: string
23+
className?: string
24+
onClick?: () => void
3025
}
3126

32-
const CardContainer = (props: StackProps) => (
33-
<HStack
34-
spacing={4}
35-
p={4}
36-
color="text"
37-
border="1px solid"
38-
borderColor="border"
39-
_hover={{
40-
borderRadius: "base",
41-
boxShadow: "0 0 1px var(--eth-colors-primary)",
42-
background: "tableBackgroundHover",
43-
}}
44-
{...props}
45-
/>
46-
)
47-
48-
type CardProps = CardListItem & Omit<StackProps, "title" | "id">
49-
5027
const Card = ({
5128
title,
5229
description,
5330
caption,
5431
link,
5532
image,
56-
imageWidth = 20, // Set 20px as default image width, can be overridden if needed
33+
className,
5734
alt,
35+
onClick,
36+
imageWidth = 20,
5837
...props
5938
}: CardProps) => {
60-
const { flipForRtl } = useRtlFlip()
39+
const { twFlipForRtl } = useRtlFlip()
6140
const isLink = !!link
6241
const isExternal = url.isExternal(link || "")
6342

64-
const descriptionColor = useColorModeValue("gray.500", "gray.400")
65-
6643
return (
67-
<CardContainer {...props}>
68-
{image && <Image src={image} alt={alt ?? ""} width={imageWidth} />}
69-
<Flex flex="1 1 75%" direction="column">
44+
<div
45+
className={cn(
46+
"text-text flex flex-row items-center gap-4 border p-4",
47+
"transition-all duration-200",
48+
"hover:bg-background-highlight",
49+
className
50+
)}
51+
onClick={onClick}
52+
{...props}
53+
>
54+
{image && <TwImage src={image} alt={alt ?? ""} width={imageWidth} />}
55+
<div className="flex flex-1 basis-3/4 flex-col">
7056
{isLink ? (
71-
<LinkOverlay
72-
as={BaseLink}
73-
href={link}
74-
isExternal={isExternal}
75-
hideArrow
76-
color="text"
77-
textDecoration="none"
78-
_hover={{ textDecoration: "none" }}
79-
>
80-
{title}
57+
<LinkOverlay asChild>
58+
<BaseLink href={link} hideArrow className="text-body no-underline">
59+
{title}
60+
</BaseLink>
8161
</LinkOverlay>
8262
) : (
83-
<Box>{title}</Box>
63+
<div>{title}</div>
8464
)}
8565

86-
<Box fontSize="sm" mb={0} color={descriptionColor}>
87-
{description}
88-
</Box>
89-
</Flex>
66+
<div className="mb-0 text-sm text-body-medium">{description}</div>
67+
</div>
9068
{caption && (
91-
<Flex flex="1 0 25%" align="center" wrap="wrap" me={4}>
92-
<Box fontSize="sm" mb={0} opacity={0.6}>
93-
{caption}
94-
</Box>
95-
</Flex>
69+
<div className="me-4 flex flex-[1_0_25%] flex-wrap items-center">
70+
<div className="mb-0 text-sm opacity-60">{caption}</div>
71+
</div>
9672
)}
97-
{isExternal && <Box transform={flipForRtl}></Box>}
98-
</CardContainer>
73+
{isExternal && <span className={twFlipForRtl}></span>}
74+
</div>
9975
)
10076
}
10177

102-
export type CardListProps = BoxProps & {
78+
export type CardListProps = {
10379
items: CardProps[]
10480
imageWidth?: number
10581
clickHandler?: (idx: string | number) => void
10682
customEventOptions?: MatomoEventOptions
83+
className?: string
10784
}
10885

10986
const CardList = ({
11087
items,
11188
imageWidth,
11289
clickHandler = () => null,
11390
customEventOptions,
114-
...props
91+
className,
11592
}: CardListProps) => (
116-
<Box bg="background.base" w="full" {...props}>
93+
<div className={cn("w-full bg-background", className)}>
11794
{items.map((listItem, idx) => {
11895
const { link, id } = listItem
11996
const isLink = !!link
@@ -123,18 +100,19 @@ const CardList = ({
123100
<Card {...listItem} imageWidth={imageWidth} />
124101
</LinkBox>
125102
) : (
126-
<Card
127-
key={idx}
128-
onClick={() => {
129-
customEventOptions && trackCustomEvent(customEventOptions)
130-
clickHandler(idx)
131-
}}
132-
mb={4}
133-
{...listItem}
134-
/>
103+
<div key={idx}>
104+
<Card
105+
onClick={() => {
106+
customEventOptions && trackCustomEvent(customEventOptions)
107+
clickHandler(idx)
108+
}}
109+
className="mb-4"
110+
{...listItem}
111+
/>
112+
</div>
135113
)
136114
})}
137-
</Box>
115+
</div>
138116
)
139117

140118
export default CardList

src/components/MergeArticleList.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { useTranslation } from "next-i18next"
22

3-
import CardList, { type CardListItem } from "@/components/CardList"
3+
import CardList, { type CardProps } from "@/components/CardList"
44

55
const MergeArticleList = () => {
66
const { t } = useTranslation(["page-upgrades", "page-upgrades-index"])
77

8-
const reads: CardListItem[] = [
8+
const reads: CardProps[] = [
99
{
1010
title: t("page-upgrades-index:page-upgrade-article-title-ethmerge"),
1111
description: t(

src/components/StablecoinAccordion/useStablecoinAccordion.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useTranslation } from "next-i18next"
22

3-
import { CardListItem } from "../CardList"
3+
import { type CardProps } from "@/components/CardList"
44

55
import aaveImg from "@/public/images/dapps/aave.png"
66
// -- borrow
@@ -25,7 +25,7 @@ import ethImg from "@/public/images/favicon.png"
2525
export const useStablecoinAccordion = () => {
2626
const { t } = useTranslation("page-stablecoins")
2727

28-
const dapps: Array<CardListItem> = [
28+
const dapps: Array<CardProps> = [
2929
{
3030
title: "Uniswap",
3131
image: uniImg,
@@ -52,7 +52,7 @@ export const useStablecoinAccordion = () => {
5252
},
5353
]
5454

55-
const borrow: Array<CardListItem> = [
55+
const borrow: Array<CardProps> = [
5656
{
5757
title: "Compound",
5858
image: compoundImg,
@@ -73,7 +73,7 @@ export const useStablecoinAccordion = () => {
7373
},
7474
]
7575

76-
const earn: Array<CardListItem> = [
76+
const earn: Array<CardProps> = [
7777
{
7878
title: t("page-stablecoins-accordion-earn-project-bounties"),
7979
image: gitcoinImg,
@@ -90,7 +90,7 @@ export const useStablecoinAccordion = () => {
9090
},
9191
]
9292

93-
const exchanges: Array<CardListItem> = [
93+
const exchanges: Array<CardProps> = [
9494
{
9595
title: "Coinbase",
9696
image: coinbaseImg,

src/components/Staking/StakingGuides.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { useTranslation } from "next-i18next"
22

3-
import CardList, { type CardListItem } from "@/components/CardList"
3+
import CardList, { type CardProps } from "@/components/CardList"
44

55
const StakingGuides = () => {
66
const { t } = useTranslation("page-staking")
77

8-
const guides: CardListItem[] = [
8+
const guides: CardProps[] = [
99
{
1010
title: t("page-staking-guide-title-coincashew-ethereum"),
1111
link: "https://www.coincashew.com/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet",

src/pages/get-eth.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ import type { ReactNode } from "react"
66
import type { BasePageProps, ChildOnlyProp, Lang } from "@/lib/types"
77

88
import CalloutBanner from "@/components/CalloutBanner"
9-
import type { CardListItem } from "@/components/CardList"
10-
import CardList from "@/components/CardList"
9+
import CardList, {
10+
type CardProps as CardListCardProps,
11+
} from "@/components/CardList"
1112
import CentralizedExchanges from "@/components/CentralizedExchanges"
1213
import Emoji from "@/components/Emoji"
1314
import EthPriceCard from "@/components/EthPriceCard"
@@ -110,7 +111,7 @@ const GetEthPage = ({
110111
md: "50%",
111112
})
112113

113-
const tokenSwaps: CardListItem[] = [
114+
const tokenSwaps: CardListCardProps[] = [
114115
{
115116
title: "Uniswap",
116117
link: "https://app.uniswap.org/#/swap",
@@ -137,7 +138,7 @@ const GetEthPage = ({
137138
},
138139
]
139140

140-
const safetyArticles: CardListItem[] = [
141+
const safetyArticles: CardListCardProps[] = [
141142
{
142143
title: t("page-get-eth-article-protecting-yourself"),
143144
link: "https://support.mycrypto.com/staying-safe/protecting-yourself-and-your-funds",

src/pages/wallets/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ const WalletsPage = () => {
306306
>
307307
<Text>{t("page-wallets-description")}</Text>
308308
<Text>{t("page-wallets-desc-2")}</Text>
309-
<CardList items={guides} mb={{ base: 6, lg: 0 }} />
309+
<CardList items={guides} className="mb-6 lg:mb-0" />
310310
</Box>
311311
<RightColumn>
312312
<Text>{t("page-wallets-desc-3")}</Text>

0 commit comments

Comments
 (0)