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