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 aa24a5635ce56..c1178944cc202 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 @@ -46,7 +46,8 @@ export interface IFocusTrapZoneProps extends React.HTMLAttributes string); 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 660d3c9215e2b..92dad15ff751c 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 @@ -1,99 +1,66 @@ 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'; import { Toggle, IToggle } from 'office-ui-fabric-react/lib/Toggle'; -import { mergeStyles } from 'office-ui-fabric-react/lib/Styling'; - -const contentClass = mergeStyles({ - border: '1px dashed #ababab' -}); +import { Stack } from 'office-ui-fabric-react/lib/Stack'; export interface IFocusTrapZoneBoxClickExampleState { - isToggled: boolean; + useTrapZone: boolean; } export class FocusTrapZoneBoxClickExample extends React.Component<{}, IFocusTrapZoneBoxClickExampleState> { - public state: IFocusTrapZoneBoxClickExampleState = { - isToggled: false - }; + public state: IFocusTrapZoneBoxClickExampleState = { useTrapZone: false }; - private _toggle: IToggle; + private _toggle = React.createRef(); public render() { - const { isToggled } = this.state; - return (
- - - {(() => { - if (isToggled) { - return ( - - {this._internalContents()} - - ); - } else { - return
{this._internalContents()}
; - } - })()} + {this.state.useTrapZone ? ( + + {this._internalContents()} + + ) : ( + this._internalContents() + )}
); } private _internalContents() { - const { isToggled } = this.state; + const { useTrapZone } = this.state; return ( -
- - Hyperlink inside FocusTrapZone -
-
+ - {(() => { - if (isToggled) { - return ( - - ); - } - })()} -
+ + Hyperlink inside trap zone + ); } - private _onButtonClickHandler = (): void => { - this.setState({ - isToggled: 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(); + } }); }; - - private _onExitButtonClickHandler = (): void => { - this.setState({ - isToggled: false - }); - }; - - private _onFocusTrapZoneToggleChanged = (ev: React.MouseEvent, isToggled: boolean): void => { - this.setState( - { - isToggled: isToggled - }, - () => this._toggle.focus() - ); - }; - - private _setRef = (toggle: IToggle): void => { - this._toggle = toggle; - }; } 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 b430c28a8f201..fe95135bb9380 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,95 +1,67 @@ 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'; import { Toggle, IToggle } from 'office-ui-fabric-react/lib/Toggle'; -import { mergeStyles } from 'office-ui-fabric-react/lib/Styling'; - -const contentClass = mergeStyles({ - border: '1px dashed #ababab' -}); +import { Stack } from 'office-ui-fabric-react/lib/Stack'; export interface IFocusTrapZoneBoxExampleState { - isChecked: boolean; + useTrapZone: boolean; } export class FocusTrapZoneBoxExample extends React.Component<{}, IFocusTrapZoneBoxExampleState> { public state: IFocusTrapZoneBoxExampleState = { - isChecked: false + useTrapZone: false }; - private _toggle: IToggle; + private _toggle = React.createRef(); public render() { - const { isChecked } = this.state; - return (
- - - {(() => { - if (isChecked) { - return {this._internalContents()}; - } else { - return
{this._internalContents()}
; - } - })()} + {this.state.useTrapZone ? ( + {this._internalContents()} + ) : ( + // prettier-ignore + this._internalContents() + )}
); } private _internalContents() { - const { isChecked } = this.state; + const { useTrapZone } = this.state; return ( -
- - Hyperlink inside FocusTrapZone -
-
+ - {(() => { - if (isChecked) { - return ( - - ); - } - })()} -
+ + Hyperlink inside trap zone + ); } - private _onButtonClickHandler = (): void => { - this.setState({ - isChecked: true - }); - }; - - private _onExitButtonClickHandler = (): void => { - this.setState({ - isChecked: false + 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(); + } }); }; - - private _onFocusTrapZoneToggleChanged = (ev: React.MouseEvent, isChecked: boolean): void => { - this.setState( - { - isChecked: isChecked - }, - () => this._toggle.focus() - ); - }; - - private _setRef = (toggle: IToggle): void => { - this._toggle = toggle; - }; } 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 f9f0ee1130692..ae5a4c4bb1d82 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 @@ -1,99 +1,70 @@ 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'; import { Toggle, IToggle } from 'office-ui-fabric-react/lib/Toggle'; +import { Stack } from 'office-ui-fabric-react/lib/Stack'; export interface IFocusTrapZoneBoxCustomElementExampleState { - isChecked: boolean; + useTrapZone: boolean; } +const _focusClassName = 'shouldFocusInput'; + export class FocusTrapZoneBoxCustomElementExample extends React.Component<{}, IFocusTrapZoneBoxCustomElementExampleState> { public state: IFocusTrapZoneBoxCustomElementExampleState = { - isChecked: false + useTrapZone: false }; - private _toggle: IToggle; - private focusClassName = 'shouldFocusInput'; + private _toggle = React.createRef(); public render() { - const { isChecked } = this.state; - return (
- - {(() => { - if (isChecked) { - return {this._internalContents()}; - } else { - return
{this._internalContents()}
; - } - })()} + {this.state.useTrapZone ? ( + {this._internalContents()} + ) : ( + this._internalContents() + )}
); } private _internalContents() { - const { isChecked } = this.state; + const { useTrapZone } = this.state; return ( -
- - - Hyperlink inside FocusTrapZone + + + + + Hyperlink which will receive initial focus when trap zone is activated -
-
-
- -
- {(() => { - if (isChecked) { - return ( - - ); - } - })()} -
+ ); } - private _onButtonClickHandler = (): void => { - this.setState({ - isChecked: true - }); - }; - - private _onExitButtonClickHandler = (): void => { - this.setState({ - isChecked: false + 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(); + } }); }; - - private _onFocusTrapZoneToggleChanged = (ev: React.MouseEvent, isChecked: boolean): void => { - this.setState( - { - isChecked: isChecked - }, - () => this._toggle.focus() - ); - }; - - private _setRef = (toggle: IToggle): void => { - this._toggle = toggle; - }; } diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.DialogInPanel.Example.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.DialogInPanel.Example.tsx index b2b3e4080fd1b..c267d62079637 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.DialogInPanel.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/examples/FocusTrapZone.DialogInPanel.Example.tsx @@ -11,19 +11,15 @@ export interface IFocusTrapZoneDialogInPanelExampleState { } export class FocusTrapZoneDialogInPanelExample extends React.Component<{}, IFocusTrapZoneDialogInPanelExampleState> { - constructor(props: {}) { - super(props); - - this.state = { - hideDialog: true, - showPanel: false - }; - } + public state: IFocusTrapZoneDialogInPanelExampleState = { + hideDialog: true, + showPanel: false + }; public render() { return (
- + - +
+ +
* { + text-overflow: ellipsis; + } + & > *:not(:first-child) { + margin-left: 10px; + } + & > *:not(.ms-StackItem) { + flex-shrink: 1; + } >
@@ -825,7 +941,7 @@ exports[`Component Examples renders FocusTrapZone.FocusZone.Example.tsx correctl margin-right: 4px; margin-top: 0; } - id="id__20" + id="id__18" > FZ2
@@ -939,7 +1055,7 @@ exports[`Component Examples renders FocusTrapZone.FocusZone.Example.tsx correctl margin-right: 4px; margin-top: 0; } - id="id__23" + id="id__21" > FZ2 @@ -947,170 +1063,6 @@ exports[`Component Examples renders FocusTrapZone.FocusZone.Example.tsx correctl -
-
- -
- - -
-
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 b7c2a659e6b19..ae0d92b0213c8 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 @@ -2,131 +2,148 @@ exports[`Component Examples renders FocusTrapZone.Nested.Example.tsx correctly 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; + } + & > *:not(:first-child) { + margin-top: 10px; + } + & > *:not(.ms-StackItem) { + flex-shrink: 1; + } + >
- Focus Trap Zone + Enable trap zone 1
-
- +
+ +
* { + text-overflow: ellipsis; + } + & > *:not(:first-child) { + margin-left: 10px; + } + & > *:not(.ms-StackItem) { + flex-shrink: 1; + } + >
-
- +
+ +
* { + text-overflow: ellipsis; + } + & > *:not(:first-child) { + margin-top: 10px; + } + & > *:not(.ms-StackItem) { + flex-shrink: 1; + } + >
-
-
+
+
* { + text-overflow: ellipsis; + } + & > *:not(:first-child) { + margin-top: 10px; + } + & > *:not(.ms-StackItem) { + flex-shrink: 1; + } + >
-
- -
- + +
+ +
* { + text-overflow: ellipsis; + } + & > *:not(:first-child) { + margin-top: 10px; + } + & > *:not(.ms-StackItem) { + flex-shrink: 1; + } + >
- Focus Trap Zone + Enable trap zone 5
-
- - - + `; diff --git a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.NoTabbable.Example.tsx.shot b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.NoTabbable.Example.tsx.shot index d5bab1cbf30cc..21af1f30eeb22 100644 --- a/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.NoTabbable.Example.tsx.shot +++ b/packages/office-ui-fabric-react/src/components/__snapshots__/FocusTrapZone.NoTabbable.Example.tsx.shot @@ -2,138 +2,57 @@ exports[`Component Examples renders FocusTrapZone.NoTabbable.Example.tsx correctly 1`] = `
- -
-
-
+ Use trap zone + +
-
- -
-
+ /> + +
+
+
-
- -
+ &::placeholder { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + color: #666666; + font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; + font-size: 14px; + font-weight: 400; + opacity: 1; + } + &:-ms-input-placeholder { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + color: #666666; + font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; + font-size: 14px; + font-weight: 400; + opacity: 1; + } + id="TextField1" + onBlur={[Function]} + onChange={[Function]} + onFocus={[Function]} + onInput={[Function]} + placeholder="Not tabbable" + tabIndex={-1} + type="text" + value="" + />
+
+
-
- -
+ &::placeholder { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + color: #666666; + font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; + font-size: 14px; + font-weight: 400; + opacity: 1; + } + &:-ms-input-placeholder { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + color: #666666; + font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; + font-size: 14px; + font-weight: 400; + opacity: 1; + } + id="TextField3" + onBlur={[Function]} + onChange={[Function]} + onFocus={[Function]} + onInput={[Function]} + placeholder="Not tabbable" + tabIndex={-1} + type="text" + value="" + />
+
+
- -
- - + &:active, &:focus, &:hover { + outline: 0px; + } + &::-ms-clear { + display: none; + } + &::placeholder { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + color: #666666; + font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; + font-size: 14px; + font-weight: 400; + opacity: 1; + } + &:-ms-input-placeholder { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + color: #666666; + font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; + font-size: 14px; + font-weight: 400; + opacity: 1; + } + id="TextField5" + onBlur={[Function]} + onChange={[Function]} + onFocus={[Function]} + onInput={[Function]} + placeholder="Not tabbable" + tabIndex={-1} + type="text" + value="" + />