@umbraco-ui/uui-breadcrumbs
Version:
This package contains two web components - uui-breadcrumb-item and uui-breadcrumbs. They can be used as an additional navigation to allow users to keep track and maintain awareness of their location.
190 lines (178 loc) • 5.72 kB
JavaScript
import { defineElement } from '@umbraco-ui/uui-base/lib/registration';
import { css, LitElement, html } from 'lit';
import { property, queryAssignedElements } from 'lit/decorators.js';
import '@umbraco-ui/uui-responsive-container/lib';
import { demandCustomElement } from '@umbraco-ui/uui-base/lib/utils';
var __defProp$1 = Object.defineProperty;
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
var __decorateClass$1 = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result) __defProp$1(target, key, result);
return result;
};
let UUIBreadcrumbItemElement = class extends LitElement {
constructor() {
super(...arguments);
this.lastItem = false;
}
connectedCallback() {
super.connectedCallback();
}
_onKeydown(e) {
if (e.key === "Enter") {
e.currentTarget.click();
}
}
renderLinkAndSeparator() {
const item = this.href ? html`<a id="link" href=${this.href}><slot></slot></a>` : html`<span
id="link"
tabindex="0"
role="link"
@keydown=${this._onKeydown}
><slot></slot
></span>`;
return html`${item}<span part="separator"></span>`;
}
renderCurrent() {
return html`<span id="last-item"><slot></slot></span>`;
}
render() {
return html`${this.lastItem ? this.renderCurrent() : this.renderLinkAndSeparator()}`;
}
};
UUIBreadcrumbItemElement.styles = [
css`
:host {
font-size: var(--uui-type-small-size,12px);
color: currentColor;
}
a,
a:visited,
span#link {
color: currentColor;
cursor: pointer;
text-decoration: underline;
}
a:hover,
span#link:hover {
color: var(--uui-color-interactive-emphasis,#3544b1);
}
a:focus,
span#link:focus {
color: var(--uui-color-focus,#3879ff);
}
a:focus-visible,
span#link:focus-visible {
border-radius: var(--uui-border-radius,3px);
outline: 2px solid var(--uui-color-focus,#3879ff);
}
[part='separator']::after {
content: '/';
speak: never;
position: relative;
top: 1px;
margin: -3px 1px 0;
color: var(--uui-color-border,#d8d7d9);
}
#link,
#last-item {
padding: 0 4px;
max-width: 150px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
`
];
__decorateClass$1([
property()
], UUIBreadcrumbItemElement.prototype, "href", 2);
__decorateClass$1([
property({ type: Boolean, attribute: "last-item" })
], UUIBreadcrumbItemElement.prototype, "lastItem", 2);
UUIBreadcrumbItemElement = __decorateClass$1([
defineElement("uui-breadcrumb-item")
], UUIBreadcrumbItemElement);
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result) __defProp(target, key, result);
return result;
};
let UUIBreadcrumbsElement = class extends LitElement {
elementIsBreadcrumbItem(el) {
return el instanceof UUIBreadcrumbItemElement;
}
connectedCallback() {
super.connectedCallback();
this.setAttribute("aria-label", "breadcrumb");
this.setAttribute("role", "navigation");
demandCustomElement(this, "uui-responsive-container");
}
handleSlotChange() {
if (this.slotNodes.length > 0) {
const lastItem = this.slotNodes[this.slotNodes.length - 1];
lastItem.setAttribute("aria-current", "page");
if (this.elementIsBreadcrumbItem(lastItem)) {
lastItem.lastItem = true;
}
}
}
render() {
return html`<uui-responsive-container
id="breadcrumbs-list"
collapse="start">
<span slot="trigger-content">
<span class="ellipsis">…</span> <span class="separator">/</span>
</span>
<slot @slotchange=${this.handleSlotChange}></slot>
</uui-responsive-container>`;
}
};
UUIBreadcrumbsElement.styles = [
css`
:host {
display: flex;
}
#breadcrumbs-list {
display: flex;
list-style-type: decimal;
margin-block-start: 0em;
margin-block-end: 0em;
margin-inline-start: 0px;
margin-inline-end: 0px;
padding-inline-start: 0px;
}
uui-responsive-container {
--uui-responsive-container-gap: 0;
}
/* Style the trigger content to match breadcrumb items */
[slot='trigger-content'] {
font-size: var(--uui-type-small-size,12px);
}
[slot='trigger-content'] .ellipsis {
color: currentColor; /* Black/default text color */
}
[slot='trigger-content'] .separator {
color: var(--uui-color-border,#d8d7d9); /* Matches breadcrumb separator */
margin-left: var(--uui-size-2,6px);
}
`
];
__decorateClass([
queryAssignedElements({
flatten: true,
selector: "uui-breadcrumb-item, [uui-breadcrumb-item], [role=listitem]"
})
], UUIBreadcrumbsElement.prototype, "slotNodes", 2);
UUIBreadcrumbsElement = __decorateClass([
defineElement("uui-breadcrumbs")
], UUIBreadcrumbsElement);
export { UUIBreadcrumbItemElement, UUIBreadcrumbsElement };