Netlify-cms: gatsby-plugin-netlify-cms - registerPreviewStyle

Created on 5 Jun 2018  路  7Comments  路  Source: netlify/netlify-cms

Is there any possibility to use a css in js solution like styled components with the preview?

At the moment there is no style applied and registerPreviewStyle does just link to a css file..

duplicate

Most helpful comment

Here, implemented with hooks!

import React, { useState, useEffect } from 'react';
import { StyleSheetManager } from 'styled-components';

function StyleInjector({ children }) {
  const [iframeRef, setIframeRef] = useState(null);

  useEffect(() => {
    const iframe = document.getElementsByTagName('iframe')[0];
    const iframeHeadElem = iframe.contentDocument.head;
    setIframeRef(iframeHeadElem);
  }, []);

  return (
    iframeRef && (
      <StyleSheetManager target={iframeRef}>{children}</StyleSheetManager>
    )
  );
}

export default function withStyledComponentsRendered(Comp) {
  return props => (
    <StyleInjector>
      <Comp {...props} />
    </StyleInjector>
  );
}

and usage:

CMS.registerPreviewTemplate(
  'index',
  withStyledComponentsRendered(IndexPagePreview)
);

I'm now getting another problem now with a forever-loading StaticQuery. Not sure if it's related yet...
(another edit -- the above was because I was trying to access the CMS locally instead of on netlify)

All 7 comments

See this issue:

https://github.com/netlify/netlify-cms/issues/793

I made a solution for styled components (not the prettiest) based on the discussion in that thread, see below.

This is in my cms.js where i register the previews:

import { StyleSheetManager } from 'styled-components'

//Component used to Enable netlify CMS to apply the styles added through styled-components
class CSSInjector extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      iframeRef: ''
    }
  }

  componentDidMount() {
    const iframe = document.querySelector(".nc-previewPane-frame")
    const iframeHeadElem = iframe.contentDocument.head;
    this.setState({ iframeRef: iframeHeadElem })
  }

  render() {
    return (
      <div>
        { this.state.iframeRef && (
          <StyleSheetManager target={this.state.iframeRef}>
            { this.props.children }
          </StyleSheetManager>
        )}
      </div>
    )
  }
}

//Used like
CMS.registerPreviewTemplate('index', props => (
  <CSSInjector>
    <IndexPagePreview {...props} />
  </CSSInjector>
))

Duplicate of #793.

Also note you can now pass strings into registerPreviewStyle: https://www.netlifycms.org/docs/beta-features/#raw-css-in-registerpreviewstyle.

this solution does not work with v2:
grafik

this might be the problem: const iframe = document.querySelector(".nc-previewPane-frame");

Replace the first line in componentDidMount with

const iframe = document.getElementsByTagName('iframe')[0]

Here, implemented with hooks!

import React, { useState, useEffect } from 'react';
import { StyleSheetManager } from 'styled-components';

function StyleInjector({ children }) {
  const [iframeRef, setIframeRef] = useState(null);

  useEffect(() => {
    const iframe = document.getElementsByTagName('iframe')[0];
    const iframeHeadElem = iframe.contentDocument.head;
    setIframeRef(iframeHeadElem);
  }, []);

  return (
    iframeRef && (
      <StyleSheetManager target={iframeRef}>{children}</StyleSheetManager>
    )
  );
}

export default function withStyledComponentsRendered(Comp) {
  return props => (
    <StyleInjector>
      <Comp {...props} />
    </StyleInjector>
  );
}

and usage:

CMS.registerPreviewTemplate(
  'index',
  withStyledComponentsRendered(IndexPagePreview)
);

I'm now getting another problem now with a forever-loading StaticQuery. Not sure if it's related yet...
(another edit -- the above was because I was trying to access the CMS locally instead of on netlify)

@a8t, have you thought of putting this in a separate package, would be pretty nice? 馃檪

Was this page helpful?
0 / 5 - 0 ratings