@@ -18,6 +18,7 @@ import MenuItem from '@material-ui/core/MenuItem';
18
18
import MoreVertIcon from '@material-ui/icons/MoreVert' ;
19
19
import Tooltip from '@material-ui/core/Tooltip' ;
20
20
import RefreshIcon from '@material-ui/icons/Refresh' ;
21
+ import ResetFocusIcon from '@material-ui/icons/CenterFocusWeak' ;
21
22
import HighlightedCode from 'docs/src/modules/components/HighlightedCode' ;
22
23
import DemoSandboxed from 'docs/src/modules/components/DemoSandboxed' ;
23
24
import DemoLanguages from 'docs/src/modules/components/DemoLanguages' ;
@@ -61,6 +62,9 @@ const styles = (theme) => ({
61
62
[ theme . breakpoints . up ( 'sm' ) ] : {
62
63
borderRadius : theme . shape . borderRadius ,
63
64
} ,
65
+ '&:focus' : {
66
+ outline : `2px dashed ${ theme . palette . text . primary } ` ,
67
+ } ,
64
68
} ,
65
69
/* Isolate the demo with an outline. */
66
70
demoBgOutlined : {
@@ -335,18 +339,33 @@ function Demo(props) {
335
339
const demoSourceId = useUniqueId ( `demo-` ) ;
336
340
const openDemoSource = codeOpen || showPreview ;
337
341
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
+
338
352
return (
339
353
< div className = { classes . root } >
354
+ { /* We're actually preventing interaction here */ }
355
+ { /* eslint-disable-next-line jsx-a11y/no-static-element-interactions */ }
340
356
< div
357
+ aria-label = { t ( 'initialFocusLabel' ) }
341
358
className = { clsx ( classes . demo , {
342
359
[ classes . demoHiddenToolbar ] : demoOptions . hideToolbar ,
343
360
[ classes . demoBgOutlined ] : demoOptions . bg === 'outlined' ,
344
361
[ classes . demoBgTrue ] : demoOptions . bg === true ,
345
362
[ classes . demoBgInline ] : demoOptions . bg === 'inline' ,
346
363
} ) }
347
- tabIndex = { - 1 }
348
364
onMouseEnter = { handleDemoHover }
349
365
onMouseLeave = { handleDemoHover }
366
+ onMouseDown = { handleDemoMouseDown }
367
+ ref = { initialFocusRef }
368
+ tabIndex = { - 1 }
350
369
>
351
370
< DemoSandboxed
352
371
key = { demoKey }
@@ -426,6 +445,21 @@ function Demo(props) {
426
445
< FileCopyIcon fontSize = "small" />
427
446
</ IconButton >
428
447
</ 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 >
429
463
< Tooltip classes = { { popper : classes . tooltip } } title = { t ( 'resetDemo' ) } placement = "top" >
430
464
< IconButton
431
465
aria-label = { t ( 'resetDemo' ) }
0 commit comments