-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0afd1e0
commit 1a7400c
Showing
17 changed files
with
5,495 additions
and
4,216 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
**/.rush/* | ||
**/node_modules/* | ||
|
||
**/coverage/* | ||
|
||
**/dist/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module.exports = { | ||
extends: ['@priceline', '@priceline/eslint-config/jsx-a11y'], | ||
parserOptions: { tsconfigRootDir: __dirname }, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# pcln-media-query-match | ||
|
||
MediaQueryMatch is a React component that is used to conditionally render children based on if a media query matches or not. | ||
|
||
Supported Breakpoints: | ||
|
||
| Name | Width in `em`s | Width in `px` | | ||
| ---- | -------------- | ------------- | | ||
| xs | 20em | 320px | | ||
| sm | 32em | 512px | | ||
| md | 40em | 640px | | ||
| lg | 48em | 768px | | ||
| xl | 64em | 1024px | | ||
| xxl | 80em | 1280px | | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = { presets: ['@priceline'] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
module.exports = { | ||
collectCoverageFrom: [ | ||
'<rootDir>/src/**/*.js', | ||
'!<rootDir>/src/**/*.stories.js', | ||
], | ||
moduleDirectories: ['node_modules', 'test'], | ||
reporters: ['jest-standard-reporter'], | ||
setupFilesAfterEnv: ['./test/jest.setup.js'], | ||
testMatch: ['<rootDir>/src/**/*.spec.js'], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
{ | ||
"name": "pcln-media-query-match", | ||
"version": "1.0.0", | ||
"description": "Conditionally render React components based on media queries", | ||
"scripts": { | ||
"start": "start-storybook", | ||
"build:babel:cjs": "cross-env NODE_ENV=production BABEL_ENV=cjs babel ./src --ignore '**/*.stories.js,**/*.spec.js' --out-dir ./dist/cjs", | ||
"build:babel:esm": "cross-env NODE_ENV=production BABEL_ENV=esm babel ./src --ignore '**/*.stories.js,**/*.spec.js' --out-dir ./dist/esm", | ||
"build:babel:es": "cross-env NODE_ENV=production BABEL_ENV=es babel ./src --ignore '**/*.stories.js,**/*.spec.js' --out-dir ./dist/es", | ||
"build": "run-p build:babel:*", | ||
"test": "jest", | ||
"test:ci": "jest --runInBand", | ||
"test:changed": "jest -o", | ||
"test:watch": "jest --watch", | ||
"postpublish": "slack-component-publish", | ||
"lint": "eslint ." | ||
}, | ||
"main": "dist/cjs/index.js", | ||
"module": "dist/esm/index.js", | ||
"license": "MIT", | ||
"author": "Steven Dalonzo", | ||
"files": [ | ||
"dist/" | ||
], | ||
"devDependencies": { | ||
"@babel/cli": "^7.12.1", | ||
"@babel/core": "^7.12.3", | ||
"@babel/runtime": "^7.12.3", | ||
"@babel/plugin-transform-react-jsx": "^7.12.5", | ||
"@priceline/babel-preset": "^0.0.1", | ||
"@priceline/eslint-config": "^0.0.1", | ||
"@compositor/kit": "^1.0.47", | ||
"@mdx-js/loader": "^1.5.7", | ||
"@storybook/addon-actions": "^5.3.14", | ||
"@storybook/react": "^5.3.14", | ||
"@testing-library/jest-dom": "^5.11.5", | ||
"@testing-library/react": "^9.5.0", | ||
"acorn": "^7.1.0", | ||
"babel-jest": "^26.3.0", | ||
"babel-loader": "^8.1.0", | ||
"cross-env": "^7.0.2", | ||
"jest": "^26.6.1", | ||
"jest-bamboo-reporter": "^1.2.1", | ||
"jest-standard-reporter": "^1.1.1", | ||
"jest-styled-components": "^6.3.4", | ||
"lodash": "^4.17.20", | ||
"pcln-design-system": "^4.1.2", | ||
"prop-types": "^15.7.2", | ||
"react": "^16.13.1", | ||
"react-dom": "^16.13.1", | ||
"react-responsive": "^6.1.2", | ||
"rimraf": "^3.0.2", | ||
"storybook-addon-deps": "^1.0.12", | ||
"styled-components": "^4.4.1", | ||
"eslint": "^7.13.0", | ||
"npm-run-all": "^4.1.5" | ||
}, | ||
"peerDependencies": { | ||
"@babel/runtime": "^7.8.4", | ||
"lodash": ">=4.17.15", | ||
"prop-types": "^15.7.2", | ||
"react": ">=16.9.0", | ||
"react-dom": ">=16.9.0", | ||
"react-responsive": "^6.1.1" | ||
}, | ||
"engines": { | ||
"npm": ">=6.4.1", | ||
"node": ">=10.15.3" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import React from 'react' | ||
import PropTypes from 'prop-types' | ||
import Responsive from 'react-responsive' | ||
|
||
const matchers = { | ||
xs: '20em', | ||
sm: '32em', | ||
md: '40em', | ||
lg: '48em', | ||
xl: '64em', | ||
xxl: '80em', | ||
} | ||
|
||
/** | ||
* MediaQueryMatch is a React component that is used to conditionally render provided children based on the | ||
* result of evaluating media queries. | ||
* | ||
* Supported breakpoints: | ||
* | ||
* | Name | Width in `em` | Width in `px` | | ||
* | :--------------- | :----------: | :------------------: | | ||
* | `xs` | `20em` | `320px` | | ||
* | `sm` | `32em` | `512px` | | ||
* | `md` | `40em` | `640px` | | ||
* | `lg` | `48em` | `768px` | | ||
* | `xl` | `64em` | `1024px` | | ||
* | `xxl` | `80em` | `1280px` | | ||
*/ | ||
const MediaQueryMatch = ({ minWidth, maxWidth, ignore, children, ...props }) => { | ||
if (ignore) return children | ||
|
||
if (!minWidth && !maxWidth) { | ||
return children | ||
} | ||
|
||
const minBreakpoint = minWidth && matchers[minWidth] | ||
const maxBreakpoint = maxWidth && matchers[maxWidth] | ||
const transFormedMaxBreakPoint = maxBreakpoint && `${parseInt(maxBreakpoint) - 0.01}em` | ||
|
||
return ( | ||
<Responsive minWidth={minBreakpoint} maxWidth={transFormedMaxBreakPoint} {...props}> | ||
{(matchesQuery) => matchesQuery && children} | ||
</Responsive> | ||
) | ||
} | ||
|
||
MediaQueryMatch.propTypes = { | ||
/** minimum width to mount the children */ | ||
minWidth: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl', 'xxl']), | ||
|
||
/** maximum width to mount the children */ | ||
maxWidth: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl', 'xxl']), | ||
|
||
/** if truthy, children will render regardless of match status. useful for SETI tests */ | ||
ignore: PropTypes.bool, | ||
|
||
/** conditionally rendered react children */ | ||
children: PropTypes.node, | ||
} | ||
|
||
MediaQueryMatch.defaultProps = { | ||
children: null, | ||
} | ||
|
||
export default MediaQueryMatch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import React from 'react' | ||
|
||
import { render } from '../test/react-testing' | ||
|
||
import MediaQueryMatch from '.' | ||
|
||
const targetNode = <span>TARGET</span> | ||
|
||
describe('MediaQueryMatch', () => { | ||
describe('minWidth - smaller than xs', () => { | ||
test('matches', () => { | ||
const { getByText } = render( | ||
<MediaQueryMatch maxWidth='xs' values={{ width: 319 }}> | ||
{targetNode} | ||
</MediaQueryMatch> | ||
) | ||
|
||
expect(getByText('TARGET')).toBeTruthy() | ||
}) | ||
|
||
it('should render children when not provided a minWidth or maxWidth', () => { | ||
const { getByText } = render(<MediaQueryMatch>{targetNode}</MediaQueryMatch>) | ||
|
||
expect(getByText('TARGET')).toBeTruthy() | ||
}) | ||
|
||
test('does not match', () => { | ||
const { queryByText } = render( | ||
<MediaQueryMatch maxWidth='xs' values={{ width: 320 }}> | ||
{targetNode} | ||
</MediaQueryMatch> | ||
) | ||
|
||
expect(queryByText('TARGET')).toBeFalsy() | ||
}) | ||
}) | ||
|
||
describe('maxWidth - mobile', () => { | ||
test('matches', () => { | ||
const { getByText } = render( | ||
<MediaQueryMatch maxWidth='md' values={{ width: 639 }}> | ||
{targetNode} | ||
</MediaQueryMatch> | ||
) | ||
|
||
expect(getByText('TARGET')).toBeTruthy() | ||
}) | ||
|
||
test('does not match', () => { | ||
const { queryByText } = render( | ||
<MediaQueryMatch maxWidth='md' values={{ width: 640 }}> | ||
{targetNode} | ||
</MediaQueryMatch> | ||
) | ||
|
||
expect(queryByText('TARGET')).toBeFalsy() | ||
}) | ||
}) | ||
|
||
describe('minWidth and maxWidth - slim sidebar', () => { | ||
test('does not match - smaller', () => { | ||
const { queryByText } = render( | ||
<MediaQueryMatch minWidth='xl' maxWidth='xxl' values={{ width: 1000 }}> | ||
{targetNode} | ||
</MediaQueryMatch> | ||
) | ||
|
||
expect(queryByText('TARGET')).toBeFalsy() | ||
}) | ||
|
||
test('matches', () => { | ||
const { getByText } = render( | ||
<MediaQueryMatch minWidth='xl' maxWidth='xxl' values={{ width: 1120 }}> | ||
{targetNode} | ||
</MediaQueryMatch> | ||
) | ||
|
||
expect(getByText('TARGET')).toBeTruthy() | ||
}) | ||
|
||
test('does not match - larger', () => { | ||
const { queryByText } = render( | ||
<MediaQueryMatch minWidth='xl' maxWidth='xxl' values={{ width: 1280 }}> | ||
{targetNode} | ||
</MediaQueryMatch> | ||
) | ||
|
||
expect(queryByText('TARGET')).toBeFalsy() | ||
}) | ||
}) | ||
|
||
describe('maxWidth - desktop, ignore', () => { | ||
test('matches, no ignore', () => { | ||
const { getByText } = render( | ||
<MediaQueryMatch maxWidth='xxl' values={{ width: 1000 }}> | ||
{targetNode} | ||
</MediaQueryMatch> | ||
) | ||
|
||
expect(getByText('TARGET')).toBeTruthy() | ||
}) | ||
|
||
test('does not match, no ignore', () => { | ||
const { queryByText } = render( | ||
<MediaQueryMatch maxWidth='xxl' values={{ width: 1600 }}> | ||
{targetNode} | ||
</MediaQueryMatch> | ||
) | ||
|
||
expect(queryByText('TARGET')).toBeFalsy() | ||
}) | ||
|
||
test('matches, ignore', () => { | ||
const { getByText } = render( | ||
<MediaQueryMatch maxWidth='xxl' ignore values={{ width: 1000 }}> | ||
{targetNode} | ||
</MediaQueryMatch> | ||
) | ||
|
||
expect(getByText('TARGET')).toBeTruthy() | ||
}) | ||
|
||
test('matches, ignore, no children', () => { | ||
const { queryByText } = render(<MediaQueryMatch maxWidth='xxl' ignore values={{ width: 1000 }} />) | ||
|
||
expect(queryByText('TARGET')).toBeFalsy() | ||
}) | ||
|
||
test('does not match, ignore', () => { | ||
const { getByText } = render( | ||
<MediaQueryMatch maxWidth='xxl' ignore values={{ width: 1600 }}> | ||
{targetNode} | ||
</MediaQueryMatch> | ||
) | ||
|
||
expect(getByText('TARGET')).toBeTruthy() | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.