From 826586ec15e0c6d8ae234e3d478b1076a58e562b Mon Sep 17 00:00:00 2001 From: Ilya Oleshko Date: Tue, 30 Jul 2019 14:17:19 +0300 Subject: [PATCH] Web: Components: Added onSelect callback at GroupButtonsMenu and isSelect property at GroupButton component. Fixed stories of GroupButtonsMenu component. --- .../src/components/group-button/index.js | 73 ++++-- .../components/group-buttons-menu/index.js | 235 +++++++++--------- .../base/base.group-buttons-menu.stories.js | 183 +++++++++----- .../people.group-buttons-menu.stories.js | 141 +++++------ 4 files changed, 348 insertions(+), 284 deletions(-) diff --git a/web/ASC.Web.Components/src/components/group-button/index.js b/web/ASC.Web.Components/src/components/group-button/index.js index 2a0a17b3bc..29f80cdb3c 100644 --- a/web/ASC.Web.Components/src/components/group-button/index.js +++ b/web/ASC.Web.Components/src/components/group-button/index.js @@ -4,6 +4,7 @@ import PropTypes from "prop-types"; import { Icons } from "../icons"; import DropDown from "../drop-down"; import DropDownItem from "../drop-down-item"; +import Checkbox from "../checkbox"; const textColor = "#333333", disabledTextColor = "#A3A9AE"; @@ -82,6 +83,15 @@ const Separator = styled.div` margin-top: 16px; `; +const StyledCheckbox = styled.div` + display: inline-block; + margin: auto 0 auto 16px; + + & > * { + margin: 0px; + } +`; + class GroupButton extends React.PureComponent { constructor(props) { super(props); @@ -89,7 +99,8 @@ class GroupButton extends React.PureComponent { this.ref = React.createRef(); this.state = { - isOpen: props.opened + isOpen: props.opened, + selected: props.selected }; this.handleClick = this.handleClick.bind(this); @@ -122,41 +133,46 @@ class GroupButton extends React.PureComponent { render() { //console.log("GroupButton render"); - const { label, isDropdown, disabled, isSeparator } = this.props; + const { label, isDropdown, disabled, isSeparator, isSelect, onSelect, checked, isIndeterminate, onChange, children, selected } = this.props; + const color = disabled ? disabledTextColor : textColor; return ( - {isDropdown ? ( - <> - + {isSelect && + + { + onChange && onChange(e.target.checked); + this.setState({ selected: selected }); + }} /> + + } + { disabled ? false : this.toggle(!this.state.isOpen); }} > - {label} - + {!isSelect ? label : this.state.selected} + - { - React.Children.map(this.props.children, (child) => - { - child.props.onClick && child.props.onClick(); - this.toggle(!this.state.isOpen); - }} - /> - ) - } + {React.Children.map(children, (child) => { + return { + child.props.onClick && child.props.onClick(); + onSelect && onSelect(child); + this.setState({ selected: child.props.label }); + this.toggle(!this.state.isOpen); + }} />; + })} + - ) : ( - {label} - )} + : {label} + } {isSeparator && } ); @@ -173,7 +189,9 @@ GroupButton.propTypes = { isSeparator: PropTypes.bool, tabIndex: PropTypes.number, onClick: PropTypes.func, - fontWeight: PropTypes.string + fontWeight: PropTypes.string, + onSelect: PropTypes.func, + isSelect: PropTypes.bool }; GroupButton.defaultProps = { @@ -185,7 +203,8 @@ GroupButton.defaultProps = { isDropdown: false, isSeparator: false, tabIndex: -1, - fontWeight: "600" + fontWeight: "600", + isSelect: false }; export default GroupButton; diff --git a/web/ASC.Web.Components/src/components/group-buttons-menu/index.js b/web/ASC.Web.Components/src/components/group-buttons-menu/index.js index 52a75b133d..eccc17b029 100644 --- a/web/ASC.Web.Components/src/components/group-buttons-menu/index.js +++ b/web/ASC.Web.Components/src/components/group-buttons-menu/index.js @@ -1,9 +1,8 @@ -import React from 'react' -import styled from 'styled-components' -import PropTypes from 'prop-types' -import GroupButton from '../group-button' -import DropDownItem from '../drop-down-item' -import Checkbox from '../checkbox' +import React from 'react'; +import styled from 'styled-components'; +import PropTypes from 'prop-types'; +import GroupButton from '../group-button'; +import DropDownItem from '../drop-down-item'; const StyledGroupButtonsMenu = styled.div` position: sticky; @@ -48,137 +47,125 @@ const CloseButton = styled.div` } `; -const StyledCheckbox = styled.div` - display: inline-block; - margin-left: 16px; - vertical-align: middle; - - & > * { - margin: 0px; - } -`; - class GroupButtonsMenu extends React.PureComponent { + constructor(props) { + super(props); - constructor(props) { - super(props); - - this.state = { - priorityItems: props.menuItems, - moreItems: [], - visible: true - } - - this.fullMenuArray = this.props.menuItems; - this.checkBox = this.props.checkBox; - - this.updateMenu = this.updateMenu.bind(this); - this.howManyItemsInMenuArray = this.howManyItemsInMenuArray.bind(this); + this.state = { + priorityItems: props.menuItems, + moreItems: [], + visible: true } - componentDidMount() { - this.widthsArray = Array.from(document.getElementById("groupMenu").children).map(item => item.getBoundingClientRect().width); + this.fullMenuArray = this.props.menuItems; + this.checkBox = this.props.checkBox; - window.addEventListener('resize', _.throttle(this.updateMenu), 100); - this.updateMenu(); + this.updateMenu = this.updateMenu.bind(this); + this.howManyItemsInMenuArray = this.howManyItemsInMenuArray.bind(this); + } + + componentDidMount() { + this.widthsArray = Array.from(document.getElementById("groupMenu").children).map(item => item.getBoundingClientRect().width); + + window.addEventListener('resize', _.throttle(this.updateMenu), 300); + + this.updateMenu(); + } + + componentDidUpdate(prevProps) { + if (this.props.visible !== prevProps.visible) { + this.setState({ visible: this.props.visible }); } + }; - componentDidUpdate(prevProps) { - if (this.props.visible !== prevProps.visible) { - this.setState({ visible: this.props.visible }); - } + howManyItemsInMenuArray = (array, outerWidth, initialWidth) => { + let total = (initialWidth + 80); + for (let i = 0, len = array.length; i < len; i++) { + if (total + array[i] > outerWidth) { + return i < 1 ? 1 : i; + } else { + total += array[i]; + } + } + }; + + updateMenu = () => { + const moreMenuElement = document.getElementById("moreMenu"); + const outerWidth = document.getElementById("groupMenuOuter").getBoundingClientRect().width; + const moreMenuWidth = moreMenuElement ? moreMenuElement.getBoundingClientRect().width : 0; + const arrayAmount = this.howManyItemsInMenuArray(this.widthsArray, outerWidth, moreMenuWidth); + const navItemsCopy = this.fullMenuArray; + const priorityItems = navItemsCopy.slice(0, arrayAmount); + + this.setState({ + priorityItems: priorityItems, + moreItems: priorityItems.length !== navItemsCopy.length ? navItemsCopy.slice(arrayAmount, navItemsCopy.length) : [] + }); + }; + + componentWillUnmount() { + window.removeEventListener('resize', this.updateMenu()); + } + + render() { + //console.log("GroupButtonsMenu render"); + + const closeMenu = (e) => { + this.setState({ visible: false }); + this.props.onClose && this.props.onClose(e); }; - howManyItemsInMenuArray = (array, outerWidth, initialWidth, minimumNumberInNav) => { - let total = (initialWidth + 180); - for (let i = 0; i < array.length; i++) { - if (total + array[i] > outerWidth) { - return i < minimumNumberInNav ? minimumNumberInNav : i; - } else { - total += array[i]; - } + return ( + +
+ {this.state.priorityItems.map((item, i) => + { + item.onClick(e); + closeMenu(e); + }} + {...this.props}> + {item.children} + + )} +
+ {this.state.moreItems.length > 0 && + + {this.state.moreItems.map((item, i) => + { + item.onClick(e); + closeMenu(e); + }} + /> + )} + } - }; - - updateMenu = () => { - this.outerWidth = document.getElementById("groupMenuOuter") ? document.getElementById("groupMenuOuter").getBoundingClientRect().width : 0; - this.moreMenu = document.getElementById("moreMenu") ? document.getElementById("moreMenu").getBoundingClientRect().width : 0; - - const arrayAmount = this.howManyItemsInMenuArray(this.widthsArray, this.outerWidth, this.moreMenu, 1); - const navItemsCopy = this.fullMenuArray; - const priorityItems = navItemsCopy.slice(0, arrayAmount); - - this.setState({ - priorityItems: priorityItems, - moreItems: priorityItems.length !== navItemsCopy.length ? navItemsCopy.slice(arrayAmount, navItemsCopy.length) : [] - }); - }; - - componentWillUnmount() { - window.removeEventListener('resize', this.updateMenu()); - } - - - render() { - console.log("GroupButtonsMenu render"); - const closeMenu = (e) => { - this.setState({ visible: false }); - this.props.onClose && this.props.onClose(e); - }; - - return ( - - {this.props.hasOwnProperty("checked") && - - { - this.props.onChange && this.props.onChange(e.target.checked); - }} /> - - } -
- {this.state.priorityItems.map((item, i) => - { - item.onClick(e); - closeMenu(e); - }}> - {item.children} - - )} -
- {this.state.moreItems.length > 0 && - - {this.state.moreItems.map((item, i) => - { - item.onClick(e); - closeMenu(e); - }} - /> - )} - - } - -
- ); - } + +
+ ); + } } GroupButtonsMenu.propTypes = { - onClick: PropTypes.func, - onClose: PropTypes.func, - onChange: PropTypes.func, - menuItems: PropTypes.array, - checked: PropTypes.bool, - visible: PropTypes.bool, - moreLabel: PropTypes.string, - closeTitle: PropTypes.string + onClick: PropTypes.func, + onClose: PropTypes.func, + onChange: PropTypes.func, + onSelect: PropTypes.func, + menuItems: PropTypes.array, + checked: PropTypes.bool, + selected: PropTypes.string, + visible: PropTypes.bool, + moreLabel: PropTypes.string, + closeTitle: PropTypes.string } export default GroupButtonsMenu; \ No newline at end of file diff --git a/web/ASC.Web.Storybook/stories/group-buttons-menu/base/base.group-buttons-menu.stories.js b/web/ASC.Web.Storybook/stories/group-buttons-menu/base/base.group-buttons-menu.stories.js index 329844afc7..c0d651d56e 100644 --- a/web/ASC.Web.Storybook/stories/group-buttons-menu/base/base.group-buttons-menu.stories.js +++ b/web/ASC.Web.Storybook/stories/group-buttons-menu/base/base.group-buttons-menu.stories.js @@ -11,69 +11,126 @@ const GroupButtonsMenuContainer = styled.div` height: 2000px; `; -const createItems = (label, dropDownLabel, menuItemLabel, count) => { - var items =[ - { - label: label, - isDropdown: true, - isSeparator: true, - fontWeight: 'bold', - children: [ - , - , - - ] - } - ]; - - for (var i=0; i console.log('Click action')}); - } - - return items; -} +const groupItems = [ + { + label: 'Select', + isDropdown: true, + isSeparator: true, + isSelect: true, + fontWeight: 'bold', + children: [ + , + , + , + ], + onSelect: (a) => console.log(a) + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + }, + { + label: 'Menu item', + onClick: () => console.log('Menu item action') + } +]; storiesOf('Components|GroupButtonsMenu', module) - .addDecorator(withReadme(Readme)) - .addDecorator(withKnobs) - .add('base', () => { - - const elements = 10; - const selectLabel = 'Select'; - const dropLabel = 'Dropdown item'; - const menuItemLabel = 'Menu item'; - - const menuItems = createItems(selectLabel, dropLabel, menuItemLabel, elements); - - return ( - - {({ value: visible, toggle }) => ( - <> -