Coder Social home page Coder Social logo

Comments (13)

smalluban avatar smalluban commented on September 23, 2024 2

It's good to hear you've dealt with the problem.

In that case it would be nice to emulate the shadow dom and Shady CSS while still working in a light DOM, and later when it gets possible just turn on the Shaodw DOM back.

The polyfill emulates Shadow DOM, but in the way, that all of your problems still exist. In another hand sometimes giving up on Shadow DOM is not possible, as its distribution and CSS encapsulation features are required.

The only way is to teach authors of the libraries to create code, which is more general and not only applies to a specific technology. It is just disappointing, but React is one of the worsts in supporting custom elements. They also have no strong intention to make changes on that soon (facebook/react#11347).

As you moved out from React, it is not needed anymore to create a snippet of React factory (with ShadyCSS support). I'm closing issue, but feel free to re-open if you have any other concerns in this subject.

from hybrids.

Avnerus avatar Avnerus commented on September 23, 2024 1

Thanks! And thanks again for making HybridsJS, I'm enjoying it very much.

from hybrids.

Avnerus avatar Avnerus commented on September 23, 2024

Hi again!
I was able to make some progress. This is how I integrated for example, react-flags-select:

import ReactFlagsSelect from 'react-flags-select';
import ReactFlagsSelectStyle from 'react-flags-select/css/react-flags-select.css';

function reactify(fn, style) {
  return (host) => {
    const Component = fn(host);
      return (host, target) => {
          const reactStyle = document.createElement('style');
          reactStyle.innerHTML = style;
          ReactDOM.render(Component, target);
          target.appendChild(reactStyle)
     }    
  }  
} 
const LanguageSelect =  {
    render: reactify(({count}) =>
        <ReactFlagsSelect />,
        ReactFlagsSelectStyle
    )   
}   

It seems to work except there is some event retargeting issue that seems specific for that component.
Is that a reasonable way to solve my problem?

from hybrids.

Avnerus avatar Avnerus commented on September 23, 2024

As a followup on this issue, I just tried integrating react-select, and this one seems even more tricky.
It uses emotion to generate the CSS classes on the fly and append them to <head>, which I guess is unusable for shadow dom? There might be some API that can change this behavior, but I'm not sure how this works with 3rd part components. Any ideas? For now my only option if I want to use React components seems to be declaring shadowRoot: false for all of my components.
Thank you :)

from hybrids.

smalluban avatar smalluban commented on September 23, 2024

React components are not designed to work well in Shadow DOM. Like you wrote, styling might be the biggest problem and some event re-targeting.

The react counter example have used default settings of the render property to not over complicate example. However, I've changed it, and now it does not use Shadow DOM. You should avoid using it when wrapping React components.

The web component should be a bridge between React eco-system and web components. You can set properties and pass them to the component, so it then is easy to use react components with web components.

Look again at the react counter example, it is updated.

EDIT: In your example with ReactFlagsSelect styles should be applied to the document head, and only once. For now, they are appended to your custom element content every time when a render method is called. You don't have other properties to update component, but when they will be there, you can end with multiple style elements inside of every instance of your component (and those styles will be global).

from hybrids.

Avnerus avatar Avnerus commented on September 23, 2024

Hi,
Thank you for the insights!
So if I understand correctly, if one wants to use React components in a Hybrids / Web components application, shadow root must be disabled all the way down the hierarchy to the React component?
My question is then, can I still apply scoped CSS to my components when shadowRoot is off?
I thought this might be handled by ShadyCSS, but I guess it's not active? I tried do it it here and there was no scoping.

Meanwhile I also stumbled upon a strange bug when shadowDom is off, but unfortunately I couldn't recreate it in StackBlitz, perhaps it relates somehow to Webpack, but maybe you will have some insight. I had a conditional element with `{shadowRoot: false} like so:

    render: render(({phase}) => 
        html`
        ${phase == PHASE.SIGN_IN && html`<sign-in></sign-in>`}
        ${phase == PHASE.MAIN && html`<h1>main phase!</h1>`}
        <div>
            <button onclick=${phaseClick}> Change phase </button>
        </div>
     `, {shadowRoot :false})

When I changed the phase I would get this error.
It was trying to access some empty #text element where everything is null.
However, if I add just one space after the sign-in element like this:

${phase == PHASE.SIGN_IN && html`<sign-in></sign-in> `}

or, if I changed the sign-in element to be shadowRoot: true. Then there is no error!

If you would like I can open another issue for this, but as I said unfortunately this doesn't happen in StackBlitz, and I really tried to reproduce the exact same environment..!

Thanks,

/Avner

from hybrids.

smalluban avatar smalluban commented on September 23, 2024

I did not consider the case when Shadow DOM is used in the parent custom element... Even though your react wrapper is not using shadow root, it will be inside of another one. Using wrapper in "light" DOM - on document level is safe then, but not inside of the other custom elements.

In that case, the only solution would be to switch back to Shadow DOM in the wrapper and pass styles into the shadow root boundary. It is not impossible, you could extend reactify() to allow to take additional styles argument, and create them only once (if they are not yet applied) and update react component with ReactDOM.render() method.

The problem with event propagation stays, so it might not be super easy to wrap complex react components into the web components after all :( It is not strictly related to hybrids as much as to Shadow DOM boundary.

About the bug - it would be great to have a reproduction of the error. If on StackBlitz it works, try on https://codesandbox.io. It looks that actually, something might be wrong. Make sure you're using the latest version and if the error occurs on all browsers or only on specific one (especially on those, which polyfills Shadow DOM, like IE11 or Edge).

from hybrids.

smalluban avatar smalluban commented on September 23, 2024

You were right! It was a bug... :( I already found it, and on the master branch, there is a fix: 4fb72fb

If all CI tests pass I will release a new version.

from hybrids.

Avnerus avatar Avnerus commented on September 23, 2024

Hi!
Thanks again for the response. Yeah, it seems traditional React components and Shadow Dom are not really meant to be... I think for my current small project I would try to just avoid react entirely.

I'm still interested about my previous question though - Providing I use shadowRoot : false for all of my components, and just use Hybrids as a functional templating engine that has the potential to use the shadow dom - how would you go about styling the components with scoping, as if ShadyCSS was being used? Is there a way to 'activate' ShadyCSS when using shadowRoot : false ? Shouldn't that actually be the standard behavior?

Great that you found the bug! Because I still couldn't reproduce it with codesandbox. Happy to contribute to Hybrids :)

from hybrids.

smalluban avatar smalluban commented on September 23, 2024

Yeah, it seems traditional React components and Shadow Dom are not really meant to be...

It depends. If the React component is isolated from the document (for example, not listening event on document level - then retargeting might be a problem), you can still inject styles into the Shadow DOM once for instance. Then it should work fine. React can be attached to shadowRoot - luckily it does not listen to events on the document level, but on the root level (to pass to own event system). However, you have to manually take care about ShadyCSS (built in template engine supports it out of the box), if you want to support older browsers.

If I find a moment, I will try to make a more functional react wrapper and I will post it here.

Great that you found the bug! Because I still couldn't reproduce it with codesandbox. Happy to contribute to Hybrids :)

v4.0.2 just has been released with bugfix. The bug was related to putting custom element (with render factory options set to shadowRoot: false) inside the nested template. The error occurs only if you remove the nested template in the sequential render, so thank you for discovering the problem!

from hybrids.

Avnerus avatar Avnerus commented on September 23, 2024

Hi,
Thanks for everything! I confirm the upgrade fixes the problem I described earlier.
About React, well what made me give up, as I wrote earlier was dealing with react-select that uses emotion css, that dynamically creates styles and appends them to head..
Have you tried this though?
https://github.com/spring-media/react-web-component

I'm not sure if you meant to answer my previous question:

Providing I use shadowRoot : false for all of my components, and just use Hybrids as a functional templating engine that has the potential to use the shadow dom - how would you go about styling the components with scoping

Did you have an advice for that?
Thanks!

from hybrids.

smalluban avatar smalluban commented on September 23, 2024

react-web-component project might help, but it won't help with styles passing to head or problems with retargeting events - it is more a problem between Shadow DOM and how to react components are built.

Avoiding Shadow DOM at all will work. You will end up with a light DOM tree, as it would be created by react itself. However, the most powerful concept of web components is the Shadow DOM. It provides not only DOM and CSS encapsulation but also children distribution (by <slot> elements). The whole idea behind creating custom elements is to make them independent and not interacting with other elements. Putting styles in head breaks this promise.

from hybrids.

Avnerus avatar Avnerus commented on September 23, 2024

Hi, thanks for the clarification. Yes I understand the advantages of Shadow DOM, in fact in the small project I am making I decided to just drop React entirely and use for example high-select as a select component.
However I was thinking about the scenario in which hybrids could be used in a sort of transition period until all React components fully support Shadow DOM, or can be replaced by native components. In that case it would be nice to emulate the shadow dom and Shady CSS while still working in a light DOM, and later when it gets possible just turn on the Shaodw DOM back.

from hybrids.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.