@carbon/ibm-products-web-components
Version:
Carbon for IBM Products Web Components
139 lines • 5.87 kB
TypeScript
/**
* @license
*
* Copyright IBM Corp. 2025
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* Registers a focusable container to be included in the focus trap.
*
* This function allows child components to register their shadow roots or DOM elements
* so that the focus trap utility can query focusable elements within them. This is necessary
* because shadow DOM boundaries prevent direct querying from parent components.
*
* @param container - The HTMLElement or ShadowRoot to register as a focusable container.
* If null, the function returns early without registering.
* @param uniqueId - Optional unique identifier to scope containers to a specific component instance.
* If not provided, uses a default key for backward compatibility.
*
* @example
* // In a child component's firstUpdated lifecycle
* protected firstUpdated() {
* const uniqueId = tearsheetSignal.get().uniqueId;
* registerFocusableContainers(this.shadowRoot, uniqueId);
* }
*
* @example
* // Without uniqueId (uses default key)
* registerFocusableContainers(this.shadowRoot);
*/
export declare const registerFocusableContainers: (container: HTMLElement | ShadowRoot | null, uniqueId?: string) => void;
/**
* UnRegisters a previously registered focusable container.
*
* This function should be called in the component's disconnectedCallback lifecycle method
* to clean up and prevent memory leaks when the component is removed from the DOM.
*
* @param container - The HTMLElement or ShadowRoot to unregister.
* If null, the function returns early without doing anything.
* @param uniqueId - Optional unique identifier that was used when registering the container.
* If not provided, uses the default key.
*
* @example
* // In a child component's disconnectedCallback
* disconnectedCallback() {
* super.disconnectedCallback();
* const uniqueId = tearsheetSignal.get().uniqueId;
* unregisterFocusableContainers(this.shadowRoot, uniqueId);
* }
*
* @example
* // Without uniqueId (uses default key)
* disconnectedCallback() {
* super.disconnectedCallback();
* unregisterFocusableContainers(this.shadowRoot);
* }
*/
export declare const unregisterFocusableContainers: (container: HTMLElement | ShadowRoot | null, uniqueId?: string) => void;
/**
* Clears all registered focusable containers, either globally or for a specific uniqueId.
*
* This function is typically called when a parent component (like a tearsheet or modal) is closing
* or being removed from the DOM. It ensures all registered containers are cleaned up to prevent
* memory leaks.
*
* @param uniqueId - Optional unique identifier to clear containers for a specific component instance.
* If provided, only containers registered with this uniqueId are cleared.
* If not provided, ALL containers across all uniqueIds are cleared.
*
* @example
* // Clear containers for a specific tearsheet instance
* clearFocusableContainers(this.uniqueId);
*
* @example
* // Clear all containers (typically in disconnectedCallback)
* disconnectedCallback() {
* super.disconnectedCallback();
* this._trapFocusAPI?.cleanup();
* clearFocusableContainers();
* }
*/
export declare const clearFocusableContainers: (uniqueId?: string) => void;
/**
* Traps keyboard focus within registered focusable containers.
*
* This function creates a focus trap that prevents Tab/Shift+Tab navigation from leaving
* the registered containers. When the user reaches the last focusable element and presses Tab,
* focus wraps to the first element, and vice versa with Shift+Tab.
*
* The function works with Shadow DOM by querying focusable elements from all registered
* containers, which can include shadow roots from child components.
*
* @param wrapper - Optional wrapper element to attach the keydown listener to.
* If not provided, defaults to document for backward compatibility.
* @param uniqueId - Optional unique identifier to scope the focus trap to specific containers.
* If provided, only containers registered with this uniqueId are included.
* @param getFirstFocusable - Optional resolver called lazily on each keydown (and for initial
* focus) to determine the first element. Using a function rather than
* a value avoids a stale reference if header-action buttons are added
* or removed while the tearsheet is open.
* Falls back to the first element across registered containers.
*
* @returns An object with a `cleanup` method that removes event listeners.
*
* @example
* * // In a parent component when opening
* protected updated(changedProps) {
* if (changedProps.has('open') && this.open) {
* // Update signal so children can register
* updateTearsheetSignals({ uniqueId: this.uniqueId });
*
* // Wait for children to register, then trap focus
* requestAnimationFrame(() => {
* this._trapFocusAPI = trapFocus(this as HTMLElement, this.uniqueId);
* });
* }
* }
*
* @example
* // Without uniqueId (uses default key)
* this._trapFocusAPI = trapFocus();
*
* @example
* // Cleanup when closing
* disconnectedCallback() {
* this._trapFocusAPI?.cleanup();
* clearFocusableContainers(this.uniqueId);
* }
* this._trapFocusAPI = trapFocus(
* this as HTMLElement,
* this.uniqueId,
* () => this._getFirstFocusable()
* );
*/
export declare const trapFocus: (wrapper?: HTMLElement, uniqueId?: string, getFirstFocusable?: (() => HTMLElement | null) | null) => {
cleanup: () => void;
};
//# sourceMappingURL=manageFocusTrap.d.ts.map