menu rewritten with radix-ui
This commit is contained in:
1 parent
e8a4ba054b
commit
c9628678d8
10 files changed
+475
-113
No files matched your search
@@ -1,35 +0,0 @@
|
||||
import s from "./styles.module.css"
|
||||
import cx from "classnames"
|
||||
import { useRouter } from "next/router"
|
||||
import { ActiveLink } from "./ActiveLink"
|
||||
import { isPartOfPath } from "src/lib/url"
|
||||
|
||||
export type MenuItemProps = {
|
||||
href: string
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
export const MenuItem: React.FC<MenuItemProps> = props => {
|
||||
const ignore = ["/"]
|
||||
const router = useRouter()
|
||||
const current = router.asPath === props.href
|
||||
const selected = current || (!ignore.includes(props.href) && isPartOfPath(props.href, router.asPath))
|
||||
const href = current ? undefined : props.href
|
||||
|
||||
return (
|
||||
<li
|
||||
className={cx({
|
||||
[s.selected]: selected,
|
||||
})}
|
||||
>
|
||||
<ActiveLink
|
||||
href={href}
|
||||
activeStyle={{
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</ActiveLink>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
@@ -1,27 +1,45 @@
|
||||
import s from "./styles.module.css"
|
||||
|
||||
import cx from "classnames"
|
||||
import { MenuItem } from "./MenuItem"
|
||||
import { IMenu } from "src/types"
|
||||
import { IMenu } from "@/types"
|
||||
import * as NavigationMenu from "@radix-ui/react-navigation-menu"
|
||||
import classnames from "classnames/bind"
|
||||
import { useRouter } from "next/router"
|
||||
import { ActiveLink } from "./ActiveLink"
|
||||
|
||||
const layoutClass = {
|
||||
desktop: s.desktop,
|
||||
mobile: s.mobile,
|
||||
}
|
||||
let cx = classnames.bind(s)
|
||||
|
||||
export type MenuLayout = "desktop" | "mobile"
|
||||
|
||||
export type MenuProps = {
|
||||
layout: "desktop" | "mobile"
|
||||
layout: MenuLayout
|
||||
items: IMenu[]
|
||||
}
|
||||
|
||||
export const Menu: React.FC<MenuProps> = props => (
|
||||
<menu className={cx(s.menu, layoutClass[props.layout])}>
|
||||
{props.items.map((item, index) => (
|
||||
<MenuItem key={index}
|
||||
href={item.href}
|
||||
>
|
||||
{item.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</menu>
|
||||
)
|
||||
export const Menu: React.FC<MenuProps> = ({ layout, items }) => {
|
||||
const router = useRouter()
|
||||
return (
|
||||
<NavigationMenu.Root>
|
||||
<NavigationMenu.List className={cx(s.menu, layout)}>
|
||||
{
|
||||
items.map(item => {
|
||||
const current = router.asPath === item.href
|
||||
const href = current ? undefined : item.href
|
||||
|
||||
if (!href) {
|
||||
return (
|
||||
<NavigationMenu.Item key={item.href} className={`${s.menuItem} ${s.current}`}>
|
||||
<ActiveLink>{item.name}</ActiveLink>
|
||||
</NavigationMenu.Item>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<NavigationMenu.Item key={item.href} className={`${s.menuItem} ${s.active}`}>
|
||||
<ActiveLink href={item.href}>{item.name}</ActiveLink>
|
||||
</NavigationMenu.Item>
|
||||
)
|
||||
})
|
||||
}
|
||||
</NavigationMenu.List>
|
||||
</NavigationMenu.Root>
|
||||
)
|
||||
}
|
||||
@@ -3,8 +3,12 @@
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
|
||||
gap: var(--size-m);
|
||||
|
||||
font-size: var(--font-size-second);
|
||||
list-style: none;
|
||||
|
||||
padding: var(--size-s);
|
||||
}
|
||||
|
||||
/* MENU LAYOUT */
|
||||
@@ -19,34 +23,28 @@
|
||||
|
||||
/* MENU ITEM */
|
||||
|
||||
.menu li {
|
||||
position: relative;
|
||||
border-top: var(--menu-mark-thickness) solid rgba(0, 0, 0, 0);
|
||||
.menuItem {
|
||||
user-select: none;
|
||||
background-color: var(--color-back-main);
|
||||
border-radius: var(--size-s);
|
||||
transition: box-shadow 200ms ease-in;
|
||||
padding: var(--size-s) var(--size-s);
|
||||
}
|
||||
|
||||
/* MENU ITEM MOBILE */
|
||||
|
||||
.mobile li {
|
||||
font-size: var(--font-size-default);
|
||||
|
||||
padding: var(--size-xs) var(--size-s);
|
||||
.menuItem.active {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mobile li.selected {
|
||||
.menuItem.active:hover {
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.menuItem.current {
|
||||
color: var(--color-text-opposite);
|
||||
background-color: var(--color-back-opposite);
|
||||
color: var(--color-text-opposite)
|
||||
}
|
||||
|
||||
.mobile li.selected a {
|
||||
color: var(--color-text-opposite)
|
||||
}
|
||||
|
||||
/* MENU ITEM DESKTOP */
|
||||
|
||||
.desktop li {
|
||||
padding: var(--size-xs) var(--size-s);
|
||||
}
|
||||
|
||||
.desktop li.selected {
|
||||
border-top-color: var(--color-back-opposite);
|
||||
.menuItem a {
|
||||
text-decoration: none;
|
||||
color: var(--color-text);
|
||||
}
|
||||
Reference in new issue
Block a user