From 2394b0595eed993abeb6e0454f2a6fbfbc5a4cf1 Mon Sep 17 00:00:00 2001 From: mxdi9i7 Date: Mon, 25 May 2020 23:28:27 -0400 Subject: [PATCH 1/4] wip --- src/components/Search/index.scss | 28 +++++++++++++++++++++ src/components/Search/index.stories.tsx | 14 +++++++++++ src/components/Search/index.tsx | 33 +++++++++++++++++++++++++ src/styles/colors.scss | 1 + src/styles/stories.scss | 4 +-- 5 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 src/components/Search/index.scss create mode 100644 src/components/Search/index.stories.tsx create mode 100644 src/components/Search/index.tsx diff --git a/src/components/Search/index.scss b/src/components/Search/index.scss new file mode 100644 index 000000000..1b91f4a40 --- /dev/null +++ b/src/components/Search/index.scss @@ -0,0 +1,28 @@ +@import '../../styles/colors.scss'; +@import '../../styles/spacing.scss'; +@import '../../styles/variables.scss'; +@import '../../styles/typography.scss'; + +$baseClass: 'vant-search'; + +.#{$baseClass} { + background-color: $default; + width: 100%; + display: flex; + padding: 10px 12px; + position: relative; + align-items: center; + + input { + width: 100%; + background-color: $grey-background; + border: none; + border-radius: 2px; + padding-left: $space-md; + } + + &:first-of-type(i) { + position: absolute; + left: 8px; + } +} diff --git a/src/components/Search/index.stories.tsx b/src/components/Search/index.stories.tsx new file mode 100644 index 000000000..c6201b05f --- /dev/null +++ b/src/components/Search/index.stories.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import Search from '.'; +import '../../styles/stories.scss'; + +export default { + title: 'Search', + component: Search +}; + +export const BasicUsage = () => ( +
+ +
+); diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx new file mode 100644 index 000000000..7bb9729b9 --- /dev/null +++ b/src/components/Search/index.tsx @@ -0,0 +1,33 @@ +import React from 'react'; + +import Icon from '../Icons'; + +import classnames from '../../utils/classNames'; + +import './index.scss'; + +interface Props { + label?: string; +} + +const baseClass = 'vant-search'; + +const Search = ({ label }: Props) => { + const searchProps = { + className: classnames(baseClass, [ + { + label + } + ]) + }; + const ICON_SIZE = '16px'; + return ( +
+ + + + + ); +}; + +export default Search; diff --git a/src/styles/colors.scss b/src/styles/colors.scss index d76589823..84e8e36a1 100644 --- a/src/styles/colors.scss +++ b/src/styles/colors.scss @@ -10,3 +10,4 @@ $grey: #969799; $dark-text: #323233; $light-text: #fff; $grey-text: #ebedf0; +$grey-background: #f7f8fa; diff --git a/src/styles/stories.scss b/src/styles/stories.scss index fb2891f06..0da27d22a 100644 --- a/src/styles/stories.scss +++ b/src/styles/stories.scss @@ -15,7 +15,7 @@ body { align-items: center; &.grey { - background-color: #f7f8fa; + background-color: $grey-background; } &.column { @@ -47,7 +47,7 @@ body { padding: 15px; display: flex; flex-direction: column; - background-color: #f7f8fa; + background-color: $grey-background; h1 { font-size: 22px; From 9bb9532e8b08897afee414b62ee312acdc755180 Mon Sep 17 00:00:00 2001 From: mxdi9i7 Date: Wed, 27 May 2020 10:09:09 -0400 Subject: [PATCH 2/4] wip --- src/components/Field/index.scss | 1 + src/components/Search/index.scss | 30 ++++++++++++++----- src/components/Search/index.tsx | 51 +++++++++++++++++++++++--------- src/components/Search/types.ts | 22 ++++++++++++++ src/index.tsx | 5 +++- 5 files changed, 86 insertions(+), 23 deletions(-) diff --git a/src/components/Field/index.scss b/src/components/Field/index.scss index d3a63d824..80ea8143a 100644 --- a/src/components/Field/index.scss +++ b/src/components/Field/index.scss @@ -86,6 +86,7 @@ $baseClass: 'vant-field'; line-height: inherit; border: 0; resize: none; + padding: 0; &::placeholder { color: $placeholder; diff --git a/src/components/Search/index.scss b/src/components/Search/index.scss index 1b91f4a40..880ca4c1b 100644 --- a/src/components/Search/index.scss +++ b/src/components/Search/index.scss @@ -13,16 +13,30 @@ $baseClass: 'vant-search'; position: relative; align-items: center; - input { - width: 100%; - background-color: $grey-background; - border: none; - border-radius: 2px; - padding-left: $space-md; - } - &:first-of-type(i) { position: absolute; left: 8px; } + + &__round { + .vant-field { + border-radius: 2px; + } + } + + .vant-field { + background-color: $grey-background; + padding: 0 0 0 8px; + + .vant-field__input { + padding: 5px 8px 5px 0; + input { + width: 100%; + background-color: $grey-background; + border: none; + border-radius: 2px; + padding-left: $space-md; + } + } + } } diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 7bb9729b9..46fce5f8e 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -1,31 +1,54 @@ -import React from 'react'; +import React, { useState } from 'react'; import Icon from '../Icons'; import classnames from '../../utils/classNames'; import './index.scss'; - -interface Props { - label?: string; -} +import { IProps } from './types'; +import Field from '../Field'; const baseClass = 'vant-search'; -const Search = ({ label }: Props) => { +const Search = ({ + label, + shape = 'square', + background, + maxLength, + placeholder, + clearable = true, + autoFocus, + showAction, + disabled, + readonly, + error, + inputAlign = 'left', + leftIcon = 'search', + rightIcon, + actionText, + search, + input, + foucs, + blur, + clear, + cancel +}: IProps) => { + const [value, setValue] = useState(''); + const searchProps = { - className: classnames(baseClass, [ - { - label - } - ]) + className: classnames(baseClass, [{ label }, { shape }]) }; const ICON_SIZE = '16px'; return (
- - - + {/* */} + setValue(e.target.value)} + clearable={clearable} + clear={() => setValue('')} + leftIcon={leftIcon} + /> ); }; diff --git a/src/components/Search/types.ts b/src/components/Search/types.ts index f9f3501eb..29b0b222c 100644 --- a/src/components/Search/types.ts +++ b/src/components/Search/types.ts @@ -1,3 +1,25 @@ +import { TAlignment } from '../Field/types'; + export interface IProps { label?: string; + shape?: 'round' | 'square'; + background?: string; + maxLength?: number; + placeholder?: string; + clearable?: boolean; + autoFocus?: boolean; + showAction?: boolean; + disabled?: boolean; + readonly?: boolean; + error?: boolean; + inputAlign?: TAlignment; + leftIcon?: string; + rightIcon?: string; + actionText?: string; + search?: Function; + input?: Function; + foucs?: Function; + blur?: Function; + clear?: Function; + cancel?: Function; } diff --git a/src/index.tsx b/src/index.tsx index 3748492a6..0c43765c5 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -3,19 +3,22 @@ import Icon from './components/Icons'; import Tag from './components/Tag'; import Navbar from './components/Navbar'; import Field from './components/Field'; +import Search from './components/Search'; export { default as Button } from './components/Button'; export { default as Icon } from './components/Icons'; export { default as Tag } from './components/Tag'; export { default as Navbar } from './components/Navbar'; export { default as Field } from './components/Field'; +export { default as Search } from './components/Search'; const Vant = { Button, Icon, Tag, Navbar, - Field + Field, + Search }; export default Vant; From d5abc76a85574e99148e58288dcf34c55d12150d Mon Sep 17 00:00:00 2001 From: mxdi9i7 Date: Wed, 27 May 2020 12:08:52 -0400 Subject: [PATCH 3/4] wrapped up search component --- src/components/Search/index.scss | 35 ++++++++- src/components/Search/index.stories.tsx | 95 ++++++++++++++++++++++++- src/components/Search/index.tsx | 88 ++++++++++++++++++++--- src/components/Search/types.ts | 9 ++- src/styles/typography.scss | 6 ++ 5 files changed, 219 insertions(+), 14 deletions(-) diff --git a/src/components/Search/index.scss b/src/components/Search/index.scss index 826346100..51c39b686 100644 --- a/src/components/Search/index.scss +++ b/src/components/Search/index.scss @@ -20,7 +20,17 @@ $baseClass: 'vant-search'; &__round { .vant-field { - border-radius: 2px; + border-radius: 999px; + } + } + + &__showAction { + padding-right: 0; + } + + &__leftIcon { + .vant-field__error { + padding-left: 24px; } } @@ -44,4 +54,27 @@ $baseClass: 'vant-search'; } } } + + &__action { + padding: 0 $space-md; + cursor: pointer; + + button { + min-height: 34px; + } + + .#{$baseClass}__cancel { + @include search-action; + cursor: pointer; + background-color: $default; + border: 0; + padding: 0; + } + } + + &__disabled { + input { + cursor: not-allowed; + } + } } diff --git a/src/components/Search/index.stories.tsx b/src/components/Search/index.stories.tsx index c6201b05f..98e58dcfc 100644 --- a/src/components/Search/index.stories.tsx +++ b/src/components/Search/index.stories.tsx @@ -1,6 +1,7 @@ -import React from 'react'; +import React, { useState } from 'react'; import Search from '.'; import '../../styles/stories.scss'; +import Button from '../Button'; export default { title: 'Search', @@ -8,7 +9,97 @@ export default { }; export const BasicUsage = () => ( -
+
+ +
+); + +export const CustomLabel = () => ( +
+ + + +
+); + +export const BackgroundColor = () => ( +
+ +
+); + +export const MaxLength = () => ( +
+ +
+); + +export const PlaceholderAutoFocus = () => ( +
+ + +
+); + +export const SearchActions = () => { + const handleClick = (e) => { + e.preventDefault(); + alert('Action clicked'); + }; + const [value, setValue] = useState(''); + const [focus, setFocus] = useState(false); + return ( +
+

Value: {value}

+ + + + } + /> + alert('Searched')} + /> + + setValue(e.target.value)} + focus={() => setFocus(true)} + blur={() => setFocus(false)} + /> +
+ ); +}; + +export const DisabledReadonlyError = () => ( +
+ + + +
+); + +export const AlignmentAndIcon = () => ( +
+ + + +
); diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 46fce5f8e..64b9c906b 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -17,7 +17,7 @@ const Search = ({ maxLength, placeholder, clearable = true, - autoFocus, + autofocus, showAction, disabled, readonly, @@ -25,30 +25,100 @@ const Search = ({ inputAlign = 'left', leftIcon = 'search', rightIcon, - actionText, + actionText = 'Cancel', search, input, - foucs, + focus, blur, clear, - cancel + cancel, + action, + errorMessage, + labelAlign, + labelWidth }: IProps) => { const [value, setValue] = useState(''); + const handleSearch = (e) => { + e.preventDefault(); + if (search) search(e); + }; + const handleActionClick = (e) => { + e.preventDefault(); + if (cancel) cancel(e); + }; + + const handleInput = (e) => { + if (input) input(e); + setValue(e.target.value); + }; + + const handleFocus = (e) => { + if (focus) focus(e); + }; + + const handleBlur = (e) => { + if (focus) blur(e); + }; + + const handleClear = (e) => { + e.preventDefault(); + if (clear) { + clear(e); + } + setValue(''); + }; + const searchProps = { - className: classnames(baseClass, [{ label }, { shape }]) + className: classnames(baseClass, [ + { label }, + { [shape]: shape }, + { disabled }, + { showAction }, + { leftIcon } + ]), + style: {}, + onSubmit: handleSearch }; - const ICON_SIZE = '16px'; + + if (background) + Object.assign(searchProps, { style: { backgroundColor: background } }); + return (
- {/* */} setValue(e.target.value)} + label={label} + labelAlign={labelAlign} + labelWidth={labelWidth} + input={handleInput} + blur={handleBlur} + focus={handleFocus} + clear={handleClear} clearable={clearable} - clear={() => setValue('')} leftIcon={leftIcon} + maxLength={maxLength} + placeholder={placeholder} + autofocus={autofocus} + readonly={readonly} + disabled={disabled} + error={error} + errorMessage={errorMessage} + inputAlign={inputAlign} + rightIcon={rightIcon} /> + {showAction && ( +
+ {action || ( + + )} +
+ )} ); }; diff --git a/src/components/Search/types.ts b/src/components/Search/types.ts index 29b0b222c..00792a8ed 100644 --- a/src/components/Search/types.ts +++ b/src/components/Search/types.ts @@ -1,13 +1,17 @@ +import { ReactElement } from 'react'; import { TAlignment } from '../Field/types'; export interface IProps { label?: string; + labelWidth?: string; + labelAlign?: TAlignment; shape?: 'round' | 'square'; background?: string; maxLength?: number; placeholder?: string; + errorMessage?: string; clearable?: boolean; - autoFocus?: boolean; + autofocus?: boolean; showAction?: boolean; disabled?: boolean; readonly?: boolean; @@ -18,8 +22,9 @@ export interface IProps { actionText?: string; search?: Function; input?: Function; - foucs?: Function; + focus?: Function; blur?: Function; clear?: Function; cancel?: Function; + action?: ReactElement; } diff --git a/src/styles/typography.scss b/src/styles/typography.scss index c80daee6f..27733cb1b 100644 --- a/src/styles/typography.scss +++ b/src/styles/typography.scss @@ -31,3 +31,9 @@ color: $dark-text; font-weight: 300; } + +@mixin search-action { + font-size: 14px; + line-height: 34px; + font-weight: 300; +} From e28192d4d7f796b588c5e804136d1ea814ae8712 Mon Sep 17 00:00:00 2001 From: mxdi9i7 Date: Thu, 28 May 2020 20:11:44 -0400 Subject: [PATCH 4/4] fix lint --- src/components/Search/index.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 64b9c906b..4caef6d7b 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -1,7 +1,5 @@ import React, { useState } from 'react'; -import Icon from '../Icons'; - import classnames from '../../utils/classNames'; import './index.scss'; @@ -58,7 +56,7 @@ const Search = ({ }; const handleBlur = (e) => { - if (focus) blur(e); + if (blur) blur(e); }; const handleClear = (e) => {