diff --git a/common/changes/office-ui-fabric-react/focuszone_2019-04-02-01-01.json b/common/changes/office-ui-fabric-react/focuszone_2019-04-02-01-01.json new file mode 100644 index 00000000000000..7ee9648cdb47a9 --- /dev/null +++ b/common/changes/office-ui-fabric-react/focuszone_2019-04-02-01-01.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "office-ui-fabric-react", + "comment": "FocusZone: fixing logic to track outer FZ components correctly.", + "type": "patch" + } + ], + "packageName": "office-ui-fabric-react", + "email": "dzearing@microsoft.com" +} \ No newline at end of file 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 1aef39e7e783cf..bfb767bcd7da1a 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 @@ -1199,6 +1199,7 @@ export class FocusZone extends React.Component implements I static defaultProps: IFocusZoneProps; focus(forceIntoFirstElement?: boolean): boolean; focusElement(element: HTMLElement): boolean; + static getOuterZones(): number; // (undocumented) render(): JSX.Element; } diff --git a/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.test.tsx b/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.test.tsx index 38dbbca03d3b5d..b5a8fd247ad789 100644 --- a/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.test.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.test.tsx @@ -230,6 +230,28 @@ describe('FocusZone', () => { expect(document.activeElement).toBe(host.querySelector('#b')); }); + it('only adds outerzones to be updated for tab changes', () => { + const activeZones = FocusZone.getOuterZones(); + + host = document.createElement('div'); + + // Render component without button A. + ReactDOM.render( + + + + + , + host + ); + + expect(FocusZone.getOuterZones()).toEqual(activeZones + 1); + + ReactDOM.unmountComponentAtNode(host); + + expect(FocusZone.getOuterZones()).toEqual(activeZones); + }); + it('can call onActiveItemChanged when the active item is changed', () => { let called = false; const component = ReactTestUtils.renderIntoDocument( diff --git a/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.tsx b/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.tsx index 06b46f229cd708..7e1577b7c7383f 100644 --- a/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.tsx @@ -79,6 +79,11 @@ export class FocusZone extends React.Component implements I /** Used to allow us to move to next focusable element even when we're focusing on a input element when pressing tab */ private _processingTabKey: boolean; + /** Used for testing purposes only. */ + public static getOuterZones(): number { + return _outerZones.size; + } + constructor(props: IFocusZoneProps) { super(props); @@ -108,10 +113,6 @@ export class FocusZone extends React.Component implements I _allInstances[this._id] = this; - if (!this._isInnerZone) { - _outerZones.add(this); - } - if (root) { const windowElement = root.ownerDocument!.defaultView; @@ -125,6 +126,10 @@ export class FocusZone extends React.Component implements I parentElement = getParent(parentElement, ALLOW_VIRTUAL_ELEMENTS); } + if (!this._isInnerZone) { + _outerZones.add(this); + } + if (windowElement && _outerZones.size === 1) { this._disposables.push(on(windowElement, 'keydown', this._onKeyDownCapture, true)); }