You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
65 lines
2.0 KiB
65 lines
2.0 KiB
// @flow
|
|
import getValueAndUnit from '../helpers/getValueAndUnit'
|
|
import PolishedError from '../internalHelpers/_errors'
|
|
|
|
/**
|
|
* Returns a CSS calc formula for linear interpolation of a property between two values. Accepts optional minScreen (defaults to '320px') and maxScreen (defaults to '1200px').
|
|
*
|
|
* @example
|
|
* // Styles as object usage
|
|
* const styles = {
|
|
* fontSize: between('20px', '100px', '400px', '1000px'),
|
|
* fontSize: between('20px', '100px')
|
|
* }
|
|
*
|
|
* // styled-components usage
|
|
* const div = styled.div`
|
|
* fontSize: ${between('20px', '100px', '400px', '1000px')};
|
|
* fontSize: ${between('20px', '100px')}
|
|
* `
|
|
*
|
|
* // CSS as JS Output
|
|
*
|
|
* h1: {
|
|
* 'fontSize': 'calc(-33.33333333333334px + 13.333333333333334vw)',
|
|
* 'fontSize': 'calc(-9.090909090909093px + 9.090909090909092vw)'
|
|
* }
|
|
*/
|
|
export default function between(
|
|
fromSize: string | number,
|
|
toSize: string | number,
|
|
minScreen?: string = '320px',
|
|
maxScreen?: string = '1200px',
|
|
): string {
|
|
const [unitlessFromSize, fromSizeUnit] = getValueAndUnit(fromSize)
|
|
const [unitlessToSize, toSizeUnit] = getValueAndUnit(toSize)
|
|
const [unitlessMinScreen, minScreenUnit] = getValueAndUnit(minScreen)
|
|
const [unitlessMaxScreen, maxScreenUnit] = getValueAndUnit(maxScreen)
|
|
|
|
if (
|
|
typeof unitlessMinScreen !== 'number'
|
|
|| typeof unitlessMaxScreen !== 'number'
|
|
|| !minScreenUnit
|
|
|| !maxScreenUnit
|
|
|| minScreenUnit !== maxScreenUnit
|
|
) {
|
|
throw new PolishedError(47)
|
|
}
|
|
|
|
if (
|
|
typeof unitlessFromSize !== 'number'
|
|
|| typeof unitlessToSize !== 'number'
|
|
|| fromSizeUnit !== toSizeUnit
|
|
) {
|
|
throw new PolishedError(48)
|
|
}
|
|
|
|
if (fromSizeUnit !== minScreenUnit || toSizeUnit !== maxScreenUnit) {
|
|
throw new PolishedError(75)
|
|
}
|
|
|
|
const slope = (unitlessFromSize - unitlessToSize) / (unitlessMinScreen - unitlessMaxScreen)
|
|
const base = unitlessToSize - slope * unitlessMaxScreen
|
|
return `calc(${base.toFixed(2)}${fromSizeUnit || ''} + ${(100 * slope).toFixed(2)}vw)`
|
|
}
|