Slots

Named positions where children can be placed.

const phoneSlots = defineSlots({
  // A named region. Declaring a slot does not create a child.
  chrome: slot(),

  screen: slot(),

  // Constrained: only these blueprints may occupy it
  sidebar: slot({ accepts: [NavPanel, SettingsPanel] }),

  // Multi-child
  overlays: slot({ multiple: true }),
});

class Phone extends LayoutActor<typeof phoneSlots> {
  static slots = phoneSlots;
}

The typeof phoneSlots type parameter is what makes child(...) field names and hostInSlot("…") strings checkable.

Options

Prop

Type

Populating

frame 0·0.00sdeck.slotChildren.cards → 3 · lift [0.00, 0.00, 0.00]

A Deck with one multi-child slot. hostInSlot("cards", Card, { label }) places each occupant; this.children("cards") gives the host a typed list to orchestrate — here a staggered enter() and exit(), which run each card's onEnter/onExit hooks — without reaching into any child's state. After exit() the slot is empty again.

  • child(Child) declares an occupant in the slot matching the field name.
  • hostInSlot("screen", Child) places an occupant during compilation.
class Phone extends LayoutActor<typeof phoneSlots> {
  static slots = phoneSlots;

  chrome = child(StatusBar); // field name === slot name

  onSpawn() {
    this.hostInSlot("screen", MailApp); // dynamic
  }
}

accepts is a design statement

Constraining a slot says what the host is for. slot({ accepts: LayoutActor }) on a window's content region says "any renderable actor can be a window's content" — which is why the Desktop example can host arbitrary apps without knowing what they are.

On this page