UNPKG

@devseed-ui/theme-provider

Version:
150 lines (136 loc) 4.9 kB
/** * 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');