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
			| 
								 
											3 years ago
										 
									 | 
							
								// @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)`
							 | 
						||
| 
								 | 
							
								}
							 |