React Component Style Encapsulation
Asked Answered
P

0

6

I am trying to encapsulate styles for an embedded component. The component must prevent sites from easily overriding the styling without a script. The Shadow Dom was chosen to be used similar to Web Components.

This, however, creates problems with styles in webpack. All styles must be imported using import 'style.css' from each individual component without modification.

style-loader's insertInto option was meant to help this but this has just caused further problems.

...
        use: [
          {
            loader: 'style-loader',
            options: {
              insertInto: () => document.getElementById('host').shadowRoot
            },
          },
          {loader: 'css-loader'},
        ],
...

It yeilds the error:

Uncaught Invariant Violation: Target container is not a DOM element.

Unsure whether the item was loaded I created file to manage this (plain javascript so webpack config can use it):

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getShadow = exports.getRoot = void 0;

var getShadow = function getShadow() {
  if (getShadow.root != null) {
    // Create the shadow root.
    var pageRoot = document.getElementById('host');
    pageRoot.attachShadow({
      mode: 'open'
    });
    getShadow.root = pageRoot.shadowRoot;
  }

  return getShadow.root;
};

exports.getShadow = getShadow;

var getRoot = function getRoot() {
  if (getRoot.react === null) {
    // Create div element for react to render into
    getRoot.react = document.createElement('div');
    getRoot.react.setAttribute('id', 'react-root'); // Append react root to shadow root.

    getShadow().appendChild(reactRoot);
  }

  return getRoot.react;
};

exports.getRoot = getRoot;

Using getShadow for insertInto and getRoot for ReactDom.render.

This further yeilds:

addStyles.js:170 Uncaught Error: Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.

When attempting to move the create shadow logic purely into the webpack config and only look for it when creating the react components a new error arises:

semantic.min.css?6945:17 Uncaught DOMException: Failed to execute 'attachShadow' on 'Element': Shadow root cannot be created on a host which already hosts a shadow tree. at ./node_modules/semantic-ui-css/semantic.min.css.options.insertInto

Is this an issue with the semantic-ui framework?

Pantechnicon answered 26/6, 2019 at 14:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.