UNPKG

gd-bs

Version:

Bootstrap JavaScript, TypeScript and Web Components library.

177 lines (147 loc) 6.09 kB
import { INav, INavLink, INavProps } from "./types"; import { Base } from "../base"; import { NavLink } from "./link"; import { HTML, HTMLTabs, HTMLVerticalTabs } from "./templates"; /** * Navigation * @param props - The navigation properties. */ class _Nav extends Base<INavProps> implements INav { private _links: Array<NavLink> = null; // Constructor constructor(props: INavProps, template: string = props.menuOnly ? HTML : (props.isVertical ? HTMLVerticalTabs : HTMLTabs), itemTemplate?: string) { super(template, props); // Configure the collapse this.configure(itemTemplate); // Configure the events this.configureEvents(); // Configure the parent this.configureParent(); } // Configure the card group private configure(itemTemplate: string) { // Update the navigation let nav = this.el.classList.contains("nav") ? this.el : this.el.querySelector(".nav"); if (nav) { this.props.id ? nav.id = this.props.id : null; this.props.enableFill ? nav.classList.add("nav-fill") : null; this.props.isJustified ? nav.classList.add("nav-justified") : null; this.props.isVertical ? nav.classList.add("flex-column") : null; // Set the class name based on the properties if (this.props.isTabs) { nav.classList.add("nav-tabs"); } else if (this.props.isPills) { nav.classList.add("nav-pills"); } else if (this.props.isTabs) { nav.classList.add("nav-tabs"); } } // Render the nav links this.renderItems(itemTemplate); } // Configure the events private configureEvents() { // Execute the event(s) this.props.onRendered ? this.props.onRendered(this.el) : null; } // Configures the tab link event private configureLinkEvents(link: NavLink) { // Add a click event link.el.addEventListener("click", () => { let prevTab: INavLink = null; let newTab: INavLink = link; // See if this link is disabled if (link.isDisabled) { // Do nothing return; } // Parse the links for (let i = 0; i < this._links.length; i++) { let link = this._links[i]; // See if it's active if (link.isActive) { // Set the old tab prevTab = link; // Toggle it link.toggle(this.props.fadeTabs); } } // Toggle the link link.toggle(this.props.fadeTabs); // Call the click event this.props.onClick ? this.props.onClick(newTab, prevTab) : null; }); } // Renders the links private renderItems(itemTemplate: string) { // Clear the links this._links = []; // Get the nav and tab elements let nav = this.el.classList.contains("nav") ? this.el : this.el.querySelector(".nav"); if (nav) { let tabs = this.el.querySelector(".tab-content"); // Parse the navigation items let links = this.props.items || []; for (let i = 0; i < links.length; i++) { // Create the link let link = new NavLink(links[i], tabs ? true : false, itemTemplate); nav.appendChild(link.el); this._links.push(link); // Configure the link event this.configureLinkEvents(link); // See if we are rendering tabs if (tabs) { // Add the tab content tabs.appendChild(link.elTabContent); // See if the fade option is enabled if (this.props.fadeTabs) { // Set the class name link.elTabContent.classList.add("fade"); // See if the tab is active if (link.props.isActive) { // Set the class name link.elTabContent.classList.add("show"); } } } // Call the render events this.props.onLinkRendered ? this.props.onLinkRendered(link.elTab, links[i]) : null; this.props.onTabRendered ? this.props.onTabRendered(link.elTabContent, links[i]) : null; } } } /** * Public Interface */ // The active tab get activeTab(): INavLink { // Parse the links for (let i = 0; i < this._links.length; i++) { let link = this._links[i]; // See if it's active if (link.isActive) { // Return the link return link; } } // Active tab not found return null; } // Shows a tab showTab(tabId?: string | number) { // Ensure tabs exist if (this.props.isTabs) { // Parse the tabs for (let i = 0; i < this._links.length; i++) { let link = this._links[i]; // See if this is the target tab if (tabId === i + 1 || link.elTabContent.getAttribute("data-title") == tabId) { // Toggle it if it's not active link.isActive ? null : link.toggle(this.props.fadeTabs); } // Else, see if it's active else if (link.isActive) { // Toggle it link.toggle(this.props.fadeTabs); } } } } } export const Nav = (props: INavProps, template?: string, itemTemplate?: string): INav => { return new _Nav(props, template, itemTemplate); }