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