Skip to content

Commit

Permalink
fix(ui5-breadcrumbs): render current location as link (#8206)
Browse files Browse the repository at this point in the history
* fix(ui5-breadcrumbs): render current location as link

* fix(ui5-breadcrumbs): reload page on current-page item click
  • Loading branch information
kineticjs committed Jan 31, 2024
1 parent 87d640e commit 01f5542
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 147 deletions.
20 changes: 4 additions & 16 deletions packages/main/src/Breadcrumbs.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,16 @@
href="{{this.href}}"
target="{{this.target}}"
id="{{this._id}}-link"
design="{{this._linkDesign}}"
accessible-name="{{this._accessibleNameText}}"
data-ui5-stable="{{this.stableDomRef}}">
{{this.innerText}}
</ui5-link>

<span class="ui5-breadcrumbs-separator" aria-hidden="true"></span>
{{#unless this._isCurrentPageItem}}
<span class="ui5-breadcrumbs-separator" aria-hidden="true"></span>
{{/unless}}
</li>
{{/each}}

{{#if _endsWithCurrentLocationLabel}}
<li class="ui5-breadcrumbs-current-location" @click="{{../_onLabelPress}}">

<span aria-current="page"
aria-label="{{_currentLocationAccName}}"
role="link"
id="{{this._id}}-labelWrapper">

<ui5-label>
{{_currentLocationText}}
</ui5-label>
</span>
</li>
{{/if}}
</ol>
</nav>
118 changes: 9 additions & 109 deletions packages/main/src/Breadcrumbs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation
import type { ITabbable } from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js";
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
import {
isEnter,
isSpace,
isShow,
} from "@ui5/webcomponents-base/dist/Keys.js";
Expand All @@ -29,7 +28,6 @@ import {
} from "./generated/i18n/i18n-defaults.js";
import Link from "./Link.js";
import type { LinkClickEventDetail } from "./Link.js";
import Label from "./Label.js";
import ResponsivePopover from "./ResponsivePopover.js";
import List from "./List.js";
import type { ListSelectionChangeEventDetail } from "./List.js";
Expand All @@ -54,10 +52,6 @@ type BreadcrumbsItemClickEventDetail = {
shiftKey: boolean;
}

type FocusAdaptor = ITabbable & {
getlabelWrapper: () => Element | null;
}

/**
* @class
*
Expand Down Expand Up @@ -101,7 +95,6 @@ type FocusAdaptor = ITabbable & {
dependencies: [
BreadcrumbsItem,
Link,
Label,
ResponsivePopover,
List,
StandardListItem,
Expand Down Expand Up @@ -194,7 +187,6 @@ class Breadcrumbs extends UI5Element {
// the width of the interactive element that opens the overflow
_dropdownArrowLinkWidth = 0;
responsivePopover?: ResponsivePopover;
_labelFocusAdaptor: FocusAdaptor;
static i18nBundle: I18nBundle;

constructor() {
Expand All @@ -206,19 +198,6 @@ class Breadcrumbs extends UI5Element {
});

this._onResizeHandler = this._updateOverflow.bind(this);

this._labelFocusAdaptor = {
id: `${this._id}-labelWrapper`,
getlabelWrapper: this.getCurrentLocationLabelWrapper.bind(this),
set _tabIndex(value: string) {
const wrapper = this.getlabelWrapper();
wrapper && wrapper.setAttribute("tabindex", value);
},
get _tabIndex() {
const wrapper = this.getlabelWrapper();
return wrapper?.getAttribute("tabindex") || "";
},
};
}

onInvalidation(changeInfo: ChangeInfo) {
Expand Down Expand Up @@ -275,16 +254,11 @@ class Breadcrumbs extends UI5Element {
items.unshift(this._dropdownArrowLink);
}

if (this._endsWithCurrentLocationLabel) {
items.push(this._labelFocusAdaptor);
}
return items;
}

_onfocusin(e: FocusEvent) {
const target = e.target,
labelWrapper = this.getCurrentLocationLabelWrapper(),
currentItem = (target === labelWrapper) ? this._labelFocusAdaptor : target as Link;
const currentItem = e.target as Link;

this._itemNavigation.setCurrentItem(currentItem);
}
Expand All @@ -299,10 +273,6 @@ class Breadcrumbs extends UI5Element {
}
if (isSpace(e) && isDropdownArrowFocused && !this._isOverflowEmpty && !this._isPickerOpen) {
e.preventDefault();
return;
}
if ((isEnter(e) || isSpace(e)) && this._isCurrentLocationLabelFocused) {
this._onLabelPress(e);
}
}

Expand All @@ -318,21 +288,14 @@ class Breadcrumbs extends UI5Element {
*/
_cacheWidths() {
const map = this._breadcrumbItemWidths,
items = this._getItems(),
label = this._currentLocationLabel;
items = this._getItems();

for (let i = this._overflowSize; i < items.length; i++) {
const item = items[i],
link = this.shadowRoot!.querySelector<HTMLElement>(`#${item._id}-link-wrapper`)!;
map.set(item, this._getElementWidth(link));
}

if (items.length && this._endsWithCurrentLocationLabel && label) {
const item = items[items.length - 1];

map.set(item, this._getElementWidth(label));
}

if (!this._isOverflowEmpty) {
const arrow = this.shadowRoot!.querySelector<HTMLElement>(".ui5-breadcrumbs-dropdown-arrow-link-wrapper")!;
this._dropdownArrowLinkWidth = this._getElementWidth(arrow);
Expand Down Expand Up @@ -413,26 +376,12 @@ class Breadcrumbs extends UI5Element {
shiftKey,
}, true)) {
e.preventDefault();
return;
}
}

_onLabelPress(e: MouseEvent | KeyboardEvent) {
const items = this._getItems(),
item = items[items.length - 1],
{
altKey,
ctrlKey,
metaKey,
shiftKey,
} = e;

this.fireEvent<BreadcrumbsItemClickEventDetail>("item-click", {
item,
altKey,
ctrlKey,
metaKey,
shiftKey,
});
if (item._isCurrentPageItem) {
window.location.reload();
}
}

_onOverflowListItemSelect(e: CustomEvent<ListSelectionChangeEventDetail>) {
Expand Down Expand Up @@ -505,44 +454,20 @@ class Breadcrumbs extends UI5Element {
return text;
}

getCurrentLocationLabelWrapper() {
return this.shadowRoot!.querySelector<HTMLElement>(".ui5-breadcrumbs-current-location > span");
}

get _visibleItems() {
return this._getItems()
.slice(this._overflowSize)
.filter(i => this._isItemVisible(i));
}

get _endsWithCurrentLocationLabel() {
get _endsWithCurrentPageItem() {
return this.design === BreadcrumbsDesign.Standard;
}

get _currentLocationText() {
const items = this._getItems();
if (this._endsWithCurrentLocationLabel && items.length) {
const item = items[items.length - 1];
if (this._isItemVisible(item)) {
return item.innerText;
}
}
return "";
}

get _currentLocationLabel() {
return this.shadowRoot!.querySelector<Label>(".ui5-breadcrumbs-current-location [ui5-label]");
}

get _isDropdownArrowFocused() {
return this._dropdownArrowLink._tabIndex === "0";
}

get _isCurrentLocationLabelFocused() {
const label = this.getCurrentLocationLabelWrapper();
return label && label.tabIndex === 0;
}

/**
* Returns the maximum allowed count of items in the overflow
* with respect to the UX requirement to never overflow the last visible item
Expand Down Expand Up @@ -576,41 +501,16 @@ class Breadcrumbs extends UI5Element {
*/
get _linksData() {
const items = this._visibleItems;
const itemsCount = items.length; // get size before removing of current location

if (this._endsWithCurrentLocationLabel) {
items.pop();
}
const itemsCount = items.length;

return items
.map((item, index) => {
item._accessibleNameText = this._getItemAccessibleName(item, index + 1, itemsCount);
item._isCurrentPageItem = index === (itemsCount - 1) && this._endsWithCurrentPageItem;
return item;
});
}

/**
* Getter for accessible name of the current location. Includes the position of the current location and the size of the breadcrumbs
*/
get _currentLocationAccName() {
const items = this._visibleItems;

const positionText = this._getItemPositionText(items.length, items.length);
const lastItem = items[items.length - 1];

if (!lastItem) {
return positionText;
}

const lastItemText = lastItem.textContent || "";

if (lastItem.accessibleName) {
return `${lastItemText.trim()} ${lastItem.accessibleName} ${positionText}`;
}

return `${lastItemText.trim()} ${positionText}`;
}

/**
* Getter for the list of links corresponding to the abstract breadcrumb items
*/
Expand Down
6 changes: 6 additions & 0 deletions packages/main/src/BreadcrumbsItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
import LinkDesign from "./types/LinkDesign.js";

/**
* @class
Expand Down Expand Up @@ -68,10 +69,15 @@ class BreadcrumbsItem extends UI5Element {
text!: Array<Node>;

_accessibleNameText?: string;
_isCurrentPageItem?: boolean;

get stableDomRef() {
return this.getAttribute("stable-dom-ref") || `${this._id}-stable-dom-ref`;
}

get _linkDesign() {
return this._isCurrentPageItem ? LinkDesign.Emphasized : LinkDesign.Default;
}
}

BreadcrumbsItem.define();
Expand Down
17 changes: 1 addition & 16 deletions packages/main/src/themes/Breadcrumbs.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
.ui5-breadcrumbs-root {
white-space: nowrap;
outline: none;
margin: 0 0 0.5rem 0;
margin:var(--_ui5_breadcrumbs_margin);
}

.ui5-breadcrumbs-root > ol {
Expand All @@ -22,21 +22,6 @@
display: inline;
}

.ui5-breadcrumbs-current-location {
min-width: 1%;
-webkit-flex: 1;
-webkit-box-flex: 1;
flex: 1 1 auto;
/* Fix extra height in ul -> li element */
font-size: 0;
align-self: center;
}

.ui5-breadcrumbs-current-location > span:focus {
outline: var(--sapContent_FocusWidth) var(--sapContent_FocusStyle) var(--sapContent_FocusColor);
border-radius: var(--_ui5_breadcrumbs_current_location_focus_border_radius);
}

.ui5-breadcrumbs-dropdown-arrow-link-wrapper[hidden] {
display: none
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
:root {
--_ui5_breadcrumbs_current_location_focus_border_radius: 0.25rem;
--_ui5_breadcrumbs_margin: 0 0 0.5rem 0;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
:root {
--_ui5_breadcrumbs_current_location_focus_border_radius: 0.25rem;
--_ui5_breadcrumbs_margin: 0 0 0.5rem 0;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
:root {
--_ui5_breadcrumbs_current_location_focus_border_radius: 0.25rem;
--_ui5_breadcrumbs_margin: 0 0 0.5rem 0;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
:root {
--_ui5_breadcrumbs_current_location_focus_border_radius: 0.25rem;
--_ui5_breadcrumbs_margin: 0 0 0.5rem 0;
}
Loading

0 comments on commit 01f5542

Please sign in to comment.