web: Components: Fixed ComboBox component, added usage ComboButton sub-component. Fixed README and story.

This commit is contained in:
Ilya Oleshko 2019-09-18 14:45:29 +03:00
parent 097f78d290
commit c4209faddb
3 changed files with 109 additions and 151 deletions

View File

@ -54,7 +54,7 @@ const advancedOptions = (
directionX="right"
>
<Icons.NavLogoIcon size="medium" key="comboIcon" />
</ComboBox>;
</ComboBox>
```
#### Usage
@ -101,3 +101,52 @@ const options = [
| `scaled` | `bool` | - | - | `true` | Indicates that component is scaled by parent |
| `size` | `oneOf` | - | `base`, `middle`, `big`, `huge`, `content` | `base` | Select component width, one of default |
| `advancedOptions` | `element` | - | - | - | If you need display options not basic options |
## ComboButton
#### Description
> This description is for reference only, the component described below is not exported.
To create designs using combobox logic, there is a child component ComboButton.
This is an independent element that responds to changes in parameters and serves only to demonstrate set values.
```js
<ComboButton
noBorder={false}
isDisabled={false}
selectedOption={
{
key: 0,
label: 'Select'
}
}
withOptions={false}
optionsLength={0}
withAdvancedOptions={true}
innerContainer={
<>Demo container</>
}
innerContainerClassName='optionalBlock'
isOpen={false}
size='content'
scaled={false}
/>
```
#### Properties
| Props | Type | Required | Values | Default | Description |
| ------------------------- | -------- | :------: | -------------------------------- | ---------------- | -------------------------------------------------------- |
| `isDisabled` | `bool` | - | - | `false` | Indicates that component is disabled |
| `noBorder` | `bool` | - | - | `false` | Indicates that component is displayed without borders |
| `selectedOption` | `object` | - | - | - | Selected option |
| `withOptions` | `bool` | - | - | `true` | Lets you style as ComboBox with options |
| `optionsLength` | `number` | - | - | - | Lets you style as ComboBox with options |
| `withAdvancedOptions` | `bool` | - | - | `false` | Lets you style as a ComboBox with advanced options |
| `innerContainer` | `node` | - | - | - | Allows displaying third-party element inside ComboButton |
| `innerContainerClassName` | `string` | - | - | `innerContainer` | Required to access third-party container |
| `isOpen` | `bool` | - | - | `false` | Lets you style as ComboBox arrow |
| `scaled` | `bool` | - | - | `false` | Indicates that component is scaled by parent |
| `size` | `oneOf` | - | `base`, `...`, `huge`, `content` | `content` | Select component width, one of default |
| `onClick` | `func` | - | - | - | Will be triggered whenever an ComboButton is clicked |

View File

@ -146,7 +146,6 @@ storiesOf('Components|Input', module)
>
<Icons.NavLogoIcon size="medium" key='comboIcon' />
</ComboBox>
</td>
</tr>
</tbody>

View File

@ -3,12 +3,11 @@ import PropTypes from 'prop-types'
import styled from 'styled-components';
import DropDownItem from '../drop-down-item'
import DropDown from '../drop-down'
import { Icons } from '../icons'
import { handleAnyClick } from '../../utils/event';
import isEqual from 'lodash/isEqual';
import ComboButton from './sub-components/combo-button'
const StyledComboBox = styled.div`
color: ${props => props.isDisabled ? '#D0D5DA' : '#333333'};
width: ${props =>
(props.scaled && '100%') ||
(props.size === 'base' && '173px') ||
@ -19,92 +18,6 @@ const StyledComboBox = styled.div`
};
position: relative;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background: #FFFFFF;
${props => !props.noBorder && `
border: 1px solid #D0D5DA;
border-radius: 3px;
`}
${props => props.isDisabled && !props.noBorder && `
border-color: #ECEEF1;
background: #F8F9F9;
`}
${props => !props.noBorder && `
height: 32px;
`}
:hover{
border-color: ${state => state.isOpen ? '#2DA7DB' : '#A3A9AE' };
cursor: ${props => (props.isDisabled || !props.options.length ) ? (props.advancedOptions) ? 'pointer' : 'default' : 'pointer'};
${props => props.isDisabled && `
border-color: #ECEEF1;
`}
}
`;
const StyledComboButton = styled.div`
display: flex;
align-items: center;
justify-content: center;
height: ${props => props.noBorder ? `18px` : `30px`};
margin-left: 8px;
`;
const StyledIcon = styled.div`
width: 16px;
margin-right: 8px;
margin-top: -2px;
`;
const StyledOptionalItem = styled.div`
margin-right: 8px;
`;
const StyledLabel = styled.div`
font-family: Open Sans;
font-style: normal;
font-weight: 600;
font-size: 13px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-right: 8px;
${props => props.noBorder && `
line-height: 11px;
border-bottom: 1px dashed transparent;
:hover{
border-bottom: 1px dashed;
}
`};
`;
const StyledArrowIcon = styled.div`
display: flex;
align-self: start;
width: ${props => props.needDisplay ? '8px' : '0px'};
flex: 0 0 ${props => props.needDisplay ? '8px' : '0px'};
margin-top: ${props => props.noBorder ? `5px` : `12px`};
margin-right: ${props => props.needDisplay ? '8px' : '0px'};
margin-left: ${props => props.needDisplay ? 'auto' : '0px'};
${props => props.isOpen && `
transform: scale(1, -1);
`}
`;
class ComboBox extends React.Component {
@ -137,11 +50,11 @@ class ComboBox extends React.Component {
};
optionClick = (option) => {
this.toggle(!this.state.isOpen);
this.setState({
isOpen: !this.state.isOpen,
selectedOption: option
});
this.props.onSelect && this.props.onSelect(option);
};
@ -171,61 +84,56 @@ class ComboBox extends React.Component {
//console.log("ComboBox render");
const {
dropDownMaxHeight,
isDisabled,
directionX,
directionY,
scaled,
children,
size,
options,
noBorder,
advancedOptions
} = this.props;
advancedOptions,
isDisabled,
children,
noBorder } = this.props;
const { isOpen, selectedOption } = this.state;
const dropDownMaxHeightProp = dropDownMaxHeight ? { maxHeight: dropDownMaxHeight } : {};
const dropDownManualWidthProp = scaled ? { manualWidth: '100%' } : {};
const boxIconColor = isDisabled ? '#D0D5DA' : '#333333';
const arrowIconColor = isDisabled ? '#D0D5DA' : '#A3A9AE';
const dropDownMaxHeightProp = dropDownMaxHeight
? { maxHeight: dropDownMaxHeight }
: {};
const dropDownManualWidthProp = scaled
? { manualWidth: '100%' }
: {};
const optionsLength = options.length
? options.length
: 0;
const advancedOptionsLength = advancedOptions
&& advancedOptions.props.children.length
? advancedOptions.props.children.length
: 0;
return (
<StyledComboBox ref={this.ref}
{...this.props}
{...this.state}
<StyledComboBox
ref={this.ref}
isDisabled={isDisabled}
scaled={scaled}
size={size}
data={selectedOption}
onClick={this.comboBoxClick}
onSelect={this.stopAction}
{...this.props}
>
<StyledComboButton noBorder={noBorder}>
{children &&
<StyledOptionalItem className='optionalBlock'>
{children}
</StyledOptionalItem>
}
{selectedOption && selectedOption.icon &&
<StyledIcon>
{React.createElement(Icons[selectedOption.icon],
{
size: 'scale',
color: boxIconColor,
isfill: true
})
}
</StyledIcon>
}
<StyledLabel noBorder={noBorder}>
{selectedOption.label}
</StyledLabel>
<StyledArrowIcon needDisplay={options.length > 0 || advancedOptions !== undefined} noBorder={noBorder} isOpen={isOpen}>
{(options.length > 0 || advancedOptions !== undefined) &&
React.createElement(Icons['ExpanderDownIcon'],
{
size: 'scale',
color: arrowIconColor,
isfill: true
})
}
</StyledArrowIcon>
</StyledComboButton>
<ComboButton
noBorder={noBorder}
isDisabled={isDisabled}
selectedOption={selectedOption}
withOptions={optionsLength > 0}
optionsLength={optionsLength}
withAdvancedOptions={advancedOptionsLength > 0}
innerContainer={children}
innerContainerClassName='optionalBlock'
isOpen={isOpen}
size={size}
scaled={scaled}
/>
<DropDown
directionX={directionX}
directionY={directionY}
@ -239,7 +147,9 @@ class ComboBox extends React.Component {
: options.map((option) =>
<DropDownItem {...option}
key={option.key}
disabled={option.disabled || (option.label === selectedOption.label)}
disabled={
option.disabled
|| (option.label === selectedOption.label)}
onClick={this.optionClick.bind(this, option)}
/>
)}