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