/
githubmirror
/
components
Обзор
Документация
Войти
/
githubmirror
/
components
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/cdk/menu/menu-bar.ts
141 строка
4 KB
Andrew Seguin
refactor: use relative imports within module npm packages (#30588)
12 мар 2025, 00:40
Не верифицирован
12 мар 2025, 00:40
626a465
Код
Авторство
О чём код?
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.dev/license */ import {AfterContentInit, Directive} from '@angular/core'; import { DOWN_ARROW, ESCAPE, hasModifierKey, LEFT_ARROW, RIGHT_ARROW, TAB, UP_ARROW, } from '../keycodes'; import {takeUntil} from 'rxjs/operators'; import {CdkMenuGroup} from './menu-group'; import {CDK_MENU} from './menu-interface'; import {FocusNext, MENU_STACK, MenuStack} from './menu-stack'; import {CdkMenuBase} from './menu-base'; /** * Directive applied to an element which configures it as a MenuBar by setting the appropriate * role, aria attributes, and accessible keyboard and mouse handling logic. The component that * this directive is applied to should contain components marked with CdkMenuItem. * */ @Directive({ selector: '[cdkMenuBar]', exportAs: 'cdkMenuBar', host: { 'role': 'menubar', 'class': 'cdk-menu-bar', '(keydown)': '_handleKeyEvent($event)', }, providers: [ {provide: CdkMenuGroup, useExisting: CdkMenuBar}, {provide: CDK_MENU, useExisting: CdkMenuBar}, {provide: MENU_STACK, useFactory: () => MenuStack.inline('horizontal')}, ], }) export class CdkMenuBar extends CdkMenuBase implements AfterContentInit { /** The direction items in the menu flow. */ override readonly orientation = 'horizontal'; /** Whether the menu is displayed inline (i.e. always present vs a conditional popup that the user triggers with a trigger element). */ override readonly isInline = true; override ngAfterContentInit() { super.ngAfterContentInit(); this._subscribeToMenuStackEmptied(); } /** * Handle keyboard events for the Menu. * @param event The keyboard event to be handled. */ _handleKeyEvent(event: KeyboardEvent) { const keyManager = this.keyManager; switch (event.keyCode) { case UP_ARROW: case DOWN_ARROW: case LEFT_ARROW: case RIGHT_ARROW: if (!hasModifierKey(event)) { const horizontalArrows = event.keyCode === LEFT_ARROW || event.keyCode === RIGHT_ARROW; // For a horizontal menu if the left/right keys were clicked, or a vertical menu if the // up/down keys were clicked: if the current menu is open, close it then focus and open the // next menu. if (horizontalArrows) { event.preventDefault(); const prevIsOpen = keyManager.activeItem?.isMenuOpen(); keyManager.activeItem?.getMenuTrigger()?.close(); keyManager.setFocusOrigin('keyboard'); keyManager.onKeydown(event); if (prevIsOpen) { keyManager.activeItem?.getMenuTrigger()?.open(); } } } break; case ESCAPE: if (!hasModifierKey(event)) { event.preventDefault(); keyManager.activeItem?.getMenuTrigger()?.close(); } break; case TAB: if (!hasModifierKey(event, 'altKey', 'metaKey', 'ctrlKey')) { keyManager.activeItem?.getMenuTrigger()?.close(); } break; default: keyManager.onKeydown(event); } } /** * Set focus to either the current, previous or next item based on the FocusNext event, then * open the previous or next item. * @param focusNext The element to focus. */ private _toggleOpenMenu(focusNext: FocusNext | undefined) { const keyManager = this.keyManager; switch (focusNext) { case FocusNext.nextItem: keyManager.setFocusOrigin('keyboard'); keyManager.setNextItemActive(); keyManager.activeItem?.getMenuTrigger()?.open(); break; case FocusNext.previousItem: keyManager.setFocusOrigin('keyboard'); keyManager.setPreviousItemActive(); keyManager.activeItem?.getMenuTrigger()?.open(); break; case FocusNext.currentItem: if (keyManager.activeItem) { keyManager.setFocusOrigin('keyboard'); keyManager.setActiveItem(keyManager.activeItem); } break; } } /** Subscribe to the MenuStack emptied events. */ private _subscribeToMenuStackEmptied() { this.menuStack?.emptied .pipe(takeUntil(this.destroyed)) .subscribe(event => this._toggleOpenMenu(event)); } }