From 09873d8450e8fab122f44f9710e14cfa46abebd9 Mon Sep 17 00:00:00 2001 From: Jon Schectman Date: Wed, 14 Mar 2018 18:47:06 -0700 Subject: [PATCH 1/6] Revert "FocusTrapZone does not correctly trap focus when last child is FocusZone (#4172)" This reverts commit 699fa697ae829e756108ce2b6725084d27e93f7e. --- .../FocusTrapZone/FocusTrapZone.test.tsx | 71 ------------------- packages/utilities/src/focus.ts | 17 +++-- 2 files changed, 8 insertions(+), 80 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 9599f02be4c3d..d23d8fc60e7e1 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 @@ -239,75 +239,4 @@ describe('FocusTrapZone', () => { ReactTestUtils.Simulate.keyDown(buttonA, { which: KeyCodes.tab }); expect(lastFocusedElement).toBe(buttonX); }); - - it('can tab across FocusZones with different button structures', () => { - const component = ReactTestUtils.renderIntoDocument( -
- - - - - - - - -
- ); - - const focusTrapZone = ReactDOM.findDOMNode(component as React.ReactInstance) as Element; - - const buttonA = focusTrapZone.querySelector('.a') as HTMLElement; - const buttonD = focusTrapZone.querySelector('.d') as HTMLElement; - const buttonE = focusTrapZone.querySelector('.e') as HTMLElement; - const buttonF = focusTrapZone.querySelector('.f') as HTMLElement; - - // Assign bounding locations to buttons. - setupElement(buttonA, { - clientRect: { - top: 0, - bottom: 30, - left: 0, - right: 30 - } - }); - - setupElement(buttonD, { - clientRect: { - top: 30, - bottom: 60, - left: 0, - right: 30 - } - }); - - setupElement(buttonE, { - clientRect: { - top: 30, - bottom: 60, - left: 30, - right: 60 - } - }); - - setupElement(buttonF, { - clientRect: { - top: 30, - bottom: 60, - left: 60, - right: 90 - } - }); - - // Focus the first button. - ReactTestUtils.Simulate.focus(buttonD); - expect(lastFocusedElement).toBe(buttonD); - - // Pressing tab should go to a. - ReactTestUtils.Simulate.keyDown(buttonD, { which: KeyCodes.tab }); - expect(lastFocusedElement).toBe(buttonA); - - // Pressing shift + tab should go to a. - ReactTestUtils.Simulate.keyDown(buttonA, { which: KeyCodes.tab, shiftKey: true }); - expect(lastFocusedElement).toBe(buttonD); - }); }); diff --git a/packages/utilities/src/focus.ts b/packages/utilities/src/focus.ts index e3f47ce9bd641..c2dc853c6932c 100644 --- a/packages/utilities/src/focus.ts +++ b/packages/utilities/src/focus.ts @@ -77,7 +77,7 @@ export function getPreviousElement( traverseChildren?: boolean, includeElementsInFocusZones?: boolean, allowFocusRoot?: boolean, - elementShouldBeTabbable?: boolean): HTMLElement | null { + tabbable?: boolean): HTMLElement | null { if (!currentElement || (!allowFocusRoot && currentElement === rootElement)) { @@ -97,10 +97,10 @@ export function getPreviousElement( true, includeElementsInFocusZones, allowFocusRoot, - elementShouldBeTabbable); + tabbable); if (childMatch) { - if ((elementShouldBeTabbable && isElementTabbable(childMatch, true)) || !elementShouldBeTabbable) { + if ((tabbable && (isElementTabbable(childMatch, true))) || !tabbable) { return childMatch; } @@ -112,7 +112,7 @@ export function getPreviousElement( true, includeElementsInFocusZones, allowFocusRoot, - elementShouldBeTabbable + tabbable ); if (childMatchSiblingMatch) { return childMatchSiblingMatch; @@ -133,7 +133,7 @@ export function getPreviousElement( true, includeElementsInFocusZones, allowFocusRoot, - elementShouldBeTabbable + tabbable ); if (childMatchParentMatch) { @@ -146,8 +146,7 @@ export function getPreviousElement( } // Check the current node, if it's not the first traversal. - if (checkNode && isCurrentElementVisible && - ((elementShouldBeTabbable && isElementTabbable(currentElement, true)) || !elementShouldBeTabbable)) { + if (checkNode && isCurrentElementVisible && isElementTabbable(currentElement)) { return currentElement; } @@ -160,7 +159,7 @@ export function getPreviousElement( true, includeElementsInFocusZones, allowFocusRoot, - elementShouldBeTabbable); + tabbable); if (siblingMatch) { return siblingMatch; @@ -169,7 +168,7 @@ export function getPreviousElement( // Check its parent. if (!suppressParentTraversal) { return getPreviousElement(rootElement, currentElement.parentElement, true, false, false, includeElementsInFocusZones, - allowFocusRoot, elementShouldBeTabbable); + allowFocusRoot, tabbable); } return null; From 0a4f039c4c6cbe01f02066321cbbc18cbb107c12 Mon Sep 17 00:00:00 2001 From: Jon Schectman Date: Mon, 16 Apr 2018 11:51:38 -0700 Subject: [PATCH 2/6] minor picker fixes --- .../src/components/Autofill/Autofill.tsx | 2 +- .../src/components/Autofill/Autofill.types.ts | 5 ++++- .../src/components/pickers/BasePicker.tsx | 9 ++++++--- .../src/components/pickers/BasePicker.types.ts | 9 ++++++++- .../PeoplePicker/examples/PeoplePicker.Types.Example.tsx | 6 ++++-- .../pickers/Suggestions/SuggestionsController.ts | 2 +- 6 files changed, 24 insertions(+), 9 deletions(-) diff --git a/packages/office-ui-fabric-react/src/components/Autofill/Autofill.tsx b/packages/office-ui-fabric-react/src/components/Autofill/Autofill.tsx index 61a9fc90f66ad..dff3c7978eed6 100644 --- a/packages/office-ui-fabric-react/src/components/Autofill/Autofill.tsx +++ b/packages/office-ui-fabric-react/src/components/Autofill/Autofill.tsx @@ -27,7 +27,7 @@ export class Autofill extends BaseComponent impl constructor(props: IAutofillProps) { super(props); - this._value = ''; + this._value = props.defaultVisibleValue || ''; this.state = { displayValue: props.defaultVisibleValue || '' }; diff --git a/packages/office-ui-fabric-react/src/components/Autofill/Autofill.types.ts b/packages/office-ui-fabric-react/src/components/Autofill/Autofill.types.ts index 2d971d8d4f943..e288850bb2a3b 100644 --- a/packages/office-ui-fabric-react/src/components/Autofill/Autofill.types.ts +++ b/packages/office-ui-fabric-react/src/components/Autofill/Autofill.types.ts @@ -67,7 +67,10 @@ export interface IAutofillProps extends enableAutofillOnKeyPress?: KeyCodes[]; /** - * the default value to be visible + * The default value to be visible. This is different from placeholder + * because it actually sets the current value of the picker + * Note: This will only be set upon component creation + * and will not update with subsequent prop updates. */ defaultVisibleValue?: string; diff --git a/packages/office-ui-fabric-react/src/components/pickers/BasePicker.tsx b/packages/office-ui-fabric-react/src/components/pickers/BasePicker.tsx index 271599cfc9c4e..f15a39620cdd5 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/BasePicker.tsx +++ b/packages/office-ui-fabric-react/src/components/pickers/BasePicker.tsx @@ -444,11 +444,14 @@ export class BasePicker> extends BaseComponent< } protected onInputBlur = (ev: React.FocusEvent): void => { - // Only blur if an unrelated element gets focus. Otherwise treat it as though it still has focus. + if (this.props.inputProps && this.props.inputProps.onBlur) { + this.props.inputProps.onBlur(ev as React.FocusEvent); + } + // Only blur the entire component if an unrelated element gets focus. Otherwise treat it as though it still has focus. if (!elementContains(this.root.value!, ev.relatedTarget as HTMLElement)) { this.setState({ isFocused: false }); - if (this.props.inputProps && this.props.inputProps.onBlur) { - this.props.inputProps.onBlur(ev as React.FocusEvent); + if (this.props.onBlur) { + this.props.onBlur(ev as React.FocusEvent); } } } diff --git a/packages/office-ui-fabric-react/src/components/pickers/BasePicker.types.ts b/packages/office-ui-fabric-react/src/components/pickers/BasePicker.types.ts index 5c5d3439a901a..81e351cb9170c 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/BasePicker.types.ts +++ b/packages/office-ui-fabric-react/src/components/pickers/BasePicker.types.ts @@ -112,7 +112,7 @@ export interface IBasePickerProps extends React.Props { /** * Function that specifies how arbitrary text entered into the well is handled. */ - createGenericItem?: (input: string, ValidationState: ValidationState) => ISuggestionModel; + createGenericItem?: (input: string, ValidationState: ValidationState) => ISuggestionModel | T; /** * Aria label for the "X" button in the selected item component. * @default '' @@ -219,4 +219,11 @@ export interface IInputProps extends React.InputHTMLAttributes * Screen reader label to apply to an input element. */ 'aria-label'?: string; + /** + * The default value to be visible when the autofill first created. + * This is different than placeholder text because the palceholder text will disappear. This + * text persists until deleted or changed. + */ + defaultVisibleValue?: string; + } \ No newline at end of file diff --git a/packages/office-ui-fabric-react/src/components/pickers/PeoplePicker/examples/PeoplePicker.Types.Example.tsx b/packages/office-ui-fabric-react/src/components/pickers/PeoplePicker/examples/PeoplePicker.Types.Example.tsx index 67b7a34a4754b..475ca1a19f0a8 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/PeoplePicker/examples/PeoplePicker.Types.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/pickers/PeoplePicker/examples/PeoplePicker.Types.Example.tsx @@ -147,7 +147,8 @@ export class PeoplePickerTypesExample extends BaseComponent) => console.log('onBlur called'), onFocus: (ev: React.FocusEvent) => console.log('onFocus called'), - 'aria-label': 'People Picker' + 'aria-label': 'People Picker', + defaultValue: "wooged" } } componentRef={ this._resolveRef('_picker') } resolveDelay={ 300 } @@ -170,7 +171,8 @@ export class PeoplePickerTypesExample extends BaseComponent) => console.log('onBlur called'), onFocus: (ev: React.FocusEvent) => console.log('onFocus called'), - 'aria-label': 'People Picker' + 'aria-label': 'People Picker', + defaultVisibleValue: 'an' } } componentRef={ this._resolveRef('_picker') } onInputChange={ this._onInputChange } diff --git a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/SuggestionsController.ts b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/SuggestionsController.ts index 140543d2b997a..a489bb771f37e 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/SuggestionsController.ts +++ b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/SuggestionsController.ts @@ -83,7 +83,7 @@ export class SuggestionsController { this.suggestions.splice(index, 1); } - public createGenericSuggestion(itemToConvert: ISuggestionModel) { + public createGenericSuggestion(itemToConvert: ISuggestionModel | T) { const itemToAdd = this.convertSuggestionsToSuggestionItems([itemToConvert])[0]; this.currentSuggestion = itemToAdd; } From 2aeac1ce9e4e6e8e7ecb136fe73b8ec9a8951eda Mon Sep 17 00:00:00 2001 From: Jon Schectman Date: Mon, 16 Apr 2018 11:52:28 -0700 Subject: [PATCH 3/6] adding change file --- .../minorpicker-fixes_2018-04-16-18-52.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/office-ui-fabric-react/minorpicker-fixes_2018-04-16-18-52.json diff --git a/common/changes/office-ui-fabric-react/minorpicker-fixes_2018-04-16-18-52.json b/common/changes/office-ui-fabric-react/minorpicker-fixes_2018-04-16-18-52.json new file mode 100644 index 0000000000000..6de2d06c45968 --- /dev/null +++ b/common/changes/office-ui-fabric-react/minorpicker-fixes_2018-04-16-18-52.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "office-ui-fabric-react", + "comment": "Pickers: Several fixes regarding certain props", + "type": "minor" + } + ], + "packageName": "office-ui-fabric-react", + "email": "joschect@microsoft.com" +} \ No newline at end of file From 3474c569cbcda71096ceee2f9fd083b0b50447e9 Mon Sep 17 00:00:00 2001 From: Jon Schectman Date: Mon, 16 Apr 2018 14:20:40 -0700 Subject: [PATCH 4/6] Undo change to examples --- .../PeoplePicker/examples/PeoplePicker.Types.Example.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/office-ui-fabric-react/src/components/pickers/PeoplePicker/examples/PeoplePicker.Types.Example.tsx b/packages/office-ui-fabric-react/src/components/pickers/PeoplePicker/examples/PeoplePicker.Types.Example.tsx index 475ca1a19f0a8..67b7a34a4754b 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/PeoplePicker/examples/PeoplePicker.Types.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/pickers/PeoplePicker/examples/PeoplePicker.Types.Example.tsx @@ -147,8 +147,7 @@ export class PeoplePickerTypesExample extends BaseComponent) => console.log('onBlur called'), onFocus: (ev: React.FocusEvent) => console.log('onFocus called'), - 'aria-label': 'People Picker', - defaultValue: "wooged" + 'aria-label': 'People Picker' } } componentRef={ this._resolveRef('_picker') } resolveDelay={ 300 } @@ -171,8 +170,7 @@ export class PeoplePickerTypesExample extends BaseComponent) => console.log('onBlur called'), onFocus: (ev: React.FocusEvent) => console.log('onFocus called'), - 'aria-label': 'People Picker', - defaultVisibleValue: 'an' + 'aria-label': 'People Picker' } } componentRef={ this._resolveRef('_picker') } onInputChange={ this._onInputChange } From 6d280418a2a2c61b4afd4c4dc49c3542cc429e43 Mon Sep 17 00:00:00 2001 From: Jon Schectman Date: Mon, 16 Apr 2018 16:45:59 -0700 Subject: [PATCH 5/6] Fix typo --- .../src/components/pickers/BasePicker.types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/office-ui-fabric-react/src/components/pickers/BasePicker.types.ts b/packages/office-ui-fabric-react/src/components/pickers/BasePicker.types.ts index 81e351cb9170c..bd30168ae581c 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/BasePicker.types.ts +++ b/packages/office-ui-fabric-react/src/components/pickers/BasePicker.types.ts @@ -221,9 +221,9 @@ export interface IInputProps extends React.InputHTMLAttributes 'aria-label'?: string; /** * The default value to be visible when the autofill first created. - * This is different than placeholder text because the palceholder text will disappear. This + * This is different than placeholder text because the placeholder text will disappear and re-appear. This * text persists until deleted or changed. */ defaultVisibleValue?: string; -} \ No newline at end of file +} From 6ed257332c740236c1a7d7df00a66201b8309382 Mon Sep 17 00:00:00 2001 From: Jon Schectman Date: Tue, 17 Apr 2018 14:40:09 -0700 Subject: [PATCH 6/6] remove space --- .../src/components/Autofill/Autofill.types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/office-ui-fabric-react/src/components/Autofill/Autofill.types.ts b/packages/office-ui-fabric-react/src/components/Autofill/Autofill.types.ts index e288850bb2a3b..aa48c349e09f4 100644 --- a/packages/office-ui-fabric-react/src/components/Autofill/Autofill.types.ts +++ b/packages/office-ui-fabric-react/src/components/Autofill/Autofill.types.ts @@ -76,7 +76,7 @@ export interface IAutofillProps extends /** * Handler for checking and updating the value if needed - * in componentWillReceiveProps + * in componentWillReceiveProps * * @param {IAutofillProps} defaultVisibleValue - the defaultVisibleValue that got passed * in to the auto fill's componentWillReceiveProps