import { html, nothing } from 'lit';
import { property } from 'lit/decorators.js';
import { BootstrapElement, defineElement } from '@bootstrap-wc/core';
/**
* `` — nav link / tab item. Host carries `.nav-link` (and
* `.active` / `.disabled`) so Bootstrap's `.nav-tabs .nav-link.active`
* descendant selectors match across the slot boundary.
*/
export class BsNavItem extends BootstrapElement {
@property({ type: Boolean, reflect: true }) active = false;
@property({ type: Boolean, reflect: true }) disabled = false;
@property({ type: String }) href = '#';
@property({ type: String, attribute: 'controls' }) controls?: string;
override connectedCallback(): void {
super.connectedCallback();
if (!this.hasAttribute('role')) this.setAttribute('role', 'tab');
this.addEventListener('click', this._onClick);
this.addEventListener('keydown', this._onKeydown);
}
override disconnectedCallback(): void {
super.disconnectedCallback();
this.removeEventListener('click', this._onClick);
this.removeEventListener('keydown', this._onKeydown);
}
override updated(changed: Map): void {
super.updated(changed);
if (changed.has('active')) {
this.setAttribute('aria-selected', this.active ? 'true' : 'false');
this.tabIndex = this.active ? 0 : -1;
}
if (changed.has('disabled')) this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
if (changed.has('controls')) {
if (this.controls) this.setAttribute('aria-controls', this.controls);
else this.removeAttribute('aria-controls');
}
}
protected override hostClasses(): string {
const parts = ['nav-link'];
if (this.active) parts.push('active');
if (this.disabled) parts.push('disabled');
return parts.join(' ');
}
private _onClick = (ev: MouseEvent) => {
if (this.disabled) {
ev.preventDefault();
return;
}
if (this.href && this.href !== '#' && ev.target === this) window.location.href = this.href;
};
private _onKeydown = (ev: KeyboardEvent) => {
if (this.disabled) return;
if (ev.key === 'Enter' || ev.key === ' ') {
ev.preventDefault();
this.click();
}
};
override render() {
return html`${nothing}`;
}
}
defineElement('bs-nav-item', BsNavItem);
declare global {
interface HTMLElementTagNameMap {
'bs-nav-item': BsNavItem;
}
}