@slotted Decorator

The @slotted decorator provides a declarative way to observe and react to changes in slotted content within your custom elements. This decorator automatically tracks which elements are projected into specific slots and provides your component with an up-to-date array of matching nodes.

Overview

When building custom elements that accept slotted content, you often need to:

  • Know which elements were projected into a specific slot

  • Filter projected elements by CSS selector

  • React when the projected content changes

The @slotted decorator handles all of this automatically, creating a reactive property that updates whenever the slotted content changes.

Basic Usage

import { slotted } from '@aurelia/runtime-html';

export class TabContainer {
  // Watch all elements in the default slot
  @slotted() tabs: Element[];

  tabsChanged(newTabs: Element[], oldTabs: Element[]) {
    console.log('Tabs changed:', newTabs);
  }
}

Usage:

Filtering with CSS Selectors

Use a CSS selector to filter which slotted elements are tracked:

Usage:

Targeting Specific Slots

When your component has multiple named slots, you can target specific slots:

Usage:

Watching All Slots

Use '*' as the slot name to watch all slots simultaneously:

Change Callbacks

The @slotted decorator automatically looks for a callback method following the naming convention {propertyName}Changed:

Custom Callback Names

You can specify a custom callback method name:

Advanced Configuration

The @slotted decorator accepts a configuration object for fine-grained control:

Configuration Options

Property
Type
Default
Description

query

string

'*'

CSS selector to filter slotted elements. Use '*' to match all elements, '$all' to include text nodes

slotName

string

'default'

Name of the slot to watch. Use '*' to watch all slots

callback

PropertyKey

'{property}Changed'

Name of the callback method to invoke when slotted content changes

Querying All Nodes Including Text Nodes

By default, @slotted only tracks element nodes. To include text nodes, use the special query '$all':

Complex Selectors

The query parameter accepts any valid CSS selector:

Complete Example: Dynamic Tab Component

Here's a comprehensive example showing how to build a tab component using @slotted:

Usage:

Subscribing to Changes Programmatically

The property decorated with @slotted has a special getObserver() method that returns a subscriber collection:

Lifecycle and Timing

The @slotted decorator integrates with Aurelia's lifecycle:

  • Activation: The watcher starts observing during the binding lifecycle

  • Deactivation: The watcher stops observing during the unbinding lifecycle

  • Initial Callback: The change callback is invoked after bound with the initial slotted elements

  • Updates: The callback is invoked whenever slotted content changes (elements added, removed, or reordered)

Comparison with @children Decorator

Both @slotted and @children decorators watch for changes in child elements, but they serve different purposes:

Feature
@slotted
@children

Purpose

Watch slotted content projected into <au-slot>

Watch direct child elements of the host

Use with

Shadow DOM or <au-slot> components

Any component

Filters by

CSS selector + slot name

CSS selector only

Tracks

Content from parent component

Direct children only

Best for

Content projection scenarios

Observing component's immediate children

Use @slotted when:

  • You're using <au-slot> for content projection

  • You need to track which content was projected into which slot

  • You want to filter projected content by selector

Use @children when:

  • You need to observe the direct children of your component's host element

  • You're not using slots

  • You need access to child component view models (via the filter and map options)

Important Notes

  • The @slotted decorator only works with <au-slot>, not native <slot> elements

  • The decorated property becomes read-only; attempting to set it manually has no effect

  • Changes to the slotted content are detected via MutationObserver, so deep changes within slotted elements aren't automatically detected

  • The query selector is evaluated against each slotted node; complex selectors may impact performance with many slotted elements

See Also

Last updated

Was this helpful?