Skip to content

Commit ea103c0

Browse files
committed
feat: menu item style
1 parent 6b12fdb commit ea103c0

File tree

1 file changed

+56
-14
lines changed

1 file changed

+56
-14
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,85 @@
11
'use client'
22

3-
import React, { memo, useMemo } from 'react'
3+
import React, { memo, useId, useMemo, useState } from 'react'
4+
import { m } from 'framer-motion'
45
import Link from 'next/link'
56
import type { IHeaderMenu } from '../config'
67

78
import { FloatPopover } from '~/components/ui/float-popover'
9+
import { microdampingPreset } from '~/constants/spring'
10+
import { clsxm } from '~/lib/helper'
811

912
export const MenuPopover: Component<{
1013
subMenu: IHeaderMenu['subMenu']
1114
}> = memo(({ children, subMenu }) => {
15+
const currentId = useId()
1216
const TriggerComponent = useMemo(() => () => children, [children])
1317
if (!subMenu) return children
18+
1419
return (
1520
<FloatPopover
1621
strategy="fixed"
1722
placement="bottom"
1823
offset={10}
24+
headless
1925
popoverWrapperClassNames="z-[19] relative"
20-
popoverClassNames="rounded-xl !p-0"
26+
popoverClassNames="rounded-xl !p-0 focus-visible:!shadow-none focus-visible:!ring-0"
2127
TriggerComponent={TriggerComponent}
2228
>
2329
{!!subMenu.length && (
24-
<div className="relative flex w-[130px] flex-col px-4">
30+
<div
31+
className={clsxm(
32+
'select-none rounded-xl bg-white/60 outline-none dark:bg-neutral-900/60',
33+
'shadow-lg shadow-zinc-800/5 ring-1 ring-zinc-900/5 backdrop-blur-md',
34+
'dark:from-zinc-900/70 dark:to-zinc-800/90 dark:ring-zinc-100/10',
35+
'relative flex w-[130px] flex-col py-1',
36+
)}
37+
>
2538
{subMenu.map((m) => {
26-
return (
27-
<Link
28-
key={m.title}
29-
href={`${m.path}`}
30-
className="flex w-full items-center justify-around space-x-2 py-3 duration-200 hover:text-accent"
31-
role="button"
32-
>
33-
{!!m.icon && <span>{m.icon}</span>}
34-
<span>{m.title}</span>
35-
</Link>
36-
)
39+
return <Item key={m.title} currentId={currentId} {...m} />
3740
})}
3841
</div>
3942
)}
4043
</FloatPopover>
4144
)
4245
})
4346
MenuPopover.displayName = 'MenuPopover'
47+
48+
const Item = memo(function Item(
49+
props: IHeaderMenu & {
50+
currentId: string
51+
},
52+
) {
53+
const { title, path, icon, currentId } = props
54+
55+
const [isEnter, setIsEnter] = useState(false)
56+
return (
57+
<Link
58+
key={title}
59+
href={`${path}`}
60+
className="relative flex w-full items-center justify-around space-x-2 px-4 py-3 duration-200 hover:text-accent"
61+
role="button"
62+
onMouseEnter={() => {
63+
setIsEnter(true)
64+
}}
65+
onMouseLeave={() => {
66+
setIsEnter(false)
67+
}}
68+
>
69+
{!!icon && <span>{icon}</span>}
70+
<span>{title}</span>
71+
72+
{isEnter && (
73+
<m.span
74+
layoutId={currentId}
75+
transition={microdampingPreset}
76+
className={clsxm(
77+
'absolute bottom-0 left-0 right-2 top-0 z-[-1] rounded-md',
78+
'bg-zinc-50 dark:bg-neutral-900',
79+
'border border-zinc-200 dark:border-zinc-800',
80+
)}
81+
/>
82+
)}
83+
</Link>
84+
)
85+
})

0 commit comments

Comments
 (0)