Merge branch 'master' of github.com:ONLYOFFICE/CommunityServer-AspNetCore

This commit is contained in:
Alexey Safronov 2019-08-12 12:42:08 +03:00
commit 9e6ebb5185
6 changed files with 274 additions and 157 deletions

View File

@ -1,50 +1,88 @@
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components';
import InputBlock from '../input-block'
import DropDownItem from '../drop-down-item'
import DropDown from '../drop-down'
import { Icons } from '../icons'
import { handleAnyClick } from '../../utils/event';
const StyledComboBox = styled.div`
* {
${props => !props.withBorder && `border-color: transparent !important;`}
}
color: ${props => props.isDisabled ? '#D0D5DA' : '#333333'};
width: ${props =>
(props.scaled && '100%') ||
(props.size === 'base' && '173px') ||
(props.size === 'middle' && '300px') ||
(props.size === 'big' && '350px') ||
(props.size === 'huge' && '500px') ||
(props.size === 'content' && 'fit-content')
};
${state => state.isOpen && `
.input-group-append > div {
-moz-transform: scaleY(-1);
-o-transform: scaleY(-1);
-webkit-transform: scaleY(-1);
transform: scaleY(-1);
}
position: relative;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background: #FFFFFF;
border: 1px solid #D0D5DA;
border-radius: 3px;
${props => props.isDisabled && `
border-color: #ECEEF1;
background: #F8F9F9;
`}
& > div > input {
&::placeholder {
font-family: Open Sans;
font-style: normal;
font-weight: 600;
font-size: 13px;
line-height: 20px;
${props => !props.isDisabled && `color: #333333;`}
${props => (!props.withBorder & !props.isDisabled) && `border-bottom: 1px dotted #333333;`}
opacity: 1;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
height: 32px;
:hover{
border-color: ${state => state.isOpen ? '#2DA7DB' : '#A3A9AE'};
${props => props.isDisabled && `
border-color: #ECEEF1;
`}
}
`;
const StyledIcon = styled.span`
width: 16px;
const StyledComboButton = styled.div`
display: flex;
align-items: center;
justify-content: center;
height: 30px;
margin-left: 8px;
line-height: 14px;
`;
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;
margin-right: 8px;
`;
const StyledArrowIcon = styled.div`
width: 8px;
margin-right: 8px;
margin-left: auto;
${state => state.isOpen && `
transform: scale(1, -1);
margin-top: 8px;
`}
`;
class ComboBox extends React.PureComponent {
@ -79,8 +117,8 @@ class ComboBox extends React.PureComponent {
toggle = (isOpen) => this.setState({ isOpen: isOpen });
comboBoxClick = (e) => {
if (this.props.isDisabled || !!e.target.closest('.input-group-prepend')) return;
if (this.props.isDisabled || e.target.closest('.optionalBlock')) return;
this.setState({
option: this.props.option,
isOpen: !this.state.isOpen
@ -110,7 +148,7 @@ class ComboBox extends React.PureComponent {
getSelectedLabel = () => {
const selectedItem = this.getSelected();
return selectedItem ? selectedItem.label : "1-1";
return selectedItem ? selectedItem.label : this.props.emptyOptionsPlaceholder;
}
componentDidUpdate(prevProps, prevState) {
@ -124,9 +162,9 @@ class ComboBox extends React.PureComponent {
if (this.props.options.length !== prevProps.options.length) { //TODO: Move options from state
const label = this.getSelectedLabel();
this.setState({
this.setState({
options: this.props.options,
boxLabel: label
boxLabel: label
});
}
@ -139,52 +177,65 @@ class ComboBox extends React.PureComponent {
render() {
console.log("ComboBox render");
const dropDownMaxHeightProp = this.props.dropDownMaxHeight ? { maxHeight: this.props.dropDownMaxHeight } : {}
const { dropDownMaxHeight, isDisabled, directionX, directionY, scaled, children } = this.props;
const { boxLabel, boxIcon, isOpen, options } = this.state;
const dropDownMaxHeightProp = dropDownMaxHeight ? { maxHeight: dropDownMaxHeight } : {};
const dropDownManualWidthProp = scaled ? { manualWidth: '100%' } : {};
const boxIconColor = isDisabled ? '#D0D5DA' : '#333333';
const arrowIconColor = isDisabled ? '#D0D5DA' : '#A3A9AE';
return (
<StyledComboBox ref={this.ref}
{...this.props}
{...this.state}
data={this.state.boxLabel}
data={boxLabel}
onClick={this.comboBoxClick}
onSelect={this.stopAction}
>
<InputBlock placeholder={this.state.boxLabel}
iconName='ExpanderDownIcon'
iconSize={8}
isIconFill={true}
iconColor='#A3A9AE'
scale={true}
isDisabled={this.props.isDisabled}
isReadOnly={true}
>
{this.state.boxIcon &&
<StyledComboButton>
<StyledOptionalItem className='optionalBlock'>
{children}
</StyledOptionalItem>
{boxIcon &&
<StyledIcon>
{React.createElement(Icons[this.state.boxIcon],
{React.createElement(Icons[boxIcon],
{
size: "scale",
color: this.props.isDisabled ? '#D0D5DA' : '#333333',
size: 'scale',
color: boxIconColor,
isfill: true
})
}
</StyledIcon>}
{this.props.children}
<DropDown
directionX={this.props.directionX}
directionY={this.props.directionY}
manualWidth='100%'
manualY='102%'
isOpen={this.state.isOpen}
{...dropDownMaxHeightProp}
>
{this.state.options.map((option) =>
<DropDownItem {...option}
disabled={option.label === this.state.boxLabel}
onClick={this.optionClick.bind(this, option)}
/>
)}
</DropDown>
</InputBlock>
</StyledIcon>
}
<StyledLabel>
{boxLabel}
</StyledLabel>
<StyledArrowIcon {...this.state}>
{React.createElement(Icons['ExpanderDownIcon'],
{
size: 'scale',
color: arrowIconColor,
isfill: true
})
}
</StyledArrowIcon>
</StyledComboButton>
<DropDown
directionX={directionX}
directionY={directionY}
manualY='102%'
isOpen={isOpen}
{...dropDownMaxHeightProp}
{...dropDownManualWidthProp}
>
{options.map((option) =>
<DropDownItem {...option}
disabled={option.label === boxLabel}
onClick={this.optionClick.bind(this, option)}
/>
)}
</DropDown>
</StyledComboBox>
);
}
@ -199,13 +250,20 @@ ComboBox.propTypes = {
]),
options: PropTypes.array,
onSelect: PropTypes.func,
dropDownMaxHeight: PropTypes.string
dropDownMaxHeight: PropTypes.string,
emptyOptionsPlaceholder: PropTypes.string,
size: PropTypes.oneOf(['base', 'middle', 'big', 'huge', 'content']),
scaled: PropTypes.bool,
}
ComboBox.defaultProps = {
isDisabled: false,
withBorder: true,
dropDownMaxHeight: null
dropDownMaxHeight: null,
emptyOptionsPlaceholder: 'Select',
size: 'base',
scaled: true
}
export default ComboBox;

View File

@ -8,26 +8,27 @@ import device from '../device'
const StyledPaging = styled.div`
display: flex;
flex-direction: row;
justify-content: flex-start;
display: flex;
flex-direction: row;
justify-content: flex-start;
& > button, div:not(:last-of-type) {
margin-right: 8px;
}
& > button {
margin-right: 8px;
width: 110px;
}
`;
const StyledOnPage = styled.div`
width: 120px;
margin-left: auto;
margin-left: auto;
margin-right: 0px;
@media ${device.mobile} {
display: none;
}
@media ${device.mobile} {
display: none;
}
`;
const StyledPage = styled.div`
margin-right: 8px;
`;
const previousAction = () => {
@ -52,13 +53,13 @@ const Paging = props => {
return (
<StyledPaging>
<Button size='medium' label={previousLabel} onClick={previousAction} isDisabled={disablePrevious} />
<Button size='medium' scale={true} label={previousLabel} onClick={previousAction} isDisabled={disablePrevious} />
{pageItems &&
<StyledPage>
<ComboBox directionY={openDirection} options={pageItems} onSelect={onSelectPageAction} selectedOption={selectedPage} dropDownMaxHeight="200px" />
</StyledPage>
}
<Button size='medium' label={nextLabel} onClick={nextAction} isDisabled={disableNext} />
<Button size='medium' scale={true} label={nextLabel} onClick={nextAction} isDisabled={disableNext} />
{countItems &&
<StyledOnPage>
<ComboBox directionY={openDirection} options={countItems} onSelect={onSelectCountAction} selectedOption={selectedCount} />

View File

@ -1,20 +1,22 @@
import React from "react";
import ContextMenuButton from '../context-menu-button';
const FilterButton = props => {
//console.log("FilterButton render");
return (
<ContextMenuButton
title={'Actions'}
iconName={'RectangleFilterIcon'}
color='#A3A9AE'
size={props.iconSize}
isDisabled={props.isDisabled}
getData={props.getData}
iconHoverName={'RectangleFilterHoverIcon'}
iconClickName={'RectangleFilterClickIcon'}
class FilterButton extends React.PureComponent{
render(){
//console.log('render FilterButton)
return(
<ContextMenuButton
title={'Actions'}
iconName={'RectangleFilterIcon'}
color='#A3A9AE'
size={this.props.iconSize}
isDisabled={this.props.isDisabled}
getData={this.props.getData}
iconHoverName={'RectangleFilterHoverIcon'}
iconClickName={'RectangleFilterClickIcon'}
></ContextMenuButton>
);
};
)
}
}
export default FilterButton

View File

@ -40,7 +40,14 @@ const options = [
}
];
<ComboBox options={options} isDisabled={false} withBorder={true} selectedOption={25} onSelect={option => console.log('selected', option)}/>
<ComboBox options={options}
isDisabled={false}
selectedOption={25}
dropDownMaxHeight='200px'
scale={true}
size='content'
onSelect={option => console.log('selected', option)}
/>
```
#### Properties
@ -49,6 +56,9 @@ const options = [
| ---------------------- | ----------------- | :------: | ---------------------------- | ------- | -------------------------------------------- |
| `options` | `array` | ✅ | - | - | Combo box options |
| `isDisabled` | `bool` | - | - | `false` | Indicates that component is disabled |
| `withBorder` | `bool` | - | - | `true` | Indicates that component contain border |
| `selectedOption` | `string`,`number` | - | - | `0` | Index of option selected by default |
| `onSelect` | `func` | - | - | - | Will be triggered whenever an ComboBox is selected option |
| `onSelect` | `func` | - | - | - | Will be triggered whenever an ComboBox is selected option |
| `dropDownMaxHeight` | `string` | - | - | - | Height of Dropdown |
| `scaled` | `bool` | - | - | `true` | Indicates that component is scaled by parent |
| `size` | `oneOf` | - | `base`, `middle`, `big`, `huge`, `content` | `base` | Select component width, one of default |
| `emptyOptionsPlaceholder`| `string` | - | - | `Select`| Label displayed in absence of options |

View File

@ -1,48 +1,107 @@
import React from 'react'
import { storiesOf } from '@storybook/react'
import { withKnobs, boolean} from '@storybook/addon-knobs/react';
import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { withKnobs, boolean, select, number } from '@storybook/addon-knobs/react';
import { optionsKnob as options } from '@storybook/addon-knobs';
import withReadme from 'storybook-readme/with-readme';
import Readme from './README.md';
import { ComboBox, Icons, Button } from 'asc-web-components'
import Section from '../../../.storybook/decorators/section';
import { ComboBox } from 'asc-web-components'
import { action } from '@storybook/addon-actions';
const options = [
{
const iconNames = Object.keys(Icons);
const sizeOptions = ['base', 'middle', 'big', 'huge', 'content'];
const appendOptions = (comboOptions, optionsCount) => {
let newOptions = comboOptions;
for (let i = 0; i <= optionsCount; i++) {
newOptions.push({
key: (i + 6),
label: 'Option ' + (i + 6)
})
}
return newOptions;
};
iconNames.push("NONE");
storiesOf('Components|Input', module)
.addDecorator(withKnobs)
.addDecorator(withReadme(Readme))
.add('combo box', () => {
const comboOptions = [
{
key: 1,
icon: 'CatalogEmployeeIcon',
label: 'Option 1'
},
{
},
{
key: 2,
icon: 'CatalogGuestIcon',
label: 'Option 2',
},
{
},
{
key: 3,
label: 'Option 3'
},
{
},
{
key: 4,
label: 'Option 4'
},
{
},
{
key: 5,
icon: 'CopyIcon',
label: 'Option 5'
}
];
}
];
storiesOf('Components|Input', module)
.addDecorator(withKnobs)
.addDecorator(withReadme(Readme))
.add('combo box', () => (
<Section>
<ComboBox
options={options}
onSelect={option => action("Selected option")(option)}
isDisabled={boolean('isDisabled', false)}
withBorder={boolean('withBorder', true)}
/>
</Section>
));
const optionsCount = number('Add options', 1,
{
range: true,
min: 1,
max: 100,
step: 1
}
);
const needScrollDropDown = boolean('Need scroll dropdown', false);
const dropDownMaxHeight = needScrollDropDown && number('dropDownMaxHeight', 200);
const optionsMultiSelect = options('Children',
{
button: 'button',
icon: 'icon'
},
['icon'],
{
display: 'multi-select',
});
let children = [];
optionsMultiSelect.forEach(function (item, i) {
switch (item) {
case "button":
children.push(<Button label="OK" key={i} />);
break;
case "icon":
children.push(<Icons.SettingsIcon size="medium" key={i} />);
break;
default:
break;
}
});
return (
<Section>
<ComboBox
options={appendOptions(comboOptions, optionsCount)}
onSelect={option => action("Selected option")(option)}
isDisabled={boolean('isDisabled', false)}
dropDownMaxHeight={dropDownMaxHeight + 'px'}
scaled={boolean('scaled', false)}
size={select('size', sizeOptions, 'content')}
>
{children}
</ComboBox>
</Section>
);
});

View File

@ -1,6 +1,6 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { withKnobs, text, boolean, select } from '@storybook/addon-knobs/react';
import { withKnobs, text, boolean, select, number } from '@storybook/addon-knobs/react';
import withReadme from 'storybook-readme/with-readme';
import Readme from './README.md';
import { Paging } from 'asc-web-components';
@ -11,28 +11,16 @@ storiesOf('Components|Paging', module)
.addDecorator(withReadme(Readme))
.add('base', () => {
const pageItems = [
{
key: 1,
label: '1 of 5'
},
{
key: 2,
label: '2 of 5'
},
{
key: 3,
label: '3 of 5'
},
{
key: 4,
label: '4 of 5'
},
{
key: 5,
label: '5 of 5'
const createPageItems = (count) => {
let pageItems = [];
for (let i = 0; i < count; i++){
pageItems.push({
key: i,
label: i + ' of ' + count
})
}
];
return pageItems;
}
const countItems = [
{
@ -51,21 +39,20 @@ storiesOf('Components|Paging', module)
const displayItems = boolean('Display pageItems', true);
const displayCount = boolean('Display countItems', true);
const selectedPage = select('selectedPage', [1, 2, 3, 4, 5], 3);
const selectedCount = select('selectedCount', [25, 50, 100], 100);
const pageCount = number('Count of pages', 5);
return (
<Section>
<Paging previousLabel={text('previousLabel', 'Previous')}
nextLabel={text('nextLabel', 'Next')}
pageItems={displayItems ? pageItems : undefined}
pageItems={displayItems ? createPageItems(pageCount) : undefined}
countItems={displayCount ? countItems : undefined}
disablePrevious={boolean('disablePrevious', false)}
disableNext={boolean('disableNext', false)}
previousAction={() => console.log('Prev')}
nextAction={() => console.log('Next')}
openDirection='bottom'
selectedPage={selectedPage}
selectedCount={selectedCount}
onSelectPage={(a) => console.log(a)}
onSelectCount={(a) => console.log(a)}