run_the_race
run_the_race

Reputation: 2368

Native web component: style host differently depending on slotted content

Say I have a native web component with an HTML template like so:

<wc-grid>
    <slot></slot>
</wc-grid>

Now I have the following two use cases (one with a text input the other with a radio):

<wc-grid>  <input type="text">   </wc-grid>
<wc-grid>  <input type="radio">  </wc-grid>

Is it possible to style the <wc-grid> differently depending on when whether it contains a text or radio type input?

e.g. If has() was around it would be something like this: (trying to change whether the grid is vertical or horizontal depending on the widget inside of it):

:host:has(> input[type="text"])  { flex-direction: row; }
:host:has(> input[type="radio"]) { flex-direction: column; }

Research has lead me to learn about :has(), but that has not landed yet. And as far as I can tell :host-context would not help either as it looks up, not down, besides its poor support.

Upvotes: 0

Views: 201

Answers (1)

Dharmendra Patel
Dharmendra Patel

Reputation: 44

The easiest and cleanest implementation of such a problem I can solve by using a named slot.

example of web component

  class MyComp extends HTMLElement {
    constructor() {
      super();
      const shadow = this.attachShadow({ mode: 'open' });
      this.shadowRoot.innerHTML = `
      <style>
        .flex {
          display: flex;
          justify-content: space-between;
        }
        .row {
          flex-direction: row;
          background: red;
        }
        .column {
          flex-direction: column;
          background: green;
        }
      </style>
      <div>
        <div class="flex row"><slot name="row"></slot></div>
        <div class="flex column"><slot name="column"></slot></div>
      </div>`;
    }
  }

  customElements.define('my-comp', MyComp);


usage in HTML

    <my-comp>
        <div slot="row">This is row 1</div>
        <div slot="row">this is row 2</div>
        <div slot="row">This is row 3</div>
    </my-comp>
    <my-comp>
        <div slot="column">This is colum 1</div>
        <div slot="column">This is colum 2</div>
        <div slot="column">This is colum 3</div>
    </my-comp>

example screenshotscreenshot

Another good way to have a attribute which can add respective classes to root elements to modify css based on it

Upvotes: 1

Related Questions