diff --git a/common/changes/office-ui-fabric-react/sayali-arrowFocusFix_2018-03-15-21-28.json b/common/changes/office-ui-fabric-react/sayali-arrowFocusFix_2018-03-15-21-28.json new file mode 100644 index 0000000000000..fb4834655a5ff --- /dev/null +++ b/common/changes/office-ui-fabric-react/sayali-arrowFocusFix_2018-03-15-21-28.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "office-ui-fabric-react", + "comment": "Add shouldInputLoseFocusOnArrowKey callback for scenario to determine if input should loose focus when arrow key is present when Tabbing is enabled on All elements or Input elements", + "type": "patch" + } + ], + "packageName": "office-ui-fabric-react", + "email": "sayalis@microsoft.com" +} \ No newline at end of file diff --git a/common/changes/office-ui-fabric-react/sayali-arrowFocusFix_2018-03-16-22-02.json b/common/changes/office-ui-fabric-react/sayali-arrowFocusFix_2018-03-16-22-02.json new file mode 100644 index 0000000000000..dc4d3300975b9 --- /dev/null +++ b/common/changes/office-ui-fabric-react/sayali-arrowFocusFix_2018-03-16-22-02.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "office-ui-fabric-react", + "comment": "FocusZone: adding `shouldInputLoseFocusOnArrowKey` optional callback for scenarios where user press an arrow key on an input element and want it to loose focus when FocusZone disables moving focus away in case when FocusZoneTabbableElements is set to All or none", + "type": "patch" + } + ], + "packageName": "office-ui-fabric-react", + "email": "sayalis@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 9ba0a6cc8551e..d5972db64ea2c 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 @@ -1259,4 +1259,49 @@ describe('FocusZone', () => { expect(inputA.tabIndex).toBe(-1); expect(buttonB.tabIndex).toBe(0); }); -}); + + it('focus should leave input box when arrow keys are pressed when tabbing is supported but shouldInputLoseFocusOnArrowKey callback method return true', () => { + const tabDownListener = jest.fn(); + const component = ReactTestUtils.renderIntoDocument( +
+ { return true; } } }> + + + +
+ ); + + const focusZone = ReactDOM.findDOMNode(component as React.ReactInstance).firstChild as Element; + + const inputA = focusZone.querySelector('.a') as HTMLElement; + const buttonB = focusZone.querySelector('.b') as HTMLElement; + + setupElement(inputA, { + clientRect: { + top: 0, + bottom: 20, + left: 20, + right: 40 + } + }); + + setupElement(buttonB, { + clientRect: { + top: 0, + bottom: 20, + left: 20, + right: 40 + } + }); + + // InputA should be focused. + inputA.focus(); + expect(lastFocusedElement).toBe(inputA); + + // Pressing arrow down, input should loose the focus and the button should get the focus + ReactTestUtils.Simulate.keyDown(focusZone, { which: KeyCodes.down }); + expect(lastFocusedElement).toBe(buttonB); + expect(inputA.tabIndex).toBe(-1); + expect(buttonB.tabIndex).toBe(0); + }); +}); \ No newline at end of file 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 58ac0603cead9..a39a4707ecac6 100644 --- a/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.tsx @@ -804,12 +804,17 @@ export class FocusZone extends BaseComponent implements IFo // We shouldn't lose focus in the following cases: // 1. There is range selected. // 2. When selection start is larger than 0 and it is backward. - // 3. when selection start is not the end of lenght and it is forward. + // 3. when selection start is not the end of length and it is forward. // 4. We press any of the arrow keys when our handleTabKey isn't none or undefined (only losing focus if we hit tab) - if (isRangeSelected || + // and if shouldInputLoseFocusOnArrowKey is defined, if scenario prefers to not loose the focus which is determined by calling the + // callback shouldInputLoseFocusOnArrowKey + if ( + isRangeSelected || (selectionStart > 0 && !isForward) || (selectionStart !== inputValue.length && isForward) || - !!this.props.handleTabKey) { + (!!this.props.handleTabKey && !(this.props.shouldInputLoseFocusOnArrowKey + && this.props.shouldInputLoseFocusOnArrowKey(element))) + ) { return false; } } diff --git a/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.types.ts b/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.types.ts index ffd003fc2a46c..234842b5d71f1 100644 --- a/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.types.ts +++ b/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.types.ts @@ -120,6 +120,13 @@ export interface IFocusZoneProps extends React.HTMLAttributes boolean; + /** * Whether the to check for data-no-horizontal-wrap or data-no-vertical-wrap attributes * when determining how to move focus diff --git a/scripts/package.json b/scripts/package.json index 2f249ee3e8b65..3f826323130d7 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -49,7 +49,7 @@ "bundlesize": [ { "path": "../apps/test-bundle-button/dist/main.min.js", - "maxSize": "45.0 kB" + "maxSize": "45.5 kB" } ] -} +} \ No newline at end of file