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.
		
		
		
		
		
			
		
			
				
					109 lines
				
				3.0 KiB
			
		
		
			
		
	
	
					109 lines
				
				3.0 KiB
			| 
											3 years ago
										 | // @flow | ||
|  | import getValueAndUnit from '../helpers/getValueAndUnit' | ||
|  | import PolishedError from '../internalHelpers/_errors' | ||
|  | 
 | ||
|  | import type { SideKeyword } from '../types/sideKeyword' | ||
|  | import type { Styles } from '../types/style' | ||
|  | import type { TriangleConfiguration } from '../types/triangleConfiguration' | ||
|  | 
 | ||
|  | const getBorderWidth = ( | ||
|  |   pointingDirection: SideKeyword, | ||
|  |   height: [number, string], | ||
|  |   width: [number, string], | ||
|  | ): string => { | ||
|  |   const fullWidth = `${width[0]}${width[1] || ''}` | ||
|  |   const halfWidth = `${width[0] / 2}${width[1] || ''}` | ||
|  |   const fullHeight = `${height[0]}${height[1] || ''}` | ||
|  |   const halfHeight = `${height[0] / 2}${height[1] || ''}` | ||
|  | 
 | ||
|  |   switch (pointingDirection) { | ||
|  |     case 'top': | ||
|  |       return `0 ${halfWidth} ${fullHeight} ${halfWidth}` | ||
|  |     case 'topLeft': | ||
|  |       return `${fullWidth} ${fullHeight} 0 0` | ||
|  |     case 'left': | ||
|  |       return `${halfHeight} ${fullWidth} ${halfHeight} 0` | ||
|  |     case 'bottomLeft': | ||
|  |       return `${fullWidth} 0 0 ${fullHeight}` | ||
|  |     case 'bottom': | ||
|  |       return `${fullHeight} ${halfWidth} 0 ${halfWidth}` | ||
|  |     case 'bottomRight': | ||
|  |       return `0 0 ${fullWidth} ${fullHeight}` | ||
|  |     case 'right': | ||
|  |       return `${halfHeight} 0 ${halfHeight} ${fullWidth}` | ||
|  |     case 'topRight': | ||
|  |     default: | ||
|  |       return `0 ${fullWidth} ${fullHeight} 0` | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | const getBorderColor = (pointingDirection: SideKeyword, foregroundColor: string): Object => { | ||
|  |   switch (pointingDirection) { | ||
|  |     case 'top': | ||
|  |     case 'bottomRight': | ||
|  |       return { borderBottomColor: foregroundColor } | ||
|  |     case 'right': | ||
|  |     case 'bottomLeft': | ||
|  |       return { borderLeftColor: foregroundColor } | ||
|  |     case 'bottom': | ||
|  |     case 'topLeft': | ||
|  |       return { borderTopColor: foregroundColor } | ||
|  |     case 'left': | ||
|  |     case 'topRight': | ||
|  |       return { borderRightColor: foregroundColor } | ||
|  | 
 | ||
|  |     default: | ||
|  |       throw new PolishedError(59) | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * CSS to represent triangle with any pointing direction with an optional background color. | ||
|  |  * | ||
|  |  * @example | ||
|  |  * // Styles as object usage | ||
|  |  * | ||
|  |  * const styles = { | ||
|  |  *   ...triangle({ pointingDirection: 'right', width: '100px', height: '100px', foregroundColor: 'red' }) | ||
|  |  * } | ||
|  |  * | ||
|  |  * | ||
|  |  * // styled-components usage | ||
|  |  * const div = styled.div` | ||
|  |  *   ${triangle({ pointingDirection: 'right', width: '100px', height: '100px', foregroundColor: 'red' })} | ||
|  |  * | ||
|  |  * | ||
|  |  * // CSS as JS Output | ||
|  |  * | ||
|  |  * div: { | ||
|  |  *  'borderColor': 'transparent transparent transparent red', | ||
|  |  *  'borderStyle': 'solid', | ||
|  |  *  'borderWidth': '50px 0 50px 100px', | ||
|  |  *  'height': '0', | ||
|  |  *  'width': '0', | ||
|  |  * } | ||
|  |  */ | ||
|  | export default function triangle({ | ||
|  |   pointingDirection, | ||
|  |   height, | ||
|  |   width, | ||
|  |   foregroundColor, | ||
|  |   backgroundColor = 'transparent', | ||
|  | }: TriangleConfiguration): Styles { | ||
|  |   const widthAndUnit = getValueAndUnit(width) | ||
|  |   const heightAndUnit = getValueAndUnit(height) | ||
|  | 
 | ||
|  |   if (isNaN(heightAndUnit[0]) || isNaN(widthAndUnit[0])) { | ||
|  |     throw new PolishedError(60) | ||
|  |   } | ||
|  | 
 | ||
|  |   return { | ||
|  |     width: '0', | ||
|  |     height: '0', | ||
|  |     borderColor: backgroundColor, | ||
|  |     ...getBorderColor(pointingDirection, foregroundColor), | ||
|  |     borderStyle: 'solid', | ||
|  |     borderWidth: getBorderWidth(pointingDirection, heightAndUnit, widthAndUnit), | ||
|  |   } | ||
|  | } |