Skip to content

Commit

Permalink
fix(): Added support for SSR
Browse files Browse the repository at this point in the history
  • Loading branch information
ykadosh committed May 25, 2021
1 parent 51fc97e commit 2a576f0
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 12 deletions.
7 changes: 4 additions & 3 deletions src/components/Poppable/Poppable.props.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@

import {node, func, shape, number, instanceOf, oneOfType} from 'prop-types';
import {noop} from 'utility/memory';
import {DOMRect, Element, _window, _document} from 'utility/mocks';
import strategy from './strategies';
import {HIDDEN_PLACEMENT} from './Poppable.constants';

export const propTypes = {
container: oneOfType([
func,
shape({current: oneOfType([instanceOf(Element), instanceOf(window.constructor)])}),
shape({current: oneOfType([instanceOf(Element), instanceOf(_window.constructor)])}),
]),
reference: oneOfType([
func,
Expand All @@ -41,8 +42,8 @@ export const propTypes = {
};

export const defaultProps = {
container: window,
reference: document.body,
container: _window,
reference: _document.body,
placements: () => [{top: 0, left: 0}],
placement: HIDDEN_PLACEMENT,
overflow: strategy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import React from 'react';
import {oneOfType, node, func, shape, instanceOf} from 'prop-types';
import {Element} from 'utility/mocks';
import Movable from '../../../Movable';
import {onUpdate} from './HorizontalScrollbar.utils';
import './HorizontalScrollbar.scss';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import React from 'react';
import {oneOfType, node, func, shape, instanceOf} from 'prop-types';
import Movable from '../../../Movable';
import {onUpdate} from './VerticalScrollbar.utils';
import {Element} from 'utility/mocks';
import './VerticalScrollbar.scss';

export default class VerticalScrollbar extends React.PureComponent {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Stackable/Stackable.props.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import {instanceOf, node, shape, number} from 'prop-types';
import {_document, Element} from 'utility/mocks';

export const propTypes = {
zIndex: number,
Expand All @@ -25,7 +26,7 @@ export const propTypes = {

export const defaultProps = {
zIndex: null,
target: document.body,
target: _document.body,
parent: {},
children: null,
};
3 changes: 2 additions & 1 deletion src/hooks/useDimensions/useDimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@

import {useState, useRef, useEffect} from 'react';
import {readResizeObserverEntry} from 'utility/rect';
import {ResizeObserver} from 'utility/mocks';

export default ref => {
const [dimensions, setDimensions] = useState({width: 0, height: 0});
const observer = useRef(new window.ResizeObserver(entries => {
const observer = useRef(new ResizeObserver(entries => {
setDimensions(readResizeObserverEntry(entries[0]));
}));
useEffect(() => {
Expand Down
7 changes: 4 additions & 3 deletions src/hooks/useDimensions/useDimensions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import {act} from 'react-dom/test-utils';
import {expect} from 'chai';
import {mount} from 'enzyme';
import useDimensions from './useDimensions';
import useDimensions, {__RewireAPI__ as rewireAPI} from './useDimensions';

const Elem = () => {
const {width, height} = useDimensions({current: {}});
Expand All @@ -15,10 +15,10 @@ describe('useDimensions()', () => {
it('Should return the previous value', async () => {
let wrapper = null;
let observed = 0, disconnected = 0;
window.ResizeObserver = class {
rewireAPI.__Rewire__('ResizeObserver', class {
disconnect = () => disconnected++;
observe = () => observed++;
};
});
act(() => {wrapper = mount(<Elem/>)});
expect(wrapper.text()).to.eql('0,0');
expect(observed).to.eql(1);
Expand All @@ -27,5 +27,6 @@ describe('useDimensions()', () => {
act(() => {wrapper.unmount()});
expect(observed).to.eql(1);
expect(disconnected).to.eql(1);
rewireAPI.__ResetDependency__('ResizeObserver');
});
});
3 changes: 2 additions & 1 deletion src/tools/ResizeObserver/ResizeObserver.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ import React, {useEffect, useRef} from 'react';
import {node, func} from 'prop-types';
import {copyComponentRef} from 'utility/react';
import {readResizeObserverEntry} from 'utility/rect';
import {ResizeObserver as NativeResizeObserver} from 'utility/mocks';
import {noop} from 'utility/memory';

const ResizeObserver = ({children, onResize}) => {
const child = React.Children.only(children);
const ref = useRef();
const observer = useRef(new window.ResizeObserver(entries => {
const observer = useRef(new NativeResizeObserver(entries => {
onResize(readResizeObserverEntry(entries[0]));
}));
useEffect(() => {
Expand Down
7 changes: 4 additions & 3 deletions src/tools/ResizeObserver/ResizeObserver.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import {mount} from 'enzyme';
import {act} from 'react-dom/test-utils';
import {expect} from 'chai';
import sinon from 'sinon';
import ResizeObserver from './ResizeObserver';
import ResizeObserver, {__RewireAPI__ as rewireAPI} from './ResizeObserver';

describe('<ResizeObserver>', () => {
describe('HTML structure', () => {
it('should render ResizeObserver', () => {
let observed = 0, disconnected = 0;
window.ResizeObserver = class {
rewireAPI.__Rewire__('NativeResizeObserver', class {
disconnect = () => disconnected++;
observe = () => observed++;
};
});

const handleOnResize = sinon.spy();
const wrapper = mount(<ResizeObserver onResize={handleOnResize}><div style={{width: 100}}/></ResizeObserver>);
Expand All @@ -22,6 +22,7 @@ describe('<ResizeObserver>', () => {
act(() => {wrapper.unmount()});
expect(observed).to.eql(1);
expect(disconnected).to.eql(1);
rewireAPI.__ResetDependency__('NativeResizeObserver');
});
});
});
1 change: 1 addition & 0 deletions src/utility/mocks/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './mocks';
10 changes: 10 additions & 0 deletions src/utility/mocks/mock.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {_document, _window, Element, DOMRect, ResizeObserver} from './mocks';
import {expect} from 'chai';

it('Mock', () => {
expect(_window).to.eql(global.window);
expect(_document).to.eql(global.document);
expect(Element).to.eql(global.window.Element);
expect(DOMRect).to.eql(global.window.DOMRect);
expect(ResizeObserver).to.eql(global.window.ResizeObserver);
});
37 changes: 37 additions & 0 deletions src/utility/mocks/mocks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* 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.
*/

/**
* All the exports in this file provide a fallback when components are rendered in
* non-browser environments (i.e. server) and the window object is not defined.
* This is only an issue when the code is accessing the window statically (like in
* propTypes) or during the initial render. Any further runtime access to the window
* object is OK since that code is only executed in the browser.
*/

export const fallback = (a, b) => (
typeof window !== 'undefined' ? a : b
);

export const _window = fallback(window, {});

export const _document = fallback(document, {});

export const ResizeObserver = fallback(window.ResizeObserver, function ResizeObserver() {});

export const DOMRect = fallback(window.DOMRect, function DOMRect() {});

export const Element = fallback(window.Element, function Element() {});

0 comments on commit 2a576f0

Please sign in to comment.