-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Aksel.nav.no] Ny Meny for sidebar og TOC (#2873)
* 🎉 WIP for ny sidebar og TOC meny * 💫 Animert farger * 🎨 Støtte for nested menuitems * 🎨 Støtter nå sidebar og toc-variant for farger * ♻️ Migrert TOC til å bruke ny meny * ♻️ Migrert Sidebar til å bruke ny meny * 🐛 Fikset story * ♿ Klikkhøyde nå minst 32px * 💄 Justert bakgrunnsanimasjon fra 200ms -> 100ms * Types: variant bruker semantiske navn * bug: MenuLink ble brukt utenfor MenuLi
- Loading branch information
Showing
7 changed files
with
287 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
aksel.nav.no/website/components/website-modules/menu/Menu.module.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
.menuListItem { | ||
padding-inline: var(--a-spacing-2); | ||
} | ||
|
||
.menuList .menuList .menuListItem { | ||
padding-inline-start: var(--a-spacing-5); | ||
} |
114 changes: 114 additions & 0 deletions
114
aksel.nav.no/website/components/website-modules/menu/Menu.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/* eslint-disable jsx-a11y/click-events-have-key-events */ | ||
|
||
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ | ||
import { Meta, StoryObj } from "@storybook/react"; | ||
import { useState } from "react"; | ||
import { Menu, MenuHeading, MenuLi, MenuLink, MenuUl } from "./Menu"; | ||
|
||
const meta = { | ||
title: "Website-modules/Menu", | ||
component: Menu, | ||
tags: ["autodocs"], | ||
} satisfies Meta<typeof Menu>; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof meta>; | ||
|
||
export const MenuDemo: Story = { | ||
render: () => { | ||
const [selected, setSelected] = useState(0); | ||
return ( | ||
<Menu loggingContext="meny" variant="action"> | ||
<> | ||
<MenuHeading as="div">Primitives</MenuHeading> | ||
<ul onClick={() => setSelected((x) => (x === 0 ? 1 : 0))}> | ||
<MenuLi> | ||
<MenuLink href="#">Bleed</MenuLink> | ||
</MenuLi> | ||
<MenuLi> | ||
<MenuLink href="#">Box</MenuLink> | ||
</MenuLi> | ||
<MenuLi> | ||
<MenuLink href="#" selected={selected === 1}> | ||
HGrid | ||
</MenuLink> | ||
</MenuLi> | ||
<MenuLi> | ||
<MenuLink href="#">Hide</MenuLink> | ||
</MenuLi> | ||
<MenuLi> | ||
<MenuLink href="#" selected={selected === 0}> | ||
HStack | ||
</MenuLink> | ||
</MenuLi> | ||
<MenuLi> | ||
<MenuLink href="#">Show</MenuLink> | ||
</MenuLi> | ||
<MenuLi> | ||
<MenuLink href="#" selected> | ||
VStack | ||
</MenuLink> | ||
</MenuLi> | ||
</ul> | ||
</> | ||
</Menu> | ||
); | ||
}, | ||
args: { | ||
children: null, | ||
loggingContext: "meny", | ||
variant: "action", | ||
}, | ||
}; | ||
|
||
export const NestedMenuDemo: Story = { | ||
render: () => { | ||
return ( | ||
<Menu loggingContext="toc" variant="neutral"> | ||
<MenuHeading as="h2">Innhold på siden</MenuHeading> | ||
<MenuUl> | ||
<MenuLi> | ||
<MenuLink href="#" selected> | ||
Så, hvordan går vi frem for å få det til? | ||
</MenuLink> | ||
</MenuLi> | ||
<MenuLi> | ||
<MenuLink href="#">Bærekraftige team</MenuLink> | ||
</MenuLi> | ||
|
||
<MenuLi> | ||
<MenuUl> | ||
<MenuLi> | ||
<MenuLink href="#">Teamstørrelse</MenuLink> | ||
</MenuLi> | ||
<MenuLi> | ||
<MenuLink href="#">Stabilitet Vs. fleksibilitet</MenuLink> | ||
</MenuLi> | ||
<MenuLi> | ||
<MenuLink href="#" selected> | ||
Myndighet og hensikt | ||
</MenuLink> | ||
</MenuLi> | ||
<MenuLi> | ||
<MenuLink href="#"> | ||
Ansvar tilpasset kognitiv kapasitet | ||
</MenuLink> | ||
</MenuLi> | ||
</MenuUl> | ||
</MenuLi> | ||
<MenuLi> | ||
<MenuLink href="#" selected> | ||
Teamtyper | ||
</MenuLink> | ||
</MenuLi> | ||
</MenuUl> | ||
</Menu> | ||
); | ||
}, | ||
args: { | ||
children: null, | ||
loggingContext: "toc", | ||
variant: "neutral", | ||
}, | ||
}; |
122 changes: 122 additions & 0 deletions
122
aksel.nav.no/website/components/website-modules/menu/Menu.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import cl from "clsx"; | ||
import Link from "next/link"; | ||
import { createContext, useContext } from "react"; | ||
import { BodyShort, Label } from "@navikt/ds-react"; | ||
import { amplitudeLogNavigation } from "@/logging"; | ||
import styles from "./Menu.module.css"; | ||
|
||
type MenuProps = { | ||
children: React.ReactNode; | ||
loggingContext: "meny" | "toc"; | ||
variant: "action" | "neutral"; | ||
}; | ||
|
||
const MenuContext = createContext<Omit<MenuProps, "children"> | null>(null); | ||
|
||
export function Menu({ children, ...rest }: MenuProps) { | ||
return <MenuContext.Provider value={rest}>{children}</MenuContext.Provider>; | ||
} | ||
|
||
type MenuHeadingProps = { | ||
children: React.ReactNode; | ||
as: "div" | "h2"; | ||
}; | ||
|
||
export function MenuHeading({ children, as }: MenuHeadingProps) { | ||
return ( | ||
<Label as={as} size="small" textColor="subtle" className="py-05"> | ||
{children} | ||
</Label> | ||
); | ||
} | ||
|
||
type MenuListProps = { | ||
children: React.ReactNode; | ||
id?: string; | ||
className?: string; | ||
}; | ||
|
||
export function MenuUl({ children, id, className }: MenuListProps) { | ||
return ( | ||
<ul className={cl(styles.menuList, className)} id={id}> | ||
{children} | ||
</ul> | ||
); | ||
} | ||
|
||
type MenuLiProps = { | ||
children: React.ReactNode; | ||
}; | ||
|
||
export function MenuLi({ children }: MenuLiProps) { | ||
return <li className="group">{children}</li>; | ||
} | ||
|
||
type MenuLinkProps = { | ||
children: React.ReactNode; | ||
selected?: boolean; | ||
href: string; | ||
id?: string; | ||
onClick?: () => void; | ||
}; | ||
|
||
export function MenuLink({ | ||
children, | ||
href, | ||
selected, | ||
id, | ||
onClick, | ||
}: MenuLinkProps) { | ||
const ctx = useContext(MenuContext); | ||
|
||
if (!ctx) { | ||
throw new Error("MenuListItem must be used inside a Menu component"); | ||
} | ||
|
||
return ( | ||
<div className="relative scroll-m-6 border-l border-border-subtle" id={id}> | ||
<BodyShort | ||
data-type={ctx.variant} | ||
size="small" | ||
as={Link} | ||
prefetch={false} | ||
href={href} | ||
onClick={(e) => { | ||
amplitudeLogNavigation( | ||
ctx.loggingContext, | ||
e.currentTarget.getAttribute("href"), | ||
); | ||
onClick?.(); | ||
}} | ||
className={cl( | ||
styles.menuListItem, | ||
"flex py-05 focus:outline-none *:focus-visible:shadow-focus group-first:pt-0 group-last:last:pb-0", | ||
"before:absolute before:-left-px before:top-05 before:h-[calc(100%-0.25rem)] before:rounded-r-sm before:transition-all group-first:before:top-0 group-first:before:h-[calc(100%-0.125rem)] group-last:before:h-[calc(100%-0.125rem)]", | ||
{ | ||
"text-text-subtle before:w-0 before:bg-gray-400 before:duration-100 before:ease-linear hover:text-text-default hover:before:w-1": | ||
!selected, | ||
"before:w-1": selected, | ||
"text-deepblue-700 before:bg-deepblue-700": | ||
selected && ctx.variant === "action", | ||
"text-text-default before:bg-gray-700": | ||
selected && ctx.variant === "neutral", | ||
}, | ||
)} | ||
> | ||
<span | ||
className={cl( | ||
"w-full rounded px-2 py-1 transition-colors duration-100 ease-out", | ||
{ | ||
"bg-surface-selected": selected && ctx.variant === "action", | ||
"bg-surface-neutral-subtle": | ||
selected && ctx.variant === "neutral", | ||
"bg-transparent": !selected, | ||
}, | ||
)} | ||
> | ||
{children} | ||
</span> | ||
</BodyShort> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.