Skip to content

Use slots in a Jadis component ​

In Jadis, much similar to how it works in web components, you can use slots in your templates, so as to create more flexible components.

Usage ​

It is very simple: you use a slot tag in the template where you want to populate with content from elsewhere, like from another component. The content between both opening and closing tags of your external component will be rendered inside the <slot></slot> tags.

jsx
// MyComponent.js with a slot
/// <reference types="@jadis/core/jsx-runtime" />
/** @jsxImportSource @jadis/core */

export class MyComponent extends Jadis {
  static selector = createSelector('my-component');

  templateHtml() { 
    return <div class="container"><slot></slot></div>; 
  } 

  templateCss() {
    return css`
      .container {
        background-color: darkblue;
        color: white;
      }
    `;
  }
}

MyComponent.register();
tsx
// MyComponent.ts with a slot
export class MyComponent extends Jadis {
  static readonly selector = 'my-component';

  templateHtml(): Node { 
    return <div class="container"><slot></slot></div>; 
  } 

  templateCss(): string {
    return css`
      .container {
        background-color: darkblue;
        color: white;
      }
    `;
  }
}

MyComponent.register();

Populate the slot

jsx
// MainPage.js using MyComponent
/// <reference types="@jadis/core/jsx-runtime" />
/** @jsxImportSource @jadis/core */

class MainPage extends Jadis {
  static selector = createSelector('main-page');

  templateHtml() { 
    return ( 
      <my-component> // [!code focus]
        <h1>My Title</h1> // [!code focus]
        <p>Hello there</p> // [!code focus]
      </my-component> 
    ); 
  } 
}

MainPage.register();
tsx
// MainPage.ts using MyComponent
class MainPage extends Jadis {
  static readonly selector = 'main-page';

  templateHtml(): Node { 
    return ( 
      <my-component> // [!code focus]
        <h1>My Title</h1> // [!code focus]
        <p>Hello there</p> // [!code focus]
      </my-component> 
    ); 
  } 
}

MainPage.register();

The <h1> and the <p> elements will be rendered through the MainPage component using the MyComponent component.

Named slots ​

If you need to use several slots in the same component, just name them!

jsx
// MyComponent.js with 2 slots
templateHtml() {
  return (
    <div class='container'>
        <slot></slot>
        <slot name='article'></slot>
    </div>
  );
}

// Using MyComponent in MainPage.js
templateHtml() {
  return (
    <my-component>
      <h1>My Title</h1>
      <p>Hello there</p>
      <div slot='article'>
        My article content is good.
      </div>
    </my-component>
  );
}
tsx

// MyComponent.ts with 2 slots
templateHtml(): Node {
  return (
    <div class='container'>
      <slot></slot>
      <slot name='article'></slot>
    </div>
  );
}

// Using MyComponent in MainPage.ts
templateHtml(): Node {
  return (
    <my-component>
      <h1>My Title</h1>
      <p>Hello there</p>
      <div slot='article'>
        My article content is good.
      </div>
    </my-component>
  );
}

Even easier With JSX children ​

JSX makes slotting natural — children are passed directly:

tsx
templateHtml(): Node {
  return (
    <my-component>
      <h1>My Title</h1>
      <p>Hello there</p>
    </my-component>
  );
}

Named slots work via the slot attribute:

tsx
templateHtml(): Node {
  return (
    <my-component>
      <h1>My Title</h1>
      <p slot="article">My article content</p>
    </my-component>
  );
}

Example with toTemplate() ​

See the dedicated documentation about the Jadis method toTemplate().

jsx
// Using MyComponent in MainPage.js
class MainPage extends Jadis {
  static selector = createSelector('main-page');

  templateHtml() {
    const fragment = document.createDocumentFragment();
    fragment.appendChild(document.createElement('h1')).textContent = 'My Article Title';
    const p = document.createElement('p');
    p.slot = 'article';
    p.textContent = 'My article content';
    fragment.appendChild(p);

    return MyComponent.toTemplate({}, fragment);
  }
}

MainPage.register();

// MyComponent.js definition with slots
export class MyComponent extends Jadis {
  static selector = createSelector('my-component');

  templateHtml() {
    return <div class='container'><slot></slot><slot name='article'></slot></div>;
  }
}

MyComponent.register();
tsx
// Using MyComponent in MainPage.ts
class MainPage extends Jadis {
  static readonly selector = 'main-page';

  templateHtml(): Node {
    const fragment = document.createDocumentFragment();
    fragment.appendChild(document.createElement('h1')).textContent = 'My Article Title';
    const p = document.createElement('p');
    p.slot = 'article';
    p.textContent = 'My article content';
    fragment.appendChild(p);

    return MyComponent.toTemplate({}, fragment);
  }
}

MainPage.register();

// MyComponent.ts definition with slots
export class MyComponent extends Jadis {
  static readonly selector = 'my-component';

  templateHtml(): Node {
    return <div class='container'><slot></slot><slot name='article'></slot></div>;
  }
}

MyComponent.register();