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 slots Multiple 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 menu
Notes 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 findSlot findSlot 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 components findSlot 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.