MCPcopy Index your code
hub / github.com/angular/components / MenuBarPattern

Class MenuBarPattern

src/aria/private/menu/menu.ts:480–634  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

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

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

Used in the wild real call sites across dependent graphs

searching dependent graphs…