mirror of
https://github.com/umami-software/umami.git
synced 2026-02-08 22:57:12 +01:00
New mobile menu.
This commit is contained in:
parent
18efd4d101
commit
34ad1d9c39
14 changed files with 189 additions and 153 deletions
44
components/common/HamburgerButton.js
Normal file
44
components/common/HamburgerButton.js
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import Button from 'components/common/Button';
|
||||
import XMark from 'assets/xmark.svg';
|
||||
import Bars from 'assets/bars.svg';
|
||||
import { useState } from 'react';
|
||||
import styles from './HamburgerButton.module.css';
|
||||
import MobileMenu from './MobileMenu';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
label: <FormattedMessage id="label.dashboard" defaultMessage="Dashboard" />,
|
||||
value: '/dashboard',
|
||||
},
|
||||
{ label: <FormattedMessage id="label.realtime" defaultMessage="Realtime" />, value: '/realtime' },
|
||||
{ label: <FormattedMessage id="label.settings" defaultMessage="Settings" />, value: '/settings' },
|
||||
{
|
||||
label: <FormattedMessage id="label.profile" defaultMessage="Profile" />,
|
||||
value: '/settings/profile',
|
||||
},
|
||||
{ label: <FormattedMessage id="label.logout" defaultMessage="Logout" />, value: '/logout' },
|
||||
];
|
||||
|
||||
export default function HamburgerButton() {
|
||||
const [active, setActive] = useState(false);
|
||||
|
||||
function handleClick() {
|
||||
setActive(state => !state);
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
setActive(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
className={styles.button}
|
||||
icon={active ? <XMark /> : <Bars />}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
{active && <MobileMenu items={menuItems} onClose={handleClose} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
9
components/common/HamburgerButton.module.css
Normal file
9
components/common/HamburgerButton.module.css
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
.button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 768px) {
|
||||
.button {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ import NextLink from 'next/link';
|
|||
import Icon from './Icon';
|
||||
import styles from './Link.module.css';
|
||||
|
||||
function Link({ className, icon, children, size, iconRight, ...props }) {
|
||||
function Link({ className, icon, children, size, iconRight, onClick, ...props }) {
|
||||
return (
|
||||
<NextLink {...props}>
|
||||
<a
|
||||
|
|
@ -15,6 +15,7 @@ function Link({ className, icon, children, size, iconRight, ...props }) {
|
|||
[styles.xsmall]: size === 'xsmall',
|
||||
[styles.iconRight]: iconRight,
|
||||
})}
|
||||
onClick={onClick}
|
||||
>
|
||||
{icon && <Icon className={styles.icon} icon={icon} size={size} />}
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -8,20 +8,14 @@ a.link:visited {
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
a.link:before {
|
||||
a.link:hover:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
width: 0;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background: var(--primary400);
|
||||
opacity: 0.5;
|
||||
transition: width 100ms;
|
||||
}
|
||||
|
||||
a.link:hover:before {
|
||||
width: 100%;
|
||||
transition: width 100ms;
|
||||
}
|
||||
|
||||
a.link.large {
|
||||
|
|
|
|||
21
components/common/MobileMenu.js
Normal file
21
components/common/MobileMenu.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import Link from './Link';
|
||||
import Button from './Button';
|
||||
import XMark from 'assets/xmark.svg';
|
||||
import styles from './MobileMenu.module.css';
|
||||
|
||||
export default function MobileMenu({ items = [], onClose }) {
|
||||
return (
|
||||
<div className={styles.menu}>
|
||||
<div className={styles.header}>
|
||||
<Button className={styles.button} icon={<XMark />} onClick={onClose} />
|
||||
</div>
|
||||
<div className={styles.items}>
|
||||
{items.map(({ label, value }) => (
|
||||
<Link key={value} href={value} className={styles.item} onClick={onClose}>
|
||||
{label}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
40
components/common/MobileMenu.module.css
Normal file
40
components/common/MobileMenu.module.css
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
.menu {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--gray50);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.items {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.item {
|
||||
font-size: var(--font-size-large);
|
||||
}
|
||||
|
||||
.item + .item {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
height: 100px;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue