Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions src/aria/accordion/accordion.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,57 @@ describe('AccordionGroup', () => {
});
});

describe('with interactive content inside a panel', () => {
let link: HTMLElement;
let button: HTMLElement;
let input: HTMLElement;

const dispatchKeydown = async (key: string, target: HTMLElement) => {
const event = new KeyboardEvent('keydown', {bubbles: true, cancelable: true, key});
target.dispatchEvent(event);
await fixture.whenStable();
return event;
};

beforeEach(async () => {
fixture = TestBed.createComponent(AccordionWithInteractiveContent);
testComponent = fixture.componentInstance;
groupElement = fixture.nativeElement.querySelector('[ngAccordionGroup]') as HTMLElement;
testComponent.expandItem('item-1');
await setupTriggerAndPanels();

link = panelElements[0].querySelector('a')!;
button = panelElements[0].querySelector('button')!;
input = panelElements[0].querySelector('input')!;
triggerElements[1].focus();
await fixture.whenStable();
expect(isTriggerExpanded(0)).toBeTrue();
});

it('should not toggle the panel or prevent default on Enter from a link', async () => {
const event = await dispatchKeydown('Enter', link);

expect(event.defaultPrevented).toBeFalse();
expect(isTriggerExpanded(0)).toBeTrue();
});

it('should not toggle the panel or prevent default on Space from a button', async () => {
const event = await dispatchKeydown(' ', button);

expect(event.defaultPrevented).toBeFalse();
expect(isTriggerExpanded(0)).toBeTrue();
});

it('should not move focus or prevent default on Home and End from an input', async () => {
const homeEvent = await dispatchKeydown('Home', input);
const endEvent = await dispatchKeydown('End', input);

expect(homeEvent.defaultPrevented).toBeFalse();
expect(endEvent.defaultPrevented).toBeFalse();
expect(isTriggerActive(1)).toBeTrue();
});
});

describe('structural validations', () => {
let consoleSpy: jasmine.Spy;

Expand Down Expand Up @@ -696,6 +747,30 @@ class AccordionGroupWithIfs extends AccordionGroupWithLoop {
includeThird = signal(true);
}

@Component({
template: `
<div ngAccordionGroup>
@for (item of items(); track item.panelId) {
<div>
<button ngAccordionTrigger [panel]="panel" [(expanded)]="item.expanded">
{{ item.header }}
</button>
<div ngAccordionPanel #panel="ngAccordionPanel">
<ng-template ngAccordionContent>
<a href="javascript:void(0)">Link inside panel</a>
<button type="button">Button inside panel</button>
<input aria-label="Input inside panel" />
</ng-template>
</div>
</div>
}
</div>
`,
imports: [AccordionGroup, AccordionTrigger, AccordionPanel, AccordionContent],
changeDetection: ChangeDetectionStrategy.Eager,
})
class AccordionWithInteractiveContent extends AccordionGroupWithLoop {}

@Component({
template: `
<div ngAccordionGroup>
Expand Down
3 changes: 3 additions & 0 deletions src/aria/private/accordion/accordion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ export class AccordionGroupPattern {

/** Handles keydown events on the trigger, delegating to the group if not disabled. */
onKeydown(event: KeyboardEvent): void {
const target = _getEventTarget<Element>(event);
if (target !== this.inputs.element() && !this._findTriggerPattern(target)) return;

this.keydown().handle(event);
}

Expand Down
Loading