Skip to content

Commit f83f0ab

Browse files
committed
fix(cdk-experimental/accordion): fix disabled trigger button can't be focused when skipDisabled=false
1 parent 25c31fd commit f83f0ab

File tree

2 files changed

+18
-24
lines changed

2 files changed

+18
-24
lines changed

src/cdk-experimental/accordion/accordion.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,12 @@ export class CdkAccordionPanel {
9393
'[attr.aria-expanded]': 'pattern.expanded()',
9494
'[attr.aria-controls]': 'pattern.controls()',
9595
'[attr.aria-disabled]': 'pattern.disabled()',
96+
'[attr.inert]': 'hardDisabled() ? true : null',
97+
'[attr.disabled]': 'hardDisabled() ? true : null',
9698
'[attr.tabindex]': 'pattern.tabindex()',
9799
'(keydown)': 'pattern.onKeydown($event)',
98100
'(pointerdown)': 'pattern.onPointerdown($event)',
99-
'(focusin)': 'pattern.onFocus($event)',
101+
'(focusin)': 'pattern.onFocus()',
100102
},
101103
})
102104
export class CdkAccordionTrigger {
@@ -115,6 +117,13 @@ export class CdkAccordionTrigger {
115117
/** Whether the trigger is disabled. */
116118
disabled = input(false, {transform: booleanAttribute});
117119

120+
/**
121+
* Whether this trigger is completely inaccessible.
122+
*
123+
* TODO(ok7sai): Consider move this to UI patterns.
124+
*/
125+
readonly hardDisabled = computed(() => this.pattern.disabled() && this.pattern.tabindex() < 0);
126+
118127
/** The accordion panel pattern controlled by this trigger. This is set by CdkAccordionGroup. */
119128
readonly accordionPanel: WritableSignal<AccordionPanelPattern | undefined> = signal(undefined);
120129

src/cdk-experimental/ui-patterns/accordion/accordion.ts

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -158,44 +158,29 @@ export class AccordionTriggerPattern {
158158
/** The pointerdown event manager for the accordion trigger. */
159159
pointerdown = computed(() => {
160160
return new PointerEventManager().on(e => {
161-
const item = this._getItem(e);
162-
163-
if (item) {
164-
this.accordionGroup().navigation.goto(item);
165-
this.expansionControl.toggle();
166-
}
161+
this.accordionGroup().navigation.goto(this);
162+
this.expansionControl.toggle();
167163
});
168164
});
169165

170166
/** Handles keydown events on the trigger, delegating to the group if not disabled. */
171-
onKeydown(event: KeyboardEvent): void {
167+
onKeydown(event: KeyboardEvent) {
172168
this.keydown().handle(event);
173169
}
174170

175171
/** Handles pointerdown events on the trigger, delegating to the group if not disabled. */
176-
onPointerdown(event: PointerEvent): void {
172+
onPointerdown(event: PointerEvent) {
177173
this.pointerdown().handle(event);
178174
}
179175

180176
/** Handles focus events on the trigger. This ensures the tabbing changes the active index. */
181-
onFocus(event: FocusEvent): void {
182-
const item = this._getItem(event);
177+
onFocus() {
178+
if (this.disabled() && this.accordionGroup().skipDisabled()) return;
183179

184-
if (item && this.inputs.accordionGroup().focusManager.isFocusable(item)) {
185-
this.accordionGroup().focusManager.focus(item);
180+
if (this.inputs.accordionGroup().focusManager.isFocusable(this)) {
181+
this.accordionGroup().focusManager.focus(this);
186182
}
187183
}
188-
189-
private _getItem(e: Event) {
190-
if (!(e.target instanceof HTMLElement)) {
191-
return;
192-
}
193-
194-
const element = e.target.closest('[role="button"]');
195-
return this.accordionGroup()
196-
.items()
197-
.find(i => i.element() === element);
198-
}
199184
}
200185

201186
/** Represents the required inputs for the AccordionPanelPattern. */

0 commit comments

Comments
 (0)