Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/improsocial/impro
An extensible Bluesky client for web impro.social
Something went wrong. Try again.
1.9 kB · 79 lines
JavaScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980import { html, render } from "/js/lib/lit-html.js";import { Component } from "/js/components/component.js";import { classnames } from "/js/utils.js";
class TabBar extends Component { static observedAttributes = ["active-tab", "full-width"];
connectedCallback() { if (this.initialized) return; this._tabs = this._tabs ?? []; this.lastScrolledTab = null; this.render(); this.initialized = true; }
attributeChangedCallback() { if (!this.initialized) return; this.render(); }
set tabs(tabs) { this._tabs = tabs ?? []; if (this.initialized) this.render(); }
get tabs() { return this._tabs; }
get activeTab() { return this.getAttribute("active-tab"); }
get fullWidth() { return this.hasAttribute("full-width"); }
render() { const activeTab = this.activeTab; render( html`${this._tabs.map( (tab) => html`<button class=${classnames("tab-bar-button", { active: activeTab === tab.value, })} data-testid="tab-${tab.value}" @click=${() => this.dispatchEvent( new CustomEvent("tab-click", { detail: tab.value }), )} > <span class="tab-bar-button-label">${tab.label}</span> </button>`, )}`, this, ); this.scrollActiveIntoView(); }
scrollActiveIntoView() { if (this.fullWidth) return; const activeTab = this.activeTab; if (activeTab === this.lastScrolledTab) return; const activeButton = this.querySelector(".tab-bar-button.active"); if (!activeButton) return; const behavior = this.lastScrolledTab === null ? "instant" : "smooth"; this.lastScrolledTab = activeTab; requestAnimationFrame(() => { activeButton.scrollIntoView({ behavior, inline: "nearest", block: "nearest", }); }); }}
TabBar.register();