-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature/oppdater stil på side meny (#3476)
* redsign av side meny
- Loading branch information
1 parent
d9fdb8a
commit b0a0cf2
Showing
8 changed files
with
110 additions
and
233 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
58 changes: 10 additions & 48 deletions
58
packages/plattform-komponenter/src/side-menu/MenuLink.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 |
---|---|---|
@@ -1,68 +1,30 @@ | ||
import { bemUtils } from '@navikt/ft-utils'; | ||
import classnames from 'classnames'; | ||
import { BodyShort, Label } from '@navikt/ds-react'; | ||
|
||
import React from 'react'; | ||
import { BodyShort } from '@navikt/ds-react'; | ||
|
||
import styles from './menuLink.module.css'; | ||
|
||
interface MenuLinkProps { | ||
label: string; | ||
onClick: () => void; | ||
active?: boolean; | ||
icon?: React.ReactNode; | ||
theme?: string; | ||
} | ||
|
||
const menuLinkCls = bemUtils('menuLink'); | ||
|
||
const MenuLink = ({ label, active, onClick, icon, theme }: MenuLinkProps): JSX.Element => { | ||
const arrowTheme = theme === 'arrow'; | ||
const MenuLink = ({ label, active, onClick, icon }: MenuLinkProps) => { | ||
const handleOnClick = (event: React.FormEvent<HTMLButtonElement>): void => { | ||
event.preventDefault(); | ||
onClick(); | ||
}; | ||
|
||
const labelCls = classnames( | ||
active | ||
? `${styles[menuLinkCls.element('label')]} ${styles['menuLink__label--active']}` | ||
: styles[menuLinkCls.element('label')], | ||
{ | ||
[styles['menuLink__label--with-icon']]: !!icon, | ||
}, | ||
); | ||
|
||
const containerClassnames = classnames(styles[menuLinkCls.block], { | ||
[styles[menuLinkCls.modifier('withArrows')]]: arrowTheme, | ||
}); | ||
|
||
const buttonCls = active ? `${styles.menuLink__button} ${styles.menuLink__button__active}` : styles.menuLink__button; | ||
return ( | ||
<li className={containerClassnames} aria-current={active ? true : undefined}> | ||
<button | ||
className={ | ||
active | ||
? `${styles[menuLinkCls.element('button')]} ${styles['menuLink__button--active']}` | ||
: styles[menuLinkCls.element('button')] | ||
} | ||
onClick={handleOnClick} | ||
type="button" | ||
data-testid={active ? 'activeMenuItemButton' : undefined} | ||
> | ||
{arrowTheme && active ? ( | ||
<Label size="small" as="span" className={labelCls}> | ||
{label} | ||
{icon} | ||
</Label> | ||
) : ( | ||
<BodyShort size="small" as="span" className={labelCls}> | ||
{label} | ||
{icon} | ||
</BodyShort> | ||
)} | ||
|
||
{arrowTheme && active && <span className={styles[menuLinkCls.element('arrow-right')]} />} | ||
<li aria-current={active ? true : undefined}> | ||
<button className={buttonCls} onClick={handleOnClick}> | ||
<BodyShort size="small" as="span"> | ||
{label} | ||
</BodyShort> | ||
{icon} | ||
</button> | ||
</li> | ||
); | ||
}; | ||
|
||
export default MenuLink; |
22 changes: 13 additions & 9 deletions
22
packages/plattform-komponenter/src/side-menu/SideMenu.spec.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 |
---|---|---|
@@ -1,17 +1,21 @@ | ||
import React from 'react'; | ||
import { render, screen } from '@testing-library/react'; | ||
import { screen } from '@testing-library/react'; | ||
import { composeStories } from '@storybook/react'; | ||
|
||
import * as stories from './SideMenu.stories'; | ||
|
||
const { StatefulSideMenu } = composeStories(stories); | ||
const { Default } = composeStories(stories); | ||
|
||
describe('<SideMenu>', () => { | ||
it('skal vise meny', async () => { | ||
render(<StatefulSideMenu />); | ||
describe('SideMenu', () => { | ||
it('skal vise side meny med et aktivt element', async () => { | ||
await Default.run(); | ||
|
||
expect(await screen.findByText('Dette er en test')).toBeInTheDocument(); | ||
expect(screen.getByText('en link')).toBeInTheDocument(); | ||
expect(screen.getByText('en link til')).toBeInTheDocument(); | ||
expect(await screen.findByText('Fakta om')).toBeInTheDocument(); | ||
expect(screen.getByText('Saken')).toBeInTheDocument(); | ||
expect(screen.getByText('Medlemskap')).toBeInTheDocument(); | ||
expect(screen.getByText('Arbeid og inntekt')).toBeInTheDocument(); | ||
|
||
expect(screen.getByText('Opptjening')).toBeInTheDocument(); | ||
expect(screen.getByText('Opptjening').closest('li')).toHaveAttribute('aria-current', 'true'); | ||
expect(screen.getByText('Opptjening').closest('button')).toHaveClass(/.menuLink__button__active/); | ||
}); | ||
}); |
73 changes: 51 additions & 22 deletions
73
packages/plattform-komponenter/src/side-menu/SideMenu.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 |
---|---|---|
@@ -1,32 +1,61 @@ | ||
import { StoryFn } from '@storybook/react'; | ||
import React, { ComponentProps } from 'react'; | ||
import WarningIcon from '../icons/WarningIcon'; | ||
import StatefulSideMenuComponent from './StatefulSideMenu'; | ||
import React, { useMemo, useState } from 'react'; | ||
import { Meta, StoryObj } from '@storybook/react'; | ||
import SideMenu from './SideMenu'; | ||
import { HStack } from '@navikt/ds-react'; | ||
import { ExclamationmarkTriangleFillIcon } from '@navikt/aksel-icons'; | ||
|
||
export default { | ||
const meta = { | ||
title: 'Side menu', | ||
component: StatefulSideMenuComponent, | ||
}; | ||
component: SideMenu, | ||
render: ({ heading, links, onClick }) => { | ||
const [currentIndex, setCurrentIndex] = useState(links.findIndex(({ active }) => active) ?? 0); | ||
const handleOnClick = (index: number): void => { | ||
setCurrentIndex(index); | ||
onClick(index); | ||
}; | ||
|
||
const linksWithActiveState = useMemo( | ||
() => | ||
links.map((link, index) => ({ | ||
...link, | ||
active: currentIndex === index, | ||
})), | ||
[links, currentIndex], | ||
); | ||
return ( | ||
<div style={{ width: '400px', border: '1px dotted black' }}> | ||
<HStack> | ||
<SideMenu heading={heading} links={linksWithActiveState} onClick={handleOnClick} /> | ||
<div style={{ width: '200px', height: '800px', padding: '24px' }}>annet innhold</div> | ||
</HStack> | ||
</div> | ||
); | ||
}, | ||
} satisfies Meta<typeof SideMenu>; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof meta>; | ||
|
||
const Template: StoryFn<ComponentProps<typeof StatefulSideMenuComponent>> = () => ( | ||
<StatefulSideMenuComponent | ||
heading="Dette er en test" | ||
links={[ | ||
export const Default: Story = { | ||
args: { | ||
heading: 'Fakta om', | ||
links: [ | ||
{ | ||
label: 'en link', | ||
label: 'Saken', | ||
}, | ||
{ | ||
label: 'en link til', | ||
label: 'Medlemskap', | ||
}, | ||
{ | ||
icon: <WarningIcon />, | ||
label: 'en link med ikon', | ||
icon: <ExclamationmarkTriangleFillIcon fontSize="1rem" color={'var(--a-icon-warning)'} />, | ||
label: 'Opptjening', | ||
active: true, | ||
}, | ||
]} | ||
onClick={() => null} | ||
/> | ||
); | ||
|
||
export const StatefulSideMenu = Template.bind({}); | ||
StatefulSideMenu.args = {}; | ||
{ | ||
label: 'Arbeid og inntekt', | ||
}, | ||
], | ||
onClick: () => null, | ||
}, | ||
}; |
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
27 changes: 0 additions & 27 deletions
27
packages/plattform-komponenter/src/side-menu/StatefulSideMenu.tsx
This file was deleted.
Oops, something went wrong.
88 changes: 18 additions & 70 deletions
88
packages/plattform-komponenter/src/side-menu/menuLink.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 |
---|---|---|
@@ -1,84 +1,32 @@ | ||
.menuLink__button { | ||
background: none; | ||
border: 3px solid transparent; | ||
color: #3e3832; | ||
border: none; | ||
cursor: pointer; | ||
padding: 0; | ||
display: flex; | ||
gap: var(--a-spacing-2); | ||
justify-content: space-between; | ||
padding-block: var(--a-spacing-2); | ||
padding-left: var(--a-spacing-6); | ||
padding-right: var(--a-spacing-4); | ||
position: relative; | ||
text-align: left; | ||
text-decoration: none; | ||
width: 100%; | ||
} | ||
|
||
.menuLink__button:hover { | ||
background: #e7e9e9; | ||
} | ||
.menuLink__button:focus { | ||
border: 3px solid #254b6d; | ||
outline: none; | ||
background: var(--a-surface-hover); | ||
} | ||
.menuLink__button--active { | ||
background: #e7e9e9; | ||
border: 3px solid #e7e9e9; | ||
border-left: transparent; | ||
padding-left: 0.1875rem; | ||
|
||
.menuLink__button__active { | ||
background: var(--a-surface-hover); | ||
text-shadow: 0 0 0.1px #333; /* bruker text-shadow i steden for font-weight for å unngå endring i bredde */ | ||
} | ||
.menuLink__button--active:before { | ||
background: #0067c5; | ||
|
||
.menuLink__button__active:before { | ||
background: var(--a-surface-action); | ||
content: ''; | ||
height: calc(100% + 0.375rem); | ||
left: 0; | ||
position: absolute; | ||
top: -0.1875rem; | ||
width: 0.25rem; | ||
z-index: 1; | ||
} | ||
.menuLink__button--active:focus { | ||
padding-left: 0; | ||
} | ||
.menuLink__button--active:focus:before { | ||
height: 100%; | ||
left: 0; | ||
top: 0; | ||
} | ||
.menuLink__label, | ||
.menuLink__label { | ||
align-items: center; | ||
color: #3e3832; | ||
display: flex; | ||
justify-content: space-between; | ||
min-height: 1.625rem; | ||
padding: 0 1.75rem; | ||
position: relative; | ||
} | ||
.menuLink__label--active, | ||
.menuLink__label--active { | ||
background: #e7e9e9; | ||
font-weight: 600; | ||
} | ||
.menuLink__label--with-icon, | ||
.menuLink__label--with-icon { | ||
padding-right: 0.8125rem; | ||
} | ||
.menuLink__icon { | ||
margin-left: 1rem; | ||
} | ||
.menuLink--withArrows .menu-link__button--active:before { | ||
display: none; | ||
} | ||
.menuLink--withArrows .menu-link__button:focus .menu-link__arrow-right { | ||
border-bottom: 13px solid transparent; | ||
border-top: 13px solid transparent; | ||
right: 0; | ||
top: 0; | ||
} | ||
.menuLink__arrow-right { | ||
background-color: white; | ||
border-bottom: 16px solid transparent; | ||
border-left: 17px solid #e7e9e9; | ||
border-top: 16px solid transparent; | ||
height: 0; | ||
position: absolute; | ||
right: -3px; | ||
top: -3px; | ||
width: 0; | ||
top: 0; | ||
width: var(--a-spacing-1); | ||
} |
Oops, something went wrong.