diff --git a/book.toml b/book.toml index e5be345..7d2b9c4 100644 --- a/book.toml +++ b/book.toml @@ -6,6 +6,7 @@ src = "src" title = "Breez SDK" [output.html] +additional-js = ["tabs.js"] git-repository-url = "https://github.com/breez/breez-sdk-docs" edit-url-template = "https://github.com/breez/breez-sdk-docs/edit/main/{path}" diff --git a/tabs.js b/tabs.js new file mode 100644 index 0000000..a804acf --- /dev/null +++ b/tabs.js @@ -0,0 +1,147 @@ +(function () { + 'use strict'; + + let selected_ = null; + + customElements.define('custom-tabs', class extends HTMLElement { + + constructor() { + super(); // always call super() first in the ctor. + + // Create shadow DOM for the component. + let shadowRoot = this.attachShadow({ mode: 'open' }); + shadowRoot.innerHTML = ` + +
+ +
+
+ +
+ `; + } + + get selected() { + return selected_; + } + + set selected(idx) { + selected_ = idx; + this._selectTab(idx); + this.setAttribute('selected', idx); + } + + connectedCallback() { + this.setAttribute('role', 'tablist'); + + const tabsSlot = this.shadowRoot.querySelector('#tabsSlot'); + const panelsSlot = this.shadowRoot.querySelector('#panelsSlot'); + + this.tabs = tabsSlot.assignedNodes({ flatten: true }); + this.panels = panelsSlot.assignedNodes({ flatten: true }).filter(el => { + return el.nodeType === Node.ELEMENT_NODE; + }); + + // Save refer to we can remove listeners later. + this._boundOnTitleClick = this._onTitleClick.bind(this); + + tabsSlot.addEventListener('click', this._boundOnTitleClick); + + this.selected = this._findFirstSelectedTab() || this._findStoredSelectedTab() || 0; + } + + disconnectedCallback() { + const tabsSlot = this.shadowRoot.querySelector('#tabsSlot'); + tabsSlot.removeEventListener('click', this._boundOnTitleClick); + } + + _onTitleClick(e) { + if (e.target.slot === 'title') { + this.selected = this.tabs.indexOf(e.target); + e.target.focus(); + } + } + + _findFirstSelectedTab() { + let selectedIdx; + for (let [i, tab] of this.tabs.entries()) { + tab.setAttribute('role', 'tab'); + if (tab.hasAttribute('selected')) { + selectedIdx = i; + } + } + return selectedIdx; + } + + _findStoredSelectedTab() { + let selectedIdx; + if (this.getAttribute("category")) { + let selectedText; + try { selectedText = localStorage.getItem('mdbook-tabs-' + this.getAttribute("category")); } catch (e) { } + if (selectedText) { + for (let [i, tab] of this.tabs.entries()) { + if (tab.textContent === selectedText) { + selectedIdx = i; + break; + } + } + } + } + return selectedIdx; + } + + _selectTab(idx = null) { + for (let i = 0, tab; tab = this.tabs[i]; ++i) { + let select = i === idx; + tab.setAttribute('tabindex', select ? 0 : -1); + tab.setAttribute('aria-selected', select); + this.panels[i].setAttribute('aria-hidden', !select); + if (select && this.getAttribute("category") && tab.textContent) { + try { localStorage.setItem('mdbook-tabs-' + this.getAttribute("category"), tab.textContent); } catch (e) { } + } + } + } + + }); + +})(); \ No newline at end of file