mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
added node edit menu
This commit is contained in:
parent
f185914c7c
commit
74f4c7562b
16 changed files with 320 additions and 175 deletions
|
@ -47,7 +47,7 @@ const CommentAvatar: FC<Props> = ({ user, withDetails, className }) => {
|
||||||
</Reference>
|
</Reference>
|
||||||
|
|
||||||
{hovered && withDetails && (
|
{hovered && withDetails && (
|
||||||
<Popper placement="right" modifiers={modifiers}>
|
<Popper placement="right" modifiers={modifiers} strategy="fixed">
|
||||||
{({ style, ref }) => (
|
{({ style, ref }) => (
|
||||||
<div style={style} ref={ref} className={styles.popper}>
|
<div style={style} ref={ref} className={styles.popper}>
|
||||||
<h4 className={styles.username}>{user.fullname || user.username}</h4>
|
<h4 className={styles.username}>{user.fullname || user.username}</h4>
|
||||||
|
|
|
@ -11,11 +11,11 @@
|
||||||
background-color: darken($content_bg, 4%);
|
background-color: darken($content_bg, 4%);
|
||||||
padding: $gap;
|
padding: $gap;
|
||||||
box-sizing:border-box;
|
box-sizing:border-box;
|
||||||
z-index: 4;
|
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
border-radius: $radius;
|
border-radius: $radius;
|
||||||
animation: appear forwards 250ms;
|
animation: appear forwards 250ms;
|
||||||
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.username {
|
.username {
|
||||||
|
|
64
src/components/menu/MenuButton/index.tsx
Normal file
64
src/components/menu/MenuButton/index.tsx
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
import React, { FC, ReactNode } from 'react';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { Manager, Popper, Reference } from 'react-popper';
|
||||||
|
|
||||||
|
import { Icon } from '~/components/input/Icon';
|
||||||
|
import { useFocusEvent } from '~/hooks/dom/useFocusEvent';
|
||||||
|
|
||||||
|
import styles from './styles.module.scss';
|
||||||
|
|
||||||
|
interface MenuButtonProps {
|
||||||
|
icon?: ReactNode;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const modifiers = [
|
||||||
|
{
|
||||||
|
name: 'offset',
|
||||||
|
options: {
|
||||||
|
offset: [5, 10],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const MenuButton: FC<MenuButtonProps> = ({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
icon = <Icon icon="dots-vertical" size={24} />,
|
||||||
|
}) => {
|
||||||
|
const { focused, onFocus, onBlur } = useFocusEvent(false, 150);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Manager>
|
||||||
|
<Reference>
|
||||||
|
{({ ref }) => (
|
||||||
|
<button
|
||||||
|
className={classNames(styles.menu, className)}
|
||||||
|
ref={ref}
|
||||||
|
onFocus={onFocus}
|
||||||
|
onBlur={onBlur}
|
||||||
|
>
|
||||||
|
{icon}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</Reference>
|
||||||
|
|
||||||
|
{focused && (
|
||||||
|
<Popper placement="bottom-end" modifiers={modifiers}>
|
||||||
|
{({ style, ref, placement }) => (
|
||||||
|
<div
|
||||||
|
style={style}
|
||||||
|
ref={ref}
|
||||||
|
className={classNames(styles.popper, { [styles.top]: placement === 'top-end' })}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Popper>
|
||||||
|
)}
|
||||||
|
</Manager>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { MenuButton };
|
40
src/components/menu/MenuButton/styles.module.scss
Normal file
40
src/components/menu/MenuButton/styles.module.scss
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
.menu {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@import "src/styles/variables.scss";
|
||||||
|
|
||||||
|
@keyframes appear {
|
||||||
|
0% { opacity: 0 }
|
||||||
|
100% { opacity: 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
.popper {
|
||||||
|
@include outer_shadow;
|
||||||
|
|
||||||
|
background-color: $menu_bg;
|
||||||
|
box-sizing: border-box;
|
||||||
|
z-index: 12;
|
||||||
|
border-radius: $radius;
|
||||||
|
animation: appear forwards 250ms;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: ' ';
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 10px 10px 10px;
|
||||||
|
border-color: transparent transparent lighten($menu_bg, 6%) transparent;
|
||||||
|
position: absolute;
|
||||||
|
top: -11px;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.top::after {
|
||||||
|
border-width: 10px 10px 0 10px;
|
||||||
|
border-color: darken($menu_bg, 8%) transparent transparent transparent;
|
||||||
|
top: auto;
|
||||||
|
bottom: -11px;
|
||||||
|
}
|
||||||
|
}
|
23
src/components/menu/MenuItemWithIcon/index.tsx
Normal file
23
src/components/menu/MenuItemWithIcon/index.tsx
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import React, { FC } from 'react';
|
||||||
|
|
||||||
|
import { Icon } from '~/components/input/Icon';
|
||||||
|
|
||||||
|
import styles from './styles.module.scss';
|
||||||
|
|
||||||
|
interface MenuItemWithIconProps {
|
||||||
|
children: string;
|
||||||
|
icon: string;
|
||||||
|
onClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MenuItemWithIcon: FC<MenuItemWithIconProps> = ({ children, icon, onClick }) => (
|
||||||
|
<button className={styles.item} onClick={onClick}>
|
||||||
|
<div className={styles.icon}>
|
||||||
|
<Icon icon={icon} size={20} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.text}>{children}</div>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|
||||||
|
export { MenuItemWithIcon };
|
29
src/components/menu/MenuItemWithIcon/styles.module.scss
Normal file
29
src/components/menu/MenuItemWithIcon/styles.module.scss
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
@import "src/styles/variables";
|
||||||
|
|
||||||
|
.item {
|
||||||
|
@include row_shadow;
|
||||||
|
@include hover_opacity;
|
||||||
|
|
||||||
|
font: $font_14_medium;
|
||||||
|
line-height: 20px;
|
||||||
|
padding: $gap + 2px $gap $gap - 2px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
color: white;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
flex: 0 0 20px;
|
||||||
|
margin-right: $gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
flex: 1;
|
||||||
|
text-align: left;
|
||||||
|
padding-right: $gap;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
31
src/components/menu/SeparatedMenu/index.tsx
Normal file
31
src/components/menu/SeparatedMenu/index.tsx
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import React, { FC, ReactNode, useMemo } from 'react';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import styles from './styles.module.scss';
|
||||||
|
|
||||||
|
interface SeparatedMenuProps {
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SeparatedMenu: FC<SeparatedMenuProps> = ({ children, className }) => {
|
||||||
|
const items = useMemo<ReactNode[]>(() => {
|
||||||
|
if (!children) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Array.isArray(children) ? children : [children]).filter(it => it);
|
||||||
|
}, [children]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classNames(styles.menu, className)}>
|
||||||
|
{items.map((item, index) => (
|
||||||
|
<div className={styles.item} key={index}>
|
||||||
|
{item}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { SeparatedMenu };
|
29
src/components/menu/SeparatedMenu/styles.module.scss
Normal file
29
src/components/menu/SeparatedMenu/styles.module.scss
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
@import "src/styles/mixins";
|
||||||
|
@import "src/styles/variables";
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
flex: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
margin-left: $gap * 4;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:not(:last-child)::after {
|
||||||
|
@include inner_shadow;
|
||||||
|
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 3px;
|
||||||
|
height: 16px;
|
||||||
|
background: darken($content_bg, 1%);
|
||||||
|
display: flex;
|
||||||
|
top: 5px;
|
||||||
|
right: -$gap * 2 - 2px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
5
src/components/menu/index.ts
Normal file
5
src/components/menu/index.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export * from './VerticalMenu';
|
||||||
|
export * from './HorizontalMenu';
|
||||||
|
export * from './MenuButton';
|
||||||
|
export * from './MenuItemWithIcon';
|
||||||
|
export * from './SeparatedMenu';
|
|
@ -1,12 +1,17 @@
|
||||||
import React, { VFC } from 'react';
|
import React, { VFC } from 'react';
|
||||||
|
|
||||||
|
import Tippy from '@tippyjs/react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import { Icon } from '~/components/input/Icon';
|
import { Icon } from '~/components/input/Icon';
|
||||||
|
import { MenuButton, MenuItemWithIcon, SeparatedMenu } from '~/components/menu';
|
||||||
|
import { useWindowSize } from '~/hooks/dom/useWindowSize';
|
||||||
|
|
||||||
import styles from './styles.module.scss';
|
import styles from './styles.module.scss';
|
||||||
|
|
||||||
interface NodeEditMenuProps {
|
interface NodeEditMenuProps {
|
||||||
|
className?: string;
|
||||||
|
|
||||||
canStar: boolean;
|
canStar: boolean;
|
||||||
|
|
||||||
isHeroic: boolean;
|
isHeroic: boolean;
|
||||||
|
@ -18,36 +23,62 @@ interface NodeEditMenuProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const NodeEditMenu: VFC<NodeEditMenuProps> = ({
|
const NodeEditMenu: VFC<NodeEditMenuProps> = ({
|
||||||
|
className,
|
||||||
canStar,
|
canStar,
|
||||||
isHeroic,
|
isHeroic,
|
||||||
isLocked,
|
isLocked,
|
||||||
onStar,
|
onStar,
|
||||||
onLock,
|
onLock,
|
||||||
onEdit,
|
onEdit,
|
||||||
}) => (
|
}) => {
|
||||||
<div className={styles.editor_menu}>
|
const { isMobile } = useWindowSize();
|
||||||
<div className={styles.editor_menu_button}>
|
|
||||||
<Icon icon="dots-vertical" size={24} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.editor_buttons}>
|
if (isMobile) {
|
||||||
|
return (
|
||||||
|
<MenuButton
|
||||||
|
icon={<Icon icon="dots-vertical" className={styles.icon} size={24} />}
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
{canStar && (
|
||||||
|
<MenuItemWithIcon icon={isHeroic ? 'star_full' : 'star'} onClick={onStar}>
|
||||||
|
{isHeroic ? 'Убрать с главной' : 'На главную'}
|
||||||
|
</MenuItemWithIcon>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<MenuItemWithIcon icon="edit" onClick={onEdit}>
|
||||||
|
Редактировать
|
||||||
|
</MenuItemWithIcon>
|
||||||
|
|
||||||
|
<MenuItemWithIcon icon={isLocked ? 'locked' : 'unlocked'} onClick={onLock}>
|
||||||
|
{isLocked ? 'Восстановить' : 'Удалить'}
|
||||||
|
</MenuItemWithIcon>
|
||||||
|
</MenuButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SeparatedMenu>
|
||||||
{canStar && (
|
{canStar && (
|
||||||
<div className={classNames(styles.star, { [styles.is_heroic]: isHeroic })}>
|
<Tippy content={isHeroic ? 'Убрать с главной' : 'На главную'}>
|
||||||
{isHeroic ? (
|
<button className={className} onClick={onStar}>
|
||||||
<Icon icon="star_full" size={24} onClick={onStar} />
|
<Icon icon={isHeroic ? 'star_full' : 'star'} size={24} />
|
||||||
) : (
|
</button>
|
||||||
<Icon icon="star" size={24} onClick={onStar} />
|
</Tippy>
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div>
|
<Tippy content="Редактировать">
|
||||||
<Icon icon={isLocked ? 'locked' : 'unlocked'} size={24} onClick={onLock} />
|
<button className={className} onClick={onEdit}>
|
||||||
</div>
|
<Icon icon="edit" size={24} />
|
||||||
|
</button>
|
||||||
|
</Tippy>
|
||||||
|
|
||||||
<Icon icon="edit" size={24} onClick={onEdit} />
|
<Tippy content={isLocked ? 'Восстановить' : 'Удалить'}>
|
||||||
</div>
|
<button className={className} onClick={onLock}>
|
||||||
</div>
|
<Icon icon={isLocked ? 'locked' : 'unlocked'} size={24} />
|
||||||
);
|
</button>
|
||||||
|
</Tippy>
|
||||||
|
</SeparatedMenu>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export { NodeEditMenu };
|
export { NodeEditMenu };
|
||||||
|
|
|
@ -1,109 +1,3 @@
|
||||||
@import "src/styles/variables";
|
.icon {
|
||||||
@import "src/styles/mixins";
|
fill: currentColor;
|
||||||
|
|
||||||
@mixin button {
|
|
||||||
margin: 12px $gap 0 $gap;
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
fill: darken(white, 50%);
|
|
||||||
transition: fill 0.25s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
svg {
|
|
||||||
fill: $red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: ' ';
|
|
||||||
flex: 0 0 6px;
|
|
||||||
height: $gap;
|
|
||||||
width: 6px;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: transparentize(black, 0.7);
|
|
||||||
margin-left: $gap * 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor_buttons {
|
|
||||||
flex: 0;
|
|
||||||
padding-right: $gap;
|
|
||||||
fill: transparentize(white, 0.7);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
& > * {
|
|
||||||
@include button;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include tablet {
|
|
||||||
align-self: center;
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
& > * {
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.star {
|
|
||||||
transition: fill, stroke 0.25s;
|
|
||||||
will-change: transform;
|
|
||||||
|
|
||||||
.is_heroic {
|
|
||||||
svg {
|
|
||||||
fill: $orange;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
fill: $orange;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor_menu_button {
|
|
||||||
display: none !important;
|
|
||||||
|
|
||||||
@include button();
|
|
||||||
|
|
||||||
@include tablet {
|
|
||||||
display: flex !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor_menu {
|
|
||||||
&:hover {
|
|
||||||
.editor_buttons {
|
|
||||||
@include tablet {
|
|
||||||
display: flex;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 100%;
|
|
||||||
background: darken($content_bg, 4%);
|
|
||||||
padding: $gap * 2;
|
|
||||||
border-radius: $radius;
|
|
||||||
box-shadow: transparentize(black, 0.8) 5px 5px 5px;
|
|
||||||
transform: translate(0, -10px);
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import React, { memo, VFC } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import { Icon } from '~/components/input/Icon';
|
import { Icon } from '~/components/input/Icon';
|
||||||
|
import { SeparatedMenu } from '~/components/menu';
|
||||||
import { NodeEditMenu } from '~/components/node/NodeEditMenu';
|
import { NodeEditMenu } from '~/components/node/NodeEditMenu';
|
||||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||||
import { getPrettyDate } from '~/utils/dom';
|
import { getPrettyDate } from '~/utils/dom';
|
||||||
|
@ -74,20 +75,23 @@ const NodeTitle: VFC<IProps> = memo(
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{canEdit && (
|
<SeparatedMenu className={styles.buttons}>
|
||||||
<NodeEditMenu
|
{canEdit && (
|
||||||
canStar={canStar}
|
<NodeEditMenu
|
||||||
isHeroic={isHeroic}
|
className={styles.button}
|
||||||
isLocked={isLocked}
|
canStar={canStar}
|
||||||
onStar={onStar}
|
isHeroic={isHeroic}
|
||||||
onLock={onLock}
|
isLocked={isLocked}
|
||||||
onEdit={onEdit}
|
onStar={onStar}
|
||||||
/>
|
onLock={onLock}
|
||||||
)}
|
onEdit={onEdit}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className={styles.buttons}>
|
|
||||||
{canLike && (
|
{canLike && (
|
||||||
<div className={classNames(styles.like, { [styles.is_liked]: isLiked })}>
|
<div
|
||||||
|
className={classNames(styles.button, styles.like, { [styles.is_liked]: isLiked })}
|
||||||
|
>
|
||||||
{isLiked ? (
|
{isLiked ? (
|
||||||
<Icon icon="heart_full" size={24} onClick={onLike} />
|
<Icon icon="heart_full" size={24} onClick={onLike} />
|
||||||
) : (
|
) : (
|
||||||
|
@ -99,7 +103,7 @@ const NodeTitle: VFC<IProps> = memo(
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</SeparatedMenu>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
font: $font_14_regular;
|
font: $font_12_regular;
|
||||||
color: transparentize(white, 0.5);
|
color: transparentize(white, 0.5);
|
||||||
text-transform: lowercase;
|
text-transform: lowercase;
|
||||||
|
|
||||||
|
@ -95,37 +95,6 @@
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttons {
|
|
||||||
flex: 0;
|
|
||||||
padding-right: $gap;
|
|
||||||
fill: transparentize(white, 0.7);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: 12px;
|
|
||||||
|
|
||||||
& > * {
|
|
||||||
@include button;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include tablet {
|
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons {
|
|
||||||
& > * {
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mark {
|
.mark {
|
||||||
flex: 0 0 32px;
|
flex: 0 0 32px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -177,8 +146,11 @@
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 0 0 32px;
|
flex: 0 0 32px;
|
||||||
|
fill: currentColor;
|
||||||
|
|
||||||
&.is_liked {
|
&.is_liked {
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
fill: $red;
|
fill: $red;
|
||||||
}
|
}
|
||||||
|
@ -213,3 +185,13 @@
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
margin-top: 12px;
|
||||||
|
margin-right: $gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
color: white;
|
||||||
|
@include hover_opacity;
|
||||||
|
}
|
||||||
|
|
|
@ -67,3 +67,4 @@ $side_pane_btn_color: lighten($main_bg_color, 0%);
|
||||||
$node_buttons_bg: darken($main_bg_color, 6%);
|
$node_buttons_bg: darken($main_bg_color, 6%);
|
||||||
|
|
||||||
$tag_bg: lighten($main_bg_color, 4%);
|
$tag_bg: lighten($main_bg_color, 4%);
|
||||||
|
$menu_bg: lighten($main_bg_color, 4%);
|
||||||
|
|
|
@ -274,3 +274,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin hover_opacity($initial_opacity: 0.5) {
|
||||||
|
opacity: $initial_opacity;
|
||||||
|
transition: opacity 0.25s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -46,3 +46,6 @@ table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
}
|
}
|
||||||
|
button {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue