Product Gallery block: Add logic to trap keyboard focus within the Product Gallery Pop-Up (#44439)
* Add logic to trap keyboard focus inside the Product Gallery Pop-Up * Add changefile(s) from automation for the following project(s): woocommerce-blocks, woocommerce * Remove unnecessary condition * Fix issue with keyboard focus trap not working within the Pop-Up --------- Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
parent
8eea9f77ff
commit
7ec1b7f3a1
|
@ -80,15 +80,15 @@ const productGallery = {
|
||||||
document.body.classList.add(
|
document.body.classList.add(
|
||||||
'wc-block-product-gallery-modal-open'
|
'wc-block-product-gallery-modal-open'
|
||||||
);
|
);
|
||||||
const dialogOverlay = document.querySelector(
|
const dialogPopUp = document.querySelector(
|
||||||
'.wc-block-product-gallery-dialog__overlay'
|
'dialog[aria-label="Product gallery"]'
|
||||||
);
|
);
|
||||||
if ( ! dialogOverlay ) {
|
if ( ! dialogPopUp ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
( dialogOverlay as HTMLElement ).focus();
|
( dialogPopUp as HTMLElement ).focus();
|
||||||
|
|
||||||
const dialogPreviousButton = dialogOverlay.querySelectorAll(
|
const dialogPreviousButton = dialogPopUp.querySelectorAll(
|
||||||
'.wc-block-product-gallery-large-image-next-previous--button'
|
'.wc-block-product-gallery-large-image-next-previous--button'
|
||||||
)[ 0 ];
|
)[ 0 ];
|
||||||
|
|
||||||
|
@ -249,6 +249,57 @@ const productGallery = {
|
||||||
return () =>
|
return () =>
|
||||||
document.removeEventListener( 'keydown', handleKeyEvents );
|
document.removeEventListener( 'keydown', handleKeyEvents );
|
||||||
},
|
},
|
||||||
|
dialogFocusTrap: () => {
|
||||||
|
const dialogPopUp = document.querySelector(
|
||||||
|
'dialog[aria-label="Product gallery"]'
|
||||||
|
) as HTMLElement | null;
|
||||||
|
|
||||||
|
if ( ! dialogPopUp ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleKeyEvents = ( event: KeyboardEvent ) => {
|
||||||
|
if ( event.code === 'Tab' ) {
|
||||||
|
const focusableElementsSelectors =
|
||||||
|
'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
||||||
|
|
||||||
|
const focusableElements = dialogPopUp.querySelectorAll(
|
||||||
|
focusableElementsSelectors
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( ! focusableElements.length ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstFocusableElement =
|
||||||
|
focusableElements[ 0 ] as HTMLElement;
|
||||||
|
const lastFocusableElement = focusableElements[
|
||||||
|
focusableElements.length - 1
|
||||||
|
] as HTMLElement;
|
||||||
|
|
||||||
|
if (
|
||||||
|
! event.shiftKey &&
|
||||||
|
event.target === lastFocusableElement
|
||||||
|
) {
|
||||||
|
event.preventDefault();
|
||||||
|
firstFocusableElement.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
event.shiftKey &&
|
||||||
|
event.target === firstFocusableElement
|
||||||
|
) {
|
||||||
|
event.preventDefault();
|
||||||
|
lastFocusableElement.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
dialogPopUp.addEventListener( 'keydown', handleKeyEvents );
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
dialogPopUp.removeEventListener( 'keydown', handleKeyEvents );
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: add
|
||||||
|
|
||||||
|
Add focus trapping within the Product Gallery Pop-Up to enhance keyboard navigation and accessibility.
|
|
@ -77,7 +77,7 @@ class ProductGallery extends AbstractBlock {
|
||||||
|
|
||||||
$gallery_dialog = strtr(
|
$gallery_dialog = strtr(
|
||||||
'
|
'
|
||||||
<dialog data-wc-bind--open="context.isDialogOpen" role="dialog" aria-modal="true" aria-label="{{dialog_aria_label}}" hidden data-wc-bind--hidden="!context.isDialogOpen" data-wc-watch="callbacks.keyboardAccess" data-wc-class--wc-block-product-gallery--dialog-open="context.isDialogOpen">
|
<dialog data-wc-bind--open="context.isDialogOpen" role="dialog" aria-modal="true" aria-label="{{dialog_aria_label}}" hidden data-wc-bind--hidden="!context.isDialogOpen" data-wc-watch="callbacks.keyboardAccess" data-wc-watch--dialog-focus-trap="callbacks.dialogFocusTrap" data-wc-class--wc-block-product-gallery--dialog-open="context.isDialogOpen">
|
||||||
<div class="wc-block-product-gallery-dialog__header">
|
<div class="wc-block-product-gallery-dialog__header">
|
||||||
<div class="wc-block-product-galler-dialog__header-right">
|
<div class="wc-block-product-galler-dialog__header-right">
|
||||||
<button class="wc-block-product-gallery-dialog__close" data-wc-on--click="actions.closeDialog" aria-label="{{close_dialog_aria_label}}">
|
<button class="wc-block-product-gallery-dialog__close" data-wc-on--click="actions.closeDialog" aria-label="{{close_dialog_aria_label}}">
|
||||||
|
|
Loading…
Reference in New Issue