Skip to content

Commit bac171d

Browse files
committed
fix(aria/toolbar): allow developers to wrap widgets (angular#32341)
(cherry picked from commit eb6ace5)
1 parent d0184ac commit bac171d

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

src/aria/toolbar/toolbar.spec.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Component, DebugElement, signal} from '@angular/core';
1+
import {Component, DebugElement, Directive, inject, signal} from '@angular/core';
22
import {ComponentFixture, TestBed} from '@angular/core/testing';
33
import {By} from '@angular/platform-browser';
44
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from './toolbar';
@@ -533,6 +533,23 @@ describe('Toolbar', () => {
533533
expect(document.activeElement).toBe(initialActiveElement);
534534
});
535535
});
536+
537+
describe('with wrapped toolbar widgets', () => {
538+
beforeEach(() => {
539+
TestBed.configureTestingModule({imports: [WrappedToolbarExample]});
540+
fixture = TestBed.createComponent(WrappedToolbarExample) as any;
541+
fixture.detectChanges();
542+
});
543+
544+
it('should navigate on click', () => {
545+
const widgets = fixture.debugElement
546+
.queryAll(By.css('[toolbar-button]'))
547+
.map((debugEl: DebugElement) => debugEl.nativeElement as HTMLElement);
548+
console.log('clicking:', widgets[0]);
549+
click(widgets[0]);
550+
expect(document.activeElement).toBe(widgets[0]);
551+
});
552+
});
536553
});
537554

538555
describe('Selection', () => {
@@ -638,3 +655,27 @@ class ToolbarExample {
638655

639656
groups = [{disabled: signal(false)}];
640657
}
658+
659+
@Directive({
660+
selector: 'button[toolbar-button]',
661+
hostDirectives: [{directive: ToolbarWidget, inputs: ['value', 'disabled']}],
662+
host: {
663+
type: 'button',
664+
class: 'example-button material-symbols-outlined',
665+
'[aria-label]': 'widget.value()',
666+
},
667+
})
668+
export class SimpleToolbarButton {
669+
widget = inject(ToolbarWidget);
670+
}
671+
672+
@Component({
673+
template: `
674+
<div ngToolbar>
675+
<button toolbar-button value="undo">undo</button>
676+
<button toolbar-button value="redo">redo</button>
677+
</div>
678+
`,
679+
imports: [Toolbar, SimpleToolbarButton],
680+
})
681+
class WrappedToolbarExample {}

src/aria/toolbar/toolbar.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,7 @@ export class Toolbar<V> {
159159

160160
/** Finds the toolbar item associated with a given element. */
161161
private _getItem(element: Element) {
162-
const widgetTarget = element.closest('[ngToolbarWidget]');
163-
return this._itemPatterns().find(widget => widget.element() === widgetTarget);
162+
return this._itemPatterns().find(item => item.element()?.contains(element));
164163
}
165164
}
166165

0 commit comments

Comments
 (0)