diff --git a/src/__tests__/transform.js b/src/__tests__/transform.js index 71b8a79..6930546 100644 --- a/src/__tests__/transform.js +++ b/src/__tests__/transform.js @@ -12,6 +12,20 @@ it('transforms a single transform value with string', () => { }) }) +it('transforms a single transform value with percentage', () => { + expect(transformCss([['transform', 'translate(100%, 100%)']])).toEqual({ + transform: [{ translateY: '100%' }, { translateX: '100%' }], + }) +}) + +it('transforms multiple transform values with percentage', () => { + expect( + transformCss([['transform', 'translateY(100%) translateX(100%)']]) + ).toEqual({ + transform: [{ translateX: '100%' }, { translateY: '100%' }], + }) +}) + it('transforms multiple transform values', () => { expect(transformCss([['transform', 'scaleX(5) skewX(1deg)']])).toEqual({ transform: [{ skewX: '1deg' }, { scaleX: 5 }], diff --git a/src/tokenTypes.js b/src/tokenTypes.js index 497001d..33e5b89 100644 --- a/src/tokenTypes.js +++ b/src/tokenTypes.js @@ -35,7 +35,7 @@ const numberRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?)$/i // Note lengthRe is sneaky: you can omit units for 0 const lengthRe = /^(0$|(?:[+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?)(?=px$))/i const unsupportedUnitRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?(ch|em|ex|rem|vh|vw|vmin|vmax|cm|mm|in|pc|pt))$/i -const angleRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?(?:deg|rad))$/i +const angleRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?(?:deg|rad|grad|turn))$/i const percentRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?%)$/i const noopToken = predicate => node => (predicate(node) ? '' : null) diff --git a/src/transforms/transform.js b/src/transforms/transform.js index b3c7bc3..c39719b 100644 --- a/src/transforms/transform.js +++ b/src/transforms/transform.js @@ -1,24 +1,24 @@ -import { SPACE, COMMA, LENGTH, NUMBER, ANGLE } from '../tokenTypes' +import { SPACE, COMMA, LENGTH, NUMBER, ANGLE, PERCENT } from '../tokenTypes' -const oneOfType = tokenType => functionStream => { - const value = functionStream.expect(tokenType) +const oneOfTypes = tokenTypes => functionStream => { + const value = functionStream.expect(...tokenTypes) functionStream.expectEmpty() return value } -const singleNumber = oneOfType(NUMBER) -const singleLength = oneOfType(LENGTH) -const singleAngle = oneOfType(ANGLE) -const xyTransformFactory = tokenType => ( +const singleNumber = oneOfTypes([NUMBER]) +const singleLengthOrPercent = oneOfTypes([LENGTH, PERCENT]) +const singleAngle = oneOfTypes([ANGLE]) +const xyTransformFactory = tokenTypes => ( key, valueIfOmitted ) => functionStream => { - const x = functionStream.expect(tokenType) + const x = functionStream.expect(...tokenTypes) let y if (functionStream.hasTokens()) { functionStream.expect(COMMA) - y = functionStream.expect(tokenType) + y = functionStream.expect(...tokenTypes) } else if (valueIfOmitted !== undefined) { y = valueIfOmitted } else { @@ -31,18 +31,18 @@ const xyTransformFactory = tokenType => ( return [{ [`${key}Y`]: y }, { [`${key}X`]: x }] } -const xyNumber = xyTransformFactory(NUMBER) -const xyLength = xyTransformFactory(LENGTH) -const xyAngle = xyTransformFactory(ANGLE) +const xyNumber = xyTransformFactory([NUMBER]) +const xyLengthOrPercent = xyTransformFactory([LENGTH, PERCENT]) +const xyAngle = xyTransformFactory([ANGLE]) const partTransforms = { perspective: singleNumber, scale: xyNumber('scale'), scaleX: singleNumber, scaleY: singleNumber, - translate: xyLength('translate', 0), - translateX: singleLength, - translateY: singleLength, + translate: xyLengthOrPercent('translate', 0), + translateX: singleLengthOrPercent, + translateY: singleLengthOrPercent, rotate: singleAngle, rotateX: singleAngle, rotateY: singleAngle,