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