diff --git a/__tests__/common/transforms.test.js b/__tests__/common/transforms.test.js index 691e2ef2..7f779eaf 100644 --- a/__tests__/common/transforms.test.js +++ b/__tests__/common/transforms.test.js @@ -544,6 +544,28 @@ describe('common', () => { }); }); + describe('size/pxToRem', () => { + const pxToRemTransformer = transforms["size/pxToRem"].transformer; + + it('converts pixel to rem', () => { + expect(pxToRemTransformer({value: '12px'})).toBe('0.75rem'); + }); + it('converts pixel to rem using custom base font', () => { + expect(pxToRemTransformer({value: '14px'}, {basePxFontSize: 14})).toBe('1rem'); + }); + it('nonzero rem value not changed', () => { + expect(pxToRemTransformer({value: '2rem'})).toBe('2rem'); + }); + ['0px', '0', '0rem'].forEach((value) => { + it(`zero value "${value}" is returned without a unit`, () => { + expect(pxToRemTransformer({value})).toBe('0'); + }); + }); + it('should throw an error if prop value is Nan', () => { + expect( () => pxToRemTransformer({value: "a"})).toThrow(); + }); + }); + describe('size/rem', () => { it('should work', () => { var value = transforms["size/rem"].transformer({ diff --git a/lib/common/transforms.js b/lib/common/transforms.js index 5343309d..cc580061 100644 --- a/lib/common/transforms.js +++ b/lib/common/transforms.js @@ -696,6 +696,40 @@ module.exports = { } }, + /** + * Scales the pixel value to rem, and adds 'rem' to the end of non-zero values. If you define a "basePxFontSize" on the platform in your config, it will be used to scale the pixel value, otherwise 16 (default web font size) will be used. + * + * ```js + * // Matches: prop.attributes.category === 'size' + * // Returns: + * 0 + * 1rem + * ``` + */ + 'size/pxToRem': { + type: 'value', + matcher: (prop) => prop.attributes.category === 'size', + transformer: (prop, options) => { + const baseFont = (options && options.basePxFontSize) || 16; + const floatVal = parseFloat(prop.value); + + if (isNaN(floatVal)) { + throwSizeError(prop.name, prop.value, 'rem'); + } + + if (floatVal === 0) { + return '0'; + } + + if (String(prop.value).indexOf('px') === -1) { + // ignore anything without a "px" unit + return prop.value; + } + + return `${floatVal / baseFont}rem`; + } + }, + /** * Takes a unicode point and transforms it into a form CSS can use. *