Skip to content

Add shadow-DOM option type for injectType #536

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

Justinidlerz
Copy link

This PR contains a:

  • new feature

Motivation / Use-Case

Extract styles and put into a container, then can injected into the shadow-DOM conainer

import component from 'component';
import getCss from 'style-loader/dist/runtime/injectStyleInScript';

class MyElement extends Element {
    constructor() {
        super();
        const shadowContent = this.attachShadow({ mode: 'open' });  
        const style = document.createElement('style');
        style.innerHTML = getCss();
        shadowContent.appendChild(style);
    }
}

@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Sep 13, 2021

CLA Signed

The committers are authorized under a signed CLA.

Copy link
Member

@alexander-akait alexander-akait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong solution, you don't need style-loader in this case, just use css-loader and use toString() from returned content

@Justinidlerz
Copy link
Author

Justinidlerz commented Sep 13, 2021

@alexander-akait Thanks for reviewing the PR.
css-loader can not combine all styles into one container.
Such as a react App has many components and I want to mount that into a shadow-DOM root.
But I don't want to import CSS files from each component.

So the full case see like:
/a/component.tsx

import css from './style.css'

// ...
export component;

/b/component.tsx

import css from './style.css'

// ...
export component;

There have many components...

main.tsx

import Main from 'components';
import {render} from 'react-dom'
import getCss from 'style-loader/dist/runtime/injectStyleInScript';

class MyElement extends Element {
    constructor() {
        super();
        const shadowContent = this.attachShadow({ mode: 'open' });  
        const style = document.createElement('style');
        style.innerHTML = getCss();
        shadowContent.appendChild(style);
        const root = document.createElement('div');
        shadowContent.appendChild(root);

        render(<Main />, root);
    }
}

@alexander-akait
Copy link
Member

run css.toString()

@alexander-akait
Copy link
Member

@Justinidlerz
Copy link
Author

@alexander-akait So you mean I can use that see like:

import Main from 'components';
import {render} from 'react-dom'
import allCss from 'css-loader/dist/runtime/api';

class MyElement extends Element {
    constructor() {
        super();
        const shadowContent = this.attachShadow({ mode: 'open' });  
        const style = document.createElement('style');
        style.innerHTML = allCss.toString(); // This one?
        shadowContent.appendChild(style);
        const root = document.createElement('div');
        shadowContent.appendChild(root);

        render(<Main />, root);
    }
}

@alexander-akait
Copy link
Member

No, just use:

import Main from 'components';
import {render} from 'react-dom'
import styles from './style.css';

class MyElement extends Element {
    constructor() {
        super();
        const shadowContent = this.attachShadow({ mode: 'open' });  
        const style = document.createElement('style');
        style.innerHTML = styles.toString();
        shadowContent.appendChild(style);
        const root = document.createElement('div');
        shadowContent.appendChild(root);

        render(<Main />, root);
    }
}

@Justinidlerz
Copy link
Author

@alexander-akait Sorry, I don't quite understand the method of use you proposed
Could you please give me an example of how to use the css-loader to getting the combined styles?

@alexander-akait
Copy link
Member

Example above

@alexander-akait
Copy link
Member

Just remove style-loader, you don't need this

@Justinidlerz
Copy link
Author

No, just use:

import Main from 'components';
import {render} from 'react-dom'
import styles from './style.css';

class MyElement extends Element {
    constructor() {
        super();
        const shadowContent = this.attachShadow({ mode: 'open' });  
        const style = document.createElement('style');
        style.innerHTML = styles.toString();
        shadowContent.appendChild(style);
        const root = document.createElement('div');
        shadowContent.appendChild(root);

        render(<Main />, root);
    }
}

I can import the root CSS file see like your provided case. But how to apply nested component styles?

@alexander-akait
Copy link
Member

Sorry, it is not QA services, please use stackoverflow for questions and personal help, we don't need this API, because css-loader provide your ability to use toString and return string of CSS, it is enough for your case

@Justinidlerz
Copy link
Author

/a/component.tsx

import css from './style.css'

const A = () => {
   return <div />
}

export default A;

/b/component.tsx

import css from './style.css'
import A from '../a/component'

const B = () => {
   return <div>
       <A />
   </div>
}
export component;

There have many components...

main.tsx

import B from 'b/component';
import {render} from 'react-dom'
import getCss from 'style-loader/dist/runtime/injectStyleInScript';

class MyElement extends Element {
    constructor() {
        super();
        const shadowContent = this.attachShadow({ mode: 'open' });  
        const style = document.createElement('style');
        style.innerHTML = getCss();
        shadowContent.appendChild(style);
        const root = document.createElement('div');
        shadowContent.appendChild(root);

        render(<Main />, root);
    }
}

@alexander-akait
Copy link
Member

You don't need this API, what is not clear from my answer? Remove style-loader and don't use this, you don't need this for custom components.

@alexander-akait
Copy link
Member

You mix multiple react component with the one custom component, this is the wrong approach to what you are trying to achieve

@alexander-akait
Copy link
Member

You should not have import css from './style.css' for react components, styles only inside custom component

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants