slotの中身を表示するCustom Element
CSSフレームワークのドキュメントとかでよくある、ボタンが並んでて、その隣にそれらがどんなHTMLでマークアップされているか併記されてるやつをやりたくなり、ちょっと調べたら行けそうだったのでやってみた。
こう書くと
<show-content> <button id="inc">+1</button> <script> let count = 0 document.querySelector('#inc').addEventListener('click', () => { console.log(++count) }) </script> </show-content>
こうなるような
show-content
です。this.innerHTML
にドカッと入ってくるので、それをcode
要素のinnerHTML
に与えているだけ。インデントの外し方はかなり適当。
<template id="show-content"> <style> pre { margin: 1rem 0 0 0; padding: 0; overflow-x: scroll; line-height: 1.3; } </style> <div> <slot></slot> <pre><code id="code"></code></pre> </div> </template> <script> class ShowContent extends HTMLElement { constructor() { super() const template = document.getElementById('show-content') const node = template.content.cloneNode(true) this.attachShadow({ mode: 'open' }).appendChild(node) } connectedCallback() { const codeBlock = this.shadowRoot.querySelector('#code') codeBlock.innerText = this.removeIndent(this.innerHTML) } removeIndent(html) { const firstLineIndent = /^\s+/.exec(html)[0] return html.replaceAll(firstLineIndent, "\n").trim() } } customElements.define('show-content', ShowContent) </script>