Skip to content

Commit 4e421b7

Browse files
jcfrancobenelan
authored andcommitted
fix(dialog, modal, sheet): preserve focus-trap extra containers across internal trap updates (#11548)
**Related Issue:** #11523 ## Summary Internal calls to `updateFocusTrap` caused user-provided `extraContainers` to be lost. This updates `useFocusTrap` to maintain stateful focusable containers for subsequent updates.
1 parent 46cf88b commit 4e421b7

File tree

4 files changed

+21
-11
lines changed

4 files changed

+21
-11
lines changed

packages/calcite-components/src/components/dialog/dialog.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@ export class Dialog extends LitElement implements OpenCloseComponent, LoadableCo
291291
async updateFocusTrapElements(
292292
extraContainers?: FocusTrapOptions["extraContainers"],
293293
): Promise<void> {
294-
this.focusTrap.updateContainerElements(extraContainers);
294+
this.focusTrap.setExtraContainers(extraContainers);
295+
this.focusTrap.updateContainerElements();
295296
}
296297

297298
/** When defined, provides a condition to disable focus trapping. When `true`, prevents focus trapping. */

packages/calcite-components/src/components/modal/modal.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@ export class Modal extends LitElement implements OpenCloseComponent, LoadableCom
253253
async updateFocusTrapElements(
254254
extraContainers?: FocusTrapOptions["extraContainers"],
255255
): Promise<void> {
256-
this.focusTrap.updateContainerElements(extraContainers);
256+
this.focusTrap.setExtraContainers(extraContainers);
257+
this.focusTrap.updateContainerElements();
257258
}
258259

259260
// #endregion

packages/calcite-components/src/components/sheet/sheet.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ export class Sheet extends LitElement implements OpenCloseComponent, LoadableCom
234234
async updateFocusTrapElements(
235235
extraContainers?: FocusTrapOptions["extraContainers"],
236236
): Promise<void> {
237-
this.focusTrap.updateContainerElements(extraContainers);
237+
this.focusTrap.setExtraContainers(extraContainers);
238+
this.focusTrap.updateContainerElements();
238239
}
239240

240241
// #endregion

packages/calcite-components/src/controllers/useFocusTrap.ts

+15-8
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,16 @@ export interface UseFocusTrap {
2424
overrideFocusTrapEl: (el: HTMLElement) => void;
2525

2626
/**
27-
* Updates focusable elements within the trap.
27+
* Sets the extra containers to be used in the focus trap.
2828
*
2929
* @see https://github.com/focus-trap/focus-trap#trapupdatecontainerelements
3030
*/
31-
updateContainerElements: (extraContainers?: FocusTrapOptions["extraContainers"]) => void;
31+
setExtraContainers: (extraContainers?: FocusTrapOptions["extraContainers"]) => void;
32+
33+
/**
34+
* Updates focusable elements within the trap.
35+
*/
36+
updateContainerElements: () => void;
3237
}
3338

3439
interface UseFocusTrapOptions<T extends LitElement = LitElement> {
@@ -100,6 +105,7 @@ export const useFocusTrap = <T extends FocusTrapComponent>(
100105
return makeGenericController<UseFocusTrap, T>((component, controller) => {
101106
let focusTrap: FocusTrap;
102107
let focusTrapEl: HTMLElement;
108+
let effectiveContainers: FocusTrapOptions["extraContainers"];
103109
const internalFocusTrapOptions = options.focusTrapOptions;
104110

105111
controller.onConnected(() => {
@@ -123,11 +129,9 @@ export const useFocusTrap = <T extends FocusTrapComponent>(
123129
...internalFocusTrapOptions,
124130
...component.focusTrapOptions,
125131
};
132+
effectiveContainers ||= getEffectiveContainerElements(targetEl, component);
126133

127-
focusTrap = createFocusTrap(
128-
getEffectiveContainerElements(targetEl, component),
129-
createFocusTrapOptions(targetEl, effectiveFocusTrapOptions),
130-
);
134+
focusTrap = createFocusTrap(effectiveContainers, createFocusTrapOptions(targetEl, effectiveFocusTrapOptions));
131135
}
132136

133137
if (
@@ -146,9 +150,12 @@ export const useFocusTrap = <T extends FocusTrapComponent>(
146150

147151
focusTrapEl = el;
148152
},
149-
updateContainerElements: (extraContainers?: FocusTrapOptions["extraContainers"]) => {
153+
setExtraContainers: (extraContainers?: FocusTrapOptions["extraContainers"]) => {
150154
const targetEl = focusTrapEl || component.el;
151-
return focusTrap?.updateContainerElements(getEffectiveContainerElements(targetEl, component, extraContainers));
155+
effectiveContainers = getEffectiveContainerElements(targetEl, component, extraContainers);
156+
},
157+
updateContainerElements: () => {
158+
return focusTrap?.updateContainerElements(effectiveContainers);
152159
},
153160
};
154161
});

0 commit comments

Comments
 (0)