1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-24 20:36:40 +07:00

made better profile menu

This commit is contained in:
Fedor Katurov 2022-07-20 15:54:22 +07:00
parent 0564fe29e2
commit efe7800743
9 changed files with 42 additions and 84 deletions

View file

@ -20,7 +20,6 @@ const CommentAvatar: FC<Props> = ({ user, className }) => {
icon={ icon={
<Avatar url={path(['photo', 'url'], user)} username={user.username} className={className} /> <Avatar url={path(['photo', 'url'], user)} username={user.username} className={className} />
} }
translucentMenu
> >
<ProfileQuickInfo user={user} /> <ProfileQuickInfo user={user} />
</MenuButton> </MenuButton>

View file

@ -2,6 +2,7 @@ import React, { FC, useCallback } from 'react';
import { Group } from '~/components/containers/Group'; import { Group } from '~/components/containers/Group';
import { Icon } from '~/components/input/Icon'; import { Icon } from '~/components/input/Icon';
import { MenuButton, MenuItemWithIcon } from '~/components/menu';
import { ImagePresets } from '~/constants/urls'; import { ImagePresets } from '~/constants/urls';
import { IUser } from '~/types/auth'; import { IUser } from '~/types/auth';
import { getURL } from '~/utils/dom'; import { getURL } from '~/utils/dom';
@ -28,19 +29,23 @@ const UserButton: FC<IProps> = ({ user: { username, photo }, authOpenProfile, on
<Group horizontal className={styles.user_button}> <Group horizontal className={styles.user_button}>
<div className={styles.username}>{username}</div> <div className={styles.username}>{username}</div>
<MenuButton
position="bottom"
translucent={false}
icon={
<div <div
className={styles.user_avatar} className={styles.user_avatar}
style={{ backgroundImage: `url('${getURL(photo, ImagePresets.avatar)}')` }} style={{ backgroundImage: `url('${getURL(photo, ImagePresets.avatar)}')` }}
> >
{(!photo || !photo.id) && <Icon icon="profile" />} {(!photo || !photo.id) && <Icon icon="profile" />}
</div> </div>
}
>
<MenuItemWithIcon onClick={onProfileOpen}>Профиль</MenuItemWithIcon>
<MenuItemWithIcon onClick={onSettingsOpen}>Настройки</MenuItemWithIcon>
<MenuItemWithIcon onClick={onLogout}>Выдох</MenuItemWithIcon>
</MenuButton>
</Group> </Group>
<div className={styles.menu}>
<div onClick={onProfileOpen}>Профиль</div>
<div onClick={onSettingsOpen}>Настройки</div>
<div onClick={onLogout}>Выдох</div>
</div>
</div> </div>
); );
}; };

View file

@ -9,63 +9,6 @@
} }
} }
.menu {
position: absolute;
right: -$gap;
top: 100%;
padding: $gap;
border-radius: $radius;
display: none;
z-index: 1;
box-sizing: border-box;
padding: $gap;
display: none;
flex-direction: column;
&::after {
content: ' ';
width: 0;
height: 0;
border-style: solid;
border-width: 0 0 16px 16px;
border-color: transparent transparent $content_bg transparent;
position: absolute;
right: 0;
top: -4px;
transform: translate(-20px, 0);
z-index: -1;
}
& > div {
background: $content_bg;
padding: $gap $gap * 2;
cursor: pointer;
box-sizing: border-box;
transition: opacity 0.25s;
width: 100%;
padding-right: 40px;
transition: background-color 0.25s;
&:first-child {
border-top-left-radius: $radius;
border-top-right-radius: $radius;
}
&:last-child {
border-bottom-left-radius: $radius;
border-bottom-right-radius: $radius;
}
&:hover {
background-color: $secondary;
}
}
&:hover > div {
opacity: 1;
}
}
.user_button { .user_button {
align-items: center; align-items: center;
border-radius: $radius; border-radius: $radius;

View file

@ -13,17 +13,19 @@ interface MenuButtonProps {
position?: Placement; position?: Placement;
icon?: ReactNode; icon?: ReactNode;
className?: string; className?: string;
translucentMenu?: boolean;
activate?: 'hover' | 'focus'; activate?: 'hover' | 'focus';
fixed?: boolean;
translucent?: boolean;
} }
const MenuButton: FC<MenuButtonProps> = ({ const MenuButton: FC<MenuButtonProps> = ({
position = 'bottom-end', position = 'auto',
children, children,
className, className,
icon = <Icon icon="dots-vertical" size={24} />, icon = <Icon icon="dots-vertical" size={24} />,
translucentMenu, translucent = true,
activate = 'focus', activate = 'focus',
fixed,
}) => { }) => {
const focus = useFocusEvent(false, 150); const focus = useFocusEvent(false, 150);
const hover = useFocusEvent(false, 150); const hover = useFocusEvent(false, 150);
@ -34,12 +36,13 @@ const MenuButton: FC<MenuButtonProps> = ({
const popper = usePopper(referenceElement, popperElement, { const popper = usePopper(referenceElement, popperElement, {
placement: position, placement: position,
strategy: fixed ? 'fixed' : 'absolute',
modifiers: [ modifiers: [
{ name: 'arrow', options: { element: arrowElement } }, { name: 'arrow', options: { element: arrowElement } },
{ {
name: 'offset', name: 'offset',
options: { options: {
offset: [5, 10], offset: [-10, 10],
}, },
}, },
], ],
@ -65,7 +68,8 @@ const MenuButton: FC<MenuButtonProps> = ({
ref={setPopperElement} ref={setPopperElement}
{...popper.attributes.popper} {...popper.attributes.popper}
className={classNames(styles.popper, { className={classNames(styles.popper, {
[styles.translucent]: translucentMenu, [styles.fixed]: fixed,
[styles.translucent]: translucent,
[styles.visible]: visible, [styles.visible]: visible,
})} })}
> >

View file

@ -7,7 +7,6 @@
.popper { .popper {
@include outer_shadow; @include outer_shadow;
@include blur($content_bg, 15px, 0.5);
box-sizing: border-box; box-sizing: border-box;
z-index: 12; z-index: 12;
@ -15,12 +14,21 @@
visibility: hidden; visibility: hidden;
pointer-events: none; pointer-events: none;
touch-action: none; touch-action: none;
background-color: transparentize($content_bg, 0.05);
&.visible { &.visible {
visibility: visible; visibility: visible;
pointer-events: all; pointer-events: all;
touch-action: initial; touch-action: initial;
} }
&.fixed {
z-index: 100;
}
&.translucent {
@include blur($content_bg, 15px, 0.5);
}
} }
.arrow { .arrow {

View file

@ -6,15 +6,17 @@ import styles from './styles.module.scss';
interface MenuItemWithIconProps { interface MenuItemWithIconProps {
children: string; children: string;
icon: string; icon?: string;
onClick?: () => void; onClick?: () => void;
} }
const MenuItemWithIcon: FC<MenuItemWithIconProps> = ({ children, icon, onClick }) => ( const MenuItemWithIcon: FC<MenuItemWithIconProps> = ({ children, icon, onClick }) => (
<button className={styles.item} onClick={onClick}> <button className={styles.item} onClick={onClick}>
{icon && (
<div className={styles.icon}> <div className={styles.icon}>
<Icon icon={icon} size={20} /> <Icon icon={icon} size={20} />
</div> </div>
)}
<div className={styles.text}>{children}</div> <div className={styles.text}>{children}</div>
</button> </button>

View file

@ -18,12 +18,11 @@
.icon { .icon {
flex: 0 0 20px; flex: 0 0 20px;
margin-right: $gap;
} }
.text { .text {
flex: 1; flex: 1;
text-align: left; text-align: left;
padding-right: $gap; padding: 0 $gap;
white-space: nowrap; white-space: nowrap;
} }

View file

@ -2,11 +2,9 @@
@keyframes appear { @keyframes appear {
from { from {
opacity: 0;
transform: translate(0, -$header_height); transform: translate(0, -$header_height);
} }
to { to {
opacity: 1;
transform: translate(0, 0); transform: translate(0, 0);
} }
} }

File diff suppressed because one or more lines are too long