From 13380830101363a7df2d64ef81eae0028fbfc66f Mon Sep 17 00:00:00 2001 From: Jason Gore Date: Mon, 22 Apr 2019 15:23:26 -0700 Subject: [PATCH 1/8] FocusTrapZone: Add new disabled prop and use in FocusTrapCallout. --- .../etc/office-ui-fabric-react.api.md | 1 + .../components/Callout/FocusTrapCallout.tsx | 4 +- .../FocusTrapZone/FocusTrapZone.doc.tsx | 10 - .../FocusTrapZone/FocusTrapZone.tsx | 23 +- .../FocusTrapZone/FocusTrapZone.types.ts | 5 + .../FocusTrapZone.Box.Click.Example.tsx | 60 +- .../examples/FocusTrapZone.Box.Example.tsx | 67 +- ...pZone.Box.FocusOnCustomElement.Example.tsx | 62 +- .../FocusTrapZone.FocusZone.Example.tsx | 66 +- .../examples/FocusTrapZone.Nested.Example.tsx | 50 +- .../FocusTrapZone.NoTabbable.Example.tsx | 66 - .../FocusTrapZone.Box.Click.Example.tsx.shot | 30 +- .../FocusTrapZone.Box.Example.tsx.shot | 720 +++-- ....Box.FocusOnCustomElement.Example.tsx.shot | 30 +- .../FocusTrapZone.FocusZone.Example.tsx.shot | 30 +- .../FocusTrapZone.Nested.Example.tsx.shot | 2314 +++++++++-------- 16 files changed, 1906 insertions(+), 1632 deletions(-) delete mode 100644 packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.NoTabbable.Example.tsx diff --git a/packages/office-ui-fabric-react/etc/office-ui-fabric-react.api.md b/packages/office-ui-fabric-react/etc/office-ui-fabric-react.api.md index 1db9733ee3dc71..ce3e93cc7afea9 100644 --- a/packages/office-ui-fabric-react/etc/office-ui-fabric-react.api.md +++ b/packages/office-ui-fabric-react/etc/office-ui-fabric-react.api.md @@ -4225,6 +4225,7 @@ export interface IFocusTrapZone { export interface IFocusTrapZoneProps extends React.HTMLAttributes { ariaLabelledBy?: string; componentRef?: IRefObject; + disabled?: boolean; disableFirstFocus?: boolean; elementToFocusOnDismiss?: HTMLElement; firstFocusableSelector?: string | (() => string); diff --git a/packages/office-ui-fabric-react/src/components/Callout/FocusTrapCallout.tsx b/packages/office-ui-fabric-react/src/components/Callout/FocusTrapCallout.tsx index 99c507688d3980..c06d7aa017c25a 100644 --- a/packages/office-ui-fabric-react/src/components/Callout/FocusTrapCallout.tsx +++ b/packages/office-ui-fabric-react/src/components/Callout/FocusTrapCallout.tsx @@ -11,7 +11,9 @@ import { FocusTrapZone } from '../../FocusTrapZone'; export const FocusTrapCallout: React.StatelessComponent = (props: IFocusTrapCalloutProps): JSX.Element => { return ( - {props.children} + + {props.children} + ); }; diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.doc.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.doc.tsx index f38ec14542b0df..2b9f37363c1de6 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.doc.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.doc.tsx @@ -18,10 +18,6 @@ import { FocusTrapZoneNestedExample } from './examples/FocusTrapZone.Nested.Exam const FocusTrapZoneNestedExampleCode = require('!raw-loader!office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx') as string; const FocusTrapZoneNestedExampleCodepen = require('!@uifabric/codepen-loader!office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx') as string; -import { FocusTrapZoneNoTabbableExample } from './examples/FocusTrapZone.NoTabbable.Example'; -const FocusTrapZoneNoTabbableExampleCode = require('!raw-loader!office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.NoTabbable.Example.tsx') as string; -const FocusTrapZoneNoTabbableExampleCodepen = require('!@uifabric/codepen-loader!office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.NoTabbable.Example.tsx') as string; - import { FocusTrapZoneFocusZoneExample } from './examples/FocusTrapZone.FocusZone.Example'; const FocusTrapZoneFocusZoneExampleCode = require('!raw-loader!office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.FocusZone.Example.tsx') as string; const FocusTrapZoneFocusZoneExampleCodepen = require('!@uifabric/codepen-loader!office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.FocusZone.Example.tsx') as string; @@ -66,12 +62,6 @@ export const FocusTrapZonePageProps: IDocPageProps = { codepenJS: FocusTrapZoneFocusZoneExampleCodepen, view: }, - { - title: 'FocusTrapZone with no tabbable elements', - code: FocusTrapZoneNoTabbableExampleCode, - codepenJS: FocusTrapZoneNoTabbableExampleCodepen, - view: - }, { title: 'A Dialog nested in a Panel', code: FocusTrapZoneDialogInPanelExampleCode, diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.tsx index d2faefa5c7a886..68991dedd595a7 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.tsx @@ -47,18 +47,22 @@ export class FocusTrapZone extends React.Component impl public componentDidUpdate(prevProps: IFocusTrapZoneProps) { const prevForceFocusInsideTrap = prevProps.forceFocusInsideTrap !== undefined ? prevProps.forceFocusInsideTrap : true; const newForceFocusInsideTrap = this.props.forceFocusInsideTrap !== undefined ? this.props.forceFocusInsideTrap : true; + const prevDisabled = prevProps.disabled !== undefined ? prevProps.disabled : false; + const newDisabled = this.props.disabled !== undefined ? this.props.disabled : false; - if (!prevForceFocusInsideTrap && newForceFocusInsideTrap) { + if ((!prevForceFocusInsideTrap && newForceFocusInsideTrap) || (prevDisabled && !newDisabled)) { // Transition from forceFocusInsideTrap disabled to enabled. Emulate what happens when a FocusTrapZone gets mounted this._bringFocusIntoZone(); - } else if (prevForceFocusInsideTrap && !newForceFocusInsideTrap) { + } else if ((prevForceFocusInsideTrap && !newForceFocusInsideTrap) || (!prevDisabled && newDisabled)) { // Transition from forceFocusInsideTrap enabled to disabled. Emulate what happens when a FocusTrapZone gets unmounted this._returnFocusToInitiator(); } } public componentWillUnmount(): void { - this._returnFocusToInitiator(); + if (!this.props.disabled) { + this._returnFocusToInitiator(); + } } public render(): JSX.Element { @@ -168,7 +172,12 @@ export class FocusTrapZone extends React.Component impl }; private _onBumperFocus = (isFirstBumper: boolean) => { + if (this.props.disabled) { + return; + } + const currentBumper = (isFirstBumper === this._hasFocus ? this._lastBumper.current : this._firstBumper.current) as HTMLElement; + if (this._root.current) { const nextFocusable = isFirstBumper === this._hasFocus @@ -252,6 +261,10 @@ export class FocusTrapZone extends React.Component impl } private _forceFocusInTrap = (ev: FocusEvent): void => { + if (this.props.disabled) { + return; + } + if (FocusTrapZone._focusStack.length && this === FocusTrapZone._focusStack[FocusTrapZone._focusStack.length - 1]) { const focusedElement = document.activeElement as HTMLElement; @@ -265,6 +278,10 @@ export class FocusTrapZone extends React.Component impl }; private _forceClickInTrap = (ev: MouseEvent): void => { + if (this.props.disabled) { + return; + } + if (FocusTrapZone._focusStack.length && this === FocusTrapZone._focusStack[FocusTrapZone._focusStack.length - 1]) { const clickedElement = ev.target as HTMLElement; diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.types.ts b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.types.ts index 6b8f0f5a98da18..3dcd73a30bbf94 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.types.ts +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.types.ts @@ -22,6 +22,11 @@ export interface IFocusTrapZoneProps extends React.HTMLAttributes; + /** + * If set, the FocusTrapZone's focus trapping behavior will be disabled. + */ + disabled?: boolean; + /** * Sets the HTMLElement to focus on when exiting the FocusTrapZone. * @defaultvalue The element.target that triggered the FTZ. diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Click.Example.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Click.Example.tsx index 2870ca3a9ad1b5..7c29bb4328e76c 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Click.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Click.Example.tsx @@ -16,51 +16,33 @@ export class FocusTrapZoneBoxClickExample extends React.Component<{}, IFocusTrap private _toggle = React.createRef(); public render() { - return ( -
- {this.state.useTrapZone ? ( - - {this._internalContents()} - - ) : ( - this._internalContents() - )} -
- ); - } - - private _internalContents() { const { useTrapZone } = this.state; return ( - - - - Hyperlink inside trap zone - + + + + + Hyperlink inside trap zone + + ); } private _onFocusTrapZoneToggleChanged = (ev: React.MouseEvent, checked?: boolean): void => { - this.setState({ useTrapZone: !!checked }, () => { - // Restore focus to toggle after disabling the trap zone - // (the trap zone itself will handle initial focus when it's enabled) - if (!checked) { - this._toggle.current!.focus(); - } - }); + this.setState({ useTrapZone: !!checked }); }; } diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx index 47b62fcecf8e7e..8ef78f2094d3c6 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; +import { DefaultButton } from 'office-ui-fabric-react/lib/Button'; import { FocusTrapZone } from 'office-ui-fabric-react/lib/FocusTrapZone'; import { Link } from 'office-ui-fabric-react/lib/Link'; import { TextField } from 'office-ui-fabric-react/lib/TextField'; @@ -18,50 +19,42 @@ export class FocusTrapZoneBoxExample extends React.Component<{}, IFocusTrapZoneB private _toggle = React.createRef(); public render() { + const { useTrapZone } = this.state; + return (
- {this.state.useTrapZone ? ( - {this._internalContents()} - ) : ( - // prettier-ignore - this._internalContents() - )} + + + + + + Hyperlink inside trap zone + +
); } - private _internalContents() { - const { useTrapZone } = this.state; - - return ( - - - - Hyperlink inside trap zone - - ); - } + private _onButtonClickHandler = (): void => { + this.setState({ + useTrapZone: true + }); + }; private _onFocusTrapZoneToggleChanged = (ev: React.MouseEvent, checked?: boolean): void => { - this.setState({ useTrapZone: !!checked }, () => { - // Restore focus to toggle after disabling the trap zone - // (the trap zone itself will handle initial focus when it's enabled) - if (!checked) { - this._toggle.current!.focus(); - } - }); + this.setState({ useTrapZone: !!checked }); }; } diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx index c558eb87318282..2381dd8dbb45d3 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx @@ -20,51 +20,35 @@ export class FocusTrapZoneBoxCustomElementExample extends React.Component<{}, IF private _toggle = React.createRef(); public render() { - return ( -
- {this.state.useTrapZone ? ( - {this._internalContents()} - ) : ( - this._internalContents() - )} -
- ); - } - - private _internalContents() { const { useTrapZone } = this.state; return ( - - - - - Hyperlink which will receive initial focus when trap zone is activated - - + + + + + + Hyperlink which will receive initial focus when trap zone is activated + + + ); } private _onFocusTrapZoneToggleChanged = (ev: React.MouseEvent, checked?: boolean): void => { - this.setState({ useTrapZone: !!checked }, () => { - // Restore focus to toggle after disabling the trap zone - // (the trap zone itself will handle initial focus when it's enabled) - if (!checked) { - this._toggle.current!.focus(); - } - }); + this.setState({ useTrapZone: !!checked }); }; } diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.FocusZone.Example.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.FocusZone.Example.tsx index 3f96bbc7560a50..d0dd9ed2249ee7 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.FocusZone.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.FocusZone.Example.tsx @@ -18,20 +18,6 @@ export class FocusTrapZoneFocusZoneExample extends React.Component<{}, IFocusTra private _toggle = React.createRef(); public render() { - return ( -
- {this.state.useTrapZone ? ( - - {this._internalContents()} - - ) : ( - this._internalContents() - )} -
- ); - } - - private _internalContents() { const { useTrapZone } = this.state; const padding = 10; const border = '2px dashed #ababab'; @@ -39,34 +25,36 @@ export class FocusTrapZoneFocusZoneExample extends React.Component<{}, IFocusTra const tokens: IStackTokens = { childrenGap: 10 }; return ( - - + + + - - - - - - - + + + + + + + - + - - - - - - - - + + + + + + + + + ); } diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx index 9c72a6509960e6..07d88f230b2bec 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx @@ -14,35 +14,33 @@ interface IFocusTrapComponentProps { class FocusTrapComponent extends React.Component { public render() { const { isActive, zoneNumber, children } = this.props; - const contents = ( - - + = 2 && zoneNumber <= 4 && { width: 200 } + root: { border: `2px solid ${isActive ? '#ababab' : 'transparent'}`, padding: 10 } }} - /> - - {children} - + > + = 2 && zoneNumber <= 4 && { width: 200 } + }} + /> + + {children} + + ); - - if (this.props.isActive) { - return {contents}; - } - return contents; } private _onStringButtonClicked = (): void => { diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.NoTabbable.Example.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.NoTabbable.Example.tsx deleted file mode 100644 index 808f2be2cd55d9..00000000000000 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.NoTabbable.Example.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import * as React from 'react'; - -import { FocusTrapZone } from 'office-ui-fabric-react/lib/FocusTrapZone'; -import { TextField } from 'office-ui-fabric-react/lib/TextField'; -import { Toggle, IToggle } from 'office-ui-fabric-react/lib/Toggle'; -import { Stack } from 'office-ui-fabric-react/lib/Stack'; - -export interface IFocusTrapZoneNoTabbableExampleState { - useTrapZone: boolean; -} - -export class FocusTrapZoneNoTabbableExample extends React.Component<{}, IFocusTrapZoneNoTabbableExampleState> { - public state: IFocusTrapZoneNoTabbableExampleState = { useTrapZone: false }; - - private _toggle = React.createRef(); - - public render() { - return ( -
- {this.state.useTrapZone ? ( - - {this._internalContents()} - - ) : ( - this._internalContents() - )} -
- ); - } - - private _internalContents() { - const { useTrapZone } = this.state; - - return ( - - - - - - - ); - } - - private _onFocusTrapZoneToggleChanged = (ev: React.MouseEvent, checked?: boolean): void => { - this.setState({ useTrapZone: !!checked }, () => { - // Restore focus to toggle after disabling the trap zone - // (the trap zone itself will handle initial focus when it's enabled) - if (!checked) { - this._toggle.current!.focus(); - } - }); - }; -} diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Click.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Click.Example.tsx.shot index 2ed16525833f26..acd8c441bda170 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Click.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Click.Example.tsx.shot @@ -1,7 +1,23 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Component Examples renders FocusTrapZone.Box.Click.Example.tsx correctly 1`] = ` -
+
+
+
`; diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot index 1cba7b46ad1b8c..847d330797dcfd 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot @@ -2,231 +2,183 @@ exports[`Component Examples renders FocusTrapZone.Box.Example.tsx correctly 1`] = `
-
* { - text-overflow: ellipsis; + @media screen and (-ms-high-contrast: active){.ms-Fabric--isFocusVisible &:focus:after { + border: none; + bottom: -2px; + left: -2px; + outline-color: ButtonText; + right: -2px; + top: -2px; } - & > *:not(:first-child) { - margin-top: 15px; + &:active > * { + left: 0px; + position: relative; + top: 0px; } - & > *:not(.ms-StackItem) { - flex-shrink: 1; + &:hover { + background-color: #eaeaea; + color: #212121; } + @media screen and (-ms-high-contrast: active){&:hover { + border-color: Highlight; + color: Highlight; + } + &:active { + background-color: #c8c8c8; + color: #212121; + } + data-is-focusable={true} + onClick={[Function]} + onKeyDown={[Function]} + onKeyPress={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseUp={[Function]} + type="button" >
-
- - + Sample Initiator +
+ +
+
* { + text-overflow: ellipsis; + } + & > *:not(:first-child) { + margin-top: 15px; + } + & > *:not(.ms-StackItem) { + flex-shrink: 1; } >
- +
+ + +
+
+
+
+ +
+ &:hover { + border-color: #333333; + } + @media screen and (-ms-high-contrast: active){&:hover { + border-color: Highlight; + } + > + +
+ + Hyperlink inside trap zone +
- - Hyperlink inside trap zone - +
`; diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot index f45756455cb72c..d8174f2d7596bb 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot @@ -1,7 +1,23 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Component Examples renders FocusTrapZone.Box.FocusOnCustomElement.Example.tsx correctly 1`] = ` -
+
+
+
`; diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.FocusZone.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.FocusZone.Example.tsx.shot index 3dde764483dd8f..200a67938b707b 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.FocusZone.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.FocusZone.Example.tsx.shot @@ -1,7 +1,23 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Component Examples renders FocusTrapZone.FocusZone.Example.tsx correctly 1`] = ` -
+
+
+
`; diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Nested.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Nested.Example.tsx.shot index 33230fc3268656..fab1d0b5a9acff 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Nested.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Nested.Example.tsx.shot @@ -118,323 +118,33 @@ exports[`Component Examples renders FocusTrapZone.Nested.Example.tsx correctly 1
* { - text-overflow: ellipsis; - } - & > *:not(:first-child) { - margin-top: 10px; - } - & > *:not(.ms-StackItem) { - flex-shrink: 1; - } + onBlur={[Function]} + onFocus={[Function]} + onFocusCapture={[Function]} >
- -
- - -
-
- + aria-hidden={true} + data-is-visible={true} + onFocus={[Function]} + style={ + Object { + "pointerEvents": "none", + "position": "fixed", + } + } + tabIndex={0} + />
*:not(:first-child) { - margin-left: 10px; + margin-top: 10px; } & > *:not(.ms-StackItem) { flex-shrink: 1; @@ -462,7 +172,6 @@ exports[`Component Examples renders FocusTrapZone.Nested.Example.tsx correctly 1 font-size: 14px; font-weight: 400; margin-bottom: 8px; - width: 200px; } >
* { - text-overflow: ellipsis; - } - & > *:not(:first-child) { - margin-top: 10px; - } - & > *:not(.ms-StackItem) { - flex-shrink: 1; - } + onBlur={[Function]} + onFocus={[Function]} + onFocusCapture={[Function]} > +
* { + text-overflow: ellipsis; + } + & > *:not(:first-child) { + margin-left: 10px; + } + & > *:not(.ms-StackItem) { + flex-shrink: 1; } > - -
- -
-
- +
+ Off +
- -
-
* { - text-overflow: ellipsis; - } - & > *:not(:first-child) { - margin-top: 10px; - } - & > *:not(.ms-StackItem) { - flex-shrink: 1; - } - > -
- -
* { + left: 0px; position: relative; + top: 0px; + } + &:hover { + background-color: #eaeaea; + color: #212121; + } + @media screen and (-ms-high-contrast: active){&:hover { + border-color: Highlight; + color: Highlight; + } + &:active { + background-color: #c8c8c8; + color: #212121; } + data-is-focusable={true} + onClick={[Function]} + onKeyDown={[Function]} + onKeyPress={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseUp={[Function]} + type="button" > -
+ +
+
+
* { + text-overflow: ellipsis; } - .ms-Fabric--isFocusVisible &:focus:after { - border: 1px solid #ffffff; - bottom: -2px; - content: ""; - left: -2px; - outline: 1px solid #666666; - position: absolute; - right: -2px; - top: -2px; - z-index: 1; + & > *:not(:first-child) { + margin-top: 10px; } - &:hover { - border-color: #333333; + & > *:not(.ms-StackItem) { + flex-shrink: 1; } - @media screen and (-ms-high-contrast: active){&:hover .ms-Toggle-thumb { - border-color: Highlight; + > +
+ +
+ + +
+
+ +
+
+
+
+
+
* { + text-overflow: ellipsis; } - @media screen and (-ms-high-contrast: active){&:hover { - border-color: Highlight; + & > *:not(:first-child) { + margin-top: 10px; + } + & > *:not(.ms-StackItem) { + flex-shrink: 1; } - data-is-focusable={true} - id="Toggle15" - onChange={[Function]} - onClick={[Function]} - role="switch" - type="button" >
+ +
+ + +
+
+ + data-is-focusable={true} + onClick={[Function]} + onKeyDown={[Function]} + onKeyPress={[Function]} + onKeyUp={[Function]} + onMouseDown={[Function]} + onMouseUp={[Function]} + type="button" + > +
+
+
+ Zone 4 button +
+
+
+ +
+
+
+
+
+
+
+
+
* { + text-overflow: ellipsis; + } + & > *:not(:first-child) { + margin-top: 10px; + } + & > *:not(.ms-StackItem) { + flex-shrink: 1; + } + > +
-
-
- +
+ Off +
- -
-
-
* { - text-overflow: ellipsis; - } - & > *:not(:first-child) { - margin-top: 10px; - } - & > *:not(.ms-StackItem) { - flex-shrink: 1; - } - > -
- -
- -
-
-
- +
+
+
`; From 6563eb1d774e8ff474d0213b1773e0b0d59fc6c8 Mon Sep 17 00:00:00 2001 From: Jason Gore Date: Mon, 22 Apr 2019 16:09:26 -0700 Subject: [PATCH 2/8] Change file. --- .../jg-ftz-disabled-prop_2019-04-22-23-09.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/office-ui-fabric-react/jg-ftz-disabled-prop_2019-04-22-23-09.json diff --git a/common/changes/office-ui-fabric-react/jg-ftz-disabled-prop_2019-04-22-23-09.json b/common/changes/office-ui-fabric-react/jg-ftz-disabled-prop_2019-04-22-23-09.json new file mode 100644 index 00000000000000..e10810e6f54c82 --- /dev/null +++ b/common/changes/office-ui-fabric-react/jg-ftz-disabled-prop_2019-04-22-23-09.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "office-ui-fabric-react", + "comment": "FocusTrapZone: Add disabled prop.", + "type": "minor" + } + ], + "packageName": "office-ui-fabric-react", + "email": "jagore@microsoft.com" +} \ No newline at end of file From 77f99ec7069752a223f97802f35710a6d5109187 Mon Sep 17 00:00:00 2001 From: Jason Gore Date: Tue, 23 Apr 2019 11:30:55 -0700 Subject: [PATCH 3/8] Fix bumpers being focusable when FocusTrapZone is disabled. Fix example regressions. --- .../FocusTrapZone/FocusTrapZone.test.tsx | 23 + .../FocusTrapZone/FocusTrapZone.tsx | 16 +- .../FocusTrapZone/FocusTrapZone.types.ts | 1 + ...pZone.Box.FocusOnCustomElement.Example.tsx | 54 +- .../examples/FocusTrapZone.Nested.Example.tsx | 8 +- .../FocusTrapZone.Box.Click.Example.tsx.shot | 4 +- .../FocusTrapZone.Box.Example.tsx.shot | 4 +- ....Box.FocusOnCustomElement.Example.tsx.shot | 752 ++++++++++-------- .../FocusTrapZone.FocusZone.Example.tsx.shot | 4 +- .../FocusTrapZone.Nested.Example.tsx.shot | 31 +- 10 files changed, 532 insertions(+), 365 deletions(-) diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.test.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.test.tsx index dec6135099c6f7..a15156067dc760 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.test.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.test.tsx @@ -579,6 +579,19 @@ describe('FocusTrapZone', () => { expect(document.activeElement).toBe(activeElement); }); + it('Does not focus first on mount with disabled', async () => { + expect.assertions(1); + + const activeElement = document.activeElement; + + setupTest({ disabled: true }); + + // document.activeElement can be used to detect activeElement after component mount, but it does not + // update based on focus events due to limitations of ReactDOM. + // Make sure activeElement didn't change. + expect(document.activeElement).toBe(activeElement); + }); + it('Focuses on firstFocusableSelector on mount', async () => { expect.assertions(1); @@ -587,6 +600,16 @@ describe('FocusTrapZone', () => { expect(document.activeElement).toBe(buttonC); }); + it('Does not focus on firstFocusableSelector on mount with disabled', async () => { + expect.assertions(1); + + const activeElement = document.activeElement; + + setupTest({ firstFocusableSelector: 'c', disabled: true }); + + expect(document.activeElement).toBe(activeElement); + }); + it('Falls back to first focusable element with invalid firstFocusableSelector', async () => { const { buttonA } = setupTest({ firstFocusableSelector: 'invalidSelector' }); diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.tsx index 68991dedd595a7..7da1c3a7daba10 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.tsx @@ -51,10 +51,12 @@ export class FocusTrapZone extends React.Component impl const newDisabled = this.props.disabled !== undefined ? this.props.disabled : false; if ((!prevForceFocusInsideTrap && newForceFocusInsideTrap) || (prevDisabled && !newDisabled)) { - // Transition from forceFocusInsideTrap disabled to enabled. Emulate what happens when a FocusTrapZone gets mounted + // Transition from forceFocusInsideTrap / FTZ disabled to enabled. + // Emulate what happens when a FocusTrapZone gets mounted. this._bringFocusIntoZone(); } else if ((prevForceFocusInsideTrap && !newForceFocusInsideTrap) || (!prevDisabled && newDisabled)) { - // Transition from forceFocusInsideTrap enabled to disabled. Emulate what happens when a FocusTrapZone gets unmounted + // Transition from forceFocusInsideTrap / FTZ enabled to disabled. + // Emulate what happens when a FocusTrapZone gets unmounted. this._returnFocusToInitiator(); } } @@ -66,7 +68,7 @@ export class FocusTrapZone extends React.Component impl } public render(): JSX.Element { - const { className, ariaLabelledBy } = this.props; + const { className, disabled = false, ariaLabelledBy } = this.props; const divProps = getNativeProps(this.props, divProperties); const bumperProps = { @@ -74,7 +76,7 @@ export class FocusTrapZone extends React.Component impl pointerEvents: 'none', position: 'fixed' // 'fixed' prevents browsers from scrolling to bumpers when viewport does not contain them }, - tabIndex: 0, + tabIndex: disabled ? -1 : 0, // make bumpers tabbable only when enabled 'aria-hidden': true, 'data-is-visible': true } as React.HTMLAttributes; @@ -196,7 +198,11 @@ export class FocusTrapZone extends React.Component impl }; private _bringFocusIntoZone(): void { - const { elementToFocusOnDismiss, disableFirstFocus = false } = this.props; + const { elementToFocusOnDismiss, disabled = false, disableFirstFocus = false } = this.props; + + if (disabled) { + return; + } FocusTrapZone._focusStack.push(this); diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.types.ts b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.types.ts index 3dcd73a30bbf94..b819df519e99bf 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.types.ts +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.types.ts @@ -24,6 +24,7 @@ export interface IFocusTrapZoneProps extends React.HTMLAttributes - - - - - Hyperlink which will receive initial focus when trap zone is activated - - - +
+ + + + + + + Hyperlink which will receive initial focus when trap zone is activated + + + +
); } + private _onButtonClickHandler = (): void => { + this.setState({ + useTrapZone: true + }); + }; + private _onFocusTrapZoneToggleChanged = (ev: React.MouseEvent, checked?: boolean): void => { this.setState({ useTrapZone: !!checked }); }; diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx index 07d88f230b2bec..0c1b26a93a5d9c 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx @@ -18,7 +18,6 @@ class FocusTrapComponent extends React.Component { return ( { }} > { const activeStates: IFocusTrapZoneNestedExampleState['activeStates'] = {}; [1, 2, 3, 4, 5].forEach(zoneNumber => { diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Click.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Click.Example.tsx.shot index acd8c441bda170..e73090a94375ef 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Click.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Click.Example.tsx.shot @@ -16,7 +16,7 @@ exports[`Component Examples renders FocusTrapZone.Box.Click.Example.tsx correctl "position": "fixed", } } - tabIndex={0} + tabIndex={-1} />
`; diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot index 847d330797dcfd..4470954f165d96 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot @@ -133,7 +133,7 @@ exports[`Component Examples renders FocusTrapZone.Box.Example.tsx correctly 1`] "position": "fixed", } } - tabIndex={0} + tabIndex={-1} />
diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot index d8174f2d7596bb..b6972f9d037397 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot @@ -1,248 +1,184 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Component Examples renders FocusTrapZone.Box.FocusOnCustomElement.Example.tsx correctly 1`] = ` -
-
-
+ - + Focus Custom Element +
+ +
+
* { + text-overflow: ellipsis; + } + & > *:not(:first-child) { + margin-top: 15px; + } + & > *:not(.ms-StackItem) { + flex-shrink: 1; } >
- +
+ + +
+
+
+
+ +
+ &:hover { + border-color: #333333; + } + @media screen and (-ms-high-contrast: active){&:hover { + border-color: Highlight; + } + > + +
+ + Hyperlink which will receive initial focus when trap zone is activated +
- - Hyperlink which will receive initial focus when trap zone is activated - -
-
+ tabIndex={-1} + /> +
`; diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.FocusZone.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.FocusZone.Example.tsx.shot index 200a67938b707b..d678bddc49af67 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.FocusZone.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.FocusZone.Example.tsx.shot @@ -16,7 +16,7 @@ exports[`Component Examples renders FocusTrapZone.FocusZone.Example.tsx correctl "position": "fixed", } } - tabIndex={0} + tabIndex={-1} />
`; diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Nested.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Nested.Example.tsx.shot index fab1d0b5a9acff..1ac9d20b0f13de 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Nested.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Nested.Example.tsx.shot @@ -132,7 +132,7 @@ exports[`Component Examples renders FocusTrapZone.Nested.Example.tsx correctly 1 "position": "fixed", } } - tabIndex={0} + tabIndex={-1} />
*:not(:first-child) { - margin-left: 10px; + margin-top: 10px; } & > *:not(.ms-StackItem) { flex-shrink: 1; @@ -540,6 +541,7 @@ exports[`Component Examples renders FocusTrapZone.Nested.Example.tsx correctly 1
@@ -1807,7 +1812,7 @@ exports[`Component Examples renders FocusTrapZone.Nested.Example.tsx correctly 1 "position": "fixed", } } - tabIndex={0} + tabIndex={-1} />
From 6f670a217ec0a315168e6ad9161655c8195ea2a9 Mon Sep 17 00:00:00 2001 From: Jason Gore Date: Tue, 23 Apr 2019 12:53:09 -0700 Subject: [PATCH 4/8] PR feedback. --- .../src/components/FocusTrapZone/FocusTrapZone.test.tsx | 4 ++-- .../src/components/FocusTrapZone/FocusTrapZone.types.ts | 4 ++-- .../examples/FocusTrapZone.Nested.Example.tsx | 9 +++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.test.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.test.tsx index a15156067dc760..613fa6afbc0ac6 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.test.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.test.tsx @@ -579,7 +579,7 @@ describe('FocusTrapZone', () => { expect(document.activeElement).toBe(activeElement); }); - it('Does not focus first on mount with disabled', async () => { + it('Does not focus first on mount while disabled', async () => { expect.assertions(1); const activeElement = document.activeElement; @@ -600,7 +600,7 @@ describe('FocusTrapZone', () => { expect(document.activeElement).toBe(buttonC); }); - it('Does not focus on firstFocusableSelector on mount with disabled', async () => { + it('Does not focus on firstFocusableSelector on mount while disabled', async () => { expect.assertions(1); const activeElement = document.activeElement; diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.types.ts b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.types.ts index b819df519e99bf..f3c71a6def8ac9 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.types.ts +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.types.ts @@ -23,14 +23,14 @@ export interface IFocusTrapZoneProps extends React.HTMLAttributes; /** - * If set, the FocusTrapZone's focus trapping behavior will be disabled. + * Disables the FocusTrapZone's focus trapping behavior when set. * @defaultvalue false */ disabled?: boolean; /** * Sets the HTMLElement to focus on when exiting the FocusTrapZone. - * @defaultvalue The element.target that triggered the FTZ. + * @defaultvalue element.target The element.target that triggered the FTZ. */ elementToFocusOnDismiss?: HTMLElement; diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx index 0c1b26a93a5d9c..5d039e9225fe5c 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Nested.Example.tsx @@ -84,10 +84,11 @@ export class FocusTrapZoneNestedExample extends React.Component<{}, IFocusTrapZo }; // This randomize example is exposing a quirk in focus stack behavior. - // Since for the example components render from the bottom up, the most recently active item in the focusStack - // ends up being the highest parent, which is the reverse order focus trap zones would normally be put on the - // focusStack. That means children aren't capturing focus as one would normally expect when toggling the FTZ's - // individually. This would also be an issue if anyone ever rendered multiple FocusTrapZones simultaneously. + // For the randomize example, components render from the bottom up with all of the new "activeStates" simultaneously set. + // The most recently active item in the focusStack ends up being the highest parent, which is the reverse order focus + // trap zones would normally be put on the focusStack. That means children aren't capturing focus as one would normally + // expect when toggling the FTZ's individually. This would also be an issue if anyone ever rendered multiple nested and enabled + // FocusTrapZones simultaneously. private _randomize = (): void => { const activeStates: IFocusTrapZoneNestedExampleState['activeStates'] = {}; [1, 2, 3, 4, 5].forEach(zoneNumber => { From 996c6f06ff5374fc2e4f0fff4f9c2800db892fca Mon Sep 17 00:00:00 2001 From: Jason Gore Date: Tue, 23 Apr 2019 13:15:20 -0700 Subject: [PATCH 5/8] PR feedback. --- .../FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx index 8ef78f2094d3c6..7a2e58fdac066b 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx @@ -23,7 +23,7 @@ export class FocusTrapZoneBoxExample extends React.Component<{}, IFocusTrapZoneB return (
- + Date: Tue, 23 Apr 2019 13:18:56 -0700 Subject: [PATCH 6/8] Update snapshot. --- .../__snapshots__/FocusTrapZone.Box.Example.tsx.shot | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot index 4470954f165d96..3e7e5a7d31912d 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot @@ -3,8 +3,6 @@ exports[`Component Examples renders FocusTrapZone.Box.Example.tsx correctly 1`] = `
From 237d1a8c04146135df11625b65e36ed70bc6bd2f Mon Sep 17 00:00:00 2001 From: Jason Gore Date: Tue, 23 Apr 2019 14:56:41 -0700 Subject: [PATCH 7/8] PR feedback. --- .../examples/FocusTrapZone.Box.Example.tsx | 16 +- ...pZone.Box.FocusOnCustomElement.Example.tsx | 14 +- .../FocusTrapZone.Box.Example.tsx.shot | 245 ++++++++++------- ....Box.FocusOnCustomElement.Example.tsx.shot | 249 +++++++++++------- 4 files changed, 336 insertions(+), 188 deletions(-) diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx index 7a2e58fdac066b..dca44a9a1eea33 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.Example.tsx @@ -3,9 +3,10 @@ import * as React from 'react'; import { DefaultButton } from 'office-ui-fabric-react/lib/Button'; import { FocusTrapZone } from 'office-ui-fabric-react/lib/FocusTrapZone'; import { Link } from 'office-ui-fabric-react/lib/Link'; +import { Stack } from 'office-ui-fabric-react/lib/Stack'; +import { Text } from 'office-ui-fabric-react/lib/Text'; import { TextField } from 'office-ui-fabric-react/lib/TextField'; import { Toggle, IToggle } from 'office-ui-fabric-react/lib/Toggle'; -import { Stack } from 'office-ui-fabric-react/lib/Stack'; export interface IFocusTrapZoneBoxExampleState { useTrapZone: boolean; @@ -22,8 +23,15 @@ export class FocusTrapZoneBoxExample extends React.Component<{}, IFocusTrapZoneB const { useTrapZone } = this.state; return ( -
- + + + + If this button is used to enable FocusTrapZone, focus should return to this button after the FocusTrapZone is disabled. + + + + + Hyperlink inside trap zone -
+ ); } diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx index 6dcc7d0cd41db0..fe361654637022 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx @@ -3,9 +3,10 @@ import * as React from 'react'; import { DefaultButton } from 'office-ui-fabric-react/lib/Button'; import { FocusTrapZone } from 'office-ui-fabric-react/lib/FocusTrapZone'; import { Link } from 'office-ui-fabric-react/lib/Link'; +import { Stack } from 'office-ui-fabric-react/lib/Stack'; +import { Text } from 'office-ui-fabric-react/lib/Text'; import { TextField } from 'office-ui-fabric-react/lib/TextField'; import { Toggle, IToggle } from 'office-ui-fabric-react/lib/Toggle'; -import { Stack } from 'office-ui-fabric-react/lib/Stack'; export interface IFocusTrapZoneBoxCustomElementExampleState { useTrapZone: boolean; @@ -24,8 +25,13 @@ export class FocusTrapZoneBoxCustomElementExample extends React.Component<{}, IF const { useTrapZone } = this.state; return ( -
- + + + If this button is used to enable FocusTrapZone, the hyperlink should be focused. + + + + -
+ ); } diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot index 3e7e5a7d31912d..b31458f09c497b 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.Example.tsx.shot @@ -1,121 +1,188 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Component Examples renders FocusTrapZone.Box.Example.tsx correctly 1`] = ` -
- + +
- + +
Date: Tue, 23 Apr 2019 15:14:52 -0700 Subject: [PATCH 8/8] Snapshot update. --- .../FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot index 40d22c5c70e114..dca8f46c5f8f05 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.Box.FocusOnCustomElement.Example.tsx.shot @@ -69,8 +69,6 @@ exports[`Component Examples renders FocusTrapZone.Box.FocusOnCustomElement.Examp } >