Skip to content

Commit 100cc2b

Browse files
committed
Refactor component API
1 parent 7a46b2d commit 100cc2b

File tree

3 files changed

+47
-79
lines changed

3 files changed

+47
-79
lines changed

src/components/ui/sidebar.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { Input } from './input'
1010
import { Separator } from './separator'
1111
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from './sheet'
1212
import { Skeleton } from './skeleton'
13-
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './tooltip'
13+
import { Tooltip, TooltipProvider } from './tooltip'
1414

1515
const SIDEBAR_COOKIE_NAME = 'sidebar_state'
1616
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
@@ -477,7 +477,7 @@ function SidebarMenuButton({
477477
}: React.ComponentProps<'button'> & {
478478
asChild?: boolean
479479
isActive?: boolean
480-
tooltip?: string | React.ComponentProps<typeof TooltipContent>
480+
tooltip?: string | { children: React.ReactNode; sideOffset?: number }
481481
} & VariantProps<typeof sidebarMenuButtonVariants>) {
482482
const Comp = asChild ? Slot : 'button'
483483
const { isMobile, state } = useSidebar()
@@ -504,9 +504,13 @@ function SidebarMenuButton({
504504
}
505505

506506
return (
507-
<Tooltip>
508-
<TooltipTrigger asChild>{button}</TooltipTrigger>
509-
<TooltipContent side="right" align="center" hidden={state !== 'collapsed' || isMobile} {...tooltip} />
507+
<Tooltip
508+
title={typeof tooltip === 'string' ? tooltip : tooltip.children}
509+
side="right"
510+
sideOffset={typeof tooltip === 'string' ? undefined : tooltip.sideOffset}
511+
hidden={state !== 'collapsed' || isMobile}
512+
>
513+
{button}
510514
</Tooltip>
511515
)
512516
}

src/components/ui/tooltip.tsx

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,23 @@ import * as TooltipPrimitive from '@radix-ui/react-tooltip'
33

44
import { cn } from '../../lib/utils'
55

6-
function TooltipProvider({
6+
const TooltipProvider = ({
77
delayDuration = 0,
88
...props
9-
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
9+
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) => {
1010
return <TooltipPrimitive.Provider data-slot="tooltip-provider" delayDuration={delayDuration} {...props} />
1111
}
1212

13-
function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {
14-
return (
15-
<TooltipProvider>
16-
<TooltipPrimitive.Root data-slot="tooltip" {...props} />
17-
</TooltipProvider>
18-
)
19-
}
20-
21-
function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
13+
const TooltipTrigger = ({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) => {
2214
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
2315
}
2416

25-
function TooltipContent({
17+
const TooltipContent = ({
2618
className,
2719
sideOffset = 0,
2820
children,
2921
...props
30-
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
22+
}: React.ComponentProps<typeof TooltipPrimitive.Content>) => {
3123
return (
3224
<TooltipPrimitive.Portal>
3325
<TooltipPrimitive.Content
@@ -46,4 +38,25 @@ function TooltipContent({
4638
)
4739
}
4840

41+
type TooltipProps = React.ComponentProps<typeof TooltipPrimitive.Root> & {
42+
title: React.ReactNode
43+
side?: 'top' | 'right' | 'bottom' | 'left'
44+
sideOffset?: number
45+
hidden?: boolean
46+
align?: 'start' | 'center' | 'end'
47+
}
48+
49+
function Tooltip({ title, children, side, sideOffset, hidden, align, ...props }: TooltipProps) {
50+
return (
51+
<TooltipProvider>
52+
<TooltipPrimitive.Root data-slot="tooltip" {...props}>
53+
<TooltipTrigger>{children}</TooltipTrigger>
54+
<TooltipContent side={side} sideOffset={sideOffset} hidden={hidden} align={align}>
55+
{title}
56+
</TooltipContent>
57+
</TooltipPrimitive.Root>
58+
</TooltipProvider>
59+
)
60+
}
61+
4962
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
Lines changed: 12 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Meta, StoryObj } from '@storybook/react-vite'
2-
import { Tooltip, TooltipContent, TooltipTrigger } from '../../components/ui/tooltip.tsx'
2+
import { Tooltip } from '../../components/ui/tooltip.tsx'
33
import { Button } from '../../components/ui/button.tsx'
44
import { expect, within } from 'storybook/test'
55

@@ -21,6 +21,15 @@ const meta: Meta<typeof Tooltip> = {
2121
},
2222
tags: ['autodocs'],
2323
argTypes: {
24+
title: {
25+
control: 'text',
26+
description: 'The content of the tooltip',
27+
},
28+
side: {
29+
control: { type: 'radio' },
30+
options: ['top', 'right', 'bottom', 'left'],
31+
description: 'The preferred side of the trigger to render against',
32+
},
2433
defaultOpen: {
2534
control: 'boolean',
2635
},
@@ -38,70 +47,12 @@ type Story = StoryObj<typeof meta>
3847

3948
export const Default: Story = {
4049
args: {
41-
children: (
42-
<>
43-
<TooltipTrigger>
44-
<Button variant="outline">Hover me</Button>
45-
</TooltipTrigger>
46-
<TooltipContent>
47-
<p>Tooltip content</p>
48-
</TooltipContent>
49-
</>
50-
),
50+
title: 'Tooltip content',
51+
children: <Button variant="outline">Hover me</Button>,
5152
},
5253
play: async ({ canvasElement }) => {
5354
const canvas = within(canvasElement)
5455
const button = canvas.getAllByRole('button', { name: 'Hover me' })[0]
5556
await expect(button).toBeInTheDocument()
5657
},
5758
}
58-
59-
export const Variants: Story = {
60-
args: {
61-
children: (
62-
<div className="flex flex-col items-center gap-4">
63-
<div className="flex justify-center gap-4">
64-
<Tooltip>
65-
<TooltipTrigger>
66-
<Button variant="outline">Top</Button>
67-
</TooltipTrigger>
68-
<TooltipContent side="top">
69-
<p>Tooltip on top</p>
70-
</TooltipContent>
71-
</Tooltip>
72-
</div>
73-
74-
<div className="flex justify-between gap-16">
75-
<Tooltip>
76-
<TooltipTrigger>
77-
<Button variant="outline">Left</Button>
78-
</TooltipTrigger>
79-
<TooltipContent side="left">
80-
<p>Tooltip on left</p>
81-
</TooltipContent>
82-
</Tooltip>
83-
84-
<Tooltip>
85-
<TooltipTrigger>
86-
<Button variant="outline">Right</Button>
87-
</TooltipTrigger>
88-
<TooltipContent side="right">
89-
<p>Tooltip on right</p>
90-
</TooltipContent>
91-
</Tooltip>
92-
</div>
93-
94-
<div className="flex justify-center gap-4">
95-
<Tooltip>
96-
<TooltipTrigger>
97-
<Button variant="outline">Bottom</Button>
98-
</TooltipTrigger>
99-
<TooltipContent side="bottom">
100-
<p>Tooltip on bottom</p>
101-
</TooltipContent>
102-
</Tooltip>
103-
</div>
104-
</div>
105-
),
106-
},
107-
}

0 commit comments

Comments
 (0)