| 57 | }, |
| 58 | }) |
| 59 | export class Toolbar implements OnDestroy { |
| 60 | /** A reference to the host element. */ |
| 61 | private readonly _elementRef = inject(ElementRef); |
| 62 | |
| 63 | /** A reference to the host element. */ |
| 64 | readonly element = this._elementRef.nativeElement as HTMLElement; |
| 65 | |
| 66 | /** The collection of widgets in the toolbar. */ |
| 67 | readonly _collection = new SortedCollection<ToolbarWidget>(); |
| 68 | |
| 69 | /** Text direction. */ |
| 70 | readonly textDirection = inject(Directionality).valueSignal; |
| 71 | |
| 72 | /** Sorted UIPatterns of the child widgets */ |
| 73 | readonly _itemPatterns = computed<ToolbarWidgetPattern[]>(() => |
| 74 | this._collection.orderedItems().map(widget => widget._pattern), |
| 75 | ); |
| 76 | |
| 77 | /** Whether the toolbar is vertically or horizontally oriented. */ |
| 78 | readonly orientation = input<'vertical' | 'horizontal'>('horizontal'); |
| 79 | |
| 80 | /** |
| 81 | * Whether to allow disabled items to receive focus. When `true`, disabled items are |
| 82 | * focusable but not interactive. When `false`, disabled items are skipped during navigation. |
| 83 | */ |
| 84 | readonly softDisabled = input(true, {transform: booleanAttribute}); |
| 85 | |
| 86 | /** Whether the toolbar is disabled. */ |
| 87 | readonly disabled = input(false, {transform: booleanAttribute}); |
| 88 | |
| 89 | /** Whether focus should wrap when navigating. */ |
| 90 | readonly wrap = input(true, {transform: booleanAttribute}); |
| 91 | |
| 92 | /** The toolbar UIPattern. */ |
| 93 | readonly _pattern: ToolbarPattern = new ToolbarPattern({ |
| 94 | ...this, |
| 95 | items: this._itemPatterns, |
| 96 | activeItem: signal(undefined), |
| 97 | textDirection: this.textDirection, |
| 98 | element: () => this._elementRef.nativeElement, |
| 99 | getItem: e => this._getItem(e), |
| 100 | }); |
| 101 | |
| 102 | constructor() { |
| 103 | afterRenderEffect({write: () => this._pattern.setDefaultStateEffect()}); |
| 104 | |
| 105 | afterNextRender(() => { |
| 106 | this._collection.startObserving(this.element); |
| 107 | }); |
| 108 | } |
| 109 | |
| 110 | ngOnDestroy() { |
| 111 | this._collection.stopObserving(); |
| 112 | } |
| 113 | |
| 114 | /** Finds the toolbar item associated with a given element. */ |
| 115 | private _getItem(element: Element) { |
| 116 | return this._itemPatterns().find(item => item.element()?.contains(element)); |