Skip to content

Commit 91ad143

Browse files
refactor(popover): convert some popovers to menus properly (#839)
1 parent b463ee6 commit 91ad143

File tree

7 files changed

+411
-371
lines changed

7 files changed

+411
-371
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"use client";
2+
3+
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
4+
5+
import { cn } from "@/utils/tailwind-merge";
6+
7+
function Root({ ...props }: MenuPrimitive.Root.Props) {
8+
return <MenuPrimitive.Root {...props} />;
9+
}
10+
11+
function Trigger({ className, ...props }: MenuPrimitive.Trigger.Props) {
12+
return <MenuPrimitive.Trigger className={cn(className)} {...props} />;
13+
}
14+
15+
function Portal(props: MenuPrimitive.Portal.Props) {
16+
return <MenuPrimitive.Portal {...props} />;
17+
}
18+
19+
function Positioner({
20+
className,
21+
sideOffset = 1,
22+
...props
23+
}: MenuPrimitive.Positioner.Props) {
24+
return (
25+
<MenuPrimitive.Positioner
26+
className={cn("z-[51]", className)}
27+
sideOffset={sideOffset}
28+
{...props}
29+
/>
30+
);
31+
}
32+
33+
function Popup({ className, ...props }: MenuPrimitive.Popup.Props) {
34+
return (
35+
<MenuPrimitive.Popup
36+
className={cn(
37+
"w-48 origin-(--transform-origin) rounded-xl bg-gray-50 p-1 shadow-custom-3 outline-hidden transition-[transform,scale,opacity] data-starting-style:scale-98 data-starting-style:opacity-0",
38+
className,
39+
)}
40+
{...props}
41+
/>
42+
);
43+
}
44+
45+
function Item({ className, ...props }: MenuPrimitive.Item.Props) {
46+
return (
47+
<MenuPrimitive.Item
48+
className={cn(
49+
"flex cursor-pointer items-center rounded-lg px-2 py-[5px] text-13 leading-[115%] font-450 tracking-[0.01em] text-gray-800 outline-hidden data-highlighted:bg-gray-200 data-highlighted:text-gray-900",
50+
className,
51+
)}
52+
{...props}
53+
/>
54+
);
55+
}
56+
57+
function Group({ ...props }: MenuPrimitive.Group.Props) {
58+
return <MenuPrimitive.Group {...props} />;
59+
}
60+
61+
function GroupLabel({ className, ...props }: MenuPrimitive.GroupLabel.Props) {
62+
return <MenuPrimitive.GroupLabel className={cn(className)} {...props} />;
63+
}
64+
65+
const Separator = MenuPrimitive.Separator;
66+
67+
export const Menu = {
68+
Group,
69+
GroupLabel,
70+
Item,
71+
Popup,
72+
Portal,
73+
Positioner,
74+
Root,
75+
Separator,
76+
Trigger,
77+
};

src/pageComponents/dashboard/cardSection/add-to-collection-popover.tsx

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
import { type Key } from "react";
2-
import { Popover } from "@base-ui/react/popover";
32
import isEmpty from "lodash/isEmpty";
43

54
import { useAddCategoryToBookmarksOptimisticMutation } from "@/async/mutationHooks/category/use-add-category-to-bookmarks-optimistic-mutation";
65
import useFetchCategories from "@/async/queryHooks/category/useFetchCategories";
7-
import { Button } from "@/components/ui/recollect/button";
6+
import { Menu } from "@/components/ui/recollect/menu";
87
import MoveIcon from "@/icons/moveIcon";
9-
import {
10-
dropdownMenuClassName,
11-
dropdownMenuItemClassName,
12-
} from "@/utils/commonClassNames";
138

149
interface AddToCollectionPopoverProps {
1510
onSuccess: () => void;
@@ -21,38 +16,36 @@ export function AddToCollectionPopover({
2116
selectedKeys,
2217
}: AddToCollectionPopoverProps) {
2318
return (
24-
<Popover.Root>
25-
<Popover.Trigger className="flex items-center rounded-lg bg-gray-200 px-2 py-[5px] text-13 leading-4 font-450 text-gray-900">
19+
<Menu.Root>
20+
<Menu.Trigger className="flex items-center rounded-lg bg-gray-200 px-2 py-[5px] text-13 leading-4 font-450 text-gray-900">
2621
<span className="mr-[6px] text-gray-1000" aria-hidden="true">
2722
<MoveIcon />
2823
</span>
2924
<p>Add to</p>
30-
</Popover.Trigger>
31-
<Popover.Portal>
32-
<Popover.Positioner align="end" className="z-10" sideOffset={1}>
33-
<Popover.Popup
34-
className={`${dropdownMenuClassName} leading-[20px] outline-hidden`}
35-
>
36-
<AddToCollectionMenu
25+
</Menu.Trigger>
26+
<Menu.Portal>
27+
<Menu.Positioner align="end">
28+
<Menu.Popup className="leading-[20px]">
29+
<AddToCollectionMenuItems
3730
onSuccess={onSuccess}
3831
selectedKeys={selectedKeys}
3932
/>
40-
</Popover.Popup>
41-
</Popover.Positioner>
42-
</Popover.Portal>
43-
</Popover.Root>
33+
</Menu.Popup>
34+
</Menu.Positioner>
35+
</Menu.Portal>
36+
</Menu.Root>
4437
);
4538
}
4639

47-
interface AddToCollectionMenuProps {
40+
interface AddToCollectionMenuItemsProps {
4841
onSuccess: () => void;
4942
selectedKeys: Set<Key>;
5043
}
5144

52-
function AddToCollectionMenu({
45+
function AddToCollectionMenuItems({
5346
onSuccess,
5447
selectedKeys,
55-
}: AddToCollectionMenuProps) {
48+
}: AddToCollectionMenuItemsProps) {
5649
const { allCategories } = useFetchCategories();
5750
const { addCategoryToBookmarksOptimisticMutation } =
5851
useAddCategoryToBookmarksOptimisticMutation();
@@ -69,8 +62,8 @@ function AddToCollectionMenu({
6962
return (
7063
<>
7164
{categories.map((item) => (
72-
<Button
73-
className={`w-full truncate text-left ${dropdownMenuItemClassName}`}
65+
<Menu.Item
66+
className="w-full truncate text-left"
7467
key={item.value}
7568
onClick={() => {
7669
const selectedIds = Array.from(selectedKeys).map(Number);
@@ -82,10 +75,9 @@ function AddToCollectionMenu({
8275
{ onSuccess },
8376
);
8477
}}
85-
type="button"
8678
>
8779
{item.label}
88-
</Button>
80+
</Menu.Item>
8981
))}
9082
</>
9183
);

0 commit comments

Comments
 (0)