UNPKG

wj-elements

Version:

WebJET Elements is a modern set of user interface tools harnessing the power of web components designed to simplify web application development.

281 lines (280 loc) 9.9 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import WJElement from "./wje-element.js"; const styles = "/*\n[ WJ Breadcrumbs ]\n*/\n\n:host {\n --wje-breadcrumbs-breakpoint-sm: 576px;\n --wje-breadcrumbs-breakpoint-md: 768px;\n --wje-breadcrumbs-breakpoint-lg: 992px;\n --wje-breadcrumbs-breakpoint-xl: 1200px;\n --wje-breadcrumbs-breakpoint-2xl: 1450px;\n --wje-breadcrumbs-breakpoint-xxl: 1450px;\n\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n min-width: 0;\n overflow: hidden;\n}\n"; const _Breadcrumbs = class _Breadcrumbs extends WJElement { /** * Breadcrumbs constructor method. * @class */ constructor() { super(); /** * Class name for the Breadcrumbs element. * @type {string} */ __publicField(this, "className", "Breadcrumbs"); this.last = false; this._isCollapsedByBreakpoint = null; } /** * Set variant attribute for the Breadcrumbs element. * @param value */ set variant(value) { this.setAttribute("variant", value); } /** * Get variant attribute for the Breadcrumbs element. * @returns {string} */ get variant() { return this.getAttribute("variant") || "button"; } /** * Get the collapsed indicator variant. * @returns {string} */ get collapsedVariant() { return this.getAttribute("collapsed-variant") || this.variant; } /** * Sets the collapse breakpoint token or value. * @param {string} value Breakpoint token or CSS size. */ set breakpoint(value) { if (value) this.setAttribute("breakpoint", value); else this.removeAttribute("breakpoint"); } /** * Gets the collapse breakpoint token or value. * @returns {string} */ get breakpoint() { return this.getAttribute("breakpoint") || ""; } /** * Get items before collapse attribute. * @param {string} value */ set maxItems(value) { this.setAttribute("max-items", value || 0); } /** * Get items before collapse attribute. * @returns {number} */ get maxItems() { return +this.getAttribute("max-items"); } /** * Get items before collapse attribute. * @param value */ set itemsBeforeCollapse(value) { this.setAttribute("items-before-collapse", value || 1); } /** * Get items before collapse attribute. * @returns {number} */ get itemsBeforeCollapse() { return +this.getAttribute("items-before-collapse") || 1; } /** * Get items after collapse attribute. * @param value */ set itemsAfterCollapse(value) { this.setAttribute("items-after-collapse", value || 1); } /** * Get items after collapse attribute. * @returns {number} */ get itemsAfterCollapse() { if (this.hasAttribute("items-after-collapse")) { return +this.getAttribute("items-after-collapse") || 1; } const derivedItemsAfterCollapse = this.maxItems - this.itemsBeforeCollapse - 1; return derivedItemsAfterCollapse > 0 ? derivedItemsAfterCollapse : 1; } /** * Get CSS stylesheet for the Breadcrumbs element. * @static * @returns {object} styles - The CSS styles */ static get cssStyleSheet() { return styles; } /** * Get observed attributes for the Breadcrumb element. * @static * @returns {Array<string>} - The observed attributes array for the Breadcrumb element. */ static get observedAttributes() { return ["breakpoint", "max-items", "items-before-collapse", "items-after-collapse", "collapsed-variant", "variant"]; } /** * Setup attributes for the Breadcrumbs element. */ setupAttributes() { this.isShadowRoot = "open"; this.setAriaState({ role: "navigation" }); } /** * Draw method for the Breadcrumbs element. * @returns {object} fragment - The document fragment */ draw() { let fragment = document.createDocumentFragment(); let element = document.createElement("slot"); fragment.appendChild(element); this.defaultSlot = element; return fragment; } /** * Updates the breadcrumb elements after they are drawn on the page. * It manages attributes on breadcrumb items and handles the logic for collapsing breadcrumbs * if the total exceeds the specified maximum items. * @returns {void} This method does not return a value. */ afterDraw() { var _a; this.onSlotChange = () => this.updateCollapse(); (_a = this.defaultSlot) == null ? void 0 : _a.addEventListener("slotchange", this.onSlotChange); this.handleResize = () => this.handleBreakpointResize(); if (this.getBreakpointWidth()) { window.addEventListener("resize", this.handleResize); } this.updateCollapse(); } /** * Removes listeners after disconnect. */ afterDisconnect() { var _a; (_a = this.defaultSlot) == null ? void 0 : _a.removeEventListener("slotchange", this.onSlotChange); window.removeEventListener("resize", this.handleResize); this._isCollapsedByBreakpoint = null; } /** * Reacts to viewport resize only when the breakpoint mode actually changes. * @returns {void} */ handleBreakpointResize() { if (!this.getBreakpointWidth()) return; const nextState = this.shouldApplyBreakpointCollapse(); if (this._isCollapsedByBreakpoint === nextState) return; this.updateCollapse(); } /** * Recalculates breadcrumb collapse state. * @returns {void} */ updateCollapse() { let breadcrumbs = this.getBreadcrumbs(); if (breadcrumbs.length === 0) return; this._isCollapsedByBreakpoint = this.shouldApplyBreakpointCollapse(); const effectiveItemsAfterCollapse = this.itemsAfterCollapse; const shouldCollapse = this._isCollapsedByBreakpoint && this.maxItems > 0 && breadcrumbs.length > this.maxItems && this.itemsBeforeCollapse + effectiveItemsAfterCollapse + 1 <= this.maxItems; const lastIndex = breadcrumbs.length - 1; const indicatorIndex = shouldCollapse ? this.itemsBeforeCollapse : -1; const collapseStart = this.itemsBeforeCollapse; const collapseEnd = breadcrumbs.length - effectiveItemsAfterCollapse; breadcrumbs.forEach((breadcrumb, index) => { this.syncManagedAttribute(breadcrumb, "last", index === lastIndex); this.syncManagedAttribute(breadcrumb, "show-collapsed-indicator", index === indicatorIndex); const isCollapsed = shouldCollapse && index >= collapseStart && index < collapseEnd; this.syncManagedAttribute(breadcrumb, "collapsed", isCollapsed); if (!isCollapsed && breadcrumb.classList.contains("collapsed")) { breadcrumb.classList.remove("collapsed"); } }); } /** * Clears attributes/classes managed by the collapse algorithm. * @param {Array<Element>} breadcrumbs Breadcrumb items. */ resetCollapseState(breadcrumbs = this.getBreadcrumbs()) { breadcrumbs.forEach((breadcrumb) => { breadcrumb.removeAttribute("collapsed"); breadcrumb.removeAttribute("show-collapsed-indicator"); breadcrumb.removeAttribute("last"); breadcrumb.classList.remove("collapsed"); }); } /** * Applies a managed boolean attribute only when its value truly changes. * @param {Element} element Breadcrumb item whose responsive state is being synchronized. * @param {string} name Managed state flag that should be synchronized on the breadcrumb item. * @param {boolean} isEnabled Whether the attribute should be present. */ syncManagedAttribute(element, name, isEnabled) { if (!element) return; const hasAttribute = element.hasAttribute(name); if (isEnabled && !hasAttribute) { element.setAttribute(name, true); } if (!isEnabled && hasAttribute) { element.removeAttribute(name); } } /** * Returns whether collapse rules should currently be applied. * @returns {boolean} */ shouldApplyBreakpointCollapse() { const breakpointWidth = this.getBreakpointWidth(); if (!breakpointWidth) return true; return window.innerWidth < breakpointWidth; } /** * Resolves the configured breakpoint to a pixel width. * @returns {number|null} */ getBreakpointWidth() { if (!this.breakpoint) return null; const token = this.breakpoint.trim().toLowerCase(); const cssValue = getComputedStyle(this).getPropertyValue(`--wje-breadcrumbs-breakpoint-${token}`).trim(); const namedBreakpoint = _Breadcrumbs.BREAKPOINTS[token]; if (cssValue) { const cssNumber = parseFloat(cssValue); if (Number.isFinite(cssNumber)) return cssNumber; } if (Number.isFinite(namedBreakpoint)) { return namedBreakpoint; } const directNumber = parseFloat(token); return Number.isFinite(directNumber) ? directNumber : null; } /** * Retrieves all breadcrumb elements within the current instance. * @returns {Array<Element>} An array of breadcrumb elements (`wje-breadcrumb`) found within the instance. Returns an empty array if no breadcrumbs are found. */ getBreadcrumbs() { return Array.from(this.querySelectorAll("wje-breadcrumb")) || []; } /** * Retrieves all breadcrumb elements that have the 'collapsed' attribute. * @returns {Array<Element>} An array of DOM elements representing breadcrumbs with the 'collapsed' attribute. */ getBreadcrumbsCollapsed() { return Array.from(this.querySelectorAll("wje-breadcrumb[collapsed]")) || []; } }; __publicField(_Breadcrumbs, "BREAKPOINTS", { sm: 576, md: 768, lg: 992, xl: 1200, "2xl": 1450, xxl: 1450 }); let Breadcrumbs = _Breadcrumbs; Breadcrumbs.define("wje-breadcrumbs", Breadcrumbs); export { Breadcrumbs as default }; //# sourceMappingURL=wje-breadcrumbs.js.map