From 47adbdf6f0d677ddc118246db90513c6dfedbd81 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Sat, 18 Apr 2020 18:46:51 +0700 Subject: [PATCH] clearing search --- src/components/flow/FlowRecent/index.tsx | 38 +---------- src/components/flow/FlowRecent/styles.scss | 56 ---------------- src/components/flow/FlowRecentItem/index.tsx | 30 +++++++++ .../flow/FlowRecentItem/styles.scss | 57 ++++++++++++++++ .../flow/FlowSearchResults/index.tsx | 31 ++++----- .../flow/FlowSearchResults/styles.scss | 66 ++++--------------- src/components/flow/FlowStamp/index.tsx | 32 ++++++++- src/components/flow/FlowStamp/styles.scss | 34 +++++++++- src/components/input/InputText/index.tsx | 4 ++ src/containers/flow/FlowLayout/styles.scss | 12 ---- src/redux/types.ts | 3 +- src/sprites/Sprites.tsx | 5 ++ src/styles/inputs.scss | 42 +++++++----- 13 files changed, 215 insertions(+), 195 deletions(-) create mode 100644 src/components/flow/FlowRecentItem/index.tsx create mode 100644 src/components/flow/FlowRecentItem/styles.scss diff --git a/src/components/flow/FlowRecent/index.tsx b/src/components/flow/FlowRecent/index.tsx index f3eee255..79bae2d4 100644 --- a/src/components/flow/FlowRecent/index.tsx +++ b/src/components/flow/FlowRecent/index.tsx @@ -1,11 +1,6 @@ import React, { FC } from 'react'; -import * as styles from './styles.scss'; import { IFlowState } from '~/redux/flow/reducer'; -import { getURL, getPrettyDate } from '~/utils/dom'; -import { Link } from 'react-router-dom'; -import { URLS, PRESETS } from '~/constants/urls'; -import classNames from 'classnames'; -import { NodeRelatedItem } from '~/components/node/NodeRelatedItem'; +import { FlowRecentItem } from '../FlowRecentItem'; interface IProps { recent: IFlowState['recent']; @@ -15,36 +10,9 @@ interface IProps { const FlowRecent: FC = ({ recent, updated }) => { return ( <> - {updated && - updated.slice(0, 20).map(node => ( - -
+ {updated && updated.map(node => )} -
-
{node.title}
-
{getPrettyDate(node.created_at)}
-
- - ))} - - {recent && - recent.slice(0, 20).map(node => ( - -
- -
- -
-
{node.title}
-
{getPrettyDate(node.created_at)}
-
- - ))} + {recent && recent.map(node => )} ); }; diff --git a/src/components/flow/FlowRecent/styles.scss b/src/components/flow/FlowRecent/styles.scss index 67cc6542..e69de29b 100644 --- a/src/components/flow/FlowRecent/styles.scss +++ b/src/components/flow/FlowRecent/styles.scss @@ -1,56 +0,0 @@ -.item { - display: flex; - align-items: center; - justify-content: center; - font: $font_12_regular; - border-radius: $radius; - flex-direction: row; - margin-bottom: $gap; - color: white; - text-decoration: none; -} - -.thumb { - height: 48px; - margin-right: $gap; - background: 50% 50% no-repeat; - background-size: cover; - border-radius: $radius; - flex: 0 0 48px; - display: flex; - align-items: center; - justify-content: center; - position: relative; - - &.new { - &::after { - content: ' '; - width: 12px; - height: 12px; - border-radius: 100%; - background: $red; - box-shadow: $content_bg 0 0 0 5px; - position: absolute; - right: -2px; - bottom: -2px; - } - } -} - -.info { - flex: 1; - min-width: 0; -} - -.title { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - font: $font_16_semibold; -} - -.comment { - font: $font_12_regular; - margin-top: 4px; - opacity: 0.5; -} diff --git a/src/components/flow/FlowRecentItem/index.tsx b/src/components/flow/FlowRecentItem/index.tsx new file mode 100644 index 00000000..f4a17ef1 --- /dev/null +++ b/src/components/flow/FlowRecentItem/index.tsx @@ -0,0 +1,30 @@ +import React, { FC } from 'react'; +import { INode } from '~/redux/types'; +import styles from './styles.scss'; +import { URLS } from '~/constants/urls'; +import { NodeRelatedItem } from '~/components/node/NodeRelatedItem'; +import { getPrettyDate } from '~/utils/dom'; +import { Link } from 'react-router-dom'; +import classNames from 'classnames'; + +interface IProps { + node: Partial; + has_new?: boolean; +} + +const FlowRecentItem: FC = ({ node, has_new }) => { + return ( + +
+ +
+ +
+
{node.title}
+
{getPrettyDate(node.created_at)}
+
+ + ); +}; + +export { FlowRecentItem }; diff --git a/src/components/flow/FlowRecentItem/styles.scss b/src/components/flow/FlowRecentItem/styles.scss new file mode 100644 index 00000000..d103d429 --- /dev/null +++ b/src/components/flow/FlowRecentItem/styles.scss @@ -0,0 +1,57 @@ +.item { + display: flex; + align-items: center; + justify-content: center; + font: $font_12_regular; + border-radius: $radius; + flex-direction: row; + margin-bottom: $gap; + color: white; + text-decoration: none; +} + +.thumb { + height: 48px; + margin-right: $gap; + background: 50% 50% no-repeat; + background-size: cover; + border-radius: $radius; + flex: 0 0 48px; + display: flex; + align-items: center; + justify-content: center; + position: relative; + + &.new { + &::after { + content: ' '; + width: 12px; + height: 12px; + border-radius: 100%; + background: $red; + box-shadow: $content_bg 0 0 0 5px; + position: absolute; + right: -2px; + bottom: -2px; + } + } +} + +.info { + flex: 1; + min-width: 0; +} + +.title { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + font: $font_16_semibold; + text-transform: capitalize; +} + +.comment { + font: $font_12_regular; + margin-top: 4px; + opacity: 0.5; +} diff --git a/src/components/flow/FlowSearchResults/index.tsx b/src/components/flow/FlowSearchResults/index.tsx index 81dba800..2b5e9925 100644 --- a/src/components/flow/FlowSearchResults/index.tsx +++ b/src/components/flow/FlowSearchResults/index.tsx @@ -1,11 +1,9 @@ -import React, { FC, useCallback, MouseEvent } from 'react'; +import React, { FC, useCallback } from 'react'; import styles from './styles.scss'; import { IFlowState } from '~/redux/flow/reducer'; import { LoaderCircle } from '~/components/input/LoaderCircle'; -import { URLS, PRESETS } from '~/constants/urls'; -import { Link } from 'react-router-dom'; -import classNames from 'classnames'; -import { getURL, getPrettyDate } from '~/utils/dom'; +import { FlowRecentItem } from '../FlowRecentItem'; +import { Icon } from '~/components/input/Icon'; interface IProps { search: IFlowState['search']; @@ -33,22 +31,19 @@ const FlowSearchResults: FC = ({ search, onLoadMore }) => { ); } + if (!search.results.length) { + return ( +
+ +
Ничего не найдено
+
+ ); + } + return (
{search.results.map(node => ( - -
- -
-
{node.title}
-
{getPrettyDate(node.created_at)}
-
- + ))}
); diff --git a/src/components/flow/FlowSearchResults/styles.scss b/src/components/flow/FlowSearchResults/styles.scss index 86a8e8f8..7c88908e 100644 --- a/src/components/flow/FlowSearchResults/styles.scss +++ b/src/components/flow/FlowSearchResults/styles.scss @@ -7,64 +7,20 @@ display: flex; align-items: center; justify-content: center; + flex-direction: column; flex: 1; opacity: 0.3; + fill: transparentize(white, 0.7); + stroke: none; } -.item { - display: flex; - align-items: center; - justify-content: center; - font: $font_12_regular; - border-radius: $radius; - flex-direction: row; - margin-bottom: $gap; +.nothing { color: white; - text-decoration: none; -} - -.thumb { - height: 48px; - margin-right: $gap; - background: 50% 50% no-repeat; - background-size: cover; - border-radius: $radius; - flex: 0 0 48px; - display: flex; - align-items: center; - justify-content: center; - position: relative; - - &.new { - &::after { - content: ' '; - width: 12px; - height: 12px; - border-radius: 100%; - background: $red; - box-shadow: $content_bg 0 0 0 5px; - position: absolute; - right: -2px; - bottom: -2px; - } - } -} - -.info { - flex: 1; - min-width: 0; -} - -.title { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - font: $font_16_semibold; - text-transform: capitalize; -} - -.comment { - font: $font_12_regular; - margin-top: 4px; - opacity: 0.5; + text-transform: uppercase; + font: $font_18_semibold; + font-weight: 900; + opacity: 0.3; + padding: 10px 20px; + text-align: center; + line-height: 1.5em; } diff --git a/src/components/flow/FlowStamp/index.tsx b/src/components/flow/FlowStamp/index.tsx index bd8f11ed..da5a6bd3 100644 --- a/src/components/flow/FlowStamp/index.tsx +++ b/src/components/flow/FlowStamp/index.tsx @@ -1,4 +1,4 @@ -import React, { FC, useCallback, FormEvent } from 'react'; +import React, { FC, useCallback, FormEvent, useMemo, KeyboardEvent } from 'react'; import { IFlowState } from '~/redux/flow/reducer'; import { InputText } from '~/components/input/InputText'; import { FlowRecent } from '../FlowRecent'; @@ -7,6 +7,7 @@ import classnames from 'classnames'; import * as styles from './styles.scss'; import * as FLOW_ACTIONS from '~/redux/flow/actions'; import { FlowSearchResults } from '../FlowSearchResults'; +import { Icon } from '~/components/input/Icon'; interface IProps { recent: IFlowState['recent']; @@ -25,10 +26,37 @@ const FlowStamp: FC = ({ recent, updated, search, flowChangeSearch, onLo event.preventDefault(); }, []); + const onClearSearch = useCallback(() => flowChangeSearch({ text: '' }), [flowChangeSearch]); + + const onKeyUp = useCallback( + event => { + if (event.key !== 'Escape') return; + onClearSearch(); + event.target.blur(); + }, + [onClearSearch] + ); + + const after = useMemo( + () => + search.text ? ( + + ) : ( + + ), + [search.text] + ); + return (
- +
diff --git a/src/components/flow/FlowStamp/styles.scss b/src/components/flow/FlowStamp/styles.scss index a0497505..15747e3d 100644 --- a/src/components/flow/FlowStamp/styles.scss +++ b/src/components/flow/FlowStamp/styles.scss @@ -13,6 +13,19 @@ flex: 1; border-radius: $radius; overflow: hidden; + position: relative; + + &::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + height: 60px; + width: 100%; + background: linear-gradient(transparentize($content_bg, 1), $content_bg 90%); + pointer-events: none; + touch-action: none; + } @include outer_shadow(); } @@ -53,9 +66,28 @@ } .search { - background: lighten($content_bg, 4%); + background: lighten($content_bg, 3%); border-radius: $radius $radius 0 0; padding: $gap; @include outer_shadow(); } + +.search_icon { + fill: white; + opacity: 0.1; + stroke: white; + stroke-width: 0.5; +} + +.close_icon { + cursor: pointer; + stroke: white; + stroke-width: 0.5; + opacity: 0.5; + transition: opacity 0.25s; + + &:hover { + opacity: 0.7; + } +} diff --git a/src/components/input/InputText/index.tsx b/src/components/input/InputText/index.tsx index cadf4c34..c4cc4668 100644 --- a/src/components/input/InputText/index.tsx +++ b/src/components/input/InputText/index.tsx @@ -16,6 +16,7 @@ const InputText: FC = ({ value = '', onRef, is_loading, + after, ...props }) => { const [focused, setFocused] = useState(false); @@ -61,6 +62,7 @@ const InputText: FC = ({
+
@@ -83,6 +85,8 @@ const InputText: FC = ({ {error}
)} + + {!!after &&
{after}
}
); }; diff --git a/src/containers/flow/FlowLayout/styles.scss b/src/containers/flow/FlowLayout/styles.scss index 688821d5..f0f4485c 100644 --- a/src/containers/flow/FlowLayout/styles.scss +++ b/src/containers/flow/FlowLayout/styles.scss @@ -80,16 +80,4 @@ $cols: $content_width / $cell; justify-content: stretch; overflow: hidden; position: relative; - - &::after { - content: ''; - position: absolute; - bottom: 0; - left: 0; - height: 60px; - width: 100%; - background: linear-gradient(transparentize($content_bg, 1), $content_bg 90%); - pointer-events: none; - touch-action: none; - } } diff --git a/src/redux/types.ts b/src/redux/types.ts index adb1e0fd..fa0bea30 100644 --- a/src/redux/types.ts +++ b/src/redux/types.ts @@ -1,4 +1,4 @@ -import { DetailedHTMLProps, InputHTMLAttributes } from 'react'; +import { DetailedHTMLProps, InputHTMLAttributes, ReactElement } from 'react'; import { DIALOGS } from '~/redux/modal/constants'; import { ERRORS } from '~/constants/errors'; import { IUser } from './auth/types'; @@ -30,6 +30,7 @@ export type IInputTextProps = DetailedHTMLProps< mask?: string; onRef?: (ref: any) => void; is_loading?: boolean; + after?: ReactElement; }; export type IIcon = string; diff --git a/src/sprites/Sprites.tsx b/src/sprites/Sprites.tsx index e418f696..5abf852b 100644 --- a/src/sprites/Sprites.tsx +++ b/src/sprites/Sprites.tsx @@ -217,6 +217,11 @@ const Sprites: FC<{}> = () => ( + + + + + diff --git a/src/styles/inputs.scss b/src/styles/inputs.scss index 74bb370e..3fc643dd 100644 --- a/src/styles/inputs.scss +++ b/src/styles/inputs.scss @@ -12,21 +12,6 @@ @include inner_shadow(); background: $input_bg_color; - &::before { - content: ' '; - background: linear-gradient(270deg, $input_bg_color $gap, transparentize($input_bg_color, 1)); - position: absolute; - width: $gap * 2; - height: $input_height; - top: 1px; - right: 1px; - transform: translateX(0); - transition: transform 0.25s; - border-radius: 0 $input_radius $input_radius 0; - pointer-events: none; - touch-action: none; - } - :global(.react-datepicker-wrapper) { flex: 1; padding: 0 18px; @@ -90,6 +75,22 @@ flex: 1 0 0; outline: none; color: white; + position: relative; + + &::before { + content: ' '; + background: linear-gradient(270deg, $input_bg_color $gap, transparentize($input_bg_color, 1)); + position: absolute; + width: $gap * 2; + height: $input_height; + top: 1px; + right: 1px; + transform: translateX(0); + transition: transform 0.25s; + border-radius: 0 $input_radius $input_radius 0; + pointer-events: none; + touch-action: none; + } } &.required { @@ -374,3 +375,14 @@ border-radius: $input_radius; } } + +.after { + width: 24px; + position: relative; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + padding: 0 5px; + top: -1px; +}