dojo dragon main logo

Custom Element Slots

Dojo widgets can support child objects, these children are supported as custom elements by using "slots." A slot attribute is added to a child of the custom element, and the child gets passed in as the value of the slot.

The most common child object scenarios are supported by Dojo custom elements.

Named Children

Widget.tsx

export interface WidgetChildren {
    foo: RenderResult;
}
<Widget>
    {{
        foo: <Label>My Label</Label>
    }}
</Widget>

index.html

<dojo-widget>
  <dojo-label slot="foo">My Label</dojo-label>
</dojo-widget>

Named Child Renderers

Widget.tsx

export interface WidgetChildren {
    foo: () => RenderResult;
}
<Widget>
    {{
        foo: () => <Label>My Label</Label>
    }}
</Widget>

index.html

<dojo-widget>
  <dojo-label slot="foo">My Label</dojo-label>
</dojo-widget>

Named Array of Children

If multiple children have the same slot name, they are bundled together in an array and passed to the custom element.

Widget.tsx

export interface WidgetChildren {
    foo: RenderResult[];
}
<Widget>
    {{
        foo: [<Label>Label 1</Label>, <Label>Label 2</Label>]
    }}
</Widget>

index.html

<dojo-widget>
  <dojo-label slot="foo">Label 1</dojo-label>
  <dojo-label slot="foo">Label 2</dojo-label>
</dojo-widget>

Named Array of Child Renderers

Widget.tsx

export interface WidgetChildren {
    foo: (() => RenderResult)[];
}
<Widget>
    {{
        foo: [() => <Label>Label 1</Label>, () => <Label>Label 2</Label>]
    }}
</Widget>

index.html

<dojo-widget>
  <dojo-label slot="foo">Label 1</dojo-label>
  <dojo-label slot="foo">Label 2</dojo-label>
</dojo-widget>

Named Child Renderers with Arguments

If the widget passes arguments to a child render function, the arguments get sent to the child in the slot via a "render" event.

Widget.tsx

export interface WidgetChildren {
    foo: (active: boolean) => RenderResult;
}
<Widget>
    {{
        foo: (active) => <Label active={active}>My Label</Label>
    }}
</Widget>

index.html

<dojo-widget>
  <dojo-label slot="foo" id="label1">Label 1</dojo-label>
  <dojo-label slot="foo" id="label2">Label 2</dojo-label>
</dojo-widget>

<script>
  function setActive(event) {
    const { detail: [active] } = event;
    event.target.active = active;
  }

  label1.addEventListener('render', setActive);
  label2.addEventListener('render', setActive);
</script>