Skip to content

Commit

Permalink
Playground block: a11y: Avoid lost focus due to activation (#338)
Browse files Browse the repository at this point in the history
## What, why, and how?

Before this PR, clicking the Activate Live Preview button loses the
focus because the button disappears as soon as it is clicked. This is
not good for accessibility. This PR updates the block to move focus to a
meaningful location, the "Beginning of Playground Preview" marker, when
the Activation button is clicked.

Related to #290

## Testing Instructions

Because the Beginning of Playground Preview marker is not actually shown
when focused, I tested via the following dance:

- Open a post with a Playground block that requires activation
- Open the dev tools console
- Run the following in the console: `setTimeout(() =>
console.log(document.querySelector(':focus')), 2000)`
- Click the Activate Live Preview button before the timeout
- Observe that the before-preview marker is logged as having the focus
  • Loading branch information
brandonpayton authored Jul 25, 2024
1 parent 12c15c7 commit 80e8797
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export default function PlaygroundPreview({
});

const iframeRef = useRef<HTMLIFrameElement>(null);
const beforePreviewRef = useRef<HTMLElement>(null);
const afterPreviewRef = useRef<HTMLSpanElement>(null);
const playgroundClientRef = useRef<PlaygroundClient | null>(null);
const fileMgrRef = useRef<FileManagerRef>(null);
Expand Down Expand Up @@ -621,7 +622,11 @@ export default function PlaygroundPreview({
<div className="playground-container">
{!inFullPageView && (
<>
<span className="screen-reader-text">
<span
className="screen-reader-text wordpress-playground-before-preview"
tabIndex={-1}
ref={beforePreviewRef}
>
{
// translators: screen reader text noting beginning of the playground iframe
__('Beginning of Playground Preview')
Expand Down Expand Up @@ -649,7 +654,16 @@ export default function PlaygroundPreview({
<Button
className="wordpress-playground-activate-button"
variant="primary"
onClick={() => setLivePreviewActivated(true)}
onClick={() => {
setLivePreviewActivated(true);
if (beforePreviewRef.current) {
// For a11y, move focus to meaningful
// "before preview" element before
// focus is simply lost as this button
// disappears.
beforePreviewRef.current.focus();
}
}}
aria-description={
iframeCreationWarningForActivation
}
Expand Down
15 changes: 15 additions & 0 deletions packages/wordpress-playground-block/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,21 @@
max-width: 100%;
border: 0;
position: relative;

.wordpress-playground-before-preview:focus {
// The before-preview element exists as a marker for
// a11y purposes. It is a meaningful place to move the
// focus before focus is lost as the clicked Activation
// button disappears. But we do not want the element to
// be shown when focused.
z-index: -1;
}
.playground-iframe {
// Set a non-transparent iframe color so the before-preview
// element behind the iframe is not rendered when the
// default iframe background is transparent.
background-color: white;
}
}
}

Expand Down

0 comments on commit 80e8797

Please sign in to comment.