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)`
 | 
						|
}
 |