Skip to content

Commit

Permalink
Optimise firstElement to be biased towards first content element
Browse files Browse the repository at this point in the history
  • Loading branch information
getdave committed Sep 12, 2023
1 parent e83fa17 commit 23234d6
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 5 deletions.
2 changes: 1 addition & 1 deletion packages/components/src/modal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ Titles are required for accessibility reasons, see `aria.labelledby` and `title`
If this property is true, it will focus the first tabbable element rendered anywhere within the modal.

If the value `firstElement` is used then the component will attempt to place focus
within the Modal's **contents**, initially skipping focusable nodes within the Modal's header. This is useful
within the Modal's **contents**, ignoring focusable nodes within the Modal's header. This is useful
for Modal's which contain immediately focusable elements such as form fields.

- Required: No
Expand Down
8 changes: 4 additions & 4 deletions packages/components/src/modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ import type { ModalProps } from './types';
// Used to count the number of open modals.
let openModalCount = 0;

const MODAL_HEADER_CLASSNAME = 'components-modal__header';

/**
* When `firstElement` is passed to `focusOnMount`, this function is optimised to
* avoid focusing on the `Close` button (or other "header" elements of the Modal
Expand All @@ -57,7 +55,7 @@ const MODAL_HEADER_CLASSNAME = 'components-modal__header';
function getFirstTabbableElement( tabbables: HTMLElement[] ) {
// Attempt to locate tabbable outside of the header portion of the Modal.
const firstContentTabbable = tabbables.find( ( tabbable ) => {
return tabbable.closest( `.${ MODAL_HEADER_CLASSNAME }` ) === null;
return tabbable.closest( '.components-modal__header' ) === null;
} );

if ( firstContentTabbable ) {
Expand Down Expand Up @@ -106,6 +104,8 @@ function UnforwardedModal(
? `components-modal-header-${ instanceId }`
: aria.labelledby;

// Modals should ignore the `Close` button which is the first focusable element.
// Remap `true` to select the next focusable element instead.
const focusOnMountRef = useFocusOnMount(
focusOnMount === 'firstElement' ? getFirstTabbableElement : focusOnMount
);
Expand Down Expand Up @@ -286,7 +286,7 @@ function UnforwardedModal(
tabIndex={ hasScrollableContent ? 0 : undefined }
>
{ ! __experimentalHideHeader && (
<div className={ MODAL_HEADER_CLASSNAME }>
<div className="components-modal__header">
<div className="components-modal__header-heading-container">
{ icon && (
<span
Expand Down

0 comments on commit 23234d6

Please sign in to comment.