Skip to content

Commit 1ee1ae5

Browse files
committed
Merge branch 'dev' into shadcn-nav
2 parents 720e267 + b8922bd commit 1ee1ae5

21 files changed

+979
-976
lines changed

.storybook/preview.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import isChromatic from "chromatic/isChromatic"
22
import { MotionGlobalConfig } from "framer-motion"
3-
import { withThemeByDataAttribute } from "@storybook/addon-themes"
43
import type { Preview } from "@storybook/react"
54

65
import ThemeProvider from "@/components/ThemeProvider"
76

87
import i18n, { baseLocales } from "./i18next"
8+
import { withNextThemes } from "./withNextThemes"
99

1010
import "@docsearch/css"
1111
import "../src/styles/global.css"
@@ -29,7 +29,7 @@ const preview: Preview = {
2929
locales: baseLocales,
3030
},
3131
decorators: [
32-
withThemeByDataAttribute({
32+
withNextThemes({
3333
themes: {
3434
light: "light",
3535
dark: "dark",

.storybook/withNextThemes.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { useEffect } from "react"
2+
import { useTheme } from "next-themes"
3+
import {
4+
type DataAttributeStrategyConfiguration,
5+
DecoratorHelpers,
6+
} from "@storybook/addon-themes"
7+
import type { Decorator } from "@storybook/react/*"
8+
9+
const { initializeThemeState, pluckThemeFromContext } = DecoratorHelpers
10+
11+
export const withNextThemes = ({
12+
themes,
13+
defaultTheme,
14+
}: DataAttributeStrategyConfiguration): Decorator => {
15+
initializeThemeState(Object.keys(themes), defaultTheme)
16+
17+
return (getStory, context) => {
18+
const selectedTheme = pluckThemeFromContext(context)
19+
const selected = selectedTheme || defaultTheme
20+
const { setTheme } = useTheme()
21+
22+
useEffect(() => {
23+
setTheme(selected)
24+
}, [selected, setTheme])
25+
26+
return getStory(context)
27+
}
28+
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ethereum-org-website",
3-
"version": "8.9.0",
3+
"version": "8.10.0",
44
"license": "MIT",
55
"private": true,
66
"scripts": {
@@ -46,6 +46,7 @@
4646
"@radix-ui/react-radio-group": "^1.2.0",
4747
"@radix-ui/react-slot": "^1.1.0",
4848
"@radix-ui/react-switch": "^1.1.0",
49+
"@radix-ui/react-tooltip": "^1.1.2",
4950
"@radix-ui/react-visually-hidden": "^1.1.0",
5051
"@sentry/nextjs": "^8.19.0",
5152
"@socialgouv/matomo-next": "^1.8.0",
@@ -63,7 +64,6 @@
6364
"lodash.merge": "^4.6.2",
6465
"lodash.shuffle": "^4.2.0",
6566
"lodash.union": "^4.6.0",
66-
"lucide-react": "^0.400.0",
6767
"next": "^14.2.3",
6868
"next-i18next": "^14.0.3",
6969
"next-mdx-remote": "^3.0.8",

src/components/ExpandableCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const ExpandableCard = ({
5959
borderColor="border"
6060
borderRadius="sm"
6161
display="flex"
62-
flex-direction="column"
62+
flexDirection="column"
6363
marginBottom="4"
6464
cursor="pointer"
6565
_hover={{

src/components/Glossary/GlossaryTooltip/GlossaryTooltip.stories.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { Center } from "@chakra-ui/react"
22
import { Meta, StoryObj } from "@storybook/react"
33

4+
import { TooltipProvider } from "@/components/ui/tooltip"
5+
46
import GlossaryTooltipComponent from "."
57

68
const meta = {
@@ -13,7 +15,9 @@ const meta = {
1315
decorators: [
1416
(Story) => (
1517
<Center boxSize="md">
16-
<Story />
18+
<TooltipProvider>
19+
<Story />
20+
</TooltipProvider>
1721
</Center>
1822
),
1923
],
@@ -28,6 +32,6 @@ export const Basic: Story = {}
2832
// for chromatic story snapshot showing the rendered popover
2933
export const OnOpen: Story = {
3034
args: {
31-
isOpen: true,
35+
open: true,
3236
},
3337
}

src/components/Glossary/GlossaryTooltip/index.tsx

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import React, { ReactNode } from "react"
22
import { useRouter } from "next/router"
3-
import { Box, Text, VStack } from "@chakra-ui/react"
43

5-
import Heading from "@/components/Heading"
64
import InlineLink from "@/components/Link"
75
import Tooltip, { type TooltipProps } from "@/components/Tooltip"
86
import Translation from "@/components/Translation"
@@ -23,36 +21,36 @@ const GlossaryTooltip = ({
2321
const { asPath } = useRouter()
2422

2523
return (
26-
<Box as="span" display="inline-block">
24+
<span className="inline-block">
2725
<Tooltip
2826
{...props}
2927
content={
30-
<VStack spacing={2} align="stretch" textAlign="start">
31-
<Heading as="h6">
28+
<div className="flex flex-col items-stretch gap-2 text-start">
29+
<h6>
3230
<Translation
3331
id={termKey + "-term"}
3432
options={{ ns: "glossary-tooltip" }}
3533
// Override the default `a` tag transformation to avoid circular
3634
// dependency issues
3735
transform={{ a: InlineLink }}
3836
/>
39-
</Heading>
37+
</h6>
4038
{/**
4139
* `as="span"` prevents hydration warnings for strings that contain
4240
* elements that cannot be nested inside `p` tags, like `ul` tags
4341
* (found in some Glossary definition).
4442
* TODO: Develop a better solution to handle this case.
4543
*/}
46-
<Text as="span">
44+
<span>
4745
<Translation
4846
id={termKey + "-definition"}
4947
options={{ ns: "glossary-tooltip" }}
5048
// Override the default `a` tag transformation to avoid circular
5149
// dependency issues
5250
transform={{ a: InlineLink }}
5351
/>
54-
</Text>
55-
</VStack>
52+
</span>
53+
</div>
5654
}
5755
onBeforeOpen={() => {
5856
trackCustomEvent({
@@ -62,20 +60,11 @@ const GlossaryTooltip = ({
6260
})
6361
}}
6462
>
65-
<Text
66-
as="u"
67-
textDecorationStyle="dotted"
68-
textUnderlineOffset="3px"
69-
_hover={{
70-
textDecorationColor: "primary.hover",
71-
color: "primary.hover",
72-
}}
73-
cursor="help"
74-
>
63+
<u className="cursor-help decoration-dotted underline-offset-3 hover:text-primary-hover hover:decoration-primary-hover">
7564
{children}
76-
</Text>
65+
</u>
7766
</Tooltip>
78-
</Box>
67+
</span>
7968
)
8069
}
8170

src/components/Tooltip/Tooltip.stories.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Meta, StoryObj } from "@storybook/react"
44

55
import InlineLink from "../Link"
66
import Translation from "../Translation"
7+
import { TooltipProvider } from "../ui/tooltip"
78

89
// TODO: remove `index` when we delete the old tooltip
910
import TooltipComponent from "./index"
@@ -46,7 +47,9 @@ const meta = {
4647
decorators: [
4748
(Story) => (
4849
<Center boxSize="md">
49-
<Story />
50+
<TooltipProvider>
51+
<Story />
52+
</TooltipProvider>
5053
</Center>
5154
),
5255
],
@@ -61,6 +64,6 @@ export const Basic: Story = {}
6164
// for chromatic story snapshot showing the rendered popover
6265
export const OnOpen: Story = {
6366
args: {
64-
isOpen: true,
67+
open: true,
6568
},
6669
}

src/components/Tooltip/index.tsx

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import React, { ReactNode, useEffect } from "react"
2-
import {
3-
Popover,
4-
PopoverArrow,
5-
PopoverBody,
6-
PopoverContent,
7-
PopoverProps,
8-
PopoverTrigger,
9-
Portal,
10-
useDisclosure,
11-
} from "@chakra-ui/react"
1+
import React, { ComponentProps, ReactNode, useEffect } from "react"
122

133
import { isMobile } from "@/lib/utils/isMobile"
144

15-
export interface TooltipProps extends PopoverProps {
5+
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"
6+
import {
7+
Tooltip as Tooltipcomponent,
8+
TooltipContent,
9+
TooltipTrigger,
10+
} from "../ui/tooltip"
11+
12+
import { useDisclosure } from "@/hooks/useDisclosure"
13+
import { useIsClient } from "@/hooks/useIsClient"
14+
15+
export type TooltipProps = ComponentProps<typeof Popover> & {
1616
content: ReactNode
1717
children?: ReactNode
1818
onBeforeOpen?: () => void
@@ -22,9 +22,10 @@ const Tooltip = ({
2222
content,
2323
children,
2424
onBeforeOpen,
25-
...rest
25+
...props
2626
}: TooltipProps) => {
2727
const { isOpen, onOpen, onClose } = useDisclosure()
28+
const isClient = useIsClient()
2829

2930
// Close the popover when the user scrolls.
3031
// This is useful for mobile devices where the popover is open by clicking the
@@ -57,24 +58,39 @@ const Tooltip = ({
5758
onOpen()
5859
}
5960

61+
const handleOpenChange = (open: boolean) => {
62+
if (open) {
63+
handleOpen()
64+
} else {
65+
onClose()
66+
}
67+
}
68+
69+
// Avoid rendering on the server since the user can't interact with it and we
70+
// need to use different components depending on the device
71+
if (!isClient) {
72+
return null
73+
}
74+
75+
// Use Popover on mobile devices since the user can't hover
76+
const Component = isMobile() ? Popover : Tooltipcomponent
77+
const Trigger = isMobile() ? PopoverTrigger : TooltipTrigger
78+
const Content = isMobile() ? PopoverContent : TooltipContent
79+
6080
return (
61-
<Popover
62-
isOpen={isOpen}
63-
onOpen={handleOpen}
64-
onClose={onClose}
65-
placement="top"
66-
trigger={isMobile() ? "click" : "hover"}
67-
gutter={8}
68-
{...rest}
69-
>
70-
<PopoverTrigger>{children}</PopoverTrigger>
71-
<Portal>
72-
<PopoverContent data-testid="tooltip-popover">
73-
<PopoverArrow />
74-
<PopoverBody>{content}</PopoverBody>
75-
</PopoverContent>
76-
</Portal>
77-
</Popover>
81+
<Component open={isOpen} onOpenChange={handleOpenChange} {...props}>
82+
<Trigger className="focus-visible:rounded-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-hover">
83+
{children}
84+
</Trigger>
85+
<Content
86+
side="top"
87+
sideOffset={2}
88+
className="w-80 px-5 text-sm"
89+
data-testid="tooltip-popover"
90+
>
91+
{content}
92+
</Content>
93+
</Component>
7894
)
7995
}
8096

src/components/ui/dialog.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from "react"
2-
import { X } from "lucide-react"
2+
import { MdClose } from "react-icons/md"
33
import * as DialogPrimitive from "@radix-ui/react-dialog"
44

55
import { cn } from "@/lib/utils/cn"
@@ -43,7 +43,7 @@ const DialogContent = React.forwardRef<
4343
>
4444
{children}
4545
<DialogPrimitive.Close className="focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none">
46-
<X className="h-4 w-4" />
46+
<MdClose className="h-4 w-4" />
4747
<span className="sr-only">Close</span>
4848
</DialogPrimitive.Close>
4949
</DialogPrimitive.Content>

src/components/ui/popover.tsx

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,28 @@ const PopoverTrigger = PopoverPrimitive.Trigger
1010
const PopoverContent = React.forwardRef<
1111
React.ElementRef<typeof PopoverPrimitive.Content>,
1212
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
13-
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
14-
<PopoverPrimitive.Portal>
15-
<PopoverPrimitive.Content
16-
ref={ref}
17-
align={align}
18-
sideOffset={sideOffset}
19-
className={cn(
20-
"text-popover-foreground z-popover w-72 rounded-md border bg-background p-4 shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
21-
className
22-
)}
23-
{...props}
24-
/>
25-
</PopoverPrimitive.Portal>
26-
))
13+
>(
14+
(
15+
{ className, children, align = "center", sideOffset = 4, ...props },
16+
ref
17+
) => (
18+
<PopoverPrimitive.Portal>
19+
<PopoverPrimitive.Content
20+
ref={ref}
21+
align={align}
22+
sideOffset={sideOffset}
23+
className={cn(
24+
"text-popover-foreground z-popover w-72 rounded border border-background-highlight bg-background-highlight p-4 shadow-lg outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
25+
className
26+
)}
27+
{...props}
28+
>
29+
{children}
30+
<PopoverPrimitive.Arrow className="z-popover fill-background-highlight" />
31+
</PopoverPrimitive.Content>
32+
</PopoverPrimitive.Portal>
33+
)
34+
)
2735
PopoverContent.displayName = PopoverPrimitive.Content.displayName
2836

2937
const PopoverClose = PopoverPrimitive.Close

0 commit comments

Comments
 (0)