diff --git a/web/ASC.Web.Components/src/components/combobox/index.js b/web/ASC.Web.Components/src/components/combobox/index.js
index 4b072e9d6e..faf76bad68 100644
--- a/web/ASC.Web.Components/src/components/combobox/index.js
+++ b/web/ASC.Web.Components/src/components/combobox/index.js
@@ -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 (
-
- {this.state.boxIcon &&
+
+
+ {children}
+
+ {boxIcon &&
- {React.createElement(Icons[this.state.boxIcon],
+ {React.createElement(Icons[boxIcon],
{
- size: "scale",
- color: this.props.isDisabled ? '#D0D5DA' : '#333333',
+ size: 'scale',
+ color: boxIconColor,
isfill: true
})
}
- }
- {this.props.children}
-
- {this.state.options.map((option) =>
-
- )}
-
-
+
+ }
+
+ {boxLabel}
+
+
+ {React.createElement(Icons['ExpanderDownIcon'],
+ {
+ size: 'scale',
+ color: arrowIconColor,
+ isfill: true
+ })
+ }
+
+
+
+ {options.map((option) =>
+
+ )}
+
);
}
@@ -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;
\ No newline at end of file
diff --git a/web/ASC.Web.Components/src/components/paging/index.js b/web/ASC.Web.Components/src/components/paging/index.js
index 5750f136ab..fb74cde1f0 100644
--- a/web/ASC.Web.Components/src/components/paging/index.js
+++ b/web/ASC.Web.Components/src/components/paging/index.js
@@ -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 (
-
+
{pageItems &&
}
-
+
{countItems &&
diff --git a/web/ASC.Web.Components/src/components/search-input/filter-button.js b/web/ASC.Web.Components/src/components/search-input/filter-button.js
index 2d886dd3c3..aa24c75e4c 100644
--- a/web/ASC.Web.Components/src/components/search-input/filter-button.js
+++ b/web/ASC.Web.Components/src/components/search-input/filter-button.js
@@ -1,20 +1,22 @@
import React from "react";
import ContextMenuButton from '../context-menu-button';
-const FilterButton = props => {
- //console.log("FilterButton render");
- return (
-
- );
-};
+ )
+ }
+}
export default FilterButton
\ No newline at end of file
diff --git a/web/ASC.Web.Storybook/stories/input/combobox/README.md b/web/ASC.Web.Storybook/stories/input/combobox/README.md
index 645ed42897..74c13b0828 100644
--- a/web/ASC.Web.Storybook/stories/input/combobox/README.md
+++ b/web/ASC.Web.Storybook/stories/input/combobox/README.md
@@ -40,7 +40,14 @@ const options = [
}
];
- console.log('selected', 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 |
\ No newline at end of file
+| `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 |
diff --git a/web/ASC.Web.Storybook/stories/input/combobox/combobox.stories.js b/web/ASC.Web.Storybook/stories/input/combobox/combobox.stories.js
index 9ca2baa16f..4711630b25 100644
--- a/web/ASC.Web.Storybook/stories/input/combobox/combobox.stories.js
+++ b/web/ASC.Web.Storybook/stories/input/combobox/combobox.stories.js
@@ -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', () => (
-
- action("Selected option")(option)}
- isDisabled={boolean('isDisabled', false)}
- withBorder={boolean('withBorder', true)}
- />
-
- ));
\ No newline at end of file
+ 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();
+ break;
+ case "icon":
+ children.push();
+ break;
+ default:
+ break;
+ }
+ });
+
+ return (
+
+ action("Selected option")(option)}
+ isDisabled={boolean('isDisabled', false)}
+ dropDownMaxHeight={dropDownMaxHeight + 'px'}
+ scaled={boolean('scaled', false)}
+ size={select('size', sizeOptions, 'content')}
+ >
+ {children}
+
+
+ );
+ });
\ No newline at end of file
diff --git a/web/ASC.Web.Storybook/stories/paging/base/base.paging.stories.js b/web/ASC.Web.Storybook/stories/paging/base/base.paging.stories.js
index 11f5c8edb5..0bb77a22ab 100644
--- a/web/ASC.Web.Storybook/stories/paging/base/base.paging.stories.js
+++ b/web/ASC.Web.Storybook/stories/paging/base/base.paging.stories.js
@@ -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 (
console.log('Prev')}
nextAction={() => console.log('Next')}
openDirection='bottom'
- selectedPage={selectedPage}
selectedCount={selectedCount}
onSelectPage={(a) => console.log(a)}
onSelectCount={(a) => console.log(a)}