Wildhoney / ReactShadow

:beginner: Utilise Shadow DOM in React with all the benefits of style encapsulation.
https://react-shadow.herokuapp.com/
MIT License
1.28k stars 79 forks source link

Using Sass -> css -> component in #shadow-root #80

Open poldee-lgi opened 4 years ago

poldee-lgi commented 4 years ago

Hello,

I'm trying to configure my webpack config to convert my scss files to css and the insert in into my component's shadow-root context.

I'm starting to think it's not possible :-|

Example :

In my component I import my style like this. Currently, it's a style.js file import { style, colors } from './style';

style is defined and usable. YEAH!! colors is defined, but colorLogoGrey, colorBrand and colorGreyActive are all undefined

style.js

import {
  colorLogoGrey,
  colorBrand,
  colorGreyActive,
} from '../../../style/style.scss';

export const colors = {
  colorLogoGrey,
  colorBrand,
  colorGreyActive,
};

export const style = {
  attachment: {
    position: 'relative',
    padding: '16px 75px 16px 54px',
    margin: '0 15px 17px 0',
    border: '1px solid #E2ECEF',
    borderRadius: '4px',
    backgroundColor: '#fff',
    display: 'flex',
    flexDirection: 'row',
    flexWrap: 'wrap',
  },
  attachmentIcon: {
    position: 'absolute',
    left: '15px',
    paddingRight: '5px',
    marginRight: '25px',
  },
  attachmentInfo: {
    width: '100%',
    padding: '0px 10px',
  },
  action: {
    display: 'flex',
    position: 'absolute',
    right: '15px',
  },
  addedBy: {
    display: 'flex',
    color: colorGreyActive,
    fontSize: '13px',
    paddingTop: '20px',
  },
  addedByLabel: {
    paddingRight: '15px',
    fontWeight: 'bold',
  },
  addedByInfo: {
    padding: '0 3px',
  }
};

As you can see, I'm trying to import colors from style.scss

I've tried many different combinations with the following webpack configuration:

  {
    test: /\.(s)?css$/,
    use: [
      // 'to-string-loader',
      // 'css-to-string-loader',
      // 'style-loader',
      {
        loader: 'style-loader',
        options: {
          insert: 'body',
        },
      }
      'css-loader?sourceMap',
      'postcss-loader?sourceMap',
      // 'resolve-url-loader',
      // {
      //   loader: 'resolve-url-loader',
      //   options: {
      //     root: sourcePath,
      //   },
      // },
      'sass-loader?sourceMap',
    ],
  },

If I simply use style-loader evertything renders properly, but the <style> tag get loaded in the head. Is it possible to set this up so the style gets bundled up inside the shadow-root?

webpack starts and serves my component properly displayed and formated except for the colors and fonts.

Please help :-) Thanks

lancesnider commented 2 years ago

I know this is an ooooold issue, but for anyone still trying to figure it out, here's how I did it.

Make sure you have the to-sass-loader and to-string-loader installed.

In my webpack.config:

  module: {
    rules: [
      ...
      {
        // look for .scss files
        test: /\.scss$/,
        use: [
          {
            loader: 'to-string-loader',
          },
          {
            loader: 'css-loader',
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true,
            },
          },
        ],
      },

In your top-level React component. The dangerouslySetInnerHTML is the important bit that you may have been missing.

import React from 'react';

import ReactDOM from 'react-dom';
import root from 'react-shadow';

import App from 'containers/App';

// To work within the shadow dom, we need to import the SASS as a string
import stylesheet from './content.styles.scss';

// attach the sidebar to the page body
const app = document.createElement('div');
app.id = 'your-root';
app.className = 'your-root';
document.body.appendChild(app);

ReactDOM.render(
      <root.div>
        <style dangerouslySetInnerHTML={{ __html: stylesheet }} />
        <App />
      </root.div>
  app
);
evanjmg commented 1 year ago

but how does one support icons?