Skip to content
This repository was archived by the owner on Jun 20, 2022. It is now read-only.

Commit b3cf968

Browse files
authored
Merge pull request #5 from smooth-code/breakpoints
feat: add up, down and between
2 parents b95f68d + 883edb6 commit b3cf968

File tree

12 files changed

+1473
-751
lines changed

12 files changed

+1473
-751
lines changed

.babelrc

Lines changed: 0 additions & 15 deletions
This file was deleted.

.babelrc.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const config = {
2+
presets: [
3+
['@babel/preset-env', { loose: true, modules: false }],
4+
'@babel/preset-react',
5+
],
6+
plugins: [
7+
'@babel/plugin-proposal-object-rest-spread',
8+
['@babel/plugin-proposal-class-properties', { loose: true }],
9+
],
10+
}
11+
12+
if (process.env.NODE_ENV === 'lib') {
13+
module.exports = Object.assign({}, config, {
14+
plugins: [
15+
...config.plugins,
16+
['@babel/plugin-transform-modules-commonjs', { loose: true }],
17+
],
18+
})
19+
} else if (process.env.NODE_ENV === 'rollup') {
20+
module.exports = Object.assign({}, config, {
21+
plugins: [...config.plugins, '@babel/plugin-external-helpers'],
22+
})
23+
} else if (process.env.NODE_ENV === 'test') {
24+
module.exports = Object.assign({}, config, {
25+
plugins: [
26+
...config.plugins,
27+
['@babel/plugin-transform-modules-commonjs', { loose: true }],
28+
],
29+
})
30+
} else {
31+
module.exports = config
32+
}

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module.exports = {
44
parser: 'babel-eslint',
55
env: {
66
browser: true,
7+
jest: true,
78
},
89
rules: {
910
'react/jsx-filename-extension': ['error', { extensions: ['.js'] }],

jest.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
setupTestFrameworkScriptFile: './unit/setupTests.js',
3+
}

package.json

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,47 +13,54 @@
1313
"build:lib": "cross-env BABEL_ENV=lib babel --out-dir build src",
1414
"build:rollup": "cross-env BABEL_ENV=rollup rollup -c",
1515
"build:watch": "yarn build:lib --watch",
16-
"ci": "yarn lint",
16+
"ci": "yarn lint && yarn test",
1717
"deploy:docs": "firebase deploy",
1818
"dev": "styleguidist server",
1919
"lint": "eslint .",
2020
"prebuild": "shx rm -rf build",
21-
"release": "standard-version && conventional-github-releaser -p angular && yarn build && yarn deploy:docs"
21+
"release": "standard-version && conventional-github-releaser -p angular && yarn build && yarn deploy:docs",
22+
"test": "jest"
2223
},
2324
"devDependencies": {
24-
"babel-cli": "^6.26.0",
25-
"babel-core": "^6.26.0",
26-
"babel-eslint": "^8.2.2",
27-
"babel-loader": "^7.1.4",
28-
"babel-plugin-external-helpers": "^6.22.0",
29-
"babel-plugin-transform-class-properties": "^6.24.1",
30-
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
31-
"babel-plugin-transform-object-rest-spread": "^6.26.0",
32-
"babel-preset-env": "^1.6.1",
33-
"babel-preset-react": "^6.24.1",
25+
"@babel/cli": "^7.0.0-beta.46",
26+
"@babel/core": "^7.0.0-beta.46",
27+
"@babel/plugin-external-helpers": "^7.0.0-beta.46",
28+
"@babel/plugin-proposal-class-properties": "^7.0.0-beta.46",
29+
"@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.46",
30+
"@babel/plugin-transform-modules-commonjs": "^7.0.0-beta.46",
31+
"@babel/preset-env": "^7.0.0-beta.46",
32+
"@babel/preset-react": "^7.0.0-beta.46",
33+
"babel-core": "^7.0.0-0",
34+
"babel-eslint": "^8.2.3",
35+
"babel-jest": "^22.4.3",
36+
"babel-loader": "^8.0.0-beta.2",
3437
"conventional-github-releaser": "^2.0.2",
3538
"cross-env": "^5.1.4",
39+
"enzyme": "^3.3.0",
40+
"enzyme-adapter-react-16": "^1.1.1",
3641
"eslint": "^4.19.1",
3742
"eslint-config-airbnb": "^16.1.0",
3843
"eslint-config-prettier": "^2.9.0",
39-
"eslint-plugin-import": "^2.10.0",
44+
"eslint-plugin-import": "^2.11.0",
4045
"eslint-plugin-jsx-a11y": "^6.0.3",
4146
"eslint-plugin-react": "^7.7.0",
4247
"jest": "^22.4.3",
43-
"react": "^16.3.0",
44-
"react-dom": "^16.3.0",
45-
"react-styleguidist": "^7.0.1",
46-
"rollup": "^0.57.1",
47-
"rollup-plugin-babel": "^3.0.3",
48+
"jest-styled-components": "^5.0.1",
49+
"react": "^16.3.2",
50+
"react-dom": "^16.3.2",
51+
"react-styleguidist": "^7.0.8",
52+
"react-test-renderer": "^16.3.2",
53+
"rollup": "^0.58.2",
54+
"rollup-plugin-babel": "^4.0.0-beta.4",
4855
"rollup-plugin-commonjs": "^9.1.0",
4956
"rollup-plugin-node-resolve": "^3.3.0",
5057
"rollup-plugin-replace": "^2.0.0",
5158
"rollup-plugin-uglify": "^3.0.0",
5259
"shx": "^0.2.2",
5360
"standard-version": "^4.3.0",
54-
"styled-components": "^3.2.5",
55-
"uglifyjs-webpack-plugin": "^1.2.4",
56-
"webpack": "^4.4.1"
61+
"styled-components": "^3.2.6",
62+
"uglifyjs-webpack-plugin": "^1.2.5",
63+
"webpack": "^4.6.0"
5764
},
5865
"dependencies": {
5966
"classnames": "^2.2.5",

src/Col.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function generateBreakPoint(breakpoint) {
1414
width: 100%;
1515
min-height: 1px;
1616
17-
@media (min-width: ${props => props.theme.breakPoints[breakpoint]}px) {
17+
@media (min-width: ${props => props.theme.breakpoints[breakpoint]}px) {
1818
flex-basis: 0;
1919
flex-grow: 1;
2020
max-width: 100%;
@@ -37,7 +37,7 @@ function generateBreakPoint(breakpoint) {
3737
min-height: 1px;
3838
3939
@media (min-width: ${props =>
40-
props.theme.breakPoints[breakpoint]}px) {
40+
props.theme.breakpoints[breakpoint]}px) {
4141
flex: 0 0 ${width};
4242
max-width: ${width === 'auto' ? 'none' : width};
4343
${width === 'auto' ? 'width: auto;' : ''}
@@ -74,7 +74,7 @@ const ColComponent = ({ className, xs, sm, md, lg, xl, theme, ...props }) => (
7474
const Col = styled(handleRef(ColComponent))`
7575
padding-left: 15px;
7676
padding-right: 15px;
77-
${props => Object.keys(props.theme.breakPoints).map(generateBreakPoint)};
77+
${props => Object.keys(props.theme.breakpoints).map(generateBreakPoint)};
7878
`
7979

8080
Col.propTypes = {

src/style/defaultBreakpoints.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default {
2+
xs: 0,
3+
sm: 576,
4+
md: 768,
5+
lg: 992,
6+
xl: 1200,
7+
}

src/style/defaultTheme.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
parseToRgb,
99
mix,
1010
} from 'polished'
11+
import defaultBreakpoints from './defaultBreakpoints'
1112
import { th, mixin } from '../utils'
1213

1314
/* eslint-disable no-unused-expressions */
@@ -173,13 +174,7 @@ export const transitionBase = 'all .2s ease-in-out'
173174

174175
// Breakpoints
175176

176-
export const breakPoints = {
177-
xs: 0,
178-
sm: 576,
179-
md: 768,
180-
lg: 992,
181-
xl: 1200,
182-
}
177+
export const breakpoints = defaultBreakpoints
183178

184179
// Color levels
185180

src/utils.js

Lines changed: 84 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,91 @@
11
import { css } from 'styled-components'
2-
import { breakPoints as defaultBreakPoints } from './style/defaultTheme'
2+
import defaultBreakpoints from './style/defaultBreakpoints'
33

4-
const getBreakPoints = props =>
5-
(props.theme && props.theme.breakPoints) || defaultBreakPoints
4+
export const getBreakpoints = props =>
5+
(props && props.theme && props.theme.breakpoints) || defaultBreakpoints
66

7-
export const upTo = (breakPoint, code) => css`
8-
@media (min-width: ${props => getBreakPoints(props)[breakPoint]}px) {
9-
${code};
7+
export const getBreakpointsEntries = props => {
8+
const breakpoints = getBreakpoints(props)
9+
const entries = Object.keys(breakpoints).reduce(
10+
(entries, key) => [...entries, [key, breakpoints[key]]],
11+
[],
12+
)
13+
return entries.sort((a, b) => a[1] > b[1])
14+
}
15+
16+
export const getNextBreakpoint = (name, props) => {
17+
const entries = getBreakpointsEntries(props)
18+
const index = entries.findIndex(([key]) => key === name)
19+
return index < entries.length - 1 ? entries[index + 1][0] : null
20+
}
21+
22+
export const getPreviousBreakpoint = (name, props) => {
23+
const entries = getBreakpointsEntries(props)
24+
const index = entries.findIndex(([key]) => key === name)
25+
return index >= 1 ? entries[index - 1][0] : null
26+
}
27+
28+
/**
29+
* Minimum breakpoint width.
30+
* Null for the smallest breakpoint.
31+
*/
32+
export const getBreakpointMin = (name, props) => {
33+
const breakpoints = getBreakpoints(props)
34+
const breakPoint = breakpoints[name]
35+
return breakPoint !== 0 ? breakPoint : null
36+
}
37+
38+
/**
39+
* Maximum breakpoint width. Null for the largest (last) breakpoint.
40+
* The maximum value is calculated as the minimum of the next one less 0.02px
41+
* to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.
42+
* See https://www.w3.org/TR/mediaqueries-4/#mq-min-max
43+
* Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.
44+
* See https://bugs.webkit.org/show_bug.cgi?id=178261
45+
*/
46+
export const getBreakpointMax = (name, props) => {
47+
const next = getNextBreakpoint(name, props)
48+
return next ? getBreakpointMin(next, props) - 0.02 : null
49+
}
50+
51+
export const up = (name, code) => props => {
52+
const value = getBreakpointMin(name, props)
53+
if (value === null) return code
54+
return css`
55+
@media (min-width: ${value}px) {
56+
${code};
57+
}
58+
`
59+
}
60+
61+
export const down = (name, code) => props => {
62+
const value = getBreakpointMax(name, props)
63+
if (value === null) return code
64+
return css`
65+
@media (max-width: ${value}px) {
66+
${code};
67+
}
68+
`
69+
}
70+
71+
export const between = (lower, upper, code) => props => {
72+
const min = getBreakpointMin(lower, props)
73+
const max = getBreakpointMax(upper, props)
74+
const upperPrevious = getPreviousBreakpoint(upper, props)
75+
const previousMax = getBreakpointMax(upperPrevious, props)
76+
77+
if (min !== null && max !== null) {
78+
return css`
79+
@media (min-width: ${min}px) and (max-width: ${previousMax}px) {
80+
${code};
81+
}
82+
`
1083
}
11-
`
84+
if (max === null) return up(lower, code)(props)
85+
if (min === null) return down(upperPrevious, code)(props)
86+
return null
87+
}
88+
1289
export const th = (name, modifier = x => x) => props => {
1390
function run(fn) {
1491
const next = fn(props)

0 commit comments

Comments
 (0)