UNPKG

3.62 kBJavaScriptView Raw
1export function isUnitless(value) {
2 return String(parseFloat(value)).length === String(value).length;
3} // Ported from Compass
4// https://github.com/Compass/compass/blob/master/core/stylesheets/compass/typography/_units.scss
5// Emulate the sass function "unit"
6
7export function getUnit(input) {
8 return String(input).match(/[\d.\-+]*\s*(.*)/)[1] || '';
9} // Emulate the sass function "unitless"
10
11export function toUnitless(length) {
12 return parseFloat(length);
13} // Convert any CSS <length> or <percentage> value to any another.
14// From https://github.com/KyleAMathews/convert-css-length
15
16export function convertLength(baseFontSize) {
17 return (length, toUnit) => {
18 const fromUnit = getUnit(length); // Optimize for cases where `from` and `to` units are accidentally the same.
19
20 if (fromUnit === toUnit) {
21 return length;
22 } // Convert input length to pixels.
23
24
25 let pxLength = toUnitless(length);
26
27 if (fromUnit !== 'px') {
28 if (fromUnit === 'em') {
29 pxLength = toUnitless(length) * toUnitless(baseFontSize);
30 } else if (fromUnit === 'rem') {
31 pxLength = toUnitless(length) * toUnitless(baseFontSize);
32 }
33 } // Convert length in pixels to the output unit
34
35
36 let outputLength = pxLength;
37
38 if (toUnit !== 'px') {
39 if (toUnit === 'em') {
40 outputLength = pxLength / toUnitless(baseFontSize);
41 } else if (toUnit === 'rem') {
42 outputLength = pxLength / toUnitless(baseFontSize);
43 } else {
44 return length;
45 }
46 }
47
48 return parseFloat(outputLength.toFixed(5)) + toUnit;
49 };
50}
51export function alignProperty({
52 size,
53 grid
54}) {
55 const sizeBelow = size - size % grid;
56 const sizeAbove = sizeBelow + grid;
57 return size - sizeBelow < sizeAbove - size ? sizeBelow : sizeAbove;
58} // fontGrid finds a minimal grid (in rem) for the fontSize values so that the
59// lineHeight falls under a x pixels grid, 4px in the case of Material Design,
60// without changing the relative line height
61
62export function fontGrid({
63 lineHeight,
64 pixels,
65 htmlFontSize
66}) {
67 return pixels / (lineHeight * htmlFontSize);
68}
69/**
70 * generate a responsive version of a given CSS property
71 * @example
72 * responsiveProperty({
73 * cssProperty: 'fontSize',
74 * min: 15,
75 * max: 20,
76 * unit: 'px',
77 * breakpoints: [300, 600],
78 * })
79 *
80 * // this returns
81 *
82 * {
83 * fontSize: '15px',
84 * '@media (min-width:300px)': {
85 * fontSize: '17.5px',
86 * },
87 * '@media (min-width:600px)': {
88 * fontSize: '20px',
89 * },
90 * }
91 * @param {Object} params
92 * @param {string} params.cssProperty - The CSS property to be made responsive
93 * @param {number} params.min - The smallest value of the CSS property
94 * @param {number} params.max - The largest value of the CSS property
95 * @param {string} [params.unit] - The unit to be used for the CSS property
96 * @param {Array.number} [params.breakpoints] - An array of breakpoints
97 * @param {number} [params.alignStep] - Round scaled value to fall under this grid
98 * @returns {Object} responsive styles for {params.cssProperty}
99 */
100
101export function responsiveProperty({
102 cssProperty,
103 min,
104 max,
105 unit = 'rem',
106 breakpoints = [600, 900, 1200],
107 transform = null
108}) {
109 const output = {
110 [cssProperty]: `${min}${unit}`
111 };
112 const factor = (max - min) / breakpoints[breakpoints.length - 1];
113 breakpoints.forEach(breakpoint => {
114 let value = min + factor * breakpoint;
115
116 if (transform !== null) {
117 value = transform(value);
118 }
119
120 output[`@media (min-width:${breakpoint}px)`] = {
121 [cssProperty]: `${Math.round(value * 10000) / 10000}${unit}`
122 };
123 });
124 return output;
125}
\No newline at end of file