diff --git a/web/ASC.Web.Components/package.json b/web/ASC.Web.Components/package.json index 742df0de57..eccc688ccb 100644 --- a/web/ASC.Web.Components/package.json +++ b/web/ASC.Web.Components/package.json @@ -1,6 +1,6 @@ { "name": "asc-web-components", - "version": "1.0.333", + "version": "1.0.334", "description": "Ascensio System SIA component library", "license": "AGPL-3.0", "main": "dist/asc-web-components.js", diff --git a/web/ASC.Web.Components/src/components/group-button/group-button.test.js b/web/ASC.Web.Components/src/components/group-button/group-button.test.js index 318ce23a55..876ba55393 100644 --- a/web/ASC.Web.Components/src/components/group-button/group-button.test.js +++ b/web/ASC.Web.Components/src/components/group-button/group-button.test.js @@ -18,109 +18,187 @@ describe('', () => { it('renders with child', () => { const wrapper = mount( - -
1
-
); + +
+ Test +
+
); expect(wrapper).toExist(); + expect(wrapper.instance().props.isDropdown).toBe(true); + }); + + it('renders with child and open first item', () => { + const wrapper = mount( + +
+ Test +
+
); + + expect(wrapper).toExist(); + expect(wrapper.instance().props.isDropdown).toBe(true); + expect(wrapper.instance().props.opened).toBe(true); }); it('applies disabled prop', () => { - const wrapper = mount(); + const wrapper = mount( + ); expect(wrapper.prop('disabled')).toEqual(true); }); it('applies opened prop', () => { - const wrapper = mount(); + const wrapper = mount( + ); expect(wrapper.prop('opened')).toEqual(true); expect(wrapper.state('isOpen')).toEqual(true); }); it('applies isDropdown prop', () => { - const wrapper = mount(); + const wrapper = mount( + ); expect(wrapper.prop('isDropdown')).toEqual(true); }); it('applies activated prop', () => { - const wrapper = mount(); + const wrapper = mount( + ); expect(wrapper.prop('activated')).toEqual(true); }); it('applies hovered prop', () => { - const wrapper = mount(); + const wrapper = mount( + ); expect(wrapper.prop('hovered')).toEqual(true); }); it('applies isSeparator prop', () => { - const wrapper = mount(); + const wrapper = mount( + ); expect(wrapper.prop('isSeparator')).toEqual(true); }); it('applies isSelect prop', () => { - const wrapper = mount(); + const wrapper = mount( + ); expect(wrapper.prop('isSelect')).toEqual(true); }); it('applies checked prop', () => { - const wrapper = mount(); + const wrapper = mount( + ); expect(wrapper.prop('checked')).toEqual(true); }); it('applies isIndeterminate prop', () => { - const wrapper = mount(); + const wrapper = mount( + ); expect(wrapper.prop('isIndeterminate')).toEqual(true); }); it('applies dropDownMaxHeight prop', () => { - const wrapper = mount(); + const wrapper = mount( + ); expect(wrapper.prop('dropDownMaxHeight')).toEqual(100); }); - it('componentDidUpdate() state lifecycle test', () => { - const wrapper = shallow(); - const instance = wrapper.instance(); - wrapper.setState({ isOpen: true }); + it('applies id', () => { + const wrapper = mount( + + ); - instance.componentDidUpdate(wrapper.props(), wrapper.state()); - - expect(wrapper.state()).toBe(wrapper.state()); + expect(wrapper.prop('id')).toEqual('testId'); }); - it('componentDidUpdate() props lifecycle test', () => { - const wrapper = shallow(); - const instance = wrapper.instance(); + it('applies className', () => { + const wrapper = mount( + + ); - instance.componentDidUpdate({ opened: true }, wrapper.state()); - - expect(wrapper.props()).toBe(wrapper.props()); + expect(wrapper.prop('className')).toEqual('test'); }); - it('componentWillUnmount() props lifecycle test', () => { - const wrapper = shallow(); - const instance = wrapper.instance(); + it('applies style', () => { + const wrapper = mount( + + ); - instance.componentWillUnmount(); - - expect(wrapper).toExist(false); + expect(wrapper.getDOMNode().style).toHaveProperty('color', 'red'); }); it('causes function dropDownItemClick()', () => { const onClick = jest.fn(); - const onSelect = jest.fn() - const child = (
1
); + const onSelect = jest.fn(); + const child = (
test
); const wrapper = shallow( - + {child} ); const instance = wrapper.instance(); @@ -132,8 +210,15 @@ describe('', () => { }); it('causes function dropDownToggleClick()', () => { + const child = (
test
); const wrapper = shallow( - ); + + {child} + ); const instance = wrapper.instance(); instance.dropDownToggleClick(); @@ -141,47 +226,82 @@ describe('', () => { expect(wrapper.state('isOpen')).toBe(false); }); - it('causes function checkboxChange()', () => { - const wrapper = shallow( - ); + it('causes function checkboxChange(e)', () => { + const child = (
test
); + const onChange = jest.fn(); + const wrapper = mount( + + {child} + ); const instance = wrapper.instance(); + const event = new Event('click', { target: { checked: true } }); - instance.checkboxChange(); + instance.checkboxChange(event); - expect(wrapper.state('selected')).toBe('demo'); + /* TODO: Way of normal simulation + wrapper.find('input[type="checkbox"]').simulate('change', {target:{checked:true}}) */ + + expect(onChange).toBeCalled(); + expect(wrapper.state('selected')).toBe('test'); }); - it('causes function handleClick()', () => { - const wrapper = mount(); + it('causes function clickOutsideAction(e)', () => { + const child = (
test
); + const wrapper = mount( + + {child} + ); const instance = wrapper.instance(); + const event = new Event('click', { target: {} }); - instance.handleClick(new Event('click')); + instance.clickOutsideAction(event); + expect(wrapper.state('selected')).toBe('test'); expect(wrapper.state('isOpen')).toBe(false); }); - it('accepts id', () => { + it('calling componentDidUpdate()', () => { + const child = (
test
); const wrapper = mount( - - ); + + {child} + ); - expect(wrapper.prop('id')).toEqual('testId'); - }); + expect(wrapper.state('selected')).toBe('test'); + expect(wrapper.state('isOpen')).toBe(true); - it('accepts className', () => { - const wrapper = mount( - - ); + wrapper.setProps({ + opened: false + }); - expect(wrapper.prop('className')).toEqual('test'); - }); + expect(wrapper.state('selected')).toBe('test'); + expect(wrapper.state('isOpen')).toBe(false); - it('accepts style', () => { - const wrapper = mount( - - ); + wrapper.setProps({ + selected: 'new test' + }); - expect(wrapper.getDOMNode().style).toHaveProperty('color', 'red'); + expect(wrapper.state('selected')).toBe('new test'); + expect(wrapper.state('isOpen')).toBe(false); }); }); 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 55e05fe3f3..c225418cb9 100644 --- a/web/ASC.Web.Components/src/components/group-button/index.js +++ b/web/ASC.Web.Components/src/components/group-button/index.js @@ -5,9 +5,8 @@ import { Icons } from "../icons"; import DropDown from "../drop-down"; import DropDownItem from "../drop-down-item"; import Checkbox from "../checkbox"; -import { handleAnyClick } from '../../utils/event'; import { tablet } from '../../utils/device' - + const textColor = "#333333", disabledTextColor = "#A3A9AE"; @@ -115,56 +114,64 @@ class GroupButton extends React.PureComponent { isOpen: props.opened, selected: props.selected }; - - if (props.opened) - handleAnyClick(true, this.handleClick); } - handleClick = (e) => - this.state.isOpen && !this.ref.current.contains(e.target) && this.toggle(false); + setIsOpen = isOpen => this.setState({ isOpen: isOpen }); - stopAction = (e) => e.preventDefault(); + setSelected = selected => this.setState({ selected: selected }); - toggle = (isOpen) => this.setState({ isOpen: isOpen }); + componentDidUpdate(prevProps) { + if (this.props.opened !== prevProps.opened) { + this.setIsOpen(this.props.opened); + } - checkboxChange = (e) => { - this.props.onChange && this.props.onChange(e.target.checked); - this.setState({ selected: this.props.selected }); + if (this.props.selected !== prevProps.selected) { + this.setSelected(this.props.selected); + } + } + + clickOutsideAction = e => { + this.state.isOpen && !this.ref.current.contains(e.target) && this.setIsOpen(false); + } + + checkboxChange = e => { + this.props.onChange && this.props.onChange(e.target && e.target.checked); + + this.setSelected(this.props.selected); }; - dropDownItemClick = (child) => { + dropDownItemClick = child => { child.props.onClick && child.props.onClick(); this.props.onSelect && this.props.onSelect(child); - this.setState({ selected: child.props.label }); - this.toggle(!this.state.isOpen); + this.setSelected(child.props.label); + this.setIsOpen(!this.state.isOpen); }; - dropDownToggleClick = (e) => { - this.props.disabled ? this.stopAction(e) : this.toggle(!this.state.isOpen); + dropDownToggleClick = () => { + this.setIsOpen(!this.state.isOpen); }; - componentWillUnmount() { - handleAnyClick(false, this.handleClick); - } - - componentDidUpdate(prevProps, prevState) { - if (this.props.opened !== prevProps.opened) { - this.toggle(this.props.opened); - } - - if (this.state.isOpen !== prevState.isOpen) { - handleAnyClick(this.state.isOpen, this.handleClick); - } - } - render() { //console.log("GroupButton render"); - const { label, isDropdown, disabled, isSeparator, isSelect, isIndeterminate, children, checked, dropDownMaxHeight, id, className, style } = this.props; + const { + checked, + children, + className, + disabled, + dropDownMaxHeight, + id, + isDropdown, + isIndeterminate, + isSelect, + isSeparator, + label, + style + } = this.props; const color = disabled ? disabledTextColor : textColor; const itemLabel = !isSelect ? label : this.state.selected; const dropDownMaxHeightProp = dropDownMaxHeight ? { maxHeight: dropDownMaxHeight } : {}; - const offsetSelectDropDown = isSelect ? { manualX : (window.innerWidth <= 1024) ? '16px' : '24px'} : {}; + const offsetSelectDropDown = isSelect ? { manualX: (window.innerWidth <= 1024) ? '16px' : '24px' } : {}; return ( @@ -197,8 +204,7 @@ class GroupButton extends React.PureComponent { {...offsetSelectDropDown} manualY='72px' open={this.state.isOpen} - clickOutsideAction={this.dropDownToggleClick} - withBackdrop={true} + clickOutsideAction={this.clickOutsideAction} > {React.Children.map(children, (child) =>