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

Class MenuBarPattern

src/aria/private/menu/menu.ts:484–638  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

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

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