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"
|
directionX="right"
|
||||||
>
|
>
|
||||||
<Icons.NavLogoIcon size="medium" key="comboIcon" />
|
<Icons.NavLogoIcon size="medium" key="comboIcon" />
|
||||||
</ComboBox>;
|
</ComboBox>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Usage
|
#### Usage
|
||||||
@ -101,3 +101,52 @@ const options = [
|
|||||||
| `scaled` | `bool` | - | - | `true` | Indicates that component is scaled by parent |
|
| `scaled` | `bool` | - | - | `true` | Indicates that component is scaled by parent |
|
||||||
| `size` | `oneOf` | - | `base`, `middle`, `big`, `huge`, `content` | `base` | Select component width, one of default |
|
| `size` | `oneOf` | - | `base`, `middle`, `big`, `huge`, `content` | `base` | Select component width, one of default |
|
||||||
| `advancedOptions` | `element` | - | - | - | If you need display options not basic options |
|
| `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' />
|
<Icons.NavLogoIcon size="medium" key='comboIcon' />
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -3,12 +3,11 @@ import PropTypes from 'prop-types'
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import DropDownItem from '../drop-down-item'
|
import DropDownItem from '../drop-down-item'
|
||||||
import DropDown from '../drop-down'
|
import DropDown from '../drop-down'
|
||||||
import { Icons } from '../icons'
|
|
||||||
import { handleAnyClick } from '../../utils/event';
|
import { handleAnyClick } from '../../utils/event';
|
||||||
import isEqual from 'lodash/isEqual';
|
import isEqual from 'lodash/isEqual';
|
||||||
|
import ComboButton from './sub-components/combo-button'
|
||||||
|
|
||||||
const StyledComboBox = styled.div`
|
const StyledComboBox = styled.div`
|
||||||
color: ${props => props.isDisabled ? '#D0D5DA' : '#333333'};
|
|
||||||
width: ${props =>
|
width: ${props =>
|
||||||
(props.scaled && '100%') ||
|
(props.scaled && '100%') ||
|
||||||
(props.size === 'base' && '173px') ||
|
(props.size === 'base' && '173px') ||
|
||||||
@ -19,92 +18,6 @@ const StyledComboBox = styled.div`
|
|||||||
};
|
};
|
||||||
|
|
||||||
position: relative;
|
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 {
|
class ComboBox extends React.Component {
|
||||||
@ -137,11 +50,11 @@ class ComboBox extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
optionClick = (option) => {
|
optionClick = (option) => {
|
||||||
this.toggle(!this.state.isOpen);
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isOpen: !this.state.isOpen,
|
isOpen: !this.state.isOpen,
|
||||||
selectedOption: option
|
selectedOption: option
|
||||||
});
|
});
|
||||||
|
|
||||||
this.props.onSelect && this.props.onSelect(option);
|
this.props.onSelect && this.props.onSelect(option);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -149,7 +62,7 @@ class ComboBox extends React.Component {
|
|||||||
handleAnyClick(false, this.handleClick);
|
handleAnyClick(false, this.handleClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps,nextState) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
return !isEqual(this.props, nextProps) || !isEqual(this.state, nextState);
|
return !isEqual(this.props, nextProps) || !isEqual(this.state, nextState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,61 +84,56 @@ class ComboBox extends React.Component {
|
|||||||
//console.log("ComboBox render");
|
//console.log("ComboBox render");
|
||||||
const {
|
const {
|
||||||
dropDownMaxHeight,
|
dropDownMaxHeight,
|
||||||
isDisabled,
|
|
||||||
directionX,
|
directionX,
|
||||||
directionY,
|
directionY,
|
||||||
scaled,
|
scaled,
|
||||||
children,
|
size,
|
||||||
options,
|
options,
|
||||||
noBorder,
|
advancedOptions,
|
||||||
advancedOptions
|
isDisabled,
|
||||||
} = this.props;
|
children,
|
||||||
|
noBorder } = this.props;
|
||||||
const { isOpen, selectedOption } = this.state;
|
const { isOpen, selectedOption } = this.state;
|
||||||
|
|
||||||
const dropDownMaxHeightProp = dropDownMaxHeight ? { maxHeight: dropDownMaxHeight } : {};
|
const dropDownMaxHeightProp = dropDownMaxHeight
|
||||||
const dropDownManualWidthProp = scaled ? { manualWidth: '100%' } : {};
|
? { maxHeight: dropDownMaxHeight }
|
||||||
const boxIconColor = isDisabled ? '#D0D5DA' : '#333333';
|
: {};
|
||||||
const arrowIconColor = isDisabled ? '#D0D5DA' : '#A3A9AE';
|
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 (
|
return (
|
||||||
<StyledComboBox ref={this.ref}
|
<StyledComboBox
|
||||||
{...this.props}
|
ref={this.ref}
|
||||||
{...this.state}
|
isDisabled={isDisabled}
|
||||||
|
scaled={scaled}
|
||||||
|
size={size}
|
||||||
data={selectedOption}
|
data={selectedOption}
|
||||||
onClick={this.comboBoxClick}
|
onClick={this.comboBoxClick}
|
||||||
onSelect={this.stopAction}
|
{...this.props}
|
||||||
>
|
>
|
||||||
<StyledComboButton noBorder={noBorder}>
|
<ComboButton
|
||||||
{children &&
|
noBorder={noBorder}
|
||||||
<StyledOptionalItem className='optionalBlock'>
|
isDisabled={isDisabled}
|
||||||
{children}
|
selectedOption={selectedOption}
|
||||||
</StyledOptionalItem>
|
withOptions={optionsLength > 0}
|
||||||
}
|
optionsLength={optionsLength}
|
||||||
{selectedOption && selectedOption.icon &&
|
withAdvancedOptions={advancedOptionsLength > 0}
|
||||||
<StyledIcon>
|
innerContainer={children}
|
||||||
{React.createElement(Icons[selectedOption.icon],
|
innerContainerClassName='optionalBlock'
|
||||||
{
|
isOpen={isOpen}
|
||||||
size: 'scale',
|
size={size}
|
||||||
color: boxIconColor,
|
scaled={scaled}
|
||||||
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>
|
|
||||||
<DropDown
|
<DropDown
|
||||||
directionX={directionX}
|
directionX={directionX}
|
||||||
directionY={directionY}
|
directionY={directionY}
|
||||||
@ -239,7 +147,9 @@ class ComboBox extends React.Component {
|
|||||||
: options.map((option) =>
|
: options.map((option) =>
|
||||||
<DropDownItem {...option}
|
<DropDownItem {...option}
|
||||||
key={option.key}
|
key={option.key}
|
||||||
disabled={option.disabled || (option.label === selectedOption.label)}
|
disabled={
|
||||||
|
option.disabled
|
||||||
|
|| (option.label === selectedOption.label)}
|
||||||
onClick={this.optionClick.bind(this, option)}
|
onClick={this.optionClick.bind(this, option)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
Loading…
Reference in New Issue
Block a user