MCPcopy Create free account
hub / github.com/angular/components / MenuBarPattern

Class MenuBarPattern

src/aria/private/menu/menu.ts:481–635  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

479
480/** The menubar ui pattern class. */
481export class MenuBarPattern<V> {
482 /** Controls list behavior for the menu items. */
483 readonly listBehavior: List<MenuItemPattern<V>, V>;
484
485 /** The tab index of the menu. */
486 readonly tabIndex = () => this.listBehavior.tabIndex();
487
488 /** The key used to navigate to the next item. */
489 private readonly _nextKey = computed(() => {
490 return this.inputs.textDirection() === 'rtl' ? 'ArrowLeft' : 'ArrowRight';
491 });
492
493 /** The key used to navigate to the previous item. */
494 private readonly _previousKey = computed(() => {
495 return this.inputs.textDirection() === 'rtl' ? 'ArrowRight' : 'ArrowLeft';
496 });
497
498 /** Represents the space key. Does nothing when the user is actively using typeahead. */
499 readonly dynamicSpaceKey = computed(() => (this.listBehavior.isTyping() ? '' : ' '));
500
501 /** The regexp used to decide if a key should trigger typeahead. */
502 readonly typeaheadRegexp = /^.$/;
503
504 /** Whether the menubar or any of its children are currently focused. */
505 readonly isFocused = signal(false);
506
507 /** Whether the menubar has been interacted with. */
508 readonly hasBeenInteracted = signal(false);
509
510 /** Whether the menubar is disabled. */
511 readonly disabled = () => this.inputs.disabled();
512
513 /** Handles keyboard events for the menu. */
514 readonly keydownManager = computed(() => {
515 return new KeyboardEventManager()
516 .on(this._nextKey, () => this.next(), {ignoreRepeat: false})
517 .on(this._previousKey, () => this.prev(), {ignoreRepeat: false})
518 .on('End', () => this.listBehavior.last())
519 .on('Home', () => this.listBehavior.first())
520 .on('Enter', () => this.inputs.activeItem()?.open({first: true}))
521 .on('ArrowUp', () => this.inputs.activeItem()?.open({last: true}))
522 .on('ArrowDown', () => this.inputs.activeItem()?.open({first: true}))
523 .on(this.dynamicSpaceKey, () => this.inputs.activeItem()?.open({first: true}))
524 .on(this.typeaheadRegexp, e => this.listBehavior.search(e.key));
525 });
526
527 constructor(readonly inputs: MenuBarInputs<V>) {
528 this.listBehavior = new List<MenuItemPattern<V>, V>(inputs);
529 }
530
531 /** Sets the default state for the menubar. */
532 setDefaultState() {
533 const firstFocusable = this.listBehavior.navigationBehavior.peekFirst();
534 if (firstFocusable) {
535 this.inputs.activeItem.set(firstFocusable);
536 }
537 }
538

Callers

nothing calls this directly

Calls 13

nextMethod · 0.95
prevMethod · 0.95
computedFunction · 0.90
signalFunction · 0.90
activeItemMethod · 0.80
openMethod · 0.65
tabIndexMethod · 0.45
isTypingMethod · 0.45
disabledMethod · 0.45
onMethod · 0.45
lastMethod · 0.45
firstMethod · 0.45

Tested by

no test coverage detected