/
between.js
67 lines (62 loc) · 1.97 KB
/
between.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// @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(76)
}
const slope = (unitlessFromSize - unitlessToSize)
/ (unitlessMinScreen - unitlessMaxScreen)
const base = unitlessToSize - slope * unitlessMaxScreen
return `calc(${base.toFixed(2)}${fromSizeUnit || ''} + ${(
100 * slope
).toFixed(2)}vw)`
}