From f5005c010e5b532e780fa09dfe44a0ba2f090208 Mon Sep 17 00:00:00 2001 From: Melloware Date: Tue, 2 Jul 2024 07:24:07 -0400 Subject: [PATCH] Fix #6718: FocusTrap better handling of autoFocus property (#6721) --- components/lib/button/Button.js | 1 + components/lib/focustrap/FocusTrap.js | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/components/lib/button/Button.js b/components/lib/button/Button.js index 1f48f43f70..01aeae0e08 100644 --- a/components/lib/button/Button.js +++ b/components/lib/button/Button.js @@ -116,6 +116,7 @@ export const Button = React.memo( { ref: elementRef, 'aria-label': defaultAriaLabel, + 'data-pc-autofocus': props.autoFocus, className: classNames(props.className, cx('root', { size, disabled })), disabled: disabled }, diff --git a/components/lib/focustrap/FocusTrap.js b/components/lib/focustrap/FocusTrap.js index 2135d272f3..68eeebd00f 100644 --- a/components/lib/focustrap/FocusTrap.js +++ b/components/lib/focustrap/FocusTrap.js @@ -39,10 +39,20 @@ export const FocusTrap = React.memo( return firstFocusableElementRef.current && firstFocusableElementRef.current.parentElement; }; + /** + * This method sets the auto focus on the first focusable element within the target element. + * It first tries to find a focusable element using the autoFocusSelector. If no such element is found, + * it then tries to find a focusable element using the firstFocusableSelector. + * If the autoFocus prop is set to true and a focusable element is found, it sets the focus on that element. + * + * @param {HTMLElement} target - The target element within which to find a focusable element. + */ const setAutoFocus = (target) => { const { autoFocusSelector = '', firstFocusableSelector = '', autoFocus = false } = props || {}; + const defaultAutoFocusSelector = `${getComputedSelector(autoFocusSelector)}`; + const computedAutoFocusSelector = `[autofocus]${defaultAutoFocusSelector}, [data-pc-autofocus='true']${defaultAutoFocusSelector}`; - let focusableElement = DomHandler.getFirstFocusableElement(target, `[autofocus]${getComputedSelector(autoFocusSelector)}`); + let focusableElement = DomHandler.getFirstFocusableElement(target, computedAutoFocusSelector); autoFocus && !focusableElement && (focusableElement = DomHandler.getFirstFocusableElement(target, getComputedSelector(firstFocusableSelector)));