web: Components: Fixed ComboBox component, added usage ComboButton sub-component. Fixed README and story.
This commit is contained in:
parent
097f78d290
commit
c4209faddb
@ -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 |
|
||||
|
@ -146,7 +146,6 @@ storiesOf('Components|Input', module)
|
||||
>
|
||||
<Icons.NavLogoIcon size="medium" key='comboIcon' />
|
||||
</ComboBox>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -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)}
|
||||
/>
|
||||
)}
|
||||
|
Loading…
Reference in New Issue
Block a user