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/docs/content/components/input-dropdown.mdx b/docs/content/components/input-dropdown.mdx
new file mode 100644
index 00000000..cc15a6a7
--- /dev/null
+++ b/docs/content/components/input-dropdown.mdx
@@ -0,0 +1,37 @@
+---
+title: InputDropdown Input 下拉框
+date: 2019-08-23
+author: lijianxin1202
+---
+作为 Input 一部分的下拉框
+
+## 使用方式
+通常和 Input 一起使用,在 Input 的前面或者后部,用来增强 Input 功能
+
+## 基本用法
+
+```jsx
+() => {
+ const [value, updateValue] = React.useState('MB');
+ return (
+
+
+
+
+
);
+}
+```
+
+## API
+```jsx previewOnly
+
+```
\ No newline at end of file
diff --git a/docs/gatsby-config.js b/docs/gatsby-config.js
index 352774b7..702df995 100644
--- a/docs/gatsby-config.js
+++ b/docs/gatsby-config.js
@@ -65,6 +65,9 @@ module.exports = {
cssLoaderOptions: {
camelCase: false,
},
+ options: {
+ precision: 8,
+ },
},
],
}
diff --git a/src/components/InputDropdown/index.test.tsx b/src/components/InputDropdown/index.test.tsx
new file mode 100644
index 00000000..e56ba74a
--- /dev/null
+++ b/src/components/InputDropdown/index.test.tsx
@@ -0,0 +1,60 @@
+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 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/src/components/InputDropdown/index.tsx b/src/components/InputDropdown/index.tsx
new file mode 100644
index 00000000..3ef8ad2f
--- /dev/null
+++ b/src/components/InputDropdown/index.tsx
@@ -0,0 +1,77 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { find, get } 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 = find(options, { value: getValue() });
+ return 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 => (
+
+ ))}
+
+ );
+}
+
+InputDropdown.propTypes = {
+ /**
+ * 下拉选项
+ **/
+ options: PropTypes.array,
+ /**
+ * 下拉框是否右对齐,默认为 true
+ **/
+ pullRight: PropTypes.bool,
+ /**
+ * 默认值
+ **/
+ defaultValue: PropTypes.string,
+ /**
+ * value 变化后回调
+ **/
+ onChange: PropTypes.func,
+ /**
+ * value,传入 value 时变为受控组件
+ **/
+ value: PropTypes.string,
+};
+
+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 92a7fb9e..e5bd8dd4 100644
--- a/src/components/index.tsx
+++ b/src/components/index.tsx
@@ -3,6 +3,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';
@@ -28,6 +29,7 @@ export {
Dropdown,
DropdownButton,
Icon,
+ InputDropdown,
Loader,
MenuItem,
Modal,
diff --git a/src/interface.tsx b/src/interface.tsx
index bb0bec32..94a65fa4 100644
--- a/src/interface.tsx
+++ b/src/interface.tsx
@@ -227,6 +227,18 @@ export interface DropdownProps extends DropdownDefaultProps {
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;
+}
export interface Query {
offset: number;
limit: number;
diff --git a/stories/InputDropdown.stories.tsx b/stories/InputDropdown.stories.tsx
new file mode 100644
index 00000000..c6bdd98f
--- /dev/null
+++ b/stories/InputDropdown.stories.tsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import { storiesOf } from '@storybook/react';
+import { InputDropdown } from '../src';
+import { FormControl, InputGroup } from 'react-bootstrap';
+
+storiesOf('InputDropdown', module)
+ .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
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,
+ }
+ },
],
},
]