@devseed-ui/theme-provider
Version:
devseed UI Kit Theme
150 lines (136 loc) • 4.9 kB
JavaScript
/**
* Creates a math function that performs the given operation taking into account
* only the unit of the first value. Eg: 2rem * 2 = 4rem | 2 * 2rem = 4
* The resulting function accepts 2 arguments to which the given operation
* will be applied.
* This function is ready to work with styled-components so that any function
* passed as an argument will receive the component props.
*
* @example Simple function
* const add = createMathOperation('+');
* add(2, 2) // -> 4
*
* @example Using with themeVal()
* const multiply = createMathOperation('*');
* multiply(themeVal('globalSpacing'), 2) // -> 2rem
*
* @param {string} op Math operation to perform. Can be + - * /
*/
const createMathOperation =
(op) =>
(a, b) =>
(...args) => {
a = typeof a === 'function' ? a(...args) : a;
b = typeof b === 'function' ? b(...args) : b;
// The final unit is driven by the `a` value.
const unit = (a + '').match(/[0-9]*(?:.[0-9]+)?(.*)/)[1];
const aVal = parseFloat(a);
const bVal = parseFloat(b);
if (op === '+') {
return `${aVal + bVal}${unit}`;
} else if (op === '-') {
return `${aVal - bVal}${unit}`;
} else if (op === '/') {
return `${aVal / bVal}${unit}`;
} else if (op === '*') {
return `${aVal * bVal}${unit}`;
}
};
/**
* Creates a math function to add values. It takes into account
* only the unit of the first value. Eg: 2rem + 2 = 4rem | 2 + 2rem = 4
* This function is ready to work with styled-components so that any function
* passed as an argument will receive the component props.
*
* @param {string} a First value
* @param {string} b Second value
*/
export const add = createMathOperation('+');
/**
* Creates a math function to subtract values. It takes into account
* only the unit of the first value. Eg: 4rem - 2 = 2rem | 4 - 2rem = 2
* This function is ready to work with styled-components so that any function
* passed as an argument will receive the component props.
*
* @param {string} a First value
* @param {string} b Second value
*/
export const subtract = createMathOperation('-');
/**
* Creates a math function to divide values. It takes into account
* only the unit of the first value. Eg: 4rem / 2 = 2rem | 4 / 2rem = 2
* This function is ready to work with styled-components so that any function
* passed as an argument will receive the component props.
*
* @param {string} a First value
* @param {string} b Second value
*/
export const divide = createMathOperation('/');
/**
* Creates a math function to multiply values. It takes into account
* only the unit of the first value. Eg: 2rem * 2 = 4rem | 2 * 2rem = 4
* This function is ready to work with styled-components so that any function
* passed as an argument will receive the component props.
*
* @param {string} a First value
* @param {string} b Second value
*/
export const multiply = createMathOperation('*');
const createMinMaxOp =
(op) =>
(a, b) =>
(...args) => {
a = typeof a === 'function' ? a(...args) : a;
b = typeof b === 'function' ? b(...args) : b;
const unitRx = /[0-9]*(?:.[0-9]+)?(.*)/;
const aUnit = (a + '').match(unitRx)[1];
const bUnit = (b + '').match(unitRx)[1];
const aVal = parseFloat(a);
const bVal = parseFloat(b);
// If the values are different but set, return no unit, otherwise return the
// unit of the value that has it. this is useful when comparing for example
// 10px with 16.
let unit = '';
if (aUnit === bUnit) {
unit = aUnit;
} else if (aUnit && !bUnit) {
unit = aUnit;
} else if (!aUnit && bUnit) {
unit = bUnit;
}
if (op === 'min') {
return `${Math.min(aVal, bVal)}${unit}`;
} else if (op === 'max') {
return `${Math.max(aVal, bVal)}${unit}`;
}
};
/**
* Creates a math function that returns the minimum of two values. Units are
* discarded when doing the comparison, but the value is returned with a unit
* if both arguments has the same one or if only one has it.
* Eg: 10px, 3px => 3px
* Eg: 10px, 3 => 3px
* Eg: 1rem, 3px => 1
*
* This function is ready to work with styled-components
* so that any function passed as an argument will receive the component props.
*
* @param {string} a First value
* @param {string} b Second value
*/
export const min = createMinMaxOp('min');
/**
* Creates a math function that returns the maximum of two values. Units are
* discarded when doing the comparison, but the value is returned with a unit
* if both arguments has the same one or if only one has it.
* Eg: 10px, 3px => 10px
* Eg: 10px, 3 => 10px
* Eg: 1rem, 3px => 3
*
* This function is ready to work with styled-components
* so that any function passed as an argument will receive the component props.
*
* @param {string} a First value
* @param {string} b Second value
*/
export const max = createMinMaxOp('max');