diff --git a/package.json b/package.json index 5894ce55..9236f183 100644 --- a/package.json +++ b/package.json @@ -31,9 +31,10 @@ }, "dependencies": { "deep-equal": "^1.0.1", + "lodash.kebabcase": "^4.1.1", "object-assign": "^4.1.1", - "react-side-effect": "^1.1.0", - "prop-types": "^15.5.4" + "prop-types": "^15.5.4", + "react-side-effect": "^1.1.0" }, "devDependencies": { "babel-cli": "^6.24.0", diff --git a/src/Helmet.js b/src/Helmet.js index d88ee7e4..bbf339b4 100644 --- a/src/Helmet.js +++ b/src/Helmet.js @@ -7,7 +7,8 @@ import { handleClientStateChange, mapStateOnServer, reducePropsToState, - warn + warn, + getBodyStyleAttributeValue } from "./HelmetUtils.js"; import {TAG_NAMES, VALID_TAG_NAMES} from "./HelmetConstants.js"; @@ -149,9 +150,16 @@ const Helmet = Component => }; case TAG_NAMES.BODY: + if (newChildProps.style) { + newChildProps.style = getBodyStyleAttributeValue( + newChildProps.style + ); + } return { ...newProps, - bodyAttributes: {...newChildProps} + bodyAttributes: { + ...newChildProps + } }; case TAG_NAMES.HTML: diff --git a/src/HelmetUtils.js b/src/HelmetUtils.js index 63ad85a6..37a84522 100644 --- a/src/HelmetUtils.js +++ b/src/HelmetUtils.js @@ -1,5 +1,7 @@ import React from "react"; import objectAssign from "object-assign"; +import kebabCase from "lodash.kebabcase"; + import { ATTRIBUTE_NAMES, HELMET_ATTRIBUTE, @@ -640,9 +642,19 @@ const mapStateOnServer = ({ title: getMethodsForTag(TAG_NAMES.TITLE, {title, titleAttributes}, encode) }); +const getBodyStyleAttributeValue = (style: ?any) => { + if (typeof style === "object") { + return Object.keys(style) + .map(key => `${kebabCase(key)}: ${style[key]}`) + .join(";"); + } + return style; +}; + export {convertReactPropstoHtmlAttributes}; export {handleClientStateChange}; export {mapStateOnServer}; export {reducePropsToState}; export {requestAnimationFrame}; export {warn}; +export {getBodyStyleAttributeValue}; diff --git a/test/HelmetDeclarativeTest.js b/test/HelmetDeclarativeTest.js index bdcf5229..a3aa39d2 100644 --- a/test/HelmetDeclarativeTest.js +++ b/test/HelmetDeclarativeTest.js @@ -774,6 +774,47 @@ describe("Helmet - Declarative API", () => { }); }); + it("body style attribute as string", done => { + ReactDOM.render( + + + , + container + ); + + requestAnimationFrame(() => { + const body = document.querySelector("body"); + const styleAttributeValue = body.getAttribute("style"); + expect(styleAttributeValue).to.be.a("string"); + expect(styleAttributeValue).to.equal("color: red"); + done(); + }); + }); + + it("body style attribute as object is translated to a string", done => { + ReactDOM.render( + + + , + container + ); + + requestAnimationFrame(() => { + const body = document.querySelector("body"); + const styleAttributeValue = body.getAttribute("style"); + + // normal behaviour + expect(styleAttributeValue).to.be.a("string"); + + // old behaviour + expect(styleAttributeValue).to.not.equal("[object Object]"); + + // new behaviour + expect(styleAttributeValue).to.equal("color: red"); + done(); + }); + }); + it("sets attributes based on the deepest nested component", done => { ReactDOM.render(
diff --git a/yarn.lock b/yarn.lock index 1cb8be5d..712ee9af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3248,6 +3248,10 @@ lodash.isarray@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" +lodash.kebabcase@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" + lodash.keys@^3.0.0, lodash.keys@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"