-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(up): remove incorrect validation when breakpoint is equal zero
- Loading branch information
Showing
2 changed files
with
184 additions
and
253 deletions.
There are no files selected for viewing
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 |
---|---|---|
@@ -1,114 +1,112 @@ | ||
const { createInvariantWithPrefix } = require('../library'); | ||
const { createInvariantWithPrefix, memoize } = require('../library'); | ||
|
||
const DEFAULT_BREAKPOINTS = { | ||
xs: '0px', | ||
sm: '576px', | ||
md: '768px', | ||
lg: '992px', | ||
xl: '1200px', | ||
xxl: '1400px', | ||
}; | ||
|
||
exports.createBreakpoints = ({ breakpoints, errorPrefix }) => { | ||
const keys = Object.keys(Object(breakpoints)); | ||
const values = Object.values(Object(breakpoints)); | ||
const entries = Object.entries(Object(breakpoints)); | ||
const invariant = createInvariantWithPrefix(errorPrefix); | ||
const ERROR_PREFIX = '[breakpoints]: '; | ||
|
||
const defaultOptions = { | ||
breakpoints: DEFAULT_BREAKPOINTS, | ||
errorPrefix: ERROR_PREFIX, | ||
}; | ||
|
||
const validation = withValidation({ | ||
invariant, | ||
exports.DEFAULT_BREAKPOINTS = DEFAULT_BREAKPOINTS; | ||
exports.ERROR_PREFIX = ERROR_PREFIX; | ||
|
||
exports.createBreakpoints = ({ breakpoints, errorPrefix } = defaultOptions) => { | ||
const names = Object.keys(breakpoints); | ||
const validation = createValidation({ | ||
names, | ||
breakpoints, | ||
keys, | ||
errorPrefix, | ||
}); | ||
|
||
return { | ||
keys, | ||
entries, | ||
invariant, | ||
...withBreakpoints({ | ||
validation, | ||
breakpoints, | ||
keys, | ||
values, | ||
}), | ||
}; | ||
}; | ||
const getValueByName = memoize((name) => { | ||
validation.checkIsValidName(name); | ||
validation.checkIsFirstName(name); | ||
|
||
function withValidation({ keys, invariant, breakpoints }) { | ||
return { | ||
throwIsInvalidName, | ||
throwIsValueIsZero, | ||
throwIsLastBreakpoint, | ||
return breakpoints[name]; | ||
}); | ||
|
||
const getNextName = (name) => { | ||
const nextIndex = names.indexOf(name) + 1; | ||
|
||
return names[nextIndex]; | ||
}; | ||
|
||
function throwIsInvalidName(name) { | ||
invariant( | ||
breakpoints[name], | ||
`breakpoint \`${name}\` not found in ${keys.join(', ')}.` | ||
); | ||
} | ||
|
||
function throwIsValueIsZero(name) { | ||
const value = breakpoints[name]; | ||
const isNotZero = parseFloat(value) !== 0; | ||
|
||
invariant( | ||
isNotZero, | ||
`\`${name}: ${value}\` cannot be assigned as minimum breakpoint.` | ||
); | ||
} | ||
|
||
function throwIsLastBreakpoint(name) { | ||
const isNotLast = name !== keys.at(-1); | ||
const validName = keys.at(-2); | ||
|
||
invariant( | ||
isNotLast, | ||
`\`${name}\` doesn't have a maximum width. Use \`${validName}\`. See https://github.com/mg901/styled-breakpoints/issues/4 .` | ||
); | ||
} | ||
} | ||
const getNextValueByName = memoize((name) => { | ||
validation.checkIsValidName(name); | ||
validation.checkIsLastName(name); | ||
|
||
return breakpoints[getNextName(name)]; | ||
}); | ||
|
||
// Maximum breakpoint width. Null for the largest (last) breakpoint. | ||
// The maximum value is calculated as the minimum of the next one less 0.02px | ||
// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths. | ||
// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max | ||
// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari. | ||
// See https://bugs.webkit.org/show_bug.cgi?id=178261 | ||
const calcMaxWidth = (value) => { | ||
return `${parseFloat(value) - 0.02}px`; | ||
}; | ||
|
||
function withBreakpoints(state) { | ||
return { | ||
up, | ||
down, | ||
between, | ||
only, | ||
up: memoize((name) => { | ||
validation.checkIsValidName(name); | ||
|
||
return breakpoints[name]; | ||
}), | ||
|
||
down: (max) => calcMaxWidth(getValueByName(max)), | ||
|
||
between: (min, max) => ({ | ||
min: getValueByName(min), | ||
max: calcMaxWidth(getValueByName(max)), | ||
}), | ||
|
||
only: (name) => ({ | ||
min: getValueByName(name), | ||
max: calcMaxWidth(getNextValueByName(name)), | ||
}), | ||
}; | ||
}; | ||
|
||
function up(min) { | ||
state.validation.throwIsInvalidName(min); | ||
|
||
return state.breakpoints[min]; | ||
} | ||
|
||
function down(max) { | ||
state.validation.throwIsInvalidName(max); | ||
state.validation.throwIsValueIsZero(max); | ||
state.validation.throwIsLastBreakpoint(max); | ||
|
||
return calcMaxWidth(state.breakpoints[max]); | ||
} | ||
|
||
function between(min, max) { | ||
return { | ||
min: up(min), | ||
max: down(max), | ||
}; | ||
} | ||
|
||
function only(name) { | ||
state.validation.throwIsInvalidName(name); | ||
state.validation.throwIsLastBreakpoint(name); | ||
const nextIndex = state.keys.indexOf(name) + 1; | ||
|
||
return { | ||
min: up(name), | ||
max: calcMaxWidth(state.values[nextIndex]), | ||
}; | ||
} | ||
} | ||
function createValidation({ names, breakpoints, errorPrefix }) { | ||
const invariant = createInvariantWithPrefix(errorPrefix); | ||
|
||
// Maximum breakpoint width. Null for the largest (last) breakpoint. | ||
// The maximum value is calculated as the minimum of the next one less 0.02px | ||
// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths. | ||
// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max | ||
// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari. | ||
// See https://bugs.webkit.org/show_bug.cgi?id=178261 | ||
function calcMaxWidth(value) { | ||
return `${parseFloat(value) - 0.02}px`; | ||
return { | ||
checkIsValidName: (name) => { | ||
invariant( | ||
breakpoints[name], | ||
`breakpoint \`${name}\` not found in ${names.join(', ')}.` | ||
); | ||
}, | ||
checkIsFirstName: (name) => { | ||
const value = breakpoints[name]; | ||
const isNotZero = parseFloat(value) !== 0; | ||
|
||
invariant( | ||
isNotZero, | ||
`\`${name}: ${value}\` cannot be assigned as minimum breakpoint.` | ||
); | ||
}, | ||
checkIsLastName: (name) => { | ||
const currentIndex = names.indexOf(name); | ||
const nextIndex = currentIndex + 1; | ||
const isNotLast = names.length !== nextIndex; | ||
const validName = names[names.length - 2]; | ||
|
||
invariant( | ||
isNotLast, | ||
`\`${name}\` doesn't have a maximum width. Use \`${validName}\`. See https://github.com/mg901/styled-breakpoints/issues/4 .` | ||
); | ||
}, | ||
}; | ||
} | ||
|
||
exports.calcMaxWidth = calcMaxWidth; |
Oops, something went wrong.