run_the_race
run_the_race

Reputation: 2318

Style web component within shadow dom, depending on its parent

I am working on a component for uploading files. I have made two web components (wc):

If the parent (wc-uploader) has the readonly or disabled attribute, I wish to style the wc-upload items differently.

I think the styling should be within the wc-upload component as it pertains to it.

This is the selector I tried within the wc-upload template but it does not work. I am guess it can't see beyond its shadow root.

wc-uploader[readonly] :host #close {  /* here host = wc-uploader */
    opacity: 0.5;
}

How would one style this element depending on its parent. E.g. like if a select item is disabled, then it's option children are disabled too.

Upvotes: 0

Views: 1363

Answers (1)

For loose coupling, so it doesn't matter when or where children Web Components are attached:

Make the children listen:

  this.closest("wc-uploader").addEventListener("close",(evt)=>{
    let parent = evt.detail; //evt.target could do
    if parent.hasAttribute("close") ...
    else ...
  });

Then the parent reports its state:

attributeChangedCallback(name,oldValue,newValue){
  if(name=="close" || name=="readonly" || name=="disabled"){
    this.dispatchEvent(new CustomEvent(name, {
      bubbles: false, // Event stays at wc-uploader
      detail: this // wc-uploader
    }));
  }
}

If your children are deeper down in shadowRoots you need:
Custom Element getRootNode.closest() function crossing multiple (parent) shadowDOM boundaries

Or use document. as your "Event Bus", but then you have to be careful with your Event-names.

Be aware addEventListener attaches a listener outside the Web Component scope; so it is not garbage collected when the Component is removed; your task to remove them in the disconnectedCallback

Upvotes: 1

Related Questions