src/index.js
function getValueDoppelganger(key, originalValue, isRtl) {
  if (isNullOrUndefined(originalValue)) {
    return originalValue
  }

  const flowDirection = isRtl ? 'rtl' : 'ltr'

  if (isObject(originalValue)) {
    return convert(originalValue, flowDirection) // recurssion 🌀
  }

  const {
    isLogical,
    logicallessValue,
    isImportant,
    importantlessValue,
  } = analyzeOriginalValue(originalValue)

  if (canHaveLogical.includes(key) && !isLogical) {
    return originalValue
  }

  const isFourDirectionalShorthand = includes(
    [
      'margin',
      'padding',
      'borderColor',
      'borderRadius',
      'borderStyle',
      'borderWidth',
    ],
    key,
  )

  if (
    isLogical &&
    !isRtl &&
    !isFourDirectionalShorthand &&
    !key.match(/(background)|((t|T)ransformOrigin)/)
  ) {
    return logicallessValue
  }

  const conversionMap = valuesToConvert[flowDirection]

  // The logical props and values changes the default way you write four-directional shorhands
  // so that the order of values is `block-start`, `inline-start`, `block-end` and `inline-end`, which,
  // for the `inline-*` sides, is the opposite of how they are written without the `logical` keyword
  if (isLogical && isFourDirectionalShorthand) {
    return isRtl
      ? logicallessValue
      : convertValues(
          key,
          importantlessValue,
          conversionMap,
          isImportant,
          // Reversing `isRtl` like this is crooked, but for the time being, it is the easiest way to
          // address how values of four-directional shorthand properties with the `logical` keyword
          // should be handled according to the spec.
          !isRtl,
        )
  }

  return convertValues(
    key,
    importantlessValue,
    conversionMap,
    isImportant,
    isRtl,
  )
}
function getValueDoppelganger(key, originalValue, isRtl) {
  if (isNullOrUndefined(originalValue)) {
    return originalValue
  }

  const flowDirection = isRtl ? 'rtl' : 'ltr'

  if (isObject(originalValue)) {
    return convert(originalValue, flowDirection) // recurssion 🌀
  }

  const {
    isLogical,
    logicallessValue,
    isImportant,
    importantlessValue,
  } = analyzeOriginalValue(originalValue)

  if (canHaveLogical.includes(key) && !isLogical) {
    return originalValue
  }

  const isFourDirectionalShorthand = includes(
    [
      'margin',
      'padding',
      'borderColor',
      'borderRadius',
      'borderStyle',
      'borderWidth',
    ],
    key,
  )

  if (
    isLogical &&
    !isRtl &&
    !isFourDirectionalShorthand &&
    !key.match(/(background)|((t|T)ransformOrigin)/)
  ) {
    return logicallessValue
  }

  const conversionMap = valuesToConvert[flowDirection]

  // The logical props and values changes the default way you write four-directional shorhands
  // so that the order of values is `block-start`, `inline-start`, `block-end` and `inline-end`, which,
  // for the `inline-*` sides, is the opposite of how they are written without the `logical` keyword
  if (isLogical && isFourDirectionalShorthand) {
    return isRtl
      ? logicallessValue
      : convertValues(
          key,
          importantlessValue,
          conversionMap,
          isImportant,
          // Reversing `isRtl` like this is crooked, but for the time being, it is the easiest way to
          // address how values of four-directional shorthand properties with the `logical` keyword
          // should be handled according to the spec.
          !isRtl,
        )
  }

  return convertValues(
    key,
    importantlessValue,
    conversionMap,
    isImportant,
    isRtl,
  )
}
let's try to keep the complexity down... If we have to do this much more, let's break this up /* eslint-disable complexity 
Logically converts the given value to the correct version based on the key and flow direction context
@param {String} key this is the key (note: this should be the RTL version of the originalKey)
@param {String|Number|Object} originalValue the original css property value. If it's an object, then we'll convert that as well
@param {Boolean} isRtl Should conversion happen in RTL context?
@return {String|Number|Object} the converted value