@@ -17,6 +17,7 @@ export function SideMenuItem({
1717 badge,
1818 target,
1919 isCollapsed = false ,
20+ action,
2021} : {
2122 icon ?: RenderIcon ;
2223 activeIconColor ?: string ;
@@ -28,59 +29,82 @@ export function SideMenuItem({
2829 badge ?: ReactNode ;
2930 target ?: AnchorHTMLAttributes < HTMLAnchorElement > [ "target" ] ;
3031 isCollapsed ?: boolean ;
32+ action ?: ReactNode ;
3133} ) {
3234 const pathName = usePathName ( ) ;
3335 const isActive = pathName === to ;
3436
35- return (
36- < SimpleTooltip
37- button = {
38- < Link
39- to = { to }
40- target = { target }
41- className = { cn (
42- "flex h-8 w-full items-center gap-2 overflow-hidden rounded pr-2 pl-[0.4375rem] text-text-bright transition-colors hover:bg-charcoal-750" ,
43- isActive ? "bg-tertiary" : ""
44- ) }
45- >
46- < Icon
47- icon = { icon }
48- className = { cn (
49- "size-5 shrink-0" ,
50- isActive ? activeIconColor : inactiveIconColor ?? "text-text-dimmed"
51- ) }
52- />
37+ const link = (
38+ < Link
39+ to = { to }
40+ target = { target }
41+ className = { cn (
42+ "flex h-8 w-full items-center gap-2 overflow-hidden rounded pr-2 pl-[0.4375rem] text-text-bright transition-colors hover:bg-charcoal-750 group-hover/menuitem:bg-charcoal-750" ,
43+ isActive ? "bg-tertiary" : ""
44+ ) }
45+ >
46+ < Icon
47+ icon = { icon }
48+ className = { cn (
49+ "size-5 shrink-0" ,
50+ isActive ? activeIconColor : inactiveIconColor ?? "text-text-dimmed"
51+ ) }
52+ />
53+ < motion . div
54+ className = "flex min-w-0 flex-1 items-center justify-between overflow-hidden"
55+ initial = { false }
56+ animate = { {
57+ width : isCollapsed ? 0 : "auto" ,
58+ opacity : isCollapsed ? 0 : 1 ,
59+ } }
60+ transition = { { duration : 0.2 , ease : "easeOut" } }
61+ >
62+ < span className = "truncate text-2sm" > { name } </ span >
63+ { badge && ! isCollapsed && (
5364 < motion . div
54- className = "flex min-w-0 flex-1 items-center justify-between overflow-hidden "
65+ className = "ml-1 flex shrink-0 items-center gap-1 "
5566 initial = { false }
5667 animate = { {
57- width : isCollapsed ? 0 : "auto" ,
58- opacity : isCollapsed ? 0 : 1 ,
68+ opacity : 1 ,
5969 } }
60- transition = { { duration : 0.2 , ease : "easeOut" } }
70+ transition = { { duration : 0.15 , ease : "easeOut" } }
6171 >
62- < span className = "truncate text-2sm" > { name } </ span >
63- { badge && ! isCollapsed && (
64- < motion . div
65- className = "ml-1 flex shrink-0 items-center gap-1"
66- initial = { false }
67- animate = { {
68- opacity : 1 ,
69- } }
70- transition = { { duration : 0.15 , ease : "easeOut" } }
71- >
72- { badge }
73- </ motion . div >
74- ) }
75- { trailingIcon && ! isCollapsed && (
76- < Icon
77- icon = { trailingIcon }
78- className = { cn ( "ml-1 size-4 shrink-0" , trailingIconClassName ) }
79- />
80- ) }
72+ { badge }
8173 </ motion . div >
82- </ Link >
83- }
74+ ) }
75+ { trailingIcon && ! isCollapsed && (
76+ < Icon
77+ icon = { trailingIcon }
78+ className = { cn ( "ml-1 size-4 shrink-0" , trailingIconClassName ) }
79+ />
80+ ) }
81+ </ motion . div >
82+ </ Link >
83+ ) ;
84+
85+ if ( action && ! isCollapsed ) {
86+ return (
87+ < div className = "group/menuitem relative h-8 w-full" >
88+ < SimpleTooltip
89+ button = { link }
90+ content = { name }
91+ side = "right"
92+ sideOffset = { 8 }
93+ buttonClassName = "!h-8 block w-full"
94+ hidden = { ! isCollapsed }
95+ asChild
96+ disableHoverableContent
97+ />
98+ < div className = "absolute top-1 right-1 bottom-1 flex aspect-square items-center justify-center" >
99+ { action }
100+ </ div >
101+ </ div >
102+ ) ;
103+ }
104+
105+ return (
106+ < SimpleTooltip
107+ button = { link }
84108 content = { name }
85109 side = "right"
86110 sideOffset = { 8 }
0 commit comments