In Aurelia 2, we have a couple of different ways of working with slotted content. If you are familiar with Web Components, the slot element is a placeholder that can have content projected into it, the common use for this is reusable components.
In Aurelia 1, we had support for the slot element and could project almost anything we wanted inside of it, but there were limitations (as per the spec) which meant it wasn’t always the best tool for the job.
In Aurelia 2 we still have the slot element, but we now also have an au-slot element as well.
Here is a basic modal that I created in one of my Aurelia 2 applications. Notice the use of au-slot inside of this element instead of slot?
<div class="modal" if.bind="showing" ref="modal"> <button type="button" data-action="close" class="close" aria-label="Close" click.trigger="close()" ><span aria-hidden="true">×</span></button> <div class="modal-inner"> <au-slot></au-slot> </div> </div>
And here is a couple of different ways that I use the modal:
<modal showing.bind="showImagePreview"> <attachments-preview au-slot attachments.bind="imagesForPreview"></attachments-preview> </modal>
Notice how I can project a custom element inside of the modal? Because I defined a slot inside of my modal without a name, it gets a value of default as the default name. When you want to inject content inside of your component if you’re using the default, you just put au-slot on the content.
And here is an example where I project HTML into the modal. It could not be any easier.
<modal showing.bind="showLocalityModal"> <div au-slot> <ul> <li repeat.for="term of localities" class="${isTermSelected(term.term_id) ? 'locality-selected' : ''}"><a href="javascript:void(0);" click.trigger="selectTerm(term, $event)">${term.name}</a></li> </ul> </div> </modal>
When to use au-slot and slot
The reason for there being two elements and subsequent attributes is because Aurelia keeping inline with its “follow the spec” philosophy dicerns the difference between proper native specification behaviour and non-standard behaviour.
The slot element is native to the Web Components spec, as such, you cannot use the slot element if you have Shadow DOM disabled in your application. You can only use the slot element if you have Shadow DOM enabled, keeping Aurelia instep with how the spec sees slot elements.
However, there are instances where you want slot behaviour (components that support replacing the inner contents) which is why au-slot was created. It gives you the same functionality as the native slot element, except it doesn’t rely on Shadow DOM being enabled.
In-fact, if you try using slot with Shadow DOM disabled, Aurelia 2 will throw an error in the console telling you that you can’t use slot with Shadow DOM turned off.
However, going further, there are instances where even when Shadow DOM is turned on, you don’t want to use the native slot. One of the limitations (by design) is styles won’t cross the component boundary in Shadow DOM, using slot means you lose the ability to style the contents with styles defined outside of your component (unless you have shared styles using Adaptive Stylesheets).
If you are creating components that you want to support styling from outside of the component itself, you would opt for the au-slot element and subsequent attribute instead of the native slot.
In most uses, you will most likely opt for au-slot over slot, but it is good to have a spec-abiding option and then a more flexible Aurelia-esque option which isn’t too different from the native version.