diff --git a/common/changes/office-ui-fabric-react/redo-focuszone-change_2018-04-15-19-20.json b/common/changes/office-ui-fabric-react/redo-focuszone-change_2018-04-15-19-20.json new file mode 100644 index 00000000000000..cf6dfeb297c7d0 --- /dev/null +++ b/common/changes/office-ui-fabric-react/redo-focuszone-change_2018-04-15-19-20.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "office-ui-fabric-react", + "comment": "FocusZone: redoing the \"reset alignment on mouse down\" change in a less intrusive manner, with test coverage.", + "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/src/components/FocusZone/FocusZone.test.tsx b/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.test.tsx index d5972db64ea2c6..585a3a14e83ad8 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 @@ -619,6 +619,91 @@ describe('FocusZone', () => { expect(lastFocusedElement).toBe(buttonA); }); + it('can reset alignment on mouse down', () => { + const component = ReactTestUtils.renderIntoDocument( +
+ + + + + + +
+ ); + + const focusZone = ReactDOM.findDOMNode(component as React.ReactInstance).firstChild as Element; + const buttonA = focusZone.querySelector('.a') as HTMLElement; + const buttonB = focusZone.querySelector('.b') as HTMLElement; + const buttonC = focusZone.querySelector('.c') as HTMLElement; + const buttonD = focusZone.querySelector('.d') as HTMLElement; + + // Set up a grid like so: + // A B + // C D + setupElement(buttonA, { + clientRect: { + top: 0, + bottom: 20, + left: 0, + right: 20 + } + }); + + setupElement(buttonB, { + clientRect: { + top: 0, + bottom: 20, + left: 20, + right: 40 + } + }); + + setupElement(buttonC, { + clientRect: { + top: 20, + bottom: 40, + left: 0, + right: 20 + } + }); + + setupElement(buttonD, { + clientRect: { + top: 20, + bottom: 40, + left: 20, + right: 40 + } + }); + + // Focus the first button. + ReactTestUtils.Simulate.focus(buttonA); + expect(lastFocusedElement).toBe(buttonA); + + // Pressing up should stay on a. + ReactTestUtils.Simulate.keyDown(focusZone, { which: KeyCodes.up }); + expect(lastFocusedElement).toBe(buttonA); + + // Pressing left should stay on a. + ReactTestUtils.Simulate.keyDown(focusZone, { which: KeyCodes.left }); + expect(lastFocusedElement).toBe(buttonA); + + // Pressing right should go to b. + ReactTestUtils.Simulate.keyDown(focusZone, { which: KeyCodes.right }); + expect(lastFocusedElement).toBe(buttonB); + + // Pressing down should go to d. + ReactTestUtils.Simulate.keyDown(focusZone, { which: KeyCodes.down }); + expect(lastFocusedElement).toBe(buttonD); + + // Mousing down on a should reset alignment to a. + ReactTestUtils.Simulate.mouseDown(focusZone, { target: buttonA }); + + // Pressing down should go to c. + ReactTestUtils.Simulate.keyDown(focusZone, { which: KeyCodes.down }); + expect(lastFocusedElement).toBe(buttonC); + }); + it('can use arrows bidirectionally with data-no-horizontal-wrap and data-no-vertical-wrap', () => { 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 6823e02c0e7b1d..030ee51140bb4b 100644 --- a/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.tsx @@ -259,7 +259,7 @@ export class FocusZone extends BaseComponent implements IFo target = path.pop() as HTMLElement; if (target && isElementTabbable(target)) { - this._setActiveElement(target); + this._setActiveElement(target, true); } if (isElementFocusZone(target)) { @@ -269,7 +269,7 @@ export class FocusZone extends BaseComponent implements IFo } } - private _setActiveElement(element: HTMLElement): void { + private _setActiveElement(element: HTMLElement, forceAlignemnt?: boolean): void { const previousActiveElement = this._activeElement; this._activeElement = element; @@ -283,7 +283,7 @@ export class FocusZone extends BaseComponent implements IFo } if (this._activeElement) { - if (!this._focusAlignment) { + if (!this._focusAlignment || forceAlignemnt) { this._setFocusAlignment(element, true, true); }