Slots
Modjool provides access to slots, allowing you to utilise
the custom element's text and markup within Modjool templates and lifecycle events.
Single slots
The HTML markup contained within an element can be output using the
slot instance parameter:
modjool.create({
tag: 'slot-example',
html: ({ slot }) => `
Content: <b>${slot}</b>
`
})<slot-example>I like slots</slot-example>I like slotsMultiple slots
At times, multiple slots can be helpful, for example, in a layout component with multiple panels:
<column-layout>
<section>
<!-- Main slot content, eg: <div>Article content here</div> -->
</section>
<aside>
<!-- Side slot content, eg: <span>Side menu</span> -->
</aside>
</column-layout>
To achieve this layout, we define our element using slot,
but as an object with properties:
modjool.create({
tag: 'column-layout',
html: ({ slot }) => `
<section>${slot.main}</section>
<aside>${slot.side}</aside>
`,
css: () => `
/* CSS for <section> and <aside> */
`
})
And we use the slot="" HTML attribute, with the value corresponding
to the slot property used in the template:
<column-layout>
<div slot="main">Article content here</div>
<span slot="side">Side menu</span>
</column-layout>
Article content here
Side menuNotes on multiple slots
When any element with a slot="" attribute is used, the slot
instance parameter will always return an object, with the property names corresponding to the
slot attributes. It will not return a string, as it would without using named slots.
Only root-level slots are compatible; nested slots will not work:
<!-- ❌ Incorrect - slot.subtitle is undefined -->
<custom-element>
<div slot="main">
<span slot="subtitle">A subtitle</span>
</div>
</custom-element>
<!-- ✅ Correct -->
<custom-element>
<div slot="main"></div>
<span slot="subtitle">A subtitle</span>
</custom-element>
Using slot values
The slot parameter, returns markup strings
that will output the slotted content to the DOM (ie <slot></slot>),
and will not necessarily intended to output the innerHTML of the element. Should you
wish to make use of the innerHTML of slots, slotVal
can be used.
Using slotVal
The slotVal parameter is particularly useful for parsing the slot values:
modjool.create({
tag: 'custom-table',
html: ({ slotVal }) => `
<table>
<tr>
${slotVal.split('|').map(cell => `<td>${cell}</td>`).join('')}
</tr>
</table>
`
})
In this example we split the slot into an array using the vertical bar (|)
as a separator, create a cell for each, then join the array together into a string, before adding
it to a table row.
The resulting element looks like this:
<custom-table>
Alice|Benjamin|Charlie
</custom-table>Alice|Benjamin|Charlie
Slot values can also be returned from multiple slots, like in the section
above, though instead, of course, returning the
innerHTML of the slots, without the containing HTML tags:
<custom-slots>
<span slot="header">This is a <b>header</b></span>
<div slot="body">This is the <b>body</b></div>
</custom-slots>js: ({ slotVal }) => {
// 'This is the <b>body</b>'
console.log(slotVal.body)
}
Slot elements
Should the custom element contain a root-level HTML element, or contain multiple
slots, the slot elements themselves can be accessed wih findSlot
(which works similarly to find and findAll).
<!-- ❌ No element to access -->
<custom-element>
No root-level element
</custom-element>
<!-- ✅ Works -->
<custom-element>
<div>Root-level div element</div>
</custom-element>
<!-- ✅ Works -->
<custom-element>
<h1 slot="title">Multiple slots</h1>
<div slot="text">in this example</div>
</custom-element>
Using findSlotfindSlot will return the HTMLElement that
corresponds to the slot with the same name. This is handy for modifying and
applying events to slotted HTML elements:
modjool.create({
tag: 'select-button',
complete: ({ findSlot }) => {
const button = findSlot`button`
button.style.border = '2px solid lightgrey'
button.style.padding = '8px'
button.onclick = () => button.innerHTML = 'Button clicked'
}
})
<select-button>
<span slot="button">Click me</span>
</select-button>
Click me
Headless componentsfindSlot is particularly useful for creating
headless components,
find more examples there.
You've got it!
On the next page, more information on attributes, and how to use them.