Skip to content

slot

Slots allow parent components to pass content to child components. ElfUI exports Custom Elements, default slots and named slots using native Web Components semantics.

Default slot

ts
export const Card = defineHtml(`
  <article class="card">
    <slot></slot>
  </article>
`);
html
<elf-card>内容</elf-card>

named slot

ts
export const Panel = defineHtml(`
  <header><slot name="title"></slot></header>
  <main><slot></slot></main>
  <footer><slot name="actions"></slot></footer>
`);
html
<elf-panel>
  <h2 slot="title">标题</h2>
  正文
  <button slot="actions">确定</button>
</elf-panel>

scope slot

WARNING

Web Components do not have native scope slots. ElfUI supports common writing methods through compile-time bridging, and sub-components use useScopedSlot() for consumption.

ts
import { defineHtml, useScopedSlot } from "@elfui/core";

const itemSlot = useScopedSlot<{ item: string }>("item");

export const ListBox = defineHtml(`
  <ul>
    <li>${itemSlot?.({ item: "A" })}</li>
  </ul>
`);

The parent component provides the rendering function with <template #name="..."> with scope parameters:

ts
export const UserListPage = defineHtml(`
  <user-list>
    <template #item="{ item, index }">
      <strong>{{ index + 1 }}</strong>
      <span>{{ item.name }}</span>
    </template>
  </user-list>
`);

item and index are slot local variables, so template expressions are used here instead of ${...} in the outer TypeScript. The useScopedSlot<{ item: User; index: number }>("item") generic of the child component also constrains its outgoing scope.

Scope slots are suitable for scenarios such as Table cells and List items that require the internal data of child components to be handed over to parent components for rendering.