gd-bs
Version:
Bootstrap JavaScript, TypeScript and Web Components library.
127 lines (105 loc) • 4.68 kB
text/typescript
import { INavLink, INavLinkProps } from "./types";
import { Base } from "../base";
import { appendContent, setClassNames } from "../common";
import { HTMLLink, HTMLTab } from "./templates";
/**
* Nav Link
*/
export class NavLink extends Base<INavLinkProps> implements INavLink {
private _elLink: HTMLAnchorElement = null;
private _elTab: HTMLDivElement = null;
// Constructor
constructor(props: INavLinkProps, isTab: boolean, template: string = HTMLLink) {
super(template, props);
// See if this is for a tab
if (isTab) {
// Create the tab element
let el = document.createElement("div");
el.innerHTML = HTMLTab;
this._elTab = el.firstChild as HTMLDivElement;
}
// Configure the item
this.configure();
// Configure the events
this.configureEvents();
}
// Configure the item
private configure() {
// Update the link
this._elLink = this.el.querySelector("a.nav-link");
if (this._elLink) {
// Set the class names
setClassNames(this._elLink, this.props.className);
this.props.isActive ? this._elLink.classList.add("active") : null;
this.props.isDisabled ? this._elLink.classList.add("disabled") : null;
// Set the html
this._elLink.innerHTML = this.props.title == null ? "" : this.props.title;
// See if this is a tab
if (this._elTab) {
let tabId = this.props.title.replace(/[^a-zA-Z]/g, "");
// Set the properties
this._elLink.id = tabId + "-tab";
this._elLink.setAttribute("href", "#" + tabId);
this._elLink.setAttribute("data-bs-toggle", "tab");
this._elLink.setAttribute("aria-controls", tabId);
this._elLink.innerHTML = this.props.title == null ? "" : this.props.title;
// Update the tab
this._elTab.id = tabId;
this._elTab.setAttribute("aria-labelledby", tabId);
this._elTab.setAttribute("data-title", this.props.title || "");
// See if this tab is active
if (this.props.isActive) {
// Update the classes
this._elTab.classList.add("active")
}
// Append the content
appendContent(this._elTab, this.props.tabContent);
} else {
// Set the properties
this._elLink.setAttribute("href", this.props.href || "#");
}
}
}
// Configures the events
private configureEvents() {
// Add a click event
(this.el as HTMLElement).addEventListener("click", ev => {
// Prevent the page from moving to the top
ev.preventDefault();
// Execute the event
this.props.onClick ? this.props.onClick(this.props, ev) : null;
});
// Execute the render events
this.props.onRender ? this.props.onRender(this._elLink, this.props) : null;
this._elTab && this.props.onRenderTab ? this.props.onRenderTab(this._elTab, this.props) : null;
}
/**
* Public Interface
*/
// The HTML tab element
get elTab(): HTMLAnchorElement { return this._elLink; }
// The HTML tab content element
get elTabContent(): HTMLDivElement { return this._elTab; }
// Returns true if the link is active
get isActive(): boolean { return this._elLink.classList.contains("active"); }
// Returns true if the link is disabled
get isDisabled(): boolean { return this._elLink.classList.contains("disabled"); }
// Gets the tab name
get tabName(): string { return this._elLink.innerHTML.trim(); }
set tabName(value: string) { this._elLink.innerHTML = (value || "").trim(); }
// Toggles a link
toggle(fadeTabs?: boolean) {
// See if this item is currently active
if (this.isActive) {
// Hide this link and tab
this._elLink.classList.remove("active");
this._elTab ? this._elTab.classList.remove("active") : null;
this._elTab ? this._elTab.classList.remove("show") : null;
} else {
// Show this link and tab
this._elLink.classList.add("active");
this._elTab ? this._elTab.classList.add("active") : null;
this._elTab && fadeTabs ? this._elTab.classList.add("show") : null;
}
}
}