",
7 | "license": "UNLICENSED",
8 | "scripts": {
9 | "clean": "rimraf lib/",
10 | "build": "NODE_ENV=production babel src --out-dir lib/",
11 | "test:watch": "BABEL_ENV=test jest --watch",
12 | "prepublishOnly": "npm run clean && npm test && npm run build",
13 | "test": "jest"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "https://github.com/Drawbotics/use-screen-size"
18 | },
19 | "publishConfig": {
20 | "access": "public",
21 | "registry": "https://npm.pkg.github.com/"
22 | },
23 | "husky": {
24 | "hooks": {
25 | "pre-commit": "lint-staged"
26 | }
27 | },
28 | "lint-staged": {
29 | "*.{js,jsx}": "eslint --format node_modules/eslint-formatter-pretty --max-warnings=0"
30 | },
31 | "peerDependencies": {
32 | "@drawbotics/drylus-style-vars": "^4",
33 | "react": "^16.8.x"
34 | },
35 | "devDependencies": {
36 | "@babel/cli": "^7.6.0",
37 | "@babel/core": "^7.6.0",
38 | "@babel/plugin-proposal-export-default-from": "^7.5.2",
39 | "@babel/preset-env": "^7.6.0",
40 | "@babel/preset-react": "^7.0.0",
41 | "@drawbotics/drylus-style-vars": "^4.0.0-alpha.4",
42 | "babel-eslint": "^10.0.3",
43 | "babel-jest": "^24.9.0",
44 | "eslint": "^6.4.0",
45 | "eslint-formatter-pretty": "^2.1.1",
46 | "eslint-plugin-jest": "^22.17.0",
47 | "eslint-plugin-react": "^7.14.3",
48 | "eslint-plugin-react-hooks": "^2.0.1",
49 | "husky": "^3.0.5",
50 | "jest": "^24.9.0",
51 | "lint-staged": "^9.2.5",
52 | "react": "^16.9.0",
53 | "react-dom": "^16.9.0",
54 | "react-test-renderer": "^16.9.0"
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/__tests__/get-screen-size.test.js:
--------------------------------------------------------------------------------
1 | import getScreenSize from '../get-screen-size';
2 |
3 |
4 | describe('get-screen-size', () => {
5 | let originalWidth;
6 |
7 | const SCREEN_MINISCULE = 100;
8 | const SCREEN_XS = 320;
9 | const SCREEN_S = 375;
10 | const SCREEN_M = 425;
11 | const SCREEN_L = 768;
12 | const SCREEN_XL = 1024;
13 | const SCREEN_HUGE = 1200;
14 | const SCREEN_MASSIVE = 3000;
15 |
16 | beforeAll(() => {
17 | originalWidth = window.innerWidth;
18 | });
19 |
20 | afterEach(() => {
21 | window.innerWidth = originalWidth;
22 | });
23 |
24 | it('correctly matches an extra small screen', () => {
25 | window.innerWidth = SCREEN_XS;
26 |
27 | const screenSize = getScreenSize();
28 | expect(screenSize).toEqual(1);
29 | });
30 |
31 | it('correctly matches a small screen', () => {
32 | window.innerWidth = SCREEN_S;
33 |
34 | const screenSize = getScreenSize();
35 | expect(screenSize).toEqual(2);
36 | });
37 |
38 | it('correctly matches an medium screen', () => {
39 | window.innerWidth = SCREEN_M;
40 |
41 | const screenSize = getScreenSize();
42 | expect(screenSize).toEqual(3);
43 | });
44 |
45 | it('correctly matches a large screen', () => {
46 | window.innerWidth = SCREEN_L;
47 |
48 | const screenSize = getScreenSize();
49 | expect(screenSize).toEqual(4);
50 | });
51 |
52 | it('correctly matches an extra large screen', () => {
53 | window.innerWidth = SCREEN_XL;
54 |
55 | const screenSize = getScreenSize();
56 | expect(screenSize).toEqual(5);
57 | });
58 |
59 | it('correctly matches a huge screen', () => {
60 | window.innerWidth = SCREEN_HUGE;
61 |
62 | const screenSize = getScreenSize();
63 | expect(screenSize).toBeGreaterThan(5);
64 | });
65 |
66 | it('it correctly matches a miniscule screen', () => {
67 | window.innerWidth = SCREEN_MINISCULE;
68 |
69 | const screenSize = getScreenSize();
70 | expect(screenSize).toEqual(1);
71 | });
72 |
73 | it('it matches a massive screen', () => {
74 | window.innerWidth = SCREEN_MASSIVE;
75 |
76 | const screenSize = getScreenSize();
77 | expect(screenSize).toBeGreaterThan(5);
78 | });
79 | });
80 |
--------------------------------------------------------------------------------
/src/__tests__/use-screen-size.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { act } from 'react-dom/test-utils';
4 |
5 | import useScreenSize from '../use-screen-size';
6 |
7 |
8 | const TestComponent = () => {
9 | const { screenSize, ScreenSizes } = useScreenSize();
10 |
11 | if (screenSize === ScreenSizes.M) {
12 | return mediumOnlyContent
;
13 | }
14 | else if (screenSize >= ScreenSizes.M && screenSize <= ScreenSizes.XL) {
15 | return betweenMediumAndXLContent
;
16 | }
17 | else if (screenSize <= ScreenSizes.S) {
18 | return smallContent
;
19 | }
20 | else if (screenSize > ScreenSizes.XL) {
21 | return largerThanHugeContent
;
22 | }
23 | else {
24 | return defaultContent
25 | }
26 | };
27 |
28 |
29 | describe('use-screen-size', () => {
30 | let container;
31 | let originalWidth;
32 |
33 | const SCREEN_XS = 320;
34 | const SCREEN_S = 375;
35 | const SCREEN_M = 425;
36 | const SCREEN_L = 768;
37 | const SCREEN_HUGE = 1200;
38 |
39 | beforeEach(() => {
40 | container = document.createElement('div');
41 | document.body.appendChild(container);
42 | originalWidth = window.innerWidth;
43 | });
44 |
45 | afterEach(() => {
46 | document.body.removeChild(container);
47 | container = null;
48 | window.innerWidth = originalWidth;
49 | });
50 |
51 | it('renders content for screens smaller and equal to S', () => {
52 | window.innerWidth = SCREEN_XS;
53 |
54 | act(() => { ReactDOM.render(, container) });
55 |
56 | const rootDiv = container.querySelector('div');
57 | expect(rootDiv.textContent).toBe('smallContent');
58 | });
59 |
60 | it('renders content for screens equal to M size (between S (excl) and M (incl) when size is M', () => {
61 | window.innerWidth = SCREEN_M;
62 |
63 | act(() => { ReactDOM.render(, container) });
64 |
65 | const rootDiv = container.querySelector('div');
66 | expect(rootDiv.textContent).toBe('mediumOnlyContent');
67 | });
68 |
69 | it('does not render content for screens equal to M size (between S (excl) and M (incl) when size is S', () => {
70 | window.innerWidth = SCREEN_S;
71 |
72 | act(() => { ReactDOM.render(, container) });
73 |
74 | const rootDiv = container.querySelector('div');
75 | expect(rootDiv.textContent).not.toBe('mediumOnlyContent');
76 | });
77 |
78 | it('renders content between two sizes', () => {
79 | window.innerWidth = SCREEN_L;
80 |
81 | act(() => { ReactDOM.render(, container) });
82 |
83 | const rootDiv = container.querySelector('div');
84 | expect(rootDiv.textContent).toBe('betweenMediumAndXLContent');
85 | });
86 |
87 | it('renders content for huge screens', () => {
88 | window.innerWidth = SCREEN_HUGE;
89 |
90 | act(() => { ReactDOM.render(, container) });
91 |
92 | const rootDiv = container.querySelector('div');
93 | expect(rootDiv.textContent).toBe('largerThanHugeContent');
94 | });
95 | });
96 |
--------------------------------------------------------------------------------
/src/get-screen-size.js:
--------------------------------------------------------------------------------
1 | import sv from '@drawbotics/drylus-style-vars';
2 |
3 |
4 | function _parseMaxWidth(mediaQuery) {
5 | const [ , maxWidth ] = mediaQuery.match(/max-width: (\d+)/);
6 | return parseInt(maxWidth);
7 | }
8 |
9 |
10 | function _parseMinWidth(mediaQuery) {
11 | const [ , minWidth ] = mediaQuery.match(/min-width: (\d+)/);
12 | return parseInt(minWidth);
13 | }
14 |
15 |
16 | export default function getScreenSize() {
17 | if (window.innerWidth <= _parseMaxWidth(sv.screenXs)) {
18 | return 1;
19 | }
20 | else if (window.innerWidth <= _parseMaxWidth(sv.screenS)) {
21 | return 2;
22 | }
23 | else if (window.innerWidth <= _parseMaxWidth(sv.screenM)) {
24 | return 3;
25 | }
26 | else if (window.innerWidth <= _parseMaxWidth(sv.screenL)) {
27 | return 4;
28 | }
29 | else if (window.innerWidth <= _parseMaxWidth(sv.screenXl)) {
30 | return 5;
31 | }
32 | else if (window.innerWidth > _parseMinWidth(sv.screenHuge)) {
33 | return window.innerWidth;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export useScreenSize from './use-screen-size';
2 | export getScreenSize from './get-screen-size';
3 |
--------------------------------------------------------------------------------
/src/use-screen-size.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react';
2 |
3 | import getScreenSize from './get-screen-size';
4 |
5 |
6 | const ScreenSizes = {
7 | XS: 1,
8 | S: 2,
9 | M: 3,
10 | L: 4,
11 | XL: 5,
12 | };
13 |
14 |
15 | export default function useScreenSize() {
16 | const [ size, setSize ] = useState(getScreenSize());
17 |
18 | useEffect(() => {
19 | const handleResize = () => {
20 | setSize(getScreenSize());
21 | };
22 |
23 | window.addEventListener('resize', handleResize);
24 | return () => {
25 | window.removeEventListener('resize', handleResize);
26 | };
27 | }, []);
28 |
29 | return { screenSize: size, ScreenSizes };
30 | }
31 |
--------------------------------------------------------------------------------