Skip to content

Commit

Permalink
Merge pull request #1870 from kodai3/pr/use-orientation-ssr
Browse files Browse the repository at this point in the history
Fix useOrientation on SSR
  • Loading branch information
xobotyi authored Mar 10, 2021
2 parents 0cb08ba + 72f4cb9 commit e2ccb62
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/useOrientation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ const defaultState: OrientationState = {
};

const useOrientation = (initialState: OrientationState = defaultState) => {
const screen = window.screen;
const [state, setState] = useState(initialState);

useEffect(() => {
const screen = window.screen;
let mounted = true;

const onChange = () => {
Expand All @@ -25,7 +25,7 @@ const useOrientation = (initialState: OrientationState = defaultState) => {
if (orientation) {
const { angle, type } = orientation;
setState({ angle, type });
} else if (window.orientation) {
} else if (window.orientation !== undefined) {
setState({
angle: typeof window.orientation === 'number' ? window.orientation : 0,
type: '',
Expand Down
87 changes: 87 additions & 0 deletions tests/useOrientation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { act, renderHook } from "@testing-library/react-hooks";
import { replaceRaf } from "raf-stub";
import useOrientation from "../src/useOrientation";

declare var requestAnimationFrame: {
reset: () => void;
step: (steps?: number, duration?: number) => void;
};

describe('useOrientation', () => {
beforeAll(() => {
replaceRaf();
});

beforeEach(() => {
(window.screen.orientation as object) = {
type: 'landscape-primary',
angle: 0,
};
(window.orientation as number) = 0;
})

afterEach(() => {
requestAnimationFrame.reset();
});

it('should be defined', () => {
expect(useOrientation).toBeDefined();
});

function getHook(...args) {
return renderHook(() => useOrientation(...args));
}

function triggerOrientation(type: string, angle: number) {
(window.screen.orientation.type as string) = type;
(window.screen.orientation.angle as number) = angle;

window.dispatchEvent(new Event('orientationchange'));
}

it('should return current window orientation', () => {
const hook = getHook();

expect(typeof hook.result.current).toBe('object');
expect(typeof hook.result.current.type).toBe('string');
expect(typeof hook.result.current.angle).toBe('number');
});

it('should use initial values in case of no parameters', () => {
const hook = getHook();

expect(hook.result.current.type).toBe('landscape-primary');
expect(hook.result.current.angle).toBe(0);
});

it("should re-render after orientation change on closest RAF", () => {
const hook = getHook();

act(() => {
triggerOrientation('portrait-secondary', 180);
requestAnimationFrame.step();
});

expect(hook.result.current.type).toBe('portrait-secondary');
expect(hook.result.current.angle).toBe(180);
});

it('should return window.orientation number if window.screen.orientation is missing', () => {
(window.screen.orientation as unknown) = undefined;

const hook = getHook();

expect(hook.result.current.type).toBe('');
expect(hook.result.current.angle).toBe(0);
});

it('should return 0 if window.orientation is not a number and if window.screen.orientation is missing', () => {
(window.screen.orientation as unknown) = undefined;
(window.orientation as unknown) = null;

const hook = getHook();

expect(hook.result.current.type).toBe('');
expect(hook.result.current.angle).toBe(0);
})
});

0 comments on commit e2ccb62

Please sign in to comment.