diff --git a/package.json b/package.json index e9e760683e..237bc64bf0 100644 --- a/package.json +++ b/package.json @@ -94,6 +94,7 @@ "react-custom-scrollbars": "^4.2.1", "react-fela": "^7.2.0", "react-popper": "^1.0.2", + "shortcss": "^0.1.3", "what-input": "^5.1.2" }, "devDependencies": { diff --git a/src/lib/felaExpandCssShorthandsPlugin.ts b/src/lib/felaExpandCssShorthandsPlugin.ts new file mode 100644 index 0000000000..0996ea7617 --- /dev/null +++ b/src/lib/felaExpandCssShorthandsPlugin.ts @@ -0,0 +1,29 @@ +import * as _ from 'lodash' +import * as SC from 'shortcss' + +export default () => { + const expandCssShorthands = styles => { + return _.keys(styles).reduce((acc, cssPropertyName) => { + const cssPropertyValue = styles[cssPropertyName] + + if (typeof cssPropertyValue === 'object') { + return { ...acc, [cssPropertyName]: expandCssShorthands(cssPropertyValue) } + } + + if (SC.isShorthand(_.kebabCase(cssPropertyName))) { + const expandedProps = SC.expand(_.kebabCase(cssPropertyName), String(cssPropertyValue)) + return { ...acc, ...transformKebabCaseKeysToCamelCase(expandedProps) } + } + + return { ...acc, [cssPropertyName]: cssPropertyValue } + }, {}) + } + + return expandCssShorthands +} + +const transformKebabCaseKeysToCamelCase = obj => { + return _.mapKeys(obj, (value, key) => { + return _.camelCase(key) + }) +} diff --git a/src/lib/felaRenderer.tsx b/src/lib/felaRenderer.tsx index 6b6b77e1bf..6ef24d41b3 100644 --- a/src/lib/felaRenderer.tsx +++ b/src/lib/felaRenderer.tsx @@ -1,5 +1,6 @@ import { createRenderer } from 'fela' import felaSanitizeCss from './felaSanitizeCssPlugin' +import felaExpandCssShorthandsPlugin from './felaExpandCssShorthandsPlugin' import felaPluginFallbackValue from 'fela-plugin-fallback-value' import felaPluginPlaceholderPrefixer from 'fela-plugin-placeholder-prefixer' import felaPluginPrefixer from 'fela-plugin-prefixer' @@ -15,6 +16,7 @@ const createRendererConfig = (options: any = {}) => ({ skip: ['content'], }), + felaExpandCssShorthandsPlugin(), felaPluginPlaceholderPrefixer(), felaPluginPrefixer(), diff --git a/test/specs/lib/felaExpandCssShorthandsPlugin-test.ts b/test/specs/lib/felaExpandCssShorthandsPlugin-test.ts new file mode 100644 index 0000000000..714827956f --- /dev/null +++ b/test/specs/lib/felaExpandCssShorthandsPlugin-test.ts @@ -0,0 +1,80 @@ +import felaExpandCssShorthandsPlugin from 'src/lib/felaExpandCssShorthandsPlugin' + +const expandCssShorthands = felaExpandCssShorthandsPlugin() + +describe('felaExpandCssShorthandsPlugin', () => { + test('should expand one-word css prop', () => { + const style = { + display: 'block', + margin: '0px 10px', + } + + expect(expandCssShorthands(style)).toEqual({ + display: 'block', + marginTop: '0px', + marginRight: '10px', + marginBottom: '0px', + marginLeft: '10px', + }) + }) + + test('should expand two-words css prop', () => { + const style = { + borderColor: 'red', + } + + expect(expandCssShorthands(style)).toEqual({ + borderTopColor: 'red', + borderRightColor: 'red', + borderBottomColor: 'red', + borderLeftColor: 'red', + }) + }) + + test('should expand pseudo object', () => { + const style = { + display: 'block', + '::before': { + margin: '0px', + }, + } + + expect(expandCssShorthands(style)).toEqual({ + display: 'block', + '::before': { + marginTop: '0px', + marginRight: '0px', + marginBottom: '0px', + marginLeft: '0px', + }, + }) + }) + + test('should expand nested pseudo object', () => { + const style = { + display: 'block', + '::before': { + margin: '0px', + ':hover': { + padding: '10px', + }, + }, + } + + expect(expandCssShorthands(style)).toEqual({ + display: 'block', + '::before': { + marginTop: '0px', + marginRight: '0px', + marginBottom: '0px', + marginLeft: '0px', + ':hover': { + paddingTop: '10px', + paddingRight: '10px', + paddingBottom: '10px', + paddingLeft: '10px', + }, + }, + }) + }) +}) diff --git a/yarn.lock b/yarn.lock index be6eee394d..874c26ac3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1680,6 +1680,10 @@ css-select@^1.1.0, css-select@~1.2.0: domutils "1.5.1" nth-check "~1.0.1" +css-shorthand-properties@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz#1c808e63553c283f289f2dd56fcee8f3337bd935" + css-what@2.1: version "2.1.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" @@ -7302,6 +7306,12 @@ shellwords@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" +shortcss@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/shortcss/-/shortcss-0.1.3.tgz#ee2a7904d80b7f5502c98408f4a2f313faadfb48" + dependencies: + css-shorthand-properties "^1.0.0" + sigmund@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"