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

#23 added boris UI tab

This commit is contained in:
Fedor Katurov 2021-03-17 14:26:01 +07:00
parent e38090c755
commit 5f57314eec
11 changed files with 206 additions and 74 deletions

View file

@ -7,6 +7,7 @@
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@tippy.js/react": "^3.1.1",
"autosize": "^4.0.2",
"axios": "^0.21.1",
"body-scroll-lock": "^2.6.4",

View file

@ -0,0 +1,40 @@
import React, { FC } from 'react';
import styles from './styles.module.scss';
import { Group } from '~/components/containers/Group';
import { NodeCommentForm } from '~/components/node/NodeCommentForm';
import { NodeNoComments } from '~/components/node/NodeNoComments';
import { NodeComments } from '~/components/node/NodeComments';
import { Footer } from '~/components/main/Footer';
import { Card } from '~/components/containers/Card';
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
import { selectAuthUser } from '~/redux/auth/selectors';
import { IComment, INode } from '~/redux/types';
interface IProps {
isLoadingComments: boolean;
commentCount: number;
node: INode;
comments: IComment[];
}
const BorisComments: FC<IProps> = ({ isLoadingComments, node, commentCount, comments }) => {
const user = useShallowSelect(selectAuthUser);
return (
<Card className={styles.content}>
<Group className={styles.grid}>
{user.is_user && <NodeCommentForm isBefore nodeId={node.id} />}
{isLoadingComments ? (
<NodeNoComments is_loading count={7} />
) : (
<NodeComments comments={comments} count={commentCount} user={user} order="ASC" />
)}
</Group>
<Footer />
</Card>
);
};
export { BorisComments };

View file

@ -0,0 +1,18 @@
@import "~/styles/variables.scss";
.content {
flex: 4;
z-index: 2;
border-radius: $radius;
padding: 0;
background: $node_bg;
box-shadow: inset transparentize(mix($wisegreen, white, 60%), 0.6) 0 1px;
@include desktop {
flex: 2.5;
}
@media(max-width: 1024px) {
flex: 2;
}
}

View file

@ -0,0 +1,51 @@
import React, { FC } from 'react';
import { Card } from '~/components/containers/Card';
import styles from './styles.module.scss';
import markdown from '~/styles/common/markdown.module.scss';
import { Group } from '~/components/containers/Group';
import { Button } from '~/components/input/Button';
interface IProps {}
const BorisUIDemo: FC<IProps> = () => (
<Card className={styles.card}>
<div className={markdown.wrapper}>
<h1>UI</h1>
<p>
Простая демонстрация элементов интерфейса. Используется, в основном, как подсказка при
разработке
</p>
<h2>Кнопки</h2>
<h4>Цвета</h4>
<Group horizontal className={styles.sample}>
<Button>Primary</Button>
<Button color="secondary">Secondary</Button>
<Button color="outline">Outline</Button>
<Button color="gray">Gray</Button>
<Button color="link">Link</Button>
</Group>
<h4>Размеры</h4>
<Group horizontal className={styles.sample}>
<Button size="micro">Micro</Button>
<Button size="mini">Mini</Button>
<Button size="normal">Normal</Button>
<Button size="big">Big</Button>
<Button size="giant">Giant</Button>
</Group>
<h4>Варианты</h4>
<Group horizontal className={styles.sample}>
<Button iconRight="check">iconRight</Button>
<Button iconLeft="send">iconLeft</Button>
<Button round>Round</Button>
</Group>
</div>
</Card>
);
export { BorisUIDemo };

View file

@ -0,0 +1,11 @@
.card {
flex: 3;
align-self: stretch;
position: relative;
z-index: 1;
padding: 20px 30px;
}
.sample {
flex-wrap: wrap;
}

View file

@ -6,11 +6,15 @@ import React, {
createElement,
memo,
useRef,
useEffect,
useMemo,
} from 'react';
import styles from './styles.module.scss';
import { Icon } from '~/components/input/Icon';
import { IIcon } from '~/redux/types';
import { usePopper } from 'react-popper';
import Tippy from '@tippy.js/react';
import 'tippy.js/dist/tippy.css';
type IButtonProps = DetailedHTMLProps<
ButtonHTMLAttributes<HTMLButtonElement>,
@ -23,7 +27,6 @@ type IButtonProps = DetailedHTMLProps<
seamless?: boolean;
transparent?: boolean;
title?: string;
non_submitting?: boolean;
is_loading?: boolean;
stretchy?: boolean;
iconOnly?: boolean;
@ -41,7 +44,6 @@ const Button: FC<IButtonProps> = memo(
children,
seamless = false,
transparent = false,
non_submitting = false,
is_loading,
title,
stretchy,
@ -52,23 +54,9 @@ const Button: FC<IButtonProps> = memo(
round,
...props
}) => {
const tooltip = useRef<HTMLSpanElement | null>(null);
const pop = usePopper(tooltip?.current?.parentElement, tooltip.current, {
placement: 'top',
modifiers: [
{
name: 'offset',
options: {
offset: [0, 5],
},
},
],
});
return createElement(
seamless || non_submitting ? 'div' : 'button',
{
className: classnames(styles.button, className, styles[size], styles[color], {
const computedClassName = useMemo(
() =>
classnames(styles.button, className, styles[size], styles[color], {
seamless,
transparent,
disabled,
@ -79,18 +67,17 @@ const Button: FC<IButtonProps> = memo(
has_icon_right: !!iconRight,
round,
}),
...props,
},
[
iconLeft && <Icon icon={iconLeft} size={20} key={0} className={styles.icon_left} />,
title ? <span>{title}</span> : children || null,
iconRight && <Icon icon={iconRight} size={20} key={2} className={styles.icon_right} />,
!!label && (
<span ref={tooltip} className={styles.tooltip} style={pop.styles.popper} key="tooltip">
{label}
</span>
),
]
[seamless, round, disabled, className, is_loading, stretchy, iconLeft, iconRight, size, color]
);
return (
<Tippy content={label || ''} enabled={!!label}>
<button className={computedClassName} {...props}>
{iconLeft && <Icon icon={iconLeft} size={20} key={0} className={styles.icon_left} />}
{!!title ? <span>{title}</span> : children}
{iconRight && <Icon icon={iconRight} size={20} key={2} className={styles.icon_right} />}
</button>
</Tippy>
);
}
);

View file

@ -184,32 +184,56 @@
font: $font_12_semibold;
padding: 0 15px;
border-radius: $radius / 2;
&:global(.round) {
border-radius: 10px;
}
}
.mini {
height: 28px;
border-radius: $radius / 2;
&:global(.round) {
border-radius: 14px;
}
}
.small {
height: 32px;
// border-radius: $radius / 2;
svg {
width: 24px;
height: 24px;
}
&:global(.round) {
border-radius: 16px;
}
}
.normal {
height: 38px;
&:global(.round) {
border-radius: 19px;
}
}
.big {
height: 40px;
&:global(.round) {
border-radius: 20px;
}
}
.giant {
height: 50px;
padding: 0 15px;
min-width: 50px;
&:global(.round) {
border-radius: 25px;
}
}
.disabled {
@ -234,14 +258,13 @@
z-index: 2;
border-radius: $input_radius;
text-transform: none;
opacity: 0;
pointer-events: none;
touch-action: none;
transition: opacity 0.1s;
border: 1px solid transparentize(white, 0.9);
//visibility: hidden;
.button:hover & {
opacity: 1;
visibility: visible;
font: $font_14_semibold;
}
}

View file

@ -95,7 +95,11 @@ const EditorDialogUnconnected: FC<IProps> = ({
maxLength={256}
/>
<Button title="Сохранить" iconRight="check" />
<Button
title="Сохранить"
iconRight="check"
color={data.is_promoted ? 'primary' : 'secondary'}
/>
</Group>
</Padder>
);

View file

@ -2,16 +2,11 @@ import React, { FC, useEffect } from 'react';
import { selectNode, selectNodeComments } from '~/redux/node/selectors';
import { selectUser } from '~/redux/auth/selectors';
import { useDispatch } from 'react-redux';
import { NodeComments } from '~/components/node/NodeComments';
import styles from './styles.module.scss';
import { Group } from '~/components/containers/Group';
import boris from '~/sprites/boris_robot.svg';
import { NodeNoComments } from '~/components/node/NodeNoComments';
import { useRandomPhrase } from '~/constants/phrases';
import { NodeCommentForm } from '~/components/node/NodeCommentForm';
import isBefore from 'date-fns/isBefore';
import { Card } from '~/components/containers/Card';
import { Footer } from '~/components/main/Footer';
import { BorisStats } from '~/components/boris/BorisStats';
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
import { selectBorisStats } from '~/redux/boris/selectors';
@ -20,6 +15,10 @@ import { nodeLoadNode } from '~/redux/node/actions';
import { borisLoadStats } from '~/redux/boris/actions';
import { Container } from '~/containers/main/Container';
import StickyBox from 'react-sticky-box/dist/esnext';
import { BorisComments } from '~/components/boris/BorisComments';
import { URLS } from '~/constants/urls';
import { Route, Switch } from 'react-router-dom';
import { BorisUIDemo } from '~/components/boris/BorisUIDemo';
type IProps = {};
@ -69,24 +68,18 @@ const BorisLayout: FC<IProps> = () => {
</div>
<div className={styles.container}>
<Card className={styles.content}>
<Group className={styles.grid}>
{user.is_user && <NodeCommentForm isBefore nodeId={node.current.id} />}
{
<Switch>
<Route path={`${URLS.BORIS}/ui`} component={BorisUIDemo} />
{node.is_loading_comments ? (
<NodeNoComments is_loading count={7} />
) : (
<NodeComments
comments={comments}
count={node.comment_count}
user={user}
order="ASC"
<BorisComments
isLoadingComments={node.is_loading_comments}
commentCount={node.comment_count}
node={node.current}
comments={node.comments}
/>
)}
</Group>
<Footer />
</Card>
</Switch>
}
<Group className={styles.stats}>
<StickyBox className={styles.sticky} offsetTop={72} offsetBottom={10}>

View file

@ -7,22 +7,6 @@
flex-direction: column;
}
.content {
flex: 4;
z-index: 2;
border-radius: $radius;
padding: 0;
background: $node_bg;
box-shadow: inset transparentize(mix($wisegreen, white, 60%), 0.6) 0 1px;
@include desktop {
flex: 2.5;
}
@media(max-width: 1024px) {
flex: 2;
}
}
.grid {
padding: $gap;

View file

@ -1594,6 +1594,14 @@
dependencies:
"@babel/runtime" "^7.10.2"
"@tippy.js/react@^3.1.1":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@tippy.js/react/-/react-3.1.1.tgz#027e4595e55f31430741fe8e0d92aaddfbe47efd"
integrity sha512-KF45vW/jKh/nBXk/2zzTFslv/T46zOMkIoDJ56ymZ+M00yHttk58J5wZ29oqGqDIUnobWSZD+cFpbR4u/UUvgw==
dependencies:
prop-types "^15.6.2"
tippy.js "^5.1.1"
"@types/aria-query@^4.2.0":
version "4.2.0"
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0"
@ -8330,6 +8338,11 @@ pnp-webpack-plugin@1.6.4:
dependencies:
ts-pnp "^1.1.6"
popper.js@^1.16.0:
version "1.16.1"
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==
portfinder@^1.0.26:
version "1.0.28"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
@ -10972,6 +10985,13 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3:
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
tippy.js@^5.1.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-5.2.1.tgz#e08d7332c103a15e427124d710d881fca82365d6"
integrity sha512-66UT6JRVn3dXNCORE+0UvUK3JZqV/VhLlU6HTDm3FmrweUUFUxUGvT8tUQ7ycMp+uhuLAwQw6dBabyC+iKf/MA==
dependencies:
popper.js "^1.16.0"
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"