@cbpds/web-components
Version:
Web components for the CBP Design System.
180 lines (179 loc) • 7.37 kB
JavaScript
/*!
* CPB Design System web components - built with Stencil
*/
import { Host, h } from "@stencil/core";
import { setCSSProps, debounce } from "../../utils/utils";
export class CbpBreadcrumb {
constructor() {
this.breadcrumbs = [];
this.children = [];
this.sizeMap = [
{
size: "compact",
width: undefined
},
{
size: "medium",
width: undefined
},
{
size: "full",
width: undefined
}
];
this.divider = undefined;
this.context = undefined;
this.sx = {};
this.menuItems = [];
this.sizeIndex = 2;
}
handleResize(width) {
this.sizeMap[this.sizeIndex]['width'] = this.nav.getBoundingClientRect().width;
if (this.sizeIndex > 0 && width <= this.sizeMap[this.sizeIndex]['width']) {
this.resizeResponsive(this.sizeIndex - 1);
}
if (this.sizeIndex < 2 && width > this.sizeMap[this.sizeIndex + 1]['width']) {
this.resizeResponsive(this.sizeIndex + 1);
}
}
resizeResponsive(mode) {
switch (this.sizeMap[mode]['size']) {
case "compact":
this.children.forEach((item, index) => {
if (index > 0) {
item.setAttribute('hidden', '');
}
});
this.menu.removeAttribute('hidden');
break;
case "medium":
this.children.forEach((item, index) => {
if (index > 0 && index < (this.children.length - 2))
item.setAttribute('hidden', '');
else
item.removeAttribute('hidden');
if (index == (this.children.length - 2))
item.style.setProperty('order', `${index}`);
});
this.menu.removeAttribute('hidden');
break;
case "full":
this.children.forEach((item, index) => {
if (index > 0)
item.removeAttribute('hidden');
});
this.menu.setAttribute('hidden', '');
break;
default:
console.log(`cbp-breadcrumb - We should never see the default case... ${this.sizeMap[mode]['size']}.`);
}
this.sizeIndex = mode;
setTimeout(() => {
this.sizeMap[mode]['width'] = this.nav.getBoundingClientRect().width;
if (mode == 1 && this.ro.getBoundingClientRect().width <= this.nav.getBoundingClientRect().width) {
this.resizeResponsive(this.sizeIndex - 1);
}
}, 200);
}
createMenu(breadcrumbs) {
let menuItems = [];
breadcrumbs.forEach((item, index) => {
let newItem = h("cbp-menu-item", { indentLevel: index }, h("a", { href: `${item.href}` }, index == 0
? h("cbp-flex", { gap: "var(--cbp-space-1x)" }, h("cbp-icon", { name: "home" }), "Home")
: item.textContent));
menuItems = [...menuItems, newItem];
});
this.menuItems = [...menuItems];
}
componentWillLoad() {
if (typeof this.sx == 'string') {
this.sx = JSON.parse(this.sx) || {};
}
setCSSProps(this.host, Object.assign({ "--cbp-breadcrumb-divider": this.divider ? `"${this.divider}"` : undefined }, this.sx));
}
componentDidLoad() {
this.children = Array.from(this.nav.querySelectorAll(':scope > *'));
this.breadcrumbs = Array.from(this.host.querySelectorAll('a[href]'));
this.createMenu(this.breadcrumbs);
}
render() {
return (h(Host, { key: 'aefe4f46cc33ca9c9408388446d40aa29967fbe2' }, h("cbp-resize-observer", { key: '5b9dc25328a16bcfbe6fb1911d9b20d29497cba8', debounce: 50, ref: el => this.ro = el, onResized: debounce((e) => {
this.handleResize(e.detail.width);
}, 10) }, h("nav", { key: 'cfc5a1c3da1d19acca7a8f6c5a4fd13732c423c0', "aria-label": "Breadcrumb", ref: el => this.nav = el }, h("slot", { key: 'ad37124823732555873aa8eaeb46f25f29e1cf2f' }), h("cbp-menu", { key: 'f04d7fe0916f5c2a79fdd902807a39ed85688684', hidden: true, uid: "cbp-breadcrumbs-menu", ref: el => this.menu = el }, h("cbp-button", { key: '1dfc66633693b13d4d415410b146b7416ead0087', fill: "outline", color: "secondary", "target-prop": "open", controls: "cbp-breadcrumbs-menu", accessibilityText: "Breadcrumbs Menu" }, h("cbp-icon", { key: '186d2d7865b97ccc15c8a73d4ce2de4a9e685d8c', name: "ellipsis-vertical", rotate: 90 })), [...this.menuItems])))));
}
static get is() { return "cbp-breadcrumb"; }
static get originalStyleUrls() {
return {
"$": ["cbp-breadcrumb.scss"]
};
}
static get styleUrls() {
return {
"$": ["cbp-breadcrumb.css"]
};
}
static get properties() {
return {
"divider": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Specifies a character as a divider between breadcrumb links. Defaults to \"/\"."
},
"attribute": "divider",
"reflect": false
},
"context": {
"type": "string",
"mutable": false,
"complexType": {
"original": "\"light-inverts\" | \"light-always\" | \"dark-inverts\" | \"dark-always\"",
"resolved": "\"dark-always\" | \"dark-inverts\" | \"light-always\" | \"light-inverts\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Specifies the context of the component as it applies to the visual design and whether it inverts when light/dark mode is toggled. Default behavior is \"light-inverts\" and does not have to be specified."
},
"attribute": "context",
"reflect": true
},
"sx": {
"type": "any",
"mutable": false,
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Supports adding inline styles as an object"
},
"attribute": "sx",
"reflect": false,
"defaultValue": "{}"
}
};
}
static get states() {
return {
"menuItems": {},
"sizeIndex": {}
};
}
static get elementRef() { return "host"; }
}
//# sourceMappingURL=cbp-breadcrumb.js.map