# All files / helpers directionalProperty.js

100% Statements 14/14
100% Branches 7/7
100% Functions 3/3
100% Lines 13/13

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    7x

    148x
    124x
    124x
    124x

    40x
    40x
    160x
    148x

    40x

    40x
    40x
    40x

     // @flow
    const positionMap = ['top', 'right', 'bottom', 'left']

    function generateProperty(property: string, position: string) {
      if (!property) return position
      const splitPropertyName = property.split('-')
      splitPropertyName.splice(1, 0, position)
      return splitPropertyName.join('-')
    }

    function generateStyles(property: string, valuesWithDefaults: Array<?string>) {
      const styles = {}
      for (let i = 0; i < valuesWithDefaults.length; i += 1) {
        if (valuesWithDefaults[i]) {
          styles[generateProperty(property, positionMap[i])] = valuesWithDefaults[i]
        }
      }
      return styles
    }

    /**
     * The directional property helper enables shorthand for direction based properties. It accepts a property and up to four values that map to top, right, bottom, and left, respectively. You can optionally pass an empty string to get only the directional values as properties. You can optionally pass a null argument for a directional value to ignore it.
     * @example
     * // Styles as object usage
     * const styles = {
     *   ...directionalProperty('padding', '12px', '24px', '36px', '48px')
     * }
     *
     * // styled-components usage
     * const div = styled.div`
     *   ${directionalProperty('padding', '12px', '24px', '36px', '48px')}
     * `
     *
     * // CSS as JS Output
     *
     * div {
     *   'padding-top': '12px',
     *   'padding-right': '24px',
     *   'padding-bottom': '36px',
     *   'padding-left': '48px'
     * }
     */

    function directionalProperty(property: string, ...values: Array<?string>) {
      // $FlowIgnoreNextLine doesn't understand destructuring with chained defaults.
      const [firstValue, secondValue = firstValue, thirdValue = firstValue, fourthValue = secondValue] = values
      const valuesWithDefaults = [firstValue, secondValue, thirdValue, fourthValue]
      return generateStyles(property, valuesWithDefaults)
    }

    export default directionalProperty