feat: Add support for flyout menu mode in MegaMenu
- Introduced `MegaMenuMode` type and `normalizeMegaMenuMode` function to handle menu modes. - Updated `MegaMenuApplicationCustomizer` to accept `menuMode` property. - Enhanced `MegaMenuRenderer` to render flyout menus based on the selected mode. - Created new HTML previews for both flyout and mega menu modes. - Removed unused mock services and user custom action service interfaces.
This commit is contained in:
@@ -5,8 +5,7 @@
|
||||
|
||||
import { IMenuItem } from '../../services/IMenuItem';
|
||||
import { debugLog } from '../../services/MegaMenuDebug';
|
||||
|
||||
import styles from './MegaMenu.module.scss'; // tslint:disable-line:no-unused-variable
|
||||
import { MegaMenuMode } from './MegaMenuMode';
|
||||
|
||||
const LOG_SOURCE: string = 'MegaMenuRenderer';
|
||||
|
||||
@@ -20,7 +19,8 @@ export class MegaMenuRenderer {
|
||||
|
||||
constructor(
|
||||
private menuItems: IMenuItem[],
|
||||
private debug: boolean = false
|
||||
private debug: boolean = false,
|
||||
private menuMode: MegaMenuMode = 'megaMenu'
|
||||
) { }
|
||||
|
||||
public render(container: HTMLElement): void {
|
||||
@@ -36,7 +36,8 @@ export class MegaMenuRenderer {
|
||||
|
||||
const nav = document.createElement('nav');
|
||||
nav.id = 'Mega-Menu';
|
||||
nav.className = 'mega-menu-main';
|
||||
nav.className = this.joinClasses('mega-menu-main', 'mega-menu-mode-' + this.menuMode);
|
||||
nav.setAttribute('data-menu-mode', this.menuMode);
|
||||
nav.setAttribute('aria-label', 'Hauptnavigation');
|
||||
|
||||
const topLevelUl = document.createElement('ul');
|
||||
@@ -99,8 +100,10 @@ export class MegaMenuRenderer {
|
||||
li.appendChild(topElement);
|
||||
|
||||
if (hasChildren) {
|
||||
const megaMenu = this.createMegaMenu(item);
|
||||
li.appendChild(megaMenu);
|
||||
const childMenu = this.menuMode === 'flyout'
|
||||
? this.createFlyoutMenu(item)
|
||||
: this.createMegaMenu(item);
|
||||
li.appendChild(childMenu);
|
||||
}
|
||||
|
||||
return li;
|
||||
@@ -246,6 +249,88 @@ export class MegaMenuRenderer {
|
||||
return categoryDiv;
|
||||
}
|
||||
|
||||
private createFlyoutMenu(parentItem: IMenuItem): HTMLDivElement {
|
||||
const flyout = document.createElement('div');
|
||||
flyout.className = 'mega-menu mega-menu-flyout';
|
||||
flyout.setAttribute('aria-expanded', 'false');
|
||||
flyout.setAttribute('aria-label', parentItem.label + ' Untermenü');
|
||||
|
||||
const list = document.createElement('ul');
|
||||
list.className = 'flyout-list flyout-level-2';
|
||||
|
||||
if (parentItem.items) {
|
||||
parentItem.items.forEach(secondLevelItem => {
|
||||
list.appendChild(this.createFlyoutItem(secondLevelItem));
|
||||
});
|
||||
}
|
||||
|
||||
flyout.appendChild(list);
|
||||
return flyout;
|
||||
}
|
||||
|
||||
private createFlyoutItem(item: IMenuItem): HTMLLIElement {
|
||||
const li = document.createElement('li');
|
||||
const hasChildren = item.hasChildren() && item.items && item.items.length > 0;
|
||||
const isActive = this.isItemActive(item);
|
||||
const isCurrent = this.isCurrentUrl(item.url);
|
||||
|
||||
li.className = this.joinClasses(
|
||||
'flyout-item',
|
||||
hasChildren ? 'has-children' : undefined,
|
||||
isActive ? 'is-active' : undefined,
|
||||
isCurrent ? 'is-current' : undefined
|
||||
);
|
||||
|
||||
const element = this.createFlyoutElement(item, hasChildren, isActive, isCurrent);
|
||||
li.appendChild(element);
|
||||
|
||||
if (hasChildren && item.items) {
|
||||
const childList = document.createElement('ul');
|
||||
childList.className = 'flyout-list flyout-level-3';
|
||||
childList.setAttribute('aria-label', item.label + ' Untermenü');
|
||||
|
||||
item.items.forEach(thirdLevelItem => {
|
||||
childList.appendChild(this.createFlyoutItem(thirdLevelItem));
|
||||
});
|
||||
|
||||
li.appendChild(childList);
|
||||
}
|
||||
|
||||
return li;
|
||||
}
|
||||
|
||||
private createFlyoutElement(item: IMenuItem, hasChildren: boolean, isActive: boolean, isCurrent: boolean): HTMLElement {
|
||||
const element: HTMLElement = item.url
|
||||
? document.createElement('a')
|
||||
: document.createElement('span');
|
||||
|
||||
if (item.url) {
|
||||
(element as HTMLAnchorElement).href = item.url;
|
||||
} else {
|
||||
element.setAttribute('tabindex', '0');
|
||||
}
|
||||
|
||||
element.textContent = item.label;
|
||||
element.className = this.joinClasses(
|
||||
'flyout-link',
|
||||
hasChildren ? 'flyout-link-has-children' : undefined,
|
||||
isActive ? 'is-active' : undefined,
|
||||
isCurrent ? 'is-current' : undefined
|
||||
);
|
||||
|
||||
if (hasChildren) {
|
||||
element.setAttribute('aria-haspopup', 'true');
|
||||
}
|
||||
if (isCurrent && item.url) {
|
||||
element.setAttribute('aria-current', 'page');
|
||||
}
|
||||
if (item.hoverText) {
|
||||
element.title = item.hoverText;
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
private attachEventListeners(): void {
|
||||
const headings = document.querySelectorAll('#Mega-Menu > ul > li > a, #Mega-Menu > ul > li > .menu-item-text');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user