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

  1. export interface WidgetChildren {
  2. foo: RenderResult;
  3. }
  1. <Widget>
  2. {{
  3. foo: <Label>My Label</Label>
  4. }}
  5. </Widget>

index.html

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

Named Child Renderers

Widget.tsx

  1. export interface WidgetChildren {
  2. foo: () => RenderResult;
  3. }
  1. <Widget>
  2. {{
  3. foo: () => <Label>My Label</Label>
  4. }}
  5. </Widget>

index.html

  1. <dojo-widget>
  2. <dojo-label slot="foo">My Label</dojo-label>
  3. </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

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

index.html

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

Named Array of Child Renderers

Widget.tsx

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

index.html

  1. <dojo-widget>
  2. <dojo-label slot="foo">Label 1</dojo-label>
  3. <dojo-label slot="foo">Label 2</dojo-label>
  4. </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

  1. export interface WidgetChildren {
  2. foo: (active: boolean) => RenderResult;
  3. }
  1. <Widget>
  2. {{
  3. foo: (active) => <Label active={active}>My Label</Label>
  4. }}
  5. </Widget>

index.html

  1. <dojo-widget>
  2. <dojo-label slot="foo" id="label1">Label 1</dojo-label>
  3. <dojo-label slot="foo" id="label2">Label 2</dojo-label>
  4. </dojo-widget>
  5. <script>
  6. function setActive(event) {
  7. const { detail: [active] } = event;
  8. event.target.active = active;
  9. }
  10. label1.addEventListener('render', setActive);
  11. label2.addEventListener('render', setActive);
  12. </script>