From 2d6c06aca629c8e4b52d12d4c8a911ce31478851 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Tue, 4 Aug 2020 00:05:59 +0200 Subject: [PATCH] [TrapFocus] Add documentation --- docs/pages/api-docs/unstable-trap-focus.md | 4 ++ docs/pages/components/trap-focus.js | 20 ++++++++ docs/src/pages.js | 1 + .../components/trap-focus/BasicTrapFocus.js | 26 ++++++++++ .../components/trap-focus/BasicTrapFocus.tsx | 26 ++++++++++ .../trap-focus/DisableEnforceFocus.js | 31 ++++++++++++ .../trap-focus/DisableEnforceFocus.tsx | 31 ++++++++++++ .../trap-focus/DisableRestoreFocus.js | 31 ++++++++++++ .../trap-focus/DisableRestoreFocus.tsx | 31 ++++++++++++ .../components/trap-focus/LazyTrapFocus.js | 31 ++++++++++++ .../components/trap-focus/LazyTrapFocus.tsx | 31 ++++++++++++ .../components/trap-focus/PortalTrapFocus.js | 33 ++++++++++++ .../components/trap-focus/PortalTrapFocus.tsx | 32 ++++++++++++ .../pages/components/trap-focus/trap-focus.md | 50 +++++++++++++++++++ .../Unstable_TrapFocus.d.ts | 4 ++ 15 files changed, 382 insertions(+) create mode 100644 docs/pages/components/trap-focus.js create mode 100644 docs/src/pages/components/trap-focus/BasicTrapFocus.js create mode 100644 docs/src/pages/components/trap-focus/BasicTrapFocus.tsx create mode 100644 docs/src/pages/components/trap-focus/DisableEnforceFocus.js create mode 100644 docs/src/pages/components/trap-focus/DisableEnforceFocus.tsx create mode 100644 docs/src/pages/components/trap-focus/DisableRestoreFocus.js create mode 100644 docs/src/pages/components/trap-focus/DisableRestoreFocus.tsx create mode 100644 docs/src/pages/components/trap-focus/LazyTrapFocus.js create mode 100644 docs/src/pages/components/trap-focus/LazyTrapFocus.tsx create mode 100644 docs/src/pages/components/trap-focus/PortalTrapFocus.js create mode 100644 docs/src/pages/components/trap-focus/PortalTrapFocus.tsx create mode 100644 docs/src/pages/components/trap-focus/trap-focus.md diff --git a/docs/pages/api-docs/unstable-trap-focus.md b/docs/pages/api-docs/unstable-trap-focus.md index 095e8bd63429b3..d1622bd14f40e3 100644 --- a/docs/pages/api-docs/unstable-trap-focus.md +++ b/docs/pages/api-docs/unstable-trap-focus.md @@ -37,3 +37,7 @@ Utility component that locks focus inside the component. The component cannot hold a ref. +## Demos + +- [Trap Focus](/components/trap-focus/) + diff --git a/docs/pages/components/trap-focus.js b/docs/pages/components/trap-focus.js new file mode 100644 index 00000000000000..f26ed07bbadda2 --- /dev/null +++ b/docs/pages/components/trap-focus.js @@ -0,0 +1,20 @@ +import React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import { prepareMarkdown } from 'docs/src/modules/utils/parseMarkdown'; + +const pageFilename = 'components/trap-focus'; +const requireDemo = require.context('docs/src/pages/components/trap-focus', false, /\.(js|tsx)$/); +const requireRaw = require.context( + '!raw-loader!../../src/pages/components/trap-focus', + false, + /\.(js|md|tsx)$/, +); + +export default function Page({ demos, docs }) { + return ; +} + +Page.getInitialProps = () => { + const { demos, docs } = prepareMarkdown({ pageFilename, requireRaw }); + return { demos, docs }; +}; diff --git a/docs/src/pages.js b/docs/src/pages.js index aa9f3c94278f81..bdf0d1533c6060 100644 --- a/docs/src/pages.js +++ b/docs/src/pages.js @@ -124,6 +124,7 @@ const pages = [ { pathname: '/components/speed-dial' }, { pathname: '/components/timeline' }, { pathname: '/components/toggle-button' }, + { pathname: '/components/trap-focus' }, { pathname: '/components/tree-view' }, ], }, diff --git a/docs/src/pages/components/trap-focus/BasicTrapFocus.js b/docs/src/pages/components/trap-focus/BasicTrapFocus.js new file mode 100644 index 00000000000000..127d8d326f3cc0 --- /dev/null +++ b/docs/src/pages/components/trap-focus/BasicTrapFocus.js @@ -0,0 +1,26 @@ +import * as React from 'react'; +import TrapFocus from '@material-ui/core/Unstable_TrapFocus'; + +export default function BasicTrapFocus() { + const [open, setOpen] = React.useState(false); + return ( +
+ +
+ {open && ( + true} getDoc={() => document}> +
+

Quick form

+ + + +
+
+ )} +
+ ); +} diff --git a/docs/src/pages/components/trap-focus/BasicTrapFocus.tsx b/docs/src/pages/components/trap-focus/BasicTrapFocus.tsx new file mode 100644 index 00000000000000..127d8d326f3cc0 --- /dev/null +++ b/docs/src/pages/components/trap-focus/BasicTrapFocus.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import TrapFocus from '@material-ui/core/Unstable_TrapFocus'; + +export default function BasicTrapFocus() { + const [open, setOpen] = React.useState(false); + return ( +
+ +
+ {open && ( + true} getDoc={() => document}> +
+

Quick form

+ + + +
+
+ )} +
+ ); +} diff --git a/docs/src/pages/components/trap-focus/DisableEnforceFocus.js b/docs/src/pages/components/trap-focus/DisableEnforceFocus.js new file mode 100644 index 00000000000000..8c94a48a8a318d --- /dev/null +++ b/docs/src/pages/components/trap-focus/DisableEnforceFocus.js @@ -0,0 +1,31 @@ +import * as React from 'react'; +import TrapFocus from '@material-ui/core/Unstable_TrapFocus'; + +export default function DisableEnforceFocus() { + const [open, setOpen] = React.useState(false); + return ( +
+ +
+ {open && ( + true} + getDoc={() => document} + > +
+

Quick form

+ + + +
+
+ )} +
+ ); +} diff --git a/docs/src/pages/components/trap-focus/DisableEnforceFocus.tsx b/docs/src/pages/components/trap-focus/DisableEnforceFocus.tsx new file mode 100644 index 00000000000000..8c94a48a8a318d --- /dev/null +++ b/docs/src/pages/components/trap-focus/DisableEnforceFocus.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import TrapFocus from '@material-ui/core/Unstable_TrapFocus'; + +export default function DisableEnforceFocus() { + const [open, setOpen] = React.useState(false); + return ( +
+ +
+ {open && ( + true} + getDoc={() => document} + > +
+

Quick form

+ + + +
+
+ )} +
+ ); +} diff --git a/docs/src/pages/components/trap-focus/DisableRestoreFocus.js b/docs/src/pages/components/trap-focus/DisableRestoreFocus.js new file mode 100644 index 00000000000000..ab5806f314f07d --- /dev/null +++ b/docs/src/pages/components/trap-focus/DisableRestoreFocus.js @@ -0,0 +1,31 @@ +import * as React from 'react'; +import TrapFocus from '@material-ui/core/Unstable_TrapFocus'; + +export default function DisableRestoreFocus() { + const [open, setOpen] = React.useState(false); + return ( +
+ +
+ {open && ( + true} + getDoc={() => document} + > +
+

Quick form

+ + + +
+
+ )} +
+ ); +} diff --git a/docs/src/pages/components/trap-focus/DisableRestoreFocus.tsx b/docs/src/pages/components/trap-focus/DisableRestoreFocus.tsx new file mode 100644 index 00000000000000..ab5806f314f07d --- /dev/null +++ b/docs/src/pages/components/trap-focus/DisableRestoreFocus.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import TrapFocus from '@material-ui/core/Unstable_TrapFocus'; + +export default function DisableRestoreFocus() { + const [open, setOpen] = React.useState(false); + return ( +
+ +
+ {open && ( + true} + getDoc={() => document} + > +
+

Quick form

+ + + +
+
+ )} +
+ ); +} diff --git a/docs/src/pages/components/trap-focus/LazyTrapFocus.js b/docs/src/pages/components/trap-focus/LazyTrapFocus.js new file mode 100644 index 00000000000000..44be0a2418cb37 --- /dev/null +++ b/docs/src/pages/components/trap-focus/LazyTrapFocus.js @@ -0,0 +1,31 @@ +import * as React from 'react'; +import TrapFocus from '@material-ui/core/Unstable_TrapFocus'; + +export default function LazyTrapFocus() { + const [open, setOpen] = React.useState(false); + return ( +
+ +
+ {open && ( + true} + getDoc={() => document} + disableAutoFocus + > +
+

Quick form

+ + + +
+
+ )} +
+ ); +} diff --git a/docs/src/pages/components/trap-focus/LazyTrapFocus.tsx b/docs/src/pages/components/trap-focus/LazyTrapFocus.tsx new file mode 100644 index 00000000000000..44be0a2418cb37 --- /dev/null +++ b/docs/src/pages/components/trap-focus/LazyTrapFocus.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import TrapFocus from '@material-ui/core/Unstable_TrapFocus'; + +export default function LazyTrapFocus() { + const [open, setOpen] = React.useState(false); + return ( +
+ +
+ {open && ( + true} + getDoc={() => document} + disableAutoFocus + > +
+

Quick form

+ + + +
+
+ )} +
+ ); +} diff --git a/docs/src/pages/components/trap-focus/PortalTrapFocus.js b/docs/src/pages/components/trap-focus/PortalTrapFocus.js new file mode 100644 index 00000000000000..910d39b1c61ad7 --- /dev/null +++ b/docs/src/pages/components/trap-focus/PortalTrapFocus.js @@ -0,0 +1,33 @@ +import React from 'react'; +import Portal from '@material-ui/core/Portal'; +import TrapFocus from '@material-ui/core/Unstable_TrapFocus'; + +export default function PortalTrapFocus() { + const [open, setOpen] = React.useState(false); + const [container, setContainer] = React.useState(null); + + return ( +
+ +
+ {open && ( + true} getDoc={() => document}> +
+

Quick form

+ + + + + +
+
+ )} + +
+
+ ); +} diff --git a/docs/src/pages/components/trap-focus/PortalTrapFocus.tsx b/docs/src/pages/components/trap-focus/PortalTrapFocus.tsx new file mode 100644 index 00000000000000..7394e5e6556295 --- /dev/null +++ b/docs/src/pages/components/trap-focus/PortalTrapFocus.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import Portal from '@material-ui/core/Portal'; +import TrapFocus from '@material-ui/core/Unstable_TrapFocus'; + +export default function PortalTrapFocus() { + const [open, setOpen] = React.useState(false); + const [container, setContainer] = React.useState(null); + + return ( +
+ +
+ {open && ( + true} getDoc={() => document}> +
+

Quick form

+ + + + + +
+
+ )} +
+
+ ); +} diff --git a/docs/src/pages/components/trap-focus/trap-focus.md b/docs/src/pages/components/trap-focus/trap-focus.md new file mode 100644 index 00000000000000..da78eb083a92c6 --- /dev/null +++ b/docs/src/pages/components/trap-focus/trap-focus.md @@ -0,0 +1,50 @@ +--- +title: Trap Focus React component +components: Unstable_TrapFocus +--- + +# Trap Focus + +

Trap focus within a DOM node.

+ +`TrapFocus` is a utility component that manage focus for its descendants. +This is useful when implementing overlays like modal dialogs, which should not allow focus to escape them while open. + +When `open={true}` the trap enables, pressing Tab or Shift+Tab will circle focus within the inner focusable elements of the component. + +- 📦 [1.5 kB gzipped](https://material-ui.com/size-snapshot). +- ⚛️ Support portals + +## Example + +{{"demo": "pages/components/trap-focus/BasicTrapFocus.js"}} + +## Disable enforce focus + +Clicks within the focus trap behave normally; but clicks outside the focus trap are blocked. + +You can disable the behavior with the `disableEnforceFocus` prop. + +{{"demo": "pages/components/trap-focus/DisableEnforceFocus.js"}} + +## Disable restore focus + +The component restores the focus back to the previously focused element when it deactivates, for example, back to a button which opened a dialog. + +You can disable this behavior with the `disableRestoreFocus` prop. + +{{"demo": "pages/components/trap-focus/DisableRestoreFocus.js"}} + +## Lazy activation + +By default, the component moves the focus to its descendants as soon as it opens, `open={true}`. + +You can disale this behavior, and make it lazy, with the `disableAutoFocus` prop. + +{{"demo": "pages/components/trap-focus/LazyTrapFocus.js"}} + +## Portal + +The following demo uses [`Portal`](/components/portal/) to render a part of the trap focus into a new "subtree" outside of current DOM hierarchy. + +{{"demo": "pages/components/trap-focus/PortalTrapFocus.js"}} diff --git a/packages/material-ui/src/Unstable_TrapFocus/Unstable_TrapFocus.d.ts b/packages/material-ui/src/Unstable_TrapFocus/Unstable_TrapFocus.d.ts index 4b5c65287cafa6..be232c4777cf90 100644 --- a/packages/material-ui/src/Unstable_TrapFocus/Unstable_TrapFocus.d.ts +++ b/packages/material-ui/src/Unstable_TrapFocus/Unstable_TrapFocus.d.ts @@ -45,6 +45,10 @@ export interface TrapFocusProps { /** * Utility component that locks focus inside the component. + * Demos: + * + * - [Trap Focus](https://material-ui.com/components/trap-focus/) + * * API: * * - [Unstable_TrapFocus API](https://material-ui.com/api/unstable-trap-focus/)