From 361e46f1bc1c258388721d26990a16451071c67d Mon Sep 17 00:00:00 2001 From: Brian Hough Date: Thu, 11 May 2017 00:38:39 +0200 Subject: [PATCH] fix(triangle): Complete triangle mixin (#162) Finishes the triangle mixin with an updated API to be more in line with Bourbon's implementation. Also updates the associated docs and properly exports the module. --- .documentation.json | 18 +- README.md | 17 +- docs/assets/polished.js | 80 ++ docs/docs/index.html | 722 ++++++++++-------- src/index.js | 2 + .../test/__snapshots__/triangle.test.js.snap | 30 +- src/mixins/test/triangle.test.js | 44 +- src/mixins/triangle.js | 96 +-- 8 files changed, 631 insertions(+), 378 deletions(-) diff --git a/.documentation.json b/.documentation.json index 0c04304d..cdf1e55b 100644 --- a/.documentation.json +++ b/.documentation.json @@ -28,6 +28,7 @@ "retinaImage", "selection", "timingFunctions", + "triangle", "wordWrap", { "name": "Color" @@ -82,16 +83,17 @@ { "name": "Types" }, - "Ratio", - "RgbColor", - "RgbaColor", + "AnimationProperty", + "ButtonState", + "FontFaceConfiguration", "HslColor", "HslaColor", - "FontFaceConfiguration", + "InputState", + "PointingDirection", "RadialGradientConfiguration", - "TimingFunction", - "AnimationProperty", - "ButtonState", - "InputState" + "Ratio", + "RgbaColor", + "RgbColor", + "TimingFunction" ] } diff --git a/README.md b/README.md index 4123dc73..ea8e88fe 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ In the documentation you will see examples using [object spread properties](http
  • retinaImage
  • selection
  • timingFunctions
  • +
  • triangle
  • wordWrap
  • @@ -121,19 +122,19 @@ In the documentation you will see examples using [object spread properties](http
    Types
    diff --git a/docs/assets/polished.js b/docs/assets/polished.js index c6320e8b..c7a5e6b6 100644 --- a/docs/assets/polished.js +++ b/docs/assets/polished.js @@ -1068,6 +1068,85 @@ function timingFunctions(timingFunction) { // +/** */ + +var getBorderWidth = function getBorderWidth(pointingDirection, height, width) { + switch (pointingDirection) { + case 'top': + return '0 ' + width / 2 + 'px ' + height + 'px ' + width / 2 + 'px'; + case 'left': + return height / 2 + 'px ' + width + 'px ' + height / 2 + 'px 0'; + case 'bottom': + return height + 'px ' + width / 2 + 'px 0 ' + width / 2 + 'px'; + case 'right': + return height / 2 + 'px 0 ' + height / 2 + 'px ' + width + 'px'; + + default: + throw new Error('Passed invalid argument to triangle, please pass correct poitingDirection e.g. \'right\'.'); + } +}; + +// needed for border-color +var reverseDirection = { + left: 'right', + right: 'left', + top: 'bottom', + bottom: 'top' +}; + +/** + * CSS to represent triangle with any pointing direction with an optional background color. Accepts number or px values for height and width. + * + * @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: { + * 'border-color': 'transparent', + * 'border-left-color': 'red !important', + * 'border-style': 'solid', + * 'border-width': '50px 0 50px 100px', + * 'height': '0', + * 'width': '0', + * } + */ + +function triangle(_ref) { + var pointingDirection = _ref.pointingDirection, + height = _ref.height, + width = _ref.width, + foregroundColor = _ref.foregroundColor, + _ref$backgroundColor = _ref.backgroundColor, + backgroundColor = _ref$backgroundColor === undefined ? 'transparent' : _ref$backgroundColor; + + var unitlessHeight = parseFloat(height); + var unitlessWidth = parseFloat(width); + if (isNaN(unitlessHeight) || isNaN(unitlessWidth)) { + throw new Error('Passed an invalid value to `height` or `width`. Please provide a pixel based unit'); + } + + return defineProperty({ + 'border-color': backgroundColor, + 'width': '0', + 'height': '0', + 'border-width': getBorderWidth(pointingDirection, unitlessHeight, unitlessWidth), + 'border-style': 'solid' + }, 'border-' + reverseDirection[pointingDirection] + '-color', foregroundColor + ' !important'); +} + +// + /** * Provides an easy way to change the `word-wrap` property. * @@ -2969,6 +3048,7 @@ exports.tint = tint$1; exports.toColorString = toColorString; exports.transitions = transitions; exports.transparentize = transparentize$1; +exports.triangle = triangle; exports.wordWrap = wordWrap; Object.defineProperty(exports, '__esModule', { value: true }); diff --git a/docs/docs/index.html b/docs/docs/index.html index 9f57352f..af23f1f5 100644 --- a/docs/docs/index.html +++ b/docs/docs/index.html @@ -184,6 +184,16 @@

    +
  • + triangle + + + +
  • + +
  • @@ -645,9 +655,9 @@

  • - Ratio + AnimationProperty @@ -655,9 +665,9 @@

  • - RgbColor + ButtonState @@ -665,9 +675,9 @@

  • - RgbaColor + FontFaceConfiguration @@ -695,9 +705,9 @@

  • - FontFaceConfiguration + InputState @@ -705,9 +715,9 @@

  • - RadialGradientConfiguration + PointingDirection @@ -715,9 +725,9 @@

  • - TimingFunction + RadialGradientConfiguration @@ -725,9 +735,9 @@

  • - AnimationProperty + Ratio @@ -735,9 +745,9 @@

  • - ButtonState + RgbaColor @@ -745,9 +755,9 @@

  • - InputState + RgbColor @@ -755,9 +765,9 @@

  • - toColorString + TimingFunction @@ -765,9 +775,9 @@

  • - PointingDirection + toColorString @@ -835,7 +845,7 @@

    - + src/mixins/clearFix.js @@ -921,7 +931,7 @@

    - + src/mixins/ellipsis.js @@ -1010,7 +1020,7 @@

    - + src/mixins/fontFace.js @@ -1172,7 +1182,7 @@

    - + src/mixins/hiDPI.js @@ -1264,7 +1274,7 @@

    - + src/mixins/hideText.js @@ -1339,7 +1349,7 @@

    - + src/mixins/normalize.js @@ -1423,7 +1433,7 @@

    - + src/mixins/placeholder.js @@ -1526,7 +1536,7 @@

    - + src/mixins/radialGradient.js @@ -1666,7 +1676,7 @@

    - + src/mixins/retinaImage.js @@ -1791,7 +1801,7 @@

    - + src/mixins/selection.js @@ -1890,7 +1900,7 @@

    - + src/mixins/timingFunctions.js @@ -1958,6 +1968,144 @@

    + + + + + +
    + + +
    + +

    + triangle +

    + + + + src/mixins/triangle.js + + +
    + + +

    CSS to represent triangle with any pointing direction with an optional background color. Accepts number or px values for height and width.

    + + +
    triangle($0: Object)
    + + + + + + + + + + +
    Parameters
    +
    + +
    +
    + $0 (Object) + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameDescription
    $0.pointingDirection Any +
    $0.height Any +
    $0.width Any +
    $0.foregroundColor Any +
    $0.backgroundColor Any + + (default 'transparent') +
    + +
    + +
    + + + + + + + + + +
    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: {
    + 'border-color': 'transparent',
    + 'border-left-color': 'red !important',
    + 'border-style': 'solid',
    + 'border-width': '50px 0 50px 100px',
    + 'height': '0',
    + 'width': '0',
    +}
    + + + + + + + +
    @@ -1973,7 +2121,7 @@

    - + src/mixins/wordWrap.js @@ -2071,7 +2219,7 @@

    - + src/color/adjustHue.js @@ -2171,7 +2319,7 @@

    - + src/color/complement.js @@ -2261,7 +2409,7 @@

    - + src/color/darken.js @@ -2360,7 +2508,7 @@

    - + src/color/desaturate.js @@ -2460,7 +2608,7 @@

    - + src/color/grayscale.js @@ -2550,7 +2698,7 @@

    - + src/color/hsl.js @@ -2657,7 +2805,7 @@

    - + src/color/hsla.js @@ -2775,7 +2923,7 @@

    - + src/color/invert.js @@ -2866,7 +3014,7 @@

    - + src/color/lighten.js @@ -2965,7 +3113,7 @@

    - + src/color/mix.js @@ -3080,7 +3228,7 @@

    - + src/color/opacify.js @@ -3177,7 +3325,7 @@

    - + src/color/parseToHsl.js @@ -3256,7 +3404,7 @@

    - + src/color/parseToRgb.js @@ -3335,7 +3483,7 @@

    - + src/color/rgb.js @@ -3442,7 +3590,7 @@

    - + src/color/rgba.js @@ -3560,7 +3708,7 @@

    - + src/color/saturate.js @@ -3661,7 +3809,7 @@

    - + src/color/setHue.js @@ -3760,7 +3908,7 @@

    - + src/color/setLightness.js @@ -3859,7 +4007,7 @@

    - + src/color/setSaturation.js @@ -3958,7 +4106,7 @@

    - + src/color/shade.js @@ -4051,7 +4199,7 @@

    - + src/color/tint.js @@ -4144,7 +4292,7 @@

    - + src/color/transparentize.js @@ -4253,7 +4401,7 @@

    - + src/shorthands/animation.js @@ -4354,7 +4502,7 @@

    - + src/shorthands/backgroundImages.js @@ -4437,7 +4585,7 @@

    - + src/shorthands/backgrounds.js @@ -4520,7 +4668,7 @@

    - + src/shorthands/borderColor.js @@ -4606,7 +4754,7 @@

    - + src/shorthands/borderRadius.js @@ -4698,7 +4846,7 @@

    - + src/shorthands/borderStyle.js @@ -4784,7 +4932,7 @@

    - + src/shorthands/borderWidth.js @@ -4870,7 +5018,7 @@

    - + src/shorthands/buttons.js @@ -4960,7 +5108,7 @@

    - + src/shorthands/margin.js @@ -5046,7 +5194,7 @@

    - + src/shorthands/padding.js @@ -5132,7 +5280,7 @@

    - + src/shorthands/position.js @@ -5246,7 +5394,7 @@

    - + src/shorthands/size.js @@ -5339,7 +5487,7 @@

    - + src/shorthands/textInputs.js @@ -5441,7 +5589,7 @@

    - + src/shorthands/transitions.js @@ -5536,7 +5684,7 @@

    - + src/helpers/directionalProperty.js @@ -5630,7 +5778,7 @@

    - + src/helpers/em.js @@ -5723,7 +5871,7 @@

    - + src/helpers/modularScale.js @@ -5826,7 +5974,7 @@

    - + src/helpers/rem.js @@ -5919,7 +6067,7 @@

    - + src/helpers/stripUnit.js @@ -6014,13 +6162,13 @@

    @@ -6028,7 +6176,7 @@

    -
    Ratio
    +
    AnimationProperty
    @@ -6063,13 +6211,13 @@

    @@ -6077,7 +6225,7 @@

    -
    RgbColor
    +
    ButtonState
    @@ -6090,29 +6238,6 @@

    -
    Properties
    -
    - -
    - red (number) - - -
    - -
    - green (number) - - -
    - -
    - blue (number) - - -
    - -
    - @@ -6135,13 +6260,13 @@

    -

    - RgbaColor +

    + FontFaceConfiguration

    - - src/types/color.js + + src/mixins/fontFace.js
    @@ -6149,7 +6274,7 @@

    -
    RgbaColor
    +
    FontFaceConfiguration
    @@ -6166,51 +6291,81 @@

    - red (number) + fontFamily (string)
    - green (number) + fontFilePath (string)
    - blue (number) + fontStretch (string)
    - alpha (number) + fontStyle (string)
    -
    - - - - - - - - - - - - - - - - +
    + fontVariant (string) + + +
    - -
    - - +
    + fontWeight (string) + + +
    + +
    + fileFormats (Array<string>) + + +
    + +
    + localFonts (Array<string>) + + +
    + +
    + unicodeRange (string) + + +
    + + + + + + + + + + + + + + + +
    + + + + +
    + +

    @@ -6218,7 +6373,7 @@

    - + src/types/color.js @@ -6290,7 +6445,7 @@

    - + src/types/color.js @@ -6363,13 +6518,13 @@

    -

    - FontFaceConfiguration +

    + InputState

    - - src/mixins/fontFace.js + + src/shorthands/textInputs.js
    @@ -6377,7 +6532,7 @@

    -
    FontFaceConfiguration
    +
    InputState
    @@ -6390,64 +6545,54 @@

    -
    Properties
    -
    - -
    - fontFamily (string) - - -
    - -
    - fontFilePath (string) - - -
    - -
    - fontStretch (string) - - -
    - -
    - fontStyle (string) - - -
    - -
    - fontVariant (string) - - -
    - -
    - fontWeight (string) - - -
    - -
    - fileFormats (Array<string>) - - -
    - -
    - localFonts (Array<string>) - - -
    - -
    - unicodeRange (string) - - -
    + + + + + + + + + + + + +

    + + - + +
    + + +
    + +

    + PointingDirection +

    + + + + src/mixins/triangle.js + + +
    + + + + +
    PointingDirection
    + + + + + + + + + + + @@ -6476,7 +6621,7 @@

    - + src/mixins/radialGradient.js @@ -6555,13 +6700,13 @@

    @@ -6569,7 +6714,7 @@

    -
    TimingFunction
    +
    Ratio
    @@ -6604,13 +6749,13 @@

    -

    - AnimationProperty +

    + RgbaColor

    - - src/shorthands/animation.js + + src/types/color.js
    @@ -6618,7 +6763,7 @@

    -
    AnimationProperty
    +
    RgbaColor
    @@ -6631,6 +6776,35 @@

    +
    Properties
    +
    + +
    + red (number) + + +
    + +
    + green (number) + + +
    + +
    + blue (number) + + +
    + +
    + alpha (number) + + +
    + +
    + @@ -6653,13 +6827,13 @@

    @@ -6667,7 +6841,7 @@

    -
    ButtonState
    +
    RgbColor
    @@ -6680,6 +6854,29 @@

    +
    Properties
    +
    + +
    + red (number) + + +
    + +
    + green (number) + + +
    + +
    + blue (number) + + +
    + +
    + @@ -6702,13 +6899,13 @@

    @@ -6716,7 +6913,7 @@

    -
    InputState
    +
    TimingFunction
    @@ -6756,7 +6953,7 @@

    - + src/color/toColorString.js @@ -6839,83 +7036,6 @@

    -

    - - - - -
    - - -
    - -

    - PointingDirection -

    - - - - src/mixins/triangle.js - - -
    - - -

    CSS to represent triangle with any pointing direction.

    - - -
    PointingDirection
    - - - - - - - - - - - - - - - - - - -
    Example
    - - -
    // Styles as object usage
    -
    -const styles = {
    -  ...triangle({ pointing: 'right', width: '100px', height: '100px', color: 'red' })
    -}
    -
    -
    -// styled-components usage
    -const div = styled.div`
    -  ${triangle({ pointing: 'right', width: '100px', height: '100px', color: 'red' })}
    -
    -
    -// CSS as JS Output
    -
    -div: {
    - 'border-color': 'transparent',
    - 'border-left-color': 'red !important',
    - 'border-style': 'solid',
    - 'border-width': '50px 0 50px 100px',
    - 'height': '0',
    - 'width': '0',
    -}
    - - - - - - - -
    diff --git a/src/index.js b/src/index.js index 1bb96a67..995a03d1 100644 --- a/src/index.js +++ b/src/index.js @@ -18,6 +18,7 @@ import radialGradient from './mixins/radialGradient' import retinaImage from './mixins/retinaImage' import selection from './mixins/selection' import timingFunctions from './mixins/timingFunctions' +import triangle from './mixins/triangle' import wordWrap from './mixins/wordWrap' // Color @@ -115,5 +116,6 @@ export { toColorString, transitions, transparentize, + triangle, wordWrap, } diff --git a/src/mixins/test/__snapshots__/triangle.test.js.snap b/src/mixins/test/__snapshots__/triangle.test.js.snap index 855eabbb..12809f27 100644 --- a/src/mixins/test/__snapshots__/triangle.test.js.snap +++ b/src/mixins/test/__snapshots__/triangle.test.js.snap @@ -1,4 +1,4 @@ -exports[`triangle should pass parameters to the values of color, border-width 1`] = ` +exports[`triangle should default to a transparent background when not passed a backgroundColor 1`] = ` Object { "border-color": "transparent", "border-left-color": "red !important", @@ -9,6 +9,28 @@ Object { } `; +exports[`triangle should generate a proper triangle when passed all parameters 1`] = ` +Object { + "border-color": "black", + "border-left-color": "red !important", + "border-style": "solid", + "border-width": "5px 0 5px 20px", + "height": "0", + "width": "0", +} +`; + +exports[`triangle should generate a proper triangle when passed string values for height and width 1`] = ` +Object { + "border-color": "black", + "border-left-color": "red !important", + "border-style": "solid", + "border-width": "5px 0 5px 20px", + "height": "0", + "width": "0", +} +`; + exports[`triangle should properly add rules when block has existing rules 1`] = ` Object { "background": "red", @@ -21,7 +43,7 @@ Object { } `; -exports[`triangle should properly render bottom pointing arrow with red color, width of 20px and height 20px 1`] = ` +exports[`triangle should properly render bottom pointing arrow with red foregroundColor, width of 20px and height 20px 1`] = ` Object { "border-color": "transparent", "border-style": "solid", @@ -32,7 +54,7 @@ Object { } `; -exports[`triangle should properly render left pointing arrow with blue color, width of 10px and height 20px 1`] = ` +exports[`triangle should properly render left pointing arrow with blue foregroundColor, width of 10px and height 20px 1`] = ` Object { "border-color": "transparent", "border-right-color": "blue !important", @@ -54,7 +76,7 @@ Object { } `; -exports[`triangle should properly render top pointing arrow with green color, width of 20px and height 20px 1`] = ` +exports[`triangle should properly render top pointing arrow with green foregroundColor, width of 20px and height 20px 1`] = ` Object { "border-bottom-color": "green !important", "border-color": "transparent", diff --git a/src/mixins/test/triangle.test.js b/src/mixins/test/triangle.test.js index 8a40854b..61c5e6e0 100644 --- a/src/mixins/test/triangle.test.js +++ b/src/mixins/test/triangle.test.js @@ -2,38 +2,46 @@ import triangle from '../triangle' describe('triangle', () => { - it('should pass parameters to the values of color, border-width', () => { - expect({ ...triangle({ color: 'red', pointingDirection: 'right', height: 10, width: 20 }) }).toMatchSnapshot() + it('should generate a proper triangle when passed all parameters', () => { + expect({ ...triangle({ foregroundColor: 'red', backgroundColor: 'black', pointingDirection: 'right', height: 10, width: 20 }) }).toMatchSnapshot() + }) + + it('should default to a transparent background when not passed a backgroundColor', () => { + expect({ ...triangle({ foregroundColor: 'red', pointingDirection: 'right', height: 10, width: 20 }) }).toMatchSnapshot() + }) + + it('should generate a proper triangle when passed string values for height and width', () => { + expect({ ...triangle({ foregroundColor: 'red', backgroundColor: 'black', pointingDirection: 'right', height: '10px', width: '20px' }) }).toMatchSnapshot() }) it('should properly add rules when block has existing rules', () => { expect({ background: 'red', - ...triangle({ color: 'grey', pointingDirection: 'right', height: 10, width: 20 }), + ...triangle({ foregroundColor: 'grey', pointingDirection: 'right', height: 10, width: 20 }), }).toMatchSnapshot() }) - it('should properly render top pointing arrow with green color, width of 20px and height 20px', () => { + it('should properly render top pointing arrow with green foregroundColor, width of 20px and height 20px', () => { expect({ - ...triangle({ color: 'green', pointingDirection: 'top', height: 20, width: 20 }), + ...triangle({ foregroundColor: 'green', pointingDirection: 'top', height: 20, width: 20 }), }).toMatchSnapshot() }) it('should properly render right pointing arrow with width of 20px and height 10px', () => { expect({ - ...triangle({ color: 'red', pointingDirection: 'right', height: 10, width: 20 }), + ...triangle({ foregroundColor: 'red', pointingDirection: 'right', height: 10, width: 20 }), }).toMatchSnapshot() }) - it('should properly render bottom pointing arrow with red color, width of 20px and height 20px', () => { + it('should properly render bottom pointing arrow with red foregroundColor, width of 20px and height 20px', () => { expect({ - ...triangle({ color: 'red', pointingDirection: 'bottom', height: 20, width: 10 }), + ...triangle({ foregroundColor: 'red', pointingDirection: 'bottom', height: 20, width: 10 }), }).toMatchSnapshot() }) - it('should properly render left pointing arrow with blue color, width of 10px and height 20px', () => { + it('should properly render left pointing arrow with blue foregroundColor, width of 10px and height 20px', () => { expect({ - ...triangle({ color: 'blue', pointingDirection: 'left', height: 20, width: 10 }), + ...triangle({ foregroundColor: 'blue', pointingDirection: 'left', height: 20, width: 10 }), }).toMatchSnapshot() }) @@ -42,7 +50,7 @@ describe('triangle', () => { // $FlowIgnoreNextLine since the coming is invalid code, flow complains triangle( { - color: 'blue', + foregroundColor: 'blue', height: 20, width: 10, poitingDirection: false, @@ -50,4 +58,18 @@ describe('triangle', () => { ) }).toThrow('Passed invalid argument to triangle, please pass correct poitingDirection e.g. \'right\'.') }) + + it('should throw an error when height or width is not a unit based value.', () => { + expect(() => { + // $FlowIgnoreNextLine since the coming is invalid code, flow complains + triangle( + { + foregroundColor: 'blue', + height: 'inherit', + width: 'inherit', + poitingDirection: false, + }, + ) + }).toThrow('Passed an invalid value to `height` or `width`. Please provide a pixel based unit') + }) }) diff --git a/src/mixins/triangle.js b/src/mixins/triangle.js index 89171070..a4507a02 100644 --- a/src/mixins/triangle.js +++ b/src/mixins/triangle.js @@ -1,20 +1,49 @@ // @flow +/** */ +type PointingDirection = 'top' | 'right' | 'bottom' | 'left' + +type TriangleArgs = { + backgroundColor?: string, + foregroundColor: string, + height: number|string, + width: number|string, + pointingDirection: PointingDirection, +} + +const getBorderWidth = (pointingDirection: PointingDirection, height: number, width: number) => { + switch (pointingDirection) { + case 'top': return `0 ${width / 2}px ${height}px ${width / 2}px` + case 'left': return `${height / 2}px ${width}px ${height / 2}px 0` + case 'bottom': return `${height}px ${width / 2}px 0 ${width / 2}px` + case 'right': return `${height / 2}px 0 ${height / 2}px ${width}px` + + default: throw new Error('Passed invalid argument to triangle, please pass correct poitingDirection e.g. \'right\'.') + } +} + +// needed for border-color +const reverseDirection = { + left: 'right', + right: 'left', + top: 'bottom', + bottom: 'top', +} /** - * CSS to represent triangle with any pointing direction. + * CSS to represent triangle with any pointing direction with an optional background color. Accepts number or px values for height and width. * * @example * // Styles as object usage * * const styles = { - * ...triangle({ pointing: 'right', width: '100px', height: '100px', color: 'red' }) + * ...triangle({ pointingDirection: 'right', width: '100px', height: '100px', foregroundColor: 'red' }) * } * * * // styled-components usage * const div = styled.div` - * ${triangle({ pointing: 'right', width: '100px', height: '100px', color: 'red' })} + * ${triangle({ pointingDirection: 'right', width: '100px', height: '100px', foregroundColor: 'red' })} * * * // CSS as JS Output @@ -29,51 +58,26 @@ * } */ -type PointingDirection = 'top' | 'right' | 'bottom' | 'left' - -type BorderWidthArgs = { - height: number, - width: number, - pointingDirection: PointingDirection, -} - -type TriangleArgs = BorderWidthArgs & { - color: string, -} - -const getBorderWidth = ({ pointingDirection, height, width } : BorderWidthArgs) => { - switch (pointingDirection) { - case 'top': return `0 ${width / 2}px ${height}px ${width / 2}px` - case 'left': return `${height / 2}px ${width}px ${height / 2}px 0` - case 'bottom': return `${height}px ${width / 2}px 0 ${width / 2}px` - case 'right': return `${height / 2}px 0 ${height / 2}px ${width}px` - - default: throw new Error('Passed invalid argument to triangle, please pass correct poitingDirection e.g. \'right\'.') +function triangle({ pointingDirection, height, width, foregroundColor, backgroundColor = 'transparent' } : TriangleArgs) { + const unitlessHeight = parseFloat(height) + const unitlessWidth = parseFloat(width) + if (isNaN(unitlessHeight) || isNaN(unitlessWidth)) { + throw new Error('Passed an invalid value to `height` or `width`. Please provide a pixel based unit') } -} -// needed for border-color -const reverseDirection = { - left: 'right', - right: 'left', - top: 'bottom', - bottom: 'top', + return { + 'border-color': backgroundColor, + 'width': '0', + 'height': '0', + 'border-width': getBorderWidth(pointingDirection, unitlessHeight, unitlessWidth), + 'border-style': 'solid', + /* + * javascript Object sorting orders 'border-color' after 'border-bottom-color' + * (bottom-b) is before (bottom-c) - !important is needed + * { border-bottom-color: 'red', border-color: 'transparent' } + */ + [`border-${reverseDirection[pointingDirection]}-color`]: `${foregroundColor} !important`, + } } -const triangle = ({ pointingDirection, width, height, color } : TriangleArgs) => ({ - 'border-color': 'transparent', - 'width': '0', - 'height': '0', - 'border-width': getBorderWidth({ height, width, pointingDirection }), - 'border-style': 'solid', - - /* - * javascript Object sorting orders 'border-color' after 'border-bottom-color' - * (bottom-b) is before (bottom-c) - !important is needed - * { border-bottom-color: 'red', border-color: 'transparent' } - */ - - [`border-${reverseDirection[pointingDirection]}-color`]: `${color} !important`, -}) - export default triangle