Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions packages/fiori/src/UserSettingsDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import type { PopupBeforeCloseEventDetail } from "@ui5/webcomponents/dist/Popup.js";
import { isPhone, isTablet, isCombi } from "@ui5/webcomponents-base/dist/Device.js";
import MediaRange from "@ui5/webcomponents-base/dist/MediaRange.js";
import { isF6Next, isF6Previous } from "@ui5/webcomponents-base/dist/Keys.js";
import { getFirstFocusableElement } from "@ui5/webcomponents-base/dist/util/FocusableElements.js";
import UserSettingsDialogTemplate from "./UserSettingsDialogTemplate.js";
import type UserSettingsItem from "./UserSettingsItem.js";
import UserSettingsDialogCss from "./generated/themes/UserSettingsDialog.css.js";
Expand Down Expand Up @@ -193,6 +195,21 @@
@property({ type: String })
_mediaRange?: any;

_boundHandleF6: (e: KeyboardEvent) => void;

constructor() {
super();
this._boundHandleF6 = this._handleF6.bind(this);

Check failure on line 202 in packages/fiori/src/UserSettingsDialog.ts

View workflow job for this annotation

GitHub Actions / check

Promise-returning function provided to variable where a void return was expected
}

onEnterDOM() {
this.addEventListener("keydown", this._boundHandleF6 as EventListener);
}

onExitDOM() {
this.removeEventListener("keydown", this._boundHandleF6 as EventListener);
}

onBeforeRendering() {
this._mediaRange = MediaRange.getCurrentRange(MediaRange.RANGESETS.RANGE_4STEPS);
const searchValue = this._searchValue.toLowerCase();
Expand Down Expand Up @@ -310,6 +327,50 @@
this._searchValue = (e.target as Input).value;
}

async _handleF6(e: KeyboardEvent) {
const forward = isF6Next(e);
const backward = isF6Previous(e);

if (!forward && !backward) {
return;
}

e.preventDefault();
e.stopPropagation();

const zones = this._getVisibleF6Zones();
if (zones.length === 0) {
return;
}

const currentZone = e.composedPath().find(node => zones.includes(node as HTMLElement)) as HTMLElement | undefined;
const currentIndex = currentZone ? zones.indexOf(currentZone) : -1;

let nextIndex: number;
if (forward) {
nextIndex = currentIndex + 1;
if (nextIndex >= zones.length) {
nextIndex = 0;
}
} else {
nextIndex = currentIndex - 1;
if (nextIndex < 0) {
nextIndex = zones.length - 1;
}
}

const elementToFocus = await getFirstFocusableElement(zones[nextIndex]);
elementToFocus?.focus();
}

_getVisibleF6Zones(): HTMLElement[] {
return Array.from(this.shadowRoot!.querySelectorAll<HTMLElement>("[data-sap-ui-fastnavgroup='true']"))
.filter(el => {
const style = getComputedStyle(el);
return style.display !== "none" && style.visibility !== "hidden";
});
}

captureRef(ref: HTMLElement & { associatedSettingItem?: UI5Element} | null) {
if (ref) {
ref.associatedSettingItem = this;
Expand Down
8 changes: 4 additions & 4 deletions packages/fiori/src/UserSettingsDialogTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function UserSettingsDialogTemplate(this: UserSettingsDialog) {
initialFocus={`setting-${this._selectedSetting?._id}`}
>
<div class="ui5-user-settings-root">
<div class="ui5-user-settings-side" aria-orientation="vertical" aria-roledescription={this.ariaRoleDescList}>
<div class="ui5-user-settings-side" data-sap-ui-fastnavgroup="true" aria-orientation="vertical" aria-roledescription={this.ariaRoleDescList}>
<div class="ui5-user-settings-side-header">
{this.headerText &&
<Title level="H1" size="H4">{this.headerText}</Title>
Expand All @@ -47,20 +47,20 @@ export default function UserSettingsDialogTemplate(this: UserSettingsDialog) {
{this._filteredFixedItems.length > 0 && renderList.call(this, this._filteredFixedItems, "ui5-user-settings-side-fixedItems")}
</div>

<div class="ui5-user-settings-content">
<div class="ui5-user-settings-content" data-sap-ui-fastnavgroup="true">
<slot name={this._selectedItemSlotName}></slot>
</div>
</div>

<Toolbar slot="footer" design="Transparent">
<Toolbar slot="footer" design="Transparent" data-sap-ui-fastnavgroup="true">
<ToolbarButton design="Transparent" text={this.closeButtonText} tooltip={this.closeButtonText} onClick={this._handleCloseButtonClick} />
</Toolbar>
</Dialog>
);
}

function renderList(this: UserSettingsDialog, items: Array<UserSettingsItem> = [], classes: string) {
return <List accessibleRole="Menu" onItemClick={this._handleItemClick} class={classes} separators="None">
return <List accessibleRole="Menu" onItemClick={this._handleItemClick} class={classes} separators="None" data-sap-ui-fastnavgroup="false">
{items.map(item => (
<ListItemStandard
class={!item._icon && item._siblingsWithIcon ? "ui5-user-settings-item-no-icon" : ""}
Expand Down
Loading