Skip to content

Commit

Permalink
Merge branch '2.x' of https://github.com/open-amdocs/webrix into 2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
Yair Even Or authored and Yair Even Or committed Apr 6, 2022
2 parents 7d6d7a2 + ef0ba27 commit 2dfa264
Show file tree
Hide file tree
Showing 22 changed files with 131 additions and 84 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ import {Movable} from 'webrix';
* [useDebounce()](https://webrix.amdocs.com/docs/hooks/usedebounce)
* [useThrottle()](https://webrix.amdocs.com/docs/hooks/usethrottle)
* [useObject()](https://webrix.amdocs.com/docs/hooks/useobject)
* [useDimensions()](https://webrix.amdocs.com/docs/hooks/usedimensions)
* [useResizeObserver()](https://webrix.amdocs.com/docs/hooks/useResizeObserver)
* [useAnimationFrame()](https://webrix.amdocs.com/docs/hooks/useanimationframe)
* [useBoundingRectObserver()](https://webrix.amdocs.com/docs/hooks/useboundingrectobserver)
* [useEventListener()](https://webrix.amdocs.com/docs/hooks/useeventlistener)
Expand All @@ -97,3 +97,4 @@ import {Movable} from 'webrix';

* [<ResizeObserver\/>](https://webrix.amdocs.com/docs/tools/resizeobserver)
* [<Puppeteer\/>](https://webrix.amdocs.com/docs/tools/puppeteer)
* [<ClickOutside\/>](https://webrix.amdocs.com/docs/tools/clickoutside)
15 changes: 9 additions & 6 deletions src/components/Movable/Movable.hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,22 @@
import {useRef, useCallback} from 'react';

export const useMove = ops => {
const opsRef = useRef(ops);
const shared = useRef({});

opsRef.current = ops;

const onBeginMove = useCallback(e => {
ops.forEach(({onBeginMove}) => onBeginMove(e, shared.current));
}, [ops]);
opsRef.current.forEach(({onBeginMove}) => onBeginMove(e, shared.current));
}, []);

const onMove = useCallback(e => {
ops.forEach(({onMove}) => onMove(e, shared.current));
}, [ops]);
opsRef.current.forEach(({onMove}) => onMove(e, shared.current));
}, []);

const onEndMove = useCallback(e => {
ops.forEach(({onEndMove}) => onEndMove(e, shared.current))
}, [ops]);
opsRef.current.forEach(({onEndMove}) => onEndMove(e, shared.current))
}, []);

return {onBeginMove, onMove, onEndMove};
};
6 changes: 4 additions & 2 deletions src/components/Movable/Movable.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ describe('<Movable/>', () => {
expect(stopPropagation.calledOnce).toEqual(true);
expect(preventDefault.calledOnce).toEqual(true);
});

it('onMove()', () => {
const handleOnMove = sinon.spy();
const wrapper = mount(<Movable onMove={handleOnMove}/>);
const handlers = {};
let event;

document.addEventListener = (type, handler) => handlers[type] = handler;
document.addEventListener = (type, handler) => {handlers[type] = handler};
wrapper.simulate('mousedown', {clientX: 10, clientY: 10});
wrapper.simulate('touchstart', {changedTouches: [{clientX: 10, clientY: 10}]});

Expand Down Expand Up @@ -78,12 +79,13 @@ describe('<Movable/>', () => {
expect(event.dx).toEqual(-10);
expect(event.dy).toEqual(-10);
});

it('onEndMove()', () => {
const handleOnEndMove = sinon.spy();
const wrapper = mount(<Movable onEndMove={handleOnEndMove}/>);
const handlers = {};

document.addEventListener = (type, handler) => handlers[type] = handler;
document.addEventListener = (type, handler) => {handlers[type] = handler};
document.removeEventListener = sinon.spy();

wrapper.simulate('mousedown', {clientX: 10, clientY: 10});
Expand Down
15 changes: 9 additions & 6 deletions src/components/Resizable/Resizable.hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,22 @@
import {useRef, useCallback} from 'react';

export const useResize = ops => {
const opsRef = useRef(ops);
const shared = useRef({});

opsRef.current = ops;

const onBeginResize = useCallback(e => {
ops.forEach(({onBeginResize}) => onBeginResize(e, shared.current));
}, [ops]);
opsRef.current.forEach(({onBeginResize}) => onBeginResize(e, shared.current));
}, []);

const onResize = useCallback(e => {
ops.forEach(({onResize}) => onResize(e, shared.current));
}, [ops]);
opsRef.current.forEach(({onResize}) => onResize(e, shared.current));
}, []);

const onEndResize = useCallback(e => {
ops.forEach(({onEndResize}) => onEndResize(e, shared.current));
}, [ops]);
opsRef.current.forEach(({onEndResize}) => onEndResize(e, shared.current));
}, []);

return {onBeginResize, onResize, onEndResize};
};
4 changes: 2 additions & 2 deletions src/components/Scrollable/Scrollable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,14 @@ export default class Scrollable extends React.PureComponent {
};

render() {
const {children, style, element} = this.props;
const {children, element, className} = this.props;
const vsb = findChildByType(children, VerticalScrollbarPlaceholder);
const hsb = findChildByType(children, HorizontalScrollbarPlaceholder);
const content = React.Children.toArray(children).filter(child => ![VerticalScrollbarPlaceholder, HorizontalScrollbarPlaceholder].includes(child.type));

return (
<ResizeObserver onResize={this.updateScrollbars}>
<div className='scrollbar' style={style} onTransitionEnd={this.handleOnTransitionEnd}>
<div {...this.props} className={classNames('scrollbar', className)} onTransitionEnd={this.handleOnTransitionEnd}>
{React.cloneElement(element, this.getElementProps(), content)}
<Context.Provider value={this.state}>
{vsb ? vsb.props.children : <VerticalScrollbar/>}
Expand Down
6 changes: 3 additions & 3 deletions src/components/Scrollable/Scrollable.props.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
*/

import React from 'react';
import {func, shape, node, bool} from 'prop-types';
import {func, node, bool, string} from 'prop-types';
import {noop} from 'utility/memory';

export const propTypes = {
style: shape({}),
className: string,
onScroll: func,
onUpdate: func,
scrollOnDOMChange: bool,
Expand All @@ -29,7 +29,7 @@ export const propTypes = {
};

export const defaultProps = {
style: null,
className: null,
onScroll: noop,
onUpdate: noop,
scrollOnDOMChange: true,
Expand Down
11 changes: 2 additions & 9 deletions src/components/Scrollable/Scrollable.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@
--scrollable-track-thickness: 12px;
--scrollable-thumb-thickness: Calc(var(--scrollable-track-thickness)/2);
--scrollable-thumb-offset: 3px;
--scrollable-thumb-color: silver;

position: relative;
max-height: 100%;
max-width: 100%;
display: flex;

&:hover > .scrollbar-track .scrollbar-thumb .scrollbar-thumb-inner {
opacity: 1;
transition-delay: 0s;
}

.scrollbar-inner {
position: relative;
overflow: auto;
Expand All @@ -37,10 +33,7 @@
cursor: pointer;

.scrollbar-thumb-inner {
background-color: rgba(28, 34, 43, 0.6);
border-radius: 4px;
opacity: 0;
transition: opacity 0.2s ease-out 0.5s; // The transition delay is used to keep the thumb visible for a short time when the cursor leaves. (see `Scrollable.constants.js`)
background-color: var(--scrollable-thumb-color);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import React, {useContext, useMemo, useRef} from 'react';
import React, {useContext, useRef} from 'react';
import Movable from 'components/Movable';
import Context from '../../Scrollable.context';
import {CSS_VARS} from '../../Scrollable.constants';
Expand All @@ -25,7 +25,7 @@ const HorizontalScrollbar = () => {
const track = useRef();
const thumb = useRef();
const {container, scrollLeft, cssVarsOnTracks} = useContext(Context);
const props = Movable.useMove(useMemo(() => [move(container, thumb, track)], [container]));
const props = Movable.useMove([move(container, thumb, track)]);

const handleOnClick = e => {
e.stopPropagation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import React, {useContext, useMemo, useRef} from 'react';
import React, {useContext, useRef} from 'react';
import Movable from 'components/Movable';
import Context from '../../Scrollable.context';
import {CSS_VARS} from '../../Scrollable.constants';
Expand All @@ -25,7 +25,7 @@ const VerticalScrollbar = () => {
const track = useRef();
const thumb = useRef();
const {container, scrollTop, cssVarsOnTracks} = useContext(Context);
const props = Movable.useMove(useMemo(() => [move(container, thumb, track)], [container]));
const props = Movable.useMove([move(container, thumb, track)]);

const handleOnClick = e => {
e.stopPropagation();
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export {default as useAnimationFrame} from './useAnimationFrame';
export {default as useBooleanState, useVisibilityState, useFocusabilityState} from './useBooleanState';
export {default as useBoundingRectObserver} from './useBoundingRectObserver';
export {default as useClickOutside, ClickOutside, ClickOutsideOverride} from './useClickOutside';
export {default as useClickOutside} from './useClickOutside';
export {default as useMounted} from './useMounted';
export {default as useDebounce} from './useDebounce';
export {default as useDimensions} from './useDimensions';
export {default as useResizeObserver} from './useResizeObserver';
export {default as useEventListener} from './useEventListener';
export {default as useThrottle} from './useThrottle';
export {default as useObject} from './useObject';
export {default as usePrevious} from './usePrevious';
export {default as useTimeout} from './useTimeout';
export {default as useTimeout} from './useTimeout';
1 change: 0 additions & 1 deletion src/hooks/useClickOutside/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@
*/

import {useClickOutside} from './useClickOutside';
export {ClickOutside, ClickOutsideOverride} from './useClickOutside';
export default useClickOutside;
28 changes: 3 additions & 25 deletions src/hooks/useClickOutside/useClickOutside.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
* limitations under the License.
*/

import React, {useRef, useCallback, useContext} from 'react';
import {func, node} from 'prop-types';
import {useRef, useCallback, useContext} from 'react';
import {_document} from 'utility/mocks';
import useEventListener from '../useEventListener';
import OverrideContext from './useClickOutside.context';
Expand All @@ -39,6 +38,8 @@ import OverrideContext from './useClickOutside.context';
* element (for example, when dragging). In such cases the click is still considered as an inside click,
* since it originated inside the element.
*
* For class components use ClickOutside from 'webrix/tools/ClickOutside'
*
* @param {Function} callback
*/
export const useClickOutside = callback => {
Expand All @@ -57,26 +58,3 @@ export const useClickOutside = callback => {
isClickedInside.current = true;
}, [isClickedInside]);
};

// Use this for class components
export const ClickOutside = ({children, onClickOutside}) => {
const handleOnMouseDownCapture = useClickOutside(onClickOutside);
// We're updating the contained element instead of adding a wrapper since adding
// a wrapper can may affect the styling/behavior
return React.cloneElement(
React.Children.only(children), {onMouseDownCapture: handleOnMouseDownCapture}
);
};

// It is sometimes necessary to modify the condition of the click-outside handler
// of one or more elements. This can be done using the ClickOutsideOverride
export const ClickOutsideOverride = ({condition, children}) => (
<OverrideContext.Provider value={condition}>
{children}
</OverrideContext.Provider>
);

ClickOutsideOverride.propTypes = {
condition: func,
children: node,
};
16 changes: 2 additions & 14 deletions src/hooks/useClickOutside/useClickOutside.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import React from 'react';
// https://reactjs.org/docs/hooks-faq.html#how-to-test-components-that-use-hooks
import {act} from 'react-dom/test-utils';
import sinon from 'sinon';
import {mount, shallow} from 'enzyme';
import OverrideContext from './useClickOutside.context';
import {useClickOutside, ClickOutside, ClickOutsideOverride} from './useClickOutside';
import {mount} from 'enzyme';
import {useClickOutside} from './useClickOutside';

const Elem = callback => {
useClickOutside(callback);
Expand Down Expand Up @@ -33,15 +32,4 @@ describe('useClickOutside()', () => {
elem.simulate('click');
expect(callback.callCount).toEqual(0);
});

it('<ClickOutside/>', () => {
const wrapper = shallow(<ClickOutside><div/></ClickOutside>);
expect(() => shallow(<ClickOutside/>)).toThrow();
expect(typeof wrapper.find('div').prop('onMouseDownCapture')).toBe('function');
});

it('<ClickOutsideOverride/>', () => {
const wrapper = shallow(<ClickOutsideOverride/>);
expect(wrapper.find(OverrideContext.Provider)).toHaveLength(1);
});
});
2 changes: 0 additions & 2 deletions src/hooks/useDimensions/readme.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
* limitations under the License.
*/

import useDimensions from './useDimensions';
import useResizeObserver from './useResizeObserver';

export default useDimensions;
export default useResizeObserver;
2 changes: 2 additions & 0 deletions src/hooks/useResizeObserver/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
See the full documentation of `useResizeObserver` at the
[Official Webrix Documentation Site](https://webrix.amdocs.com/docs/hooks/useResizeObserver)
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React from 'react';
import {act} from 'react-dom/test-utils';
import {mount} from 'enzyme';
import useDimensions, {__RewireAPI__ as rewireAPI} from './useDimensions';
import useResizeObserver, {__RewireAPI__ as rewireAPI} from './useResizeObserver';

const Elem = () => {
const {width, height} = useDimensions({current: {}});
const {width, height} = useResizeObserver({current: {}});
return (
<div>{width},{height}</div>
);
};

describe('useDimensions()', () => {
describe('useResizeObserver()', () => {
it('Should return the previous value', async () => {
let wrapper = null;
let observed = 0, disconnected = 0;
Expand Down
42 changes: 42 additions & 0 deletions src/tools/ClickOutside/ClickOutside.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (c) 2020, Amdocs Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import React from 'react';
import {func, node} from 'prop-types';
import OverrideContext from 'hooks/useClickOutside/useClickOutside.context';
import {useClickOutside} from 'hooks';

export const ClickOutside = ({children, onClickOutside}) => {
const handleOnMouseDownCapture = useClickOutside(onClickOutside);
// We're updating the contained element instead of adding a wrapper since adding
// a wrapper can may affect the styling/behavior
return React.cloneElement(
React.Children.only(children), {onMouseDownCapture: handleOnMouseDownCapture}
);
};

// It is sometimes necessary to modify the condition of the click-outside handler
// of one or more elements. This can be done using the ClickOutsideOverride
export const ClickOutsideOverride = ({condition, children}) => (
<OverrideContext.Provider value={condition}>
{children}
</OverrideContext.Provider>
);

ClickOutsideOverride.propTypes = {
condition: func,
children: node,
};
Loading

0 comments on commit 2dfa264

Please sign in to comment.