Slots without shadows.
This module is installable through npm.
npm install --save @boulevard/vampire
This example demonstrates moving content to a nameless slot.
const div = Object.assign(document.createElement('div'), {
innerHTML: `
<v-root>
<h4>Example</h4>
<v-slot></v-slot>
</v-root>
`
};
div.appendChild(document.createTextNode('👻'));
The above script will produce the following output.
<div>
<v-root>
<h4>Example</h4>
<v-slot>
<v-slot-assigned-content>
👻
</v-slot-assigned-content>
</v-slot>
</v-root>
</div>
Slots are most useful when combined with custom elements. This is example shows how easy it is to use Vampire with LitElement.
import '@boulevard/vampire';
import { render } from 'lit-html';
import { customElement, html, LitElement } from 'lit-element';
const WithSlots = (BaseClass: typeof LitElement) => class extends BaseClass {
static render = render;
createRenderRoot() {
return document.createElement('v-root');
}
connectedCallback() {
if (!this.renderRoot.parentElement) {
this.appendChild(this.renderRoot);
}
super.connectedCallback();
}
}
@customElement('x-example')
export class ExampleElement extends WithSlots(LitElement) {
render() {
return html`
<h5>Example</h5>
<v-slot></v-slot>
`;
}
}
Given the following markup.
<x-example>
This content will be slotted.
<x-example>
The above component will produce the following output when rendered.
<x-example>
<v-root>
<h5>Example</h5>
<v-slot>
<v-slot-assigned-content>
This content will be slotted.
</v-slot-assigned-content>
</v-slot>
</v-root>
<x-example>
https://stackblitz.com/edit/typescript-uykxn4
Vampire is distributed in ES2015 module format.
A VampireRoot
is the root node of a DOM subtree.
A VampireSlot
marks the insertion point of foreign content.
VampireSlot::name: string = '';
A slot may be given a name so that it can be targeted.
VampireSlot::assignedElements(options?: {flatten?: boolean}): Element[];
Returns the elements assigned to this slot. If the flatten
option is set to
true
it will return fallback content if, and only if, there is no assigned
content, otherwise it will still return the assigned content.
VampireSlot::assignedNodes(options?: {flatten?: boolean}): Node[];
Returns the nodes assigned to this slot. If the flatten
option is set to
true
it will return fallback content if, and only if, there is no assigned
content, otherwise it will still return the assigned content.
Example
<div>
<v-root>
<v-slot></v-slot>
<v-slot name="second-slot"></v-slot>
</v-root>
<div>This will be moved to the default slot</div>
<div v-slot="second-slot">This will be moved to the second slot.</div>
</div>
interface ISlotChangeEvent extends CustomEvent {
readonly type = 'v::slotchange';
readonly bubbles = true;
}
The v::slotchange
event is fired when the slot's assigned content changes.
Example
slot.addEventListener('v::slotchange', (event: Event) => {
console.log(event.target.assignedNodes());
});
Allows fallback content to be assigned to a slot.
Example
<v-slot>
<v-slot-fallback-content>
This will be rendered if no content is assigned to this slot.
</v-slot-fallback-content>
</v-slot>
The last 2 versions of all modern browsers are supported. In addition, IE 11 is also supported.
IE 11 requires a custom elements polyfill as well as a CustomEvent
constructor
polyfill.
- A
VampireRoot
cannot be a direct ancestor of aVampireRoot
. - Empty
Text
nodes will be assign to a slot and will prevent fallback content from being rendered. - Fallback content cannot contain more slots.
- IE and Edge do not support
display: contents
. If you need to support these browsers you'll need to account for the extra elements when doing layout.