Skip to content

Commit 02d45cc

Browse files
authored
[docs] Add "reset focus" control to demo tools (#20724)
1 parent 21d01a5 commit 02d45cc

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

docs/src/modules/components/Demo.js

+35-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import MenuItem from '@material-ui/core/MenuItem';
1818
import MoreVertIcon from '@material-ui/icons/MoreVert';
1919
import Tooltip from '@material-ui/core/Tooltip';
2020
import RefreshIcon from '@material-ui/icons/Refresh';
21+
import ResetFocusIcon from '@material-ui/icons/CenterFocusWeak';
2122
import HighlightedCode from 'docs/src/modules/components/HighlightedCode';
2223
import DemoSandboxed from 'docs/src/modules/components/DemoSandboxed';
2324
import DemoLanguages from 'docs/src/modules/components/DemoLanguages';
@@ -61,6 +62,9 @@ const styles = (theme) => ({
6162
[theme.breakpoints.up('sm')]: {
6263
borderRadius: theme.shape.borderRadius,
6364
},
65+
'&:focus': {
66+
outline: `2px dashed ${theme.palette.text.primary}`,
67+
},
6468
},
6569
/* Isolate the demo with an outline. */
6670
demoBgOutlined: {
@@ -335,18 +339,33 @@ function Demo(props) {
335339
const demoSourceId = useUniqueId(`demo-`);
336340
const openDemoSource = codeOpen || showPreview;
337341

342+
const initialFocusRef = React.useRef(null);
343+
function handleResetFocusClick() {
344+
initialFocusRef.current.focus();
345+
}
346+
function handleDemoMouseDown(event) {
347+
// Otherwise clicking any non-focusable element in the demo focuses the demo container
348+
// which is surprising and not how the code would behave outside of this page
349+
event.preventDefault();
350+
}
351+
338352
return (
339353
<div className={classes.root}>
354+
{/* We're actually preventing interaction here */}
355+
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
340356
<div
357+
aria-label={t('initialFocusLabel')}
341358
className={clsx(classes.demo, {
342359
[classes.demoHiddenToolbar]: demoOptions.hideToolbar,
343360
[classes.demoBgOutlined]: demoOptions.bg === 'outlined',
344361
[classes.demoBgTrue]: demoOptions.bg === true,
345362
[classes.demoBgInline]: demoOptions.bg === 'inline',
346363
})}
347-
tabIndex={-1}
348364
onMouseEnter={handleDemoHover}
349365
onMouseLeave={handleDemoHover}
366+
onMouseDown={handleDemoMouseDown}
367+
ref={initialFocusRef}
368+
tabIndex={-1}
350369
>
351370
<DemoSandboxed
352371
key={demoKey}
@@ -426,6 +445,21 @@ function Demo(props) {
426445
<FileCopyIcon fontSize="small" />
427446
</IconButton>
428447
</Tooltip>
448+
<Tooltip
449+
classes={{ popper: classes.tooltip }}
450+
title={t('resetFocus')}
451+
placement="top"
452+
>
453+
<IconButton
454+
aria-label={t('resetFocus')}
455+
data-ga-event-category="demo"
456+
data-ga-event-label={demoOptions.demo}
457+
data-ga-event-action="reset-focus"
458+
onClick={handleResetFocusClick}
459+
>
460+
<ResetFocusIcon fontSize="small" />
461+
</IconButton>
462+
</Tooltip>
429463
<Tooltip classes={{ popper: classes.tooltip }} title={t('resetDemo')} placement="top">
430464
<IconButton
431465
aria-label={t('resetDemo')}

docs/translations/translations.json

+2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@
9494
"viewGitHub": "View the source on GitHub",
9595
"visit": "Visit the website",
9696
"whosUsing": "Who's using Material-UI?",
97+
"initialFocusLabel": "A generic container that is programmatically focused to test keyboard navigation of our components.",
98+
"resetFocus": "Reset focus to test keyboard navigation",
9799
"pages": {
98100
"/getting-started": "Getting Started",
99101
"/getting-started/installation": "Installation",

0 commit comments

Comments
 (0)