From 0534009e7968995914c6168d0955aa652785dadd Mon Sep 17 00:00:00 2001 From: xsky Date: Fri, 23 Aug 2019 16:24:29 +0800 Subject: [PATCH 1/7] feat: Add InputDropdown. --- docs/content/components/input-dropdown.mdx | 32 +++++++++ src/components/InputDropdown/index.test.tsx | 23 +++++++ src/components/InputDropdown/index.tsx | 73 +++++++++++++++++++++ src/components/index.tsx | 2 + src/interface.tsx | 13 ++++ stories/InputDropdown.stories.tsx | 21 ++++++ 6 files changed, 164 insertions(+) create mode 100644 docs/content/components/input-dropdown.mdx create mode 100644 src/components/InputDropdown/index.test.tsx create mode 100644 src/components/InputDropdown/index.tsx create mode 100644 stories/InputDropdown.stories.tsx diff --git a/docs/content/components/input-dropdown.mdx b/docs/content/components/input-dropdown.mdx new file mode 100644 index 00000000..04329574 --- /dev/null +++ b/docs/content/components/input-dropdown.mdx @@ -0,0 +1,32 @@ +--- +title: InputDropdown Input 下拉框 +date: 2019-08-23 +author: lijianxin1202 +--- +作为 Input 一部分的下拉框 + +## 使用方式 +通常和 Input 一起使用,在 Input 的前面或者后部,用来增强 Input 功能 + +## 基本用法 + +```jsx +
+ + + + +
+``` + +## API +```jsx previewOnly + +``` \ No newline at end of file diff --git a/src/components/InputDropdown/index.test.tsx b/src/components/InputDropdown/index.test.tsx new file mode 100644 index 00000000..09e64131 --- /dev/null +++ b/src/components/InputDropdown/index.test.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import InputDropdown from './index'; +import { mount } from 'enzyme'; +import { InputGroup, FormControl } from 'react-bootstrap'; + +describe('InputDropdown', () => { + it('should render corrent dropdown', () => { + const dropdown = mount(
+ + + + +
) + expect(dropdown.find('.dropdown.input-group-btn').length).toBe(1); + }); +}); \ No newline at end of file diff --git a/src/components/InputDropdown/index.tsx b/src/components/InputDropdown/index.tsx new file mode 100644 index 00000000..584b5078 --- /dev/null +++ b/src/components/InputDropdown/index.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import lodash from 'lodash'; +import { DropdownButton, MenuItem, InputGroup } from 'react-bootstrap'; +import { uuid } from '../../utils'; +import { InputDropdownProps } from '../../interface'; + +const InputDropdown = (props: InputDropdownProps) => { + function getValue() { + const { input, value, defaultValue } = props; + if (input && input.value !== undefined) { + return input.value; + } + return value !== undefined ? value : defaultValue; + } + + function getTitle() { + const { options } = props; + const option = lodash.find(options, { value: getValue() }); + return lodash.get(option, 'title'); + } + + function handleSelect(eventKey: any) { + const { input, onChange } = props; + if (onChange) { + onChange(eventKey); + } else if (input) { + input.onChange(eventKey); + } + } + const { input, meta, options, ...rest } = props; + return ( + + {options && + options.map(option => ( + + {option.title} + + ))} + + ); +} + +InputDropdown.propTypes = { + /** + * 下拉选项 + **/ + options: PropTypes.array, + /** + * 下拉框是否右对齐,默认为 true + **/ + pullRight: PropTypes.bool, + /** + * 默认值 + **/ + defaultValue: PropTypes.string, + /** + * value 变化后回调 + **/ + onChange: PropTypes.func, +}; + +InputDropdown.defaultProps = { + pullRight: true, +}; + +export default InputDropdown; \ No newline at end of file diff --git a/src/components/index.tsx b/src/components/index.tsx index 432a9b09..08d554db 100644 --- a/src/components/index.tsx +++ b/src/components/index.tsx @@ -2,6 +2,7 @@ import Badge from './Badge'; import Dropdown from './Dropdown'; import DropdownButton from './DropdownButton'; import Icon from './Icon'; +import InputDropdown from './InputDropdown'; import Loader from './Loader'; import Modal from './Modal'; import Navigation from './Navigation'; @@ -23,6 +24,7 @@ export { Dropdown, DropdownButton, Icon, + InputDropdown, Loader, MenuItem, Modal, diff --git a/src/interface.tsx b/src/interface.tsx index 2cc689e7..1129e08e 100644 --- a/src/interface.tsx +++ b/src/interface.tsx @@ -212,3 +212,16 @@ export interface DropdownProps extends DropdownDefaultProps { title?: string; children?: React.ReactNode; } + +export interface MenuItemOptions { + title: string; + value: string; +} +export interface InputDropdownProps { + options?: MenuItemOptions[]; + defaultValue?: string; + value?: string; + onChange?: SelectCallback; + input?: any; + meta?: any; +} diff --git a/stories/InputDropdown.stories.tsx b/stories/InputDropdown.stories.tsx new file mode 100644 index 00000000..6adc7c73 --- /dev/null +++ b/stories/InputDropdown.stories.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { storiesOf } from '@storybook/react'; +import { InputDropdown } from '../src'; +import { FormControl, InputGroup } from 'react-bootstrap'; + +storiesOf('InputDropdown', module) + .add('default', () => ( +
+ + + + +
+ )) \ No newline at end of file From 448778c1ce4979cd119bb6448dabdbd7b2e004e4 Mon Sep 17 00:00:00 2001 From: xsky Date: Fri, 23 Aug 2019 16:57:37 +0800 Subject: [PATCH 2/7] Update case. --- docs/content/components/input-dropdown.mdx | 33 +++++++++++--------- src/components/InputDropdown/index.tsx | 4 +++ stories/InputDropdown.stories.tsx | 36 +++++++++++++--------- 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/docs/content/components/input-dropdown.mdx b/docs/content/components/input-dropdown.mdx index 04329574..639ca54b 100644 --- a/docs/content/components/input-dropdown.mdx +++ b/docs/content/components/input-dropdown.mdx @@ -10,20 +10,25 @@ author: lijianxin1202 ## 基本用法 -```jsx -
- - - - -
+``jsx +() => { + const [value, updateValue] = React.useState('MB'); + return (
+ + + updateValue(key)} + value={value} + options={[ + { title: 'MB', value: 'MB' }, + { title: 'GB', value: 'GB' }, + { title: 'TB', value: 'TB' }, + ]} /> + +
); +} ``` ## API diff --git a/src/components/InputDropdown/index.tsx b/src/components/InputDropdown/index.tsx index 584b5078..6e9e6ef6 100644 --- a/src/components/InputDropdown/index.tsx +++ b/src/components/InputDropdown/index.tsx @@ -64,6 +64,10 @@ InputDropdown.propTypes = { * value 变化后回调 **/ onChange: PropTypes.func, + /** + * value,传入 value 时变为受控组件 + **/ + value: PropTypes.string, }; InputDropdown.defaultProps = { diff --git a/stories/InputDropdown.stories.tsx b/stories/InputDropdown.stories.tsx index 6adc7c73..6a9b9789 100644 --- a/stories/InputDropdown.stories.tsx +++ b/stories/InputDropdown.stories.tsx @@ -4,18 +4,24 @@ import { InputDropdown } from '../src'; import { FormControl, InputGroup } from 'react-bootstrap'; storiesOf('InputDropdown', module) - .add('default', () => ( -
- - - - -
- )) \ No newline at end of file + .add('default', () => { + const Demo = () => { + const [value, updateValue] = React.useState('MB'); + return (
+ + + updateValue(key)} + value={value} + options={[ + { title: 'MB', value: 'MB' }, + { title: 'GB', value: 'GB' }, + { title: 'TB', value: 'TB' }, + ]} /> + +
); + } + return + }) \ No newline at end of file From 483f3a7c94868b6d4dfadc38599ce4410d4d0e99 Mon Sep 17 00:00:00 2001 From: xsky Date: Fri, 23 Aug 2019 17:31:15 +0800 Subject: [PATCH 3/7] Update. --- docs/content/components/input-dropdown.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/components/input-dropdown.mdx b/docs/content/components/input-dropdown.mdx index 639ca54b..8632424a 100644 --- a/docs/content/components/input-dropdown.mdx +++ b/docs/content/components/input-dropdown.mdx @@ -10,7 +10,7 @@ author: lijianxin1202 ## 基本用法 -``jsx +```jsx () => { const [value, updateValue] = React.useState('MB'); return (
From 1eb63580061af69181382460d92271fa3e66dd9f Mon Sep 17 00:00:00 2001 From: xsky Date: Fri, 23 Aug 2019 18:27:02 +0800 Subject: [PATCH 4/7] Add test case. --- docs/content/components/input-dropdown.mdx | 2 +- src/components/InputDropdown/index.test.tsx | 63 ++++++++++++++++----- stories/InputDropdown.stories.tsx | 2 +- 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/docs/content/components/input-dropdown.mdx b/docs/content/components/input-dropdown.mdx index 8632424a..cc15a6a7 100644 --- a/docs/content/components/input-dropdown.mdx +++ b/docs/content/components/input-dropdown.mdx @@ -19,7 +19,7 @@ author: lijianxin1202 updateValue(key)} + onChange={updateValue} value={value} options={[ { title: 'MB', value: 'MB' }, diff --git a/src/components/InputDropdown/index.test.tsx b/src/components/InputDropdown/index.test.tsx index 09e64131..e56ba74a 100644 --- a/src/components/InputDropdown/index.test.tsx +++ b/src/components/InputDropdown/index.test.tsx @@ -5,19 +5,56 @@ import { InputGroup, FormControl } from 'react-bootstrap'; describe('InputDropdown', () => { it('should render corrent dropdown', () => { - const dropdown = mount(
- - - - -
) + const Demo = () => { + const [value, updateValue] = React.useState('MB'); + return (
+ + + updateValue(key)} + value={value} + options={[ + { title: 'MB', value: 'MB' }, + { title: 'GB', value: 'GB' }, + { title: 'TB', value: 'TB' }, + ]} /> + +
); + } + const dropdown = mount(); + const button = dropdown.find('button'); expect(dropdown.find('.dropdown.input-group-btn').length).toBe(1); + button.simulate('click'); + const tb = dropdown.find('a').at(2); + tb.simulate('click'); + expect(dropdown.find('button[value="TB"]').length).toBe(1); + }); + + it('should render corrent with input', () => { + const Demo = () => { + const [value, updateValue] = React.useState('MB'); + return (
+ + + + +
); + } + const dropdown = mount(); + const button = dropdown.find('button'); + button.simulate('click'); + const tb = dropdown.find('a').at(2); + tb.simulate('click'); + // @ts-ignore + expect(dropdown.find('button').instance().textContent).toBe('TB '); }); }); \ No newline at end of file diff --git a/stories/InputDropdown.stories.tsx b/stories/InputDropdown.stories.tsx index 6a9b9789..c6bdd98f 100644 --- a/stories/InputDropdown.stories.tsx +++ b/stories/InputDropdown.stories.tsx @@ -23,5 +23,5 @@ storiesOf('InputDropdown', module)
); } - return + return ; }) \ No newline at end of file From edecf074d38efc2517d525fb9865b0683b4234e8 Mon Sep 17 00:00:00 2001 From: xsky Date: Wed, 28 Aug 2019 11:03:54 +0800 Subject: [PATCH 5/7] Use higher precision in sass loader. --- .storybook/webpack.config.js | 14 ++++++++++++-- webpack.config.js | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js index 2436ed51..3caf0a64 100644 --- a/.storybook/webpack.config.js +++ b/.storybook/webpack.config.js @@ -29,7 +29,12 @@ module.exports = async ({ config, mode }) => { use: [ 'style-loader', 'css-loader', - 'sass-loader', + { + loader: require.resolve('sass-loader'), + options: { + precision: 8, + } + }, ], include: path.resolve(__dirname, '../') }); @@ -56,7 +61,12 @@ module.exports = async ({ config, mode }) => { }, }, }, - 'sass-loader' + { + loader: require.resolve('sass-loader'), + options: { + precision: 8, + } + }, ], },) config.resolve.extensions.push('.ts', '.tsx') diff --git a/webpack.config.js b/webpack.config.js index dd78eb7d..b2da0d15 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -32,7 +32,12 @@ module.exports = { use: [ MiniCssExtractPlugin.loader, 'css-loader', - 'sass-loader', + { + loader: require.resolve('sass-loader'), + options: { + precision: 8, + } + }, ], }, { @@ -48,7 +53,12 @@ module.exports = { }, }, }, - 'sass-loader' + { + loader: require.resolve('sass-loader'), + options: { + precision: 8, + } + }, ], }, ] From 2354d8f563e976f88f8ede4e6bb984475d76ddad Mon Sep 17 00:00:00 2001 From: xsky Date: Wed, 28 Aug 2019 11:15:46 +0800 Subject: [PATCH 6/7] Config docs sass precision. --- docs/gatsby-config.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/gatsby-config.js b/docs/gatsby-config.js index 175c1e22..2c3f245e 100644 --- a/docs/gatsby-config.js +++ b/docs/gatsby-config.js @@ -49,6 +49,9 @@ module.exports = { cssLoaderOptions: { camelCase: false, }, + options: { + precision: 8, + }, }, ], } From 6f9ce30bfa050028ead339857a512ac00467cbf9 Mon Sep 17 00:00:00 2001 From: xsky Date: Wed, 28 Aug 2019 11:22:57 +0800 Subject: [PATCH 7/7] Update. --- src/components/InputDropdown/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/InputDropdown/index.tsx b/src/components/InputDropdown/index.tsx index 6e9e6ef6..3ef8ad2f 100644 --- a/src/components/InputDropdown/index.tsx +++ b/src/components/InputDropdown/index.tsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import lodash from 'lodash'; +import { find, get } from 'lodash'; import { DropdownButton, MenuItem, InputGroup } from 'react-bootstrap'; import { uuid } from '../../utils'; import { InputDropdownProps } from '../../interface'; @@ -16,8 +16,8 @@ const InputDropdown = (props: InputDropdownProps) => { function getTitle() { const { options } = props; - const option = lodash.find(options, { value: getValue() }); - return lodash.get(option, 'title'); + const option = find(options, { value: getValue() }); + return get(option, 'title'); } function handleSelect(eventKey: any) {