From 2c1738ad810353f5e69e86383610098937323976 Mon Sep 17 00:00:00 2001 From: Amy Nguyen Date: Thu, 8 Feb 2018 13:26:08 -0800 Subject: [PATCH 1/9] add use current input command to suggestions --- .../src/components/pickers/BasePicker.tsx | 21 ++- .../components/pickers/BasePicker.types.ts | 4 + .../pickers/Suggestions/Suggestions.scss | 6 +- .../pickers/Suggestions/Suggestions.tsx | 148 +++++++++++++++++- .../pickers/Suggestions/Suggestions.types.ts | 12 ++ .../Suggestions/SuggestionsController.ts | 6 +- 6 files changed, 178 insertions(+), 19 deletions(-) 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 b5473a54698110..822455d21e6bbf 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/BasePicker.tsx +++ b/packages/office-ui-fabric-react/src/components/pickers/BasePicker.tsx @@ -155,10 +155,12 @@ export class BasePicker> extends BaseComponent< @autobind public refocusSuggestions(keyCode: KeyCodes) { this.resetFocus(); - if (keyCode === KeyCodes.up) { - this.suggestionStore.setSelectedSuggestion(this.suggestionStore.suggestions.length - 1); - } else if (keyCode === KeyCodes.down) { - this.suggestionStore.setSelectedSuggestion(0); + if (this.suggestionStore.suggestions && this.suggestionStore.suggestions.length > 0) { + if (keyCode === KeyCodes.up) { + this.suggestionStore.setSelectedSuggestion(this.suggestionStore.suggestions.length - 1); + } else if (keyCode === KeyCodes.down) { + this.suggestionStore.setSelectedSuggestion(0); + } } } @@ -443,7 +445,8 @@ export class BasePicker> extends BaseComponent< @autobind protected onKeyDown(ev: React.KeyboardEvent) { - switch (ev.which) { + let keyCode = ev.which; + switch (keyCode) { case KeyCodes.escape: if (this.state.suggestionsVisible) { this.setState({ suggestionsVisible: false }); @@ -454,7 +457,9 @@ export class BasePicker> extends BaseComponent< case KeyCodes.tab: case KeyCodes.enter: - if (!ev.shiftKey && this.suggestionStore.hasSelectedSuggestion() && this.state.suggestionsVisible) { + if (this.suggestionElement.hasSuggestedActionSelected()) { + this.suggestionElement.executeSelectedAction(); + } else if (!ev.shiftKey && this.suggestionStore.hasSelectedSuggestion() && this.state.suggestionsVisible) { this.completeSuggestion(); ev.preventDefault(); ev.stopPropagation(); @@ -487,7 +492,7 @@ export class BasePicker> extends BaseComponent< break; case KeyCodes.up: - if (ev.target === this.input.inputElement && this.state.suggestionsVisible) { + if (ev.target === this.input.inputElement && this.state.suggestionsVisible && !this.suggestionElement.tryHandleKeyDown(keyCode)) { if (this.state.moreSuggestionsAvailable && this.suggestionElement.props.searchForMoreText && this.suggestionStore.currentIndex === 0) { this.suggestionElement.focusSearchForMoreButton(); this.suggestionStore.deselectAllSuggestions(); @@ -503,7 +508,7 @@ export class BasePicker> extends BaseComponent< break; case KeyCodes.down: - if (ev.target === this.input.inputElement && this.state.suggestionsVisible) { + if (ev.target === this.input.inputElement && this.state.suggestionsVisible && !this.suggestionElement.tryHandleKeyDown(keyCode)) { if (this.state.moreSuggestionsAvailable && this.suggestionElement.props.searchForMoreText && (this.suggestionStore.currentIndex + 1) === this.suggestionStore.suggestions.length) { this.suggestionElement.focusSearchForMoreButton(); this.suggestionStore.deselectAllSuggestions(); 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 4e15c252db4ca1..07fb3dcab7e8eb 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 @@ -162,6 +162,10 @@ export interface IBasePickerSuggestionsProps { * The text that should appear on the button to search for more. */ searchForMoreText?: string; + /** + * The text that appears indicated to the user that they can use the inputed text as an item + */ + useInputText?: string; /** * The text to display while the results are loading. */ diff --git a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.scss b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.scss index 350d4ca0aa8121..c8a4d6fe6eb526 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.scss +++ b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.scss @@ -61,7 +61,7 @@ } } -.searchMoreButton { +.actionButton { background: none; border: 0; cursor: pointer; @@ -93,6 +93,10 @@ } } +.buttonSelected { + background-color: $ms-color-themeLight; +} + .suggestionsTitle { padding: 0 12px; color: $ms-color-themePrimary; diff --git a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx index cf07bd537d4df3..9ebd00d051b465 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx +++ b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx @@ -11,6 +11,16 @@ import { ISuggestionItemProps, ISuggestionsProps } from './Suggestions.types'; import * as stylesImport from './Suggestions.scss'; const styles: any = stylesImport; +export enum SuggestionActionType { + none, + useInputText, + searchMore, +} + +export interface ISuggestionsState { + selectedActionType: SuggestionActionType; +} + export class SuggestionsItem extends BaseComponent, {}> { public render() { let { @@ -51,14 +61,18 @@ export class SuggestionsItem extends BaseComponent, { } } -export class Suggestions extends BaseComponent, {}> { +export class Suggestions extends BaseComponent, ISuggestionsState> { + protected _useInputButton: IButton; protected _searchForMoreButton: IButton; protected _selectedElement: HTMLDivElement; private SuggestionsItemOfProperType = SuggestionsItem as new (props: ISuggestionItemProps) => SuggestionsItem; constructor(suggestionsProps: ISuggestionsProps) { super(suggestionsProps); + this.state = { + selectedActionType: SuggestionActionType.none, + }; } public componentDidUpdate() { @@ -67,6 +81,9 @@ export class Suggestions extends BaseComponent, {}> { public render() { let { + useInputText, + createGenericItem, + isTextValid, mostRecentlyUsedHeaderText, searchForMoreText, className, @@ -83,7 +100,7 @@ export class Suggestions extends BaseComponent, {}> { resultsFooterFull, resultsFooter, suggestionsAvailableAlertText, - suggestionsHeaderText + suggestionsHeaderText, } = this.props; let noResults = () => { @@ -100,6 +117,7 @@ export class Suggestions extends BaseComponent, {}> { headerText = mostRecentlyUsedHeaderText; } let footerTitle = (suggestions.length >= (resultsMaximumNumber as number)) ? resultsFooterFull : resultsFooter; + let hasNoSuggestions = (!suggestions || !suggestions.length) && !isLoading; return (
extends BaseComponent, {}> { className={ css('ms-Suggestions-spinner', styles.suggestionsSpinner) } label={ loadingText } />) } - { (!suggestions || !suggestions.length) && !isLoading ? + { hasNoSuggestions ? (onRenderNoResultFound ? onRenderNoResultFound(undefined, noResults) : noResults()) : this._renderSuggestions() } + { useInputText && !moreSuggestionsAvailable && hasNoSuggestions && this._isTextValid() && ( + + { useInputText } + + ) } { searchForMoreText && moreSuggestionsAvailable && ( { searchForMoreText } @@ -155,6 +192,89 @@ export class Suggestions extends BaseComponent, {}> { ); } + @autobind + public tryHandleKeyDown(keyCode: number): boolean { + let isEventHandled = false; + let newSelectedActionType = null; + let currentSelectedAction = this.state.selectedActionType; + if (currentSelectedAction !== SuggestionActionType.none) { + if (keyCode === KeyCodes.down) { + switch (currentSelectedAction) { + case SuggestionActionType.useInputText: + if (this._searchForMoreButton) { + newSelectedActionType = SuggestionActionType.searchMore; + } else { + this._refocusOnSuggestions(keyCode); + newSelectedActionType = SuggestionActionType.none; + } + break; + case SuggestionActionType.searchMore: + this._refocusOnSuggestions(keyCode); + newSelectedActionType = SuggestionActionType.none; + break; + } + } else if (keyCode === KeyCodes.up) { + switch (currentSelectedAction) { + case SuggestionActionType.useInputText: + this._refocusOnSuggestions(keyCode); + newSelectedActionType = SuggestionActionType.none; + break; + case SuggestionActionType.searchMore: + if (this._useInputButton) { + newSelectedActionType = SuggestionActionType.useInputText; + } else { + this._refocusOnSuggestions(keyCode); + newSelectedActionType = SuggestionActionType.none; + } + break; + } + } + + if (newSelectedActionType !== null) { + this.setState({ selectedActionType: newSelectedActionType }); + isEventHandled = true; + } + } + + return isEventHandled; + } + + public hasSuggestedAction(): boolean { + return this._searchForMoreButton !== null || this._useInputButton !== null; + } + + public hasSuggestedActionSelected(): boolean { + return (this.state.selectedActionType !== SuggestionActionType.none); + } + + public executeSelectedAction(): void { + switch (this.state.selectedActionType) { + case SuggestionActionType.useInputText: + this._useInput(); + break; + case SuggestionActionType.searchMore: + this._getMoreResults(); + break; + } + } + + public focusAboveSuggestions(): void { + let newSelectedActionType = null; + if (this._searchForMoreButton) { + this.setState({ selectedActionType: SuggestionActionType.searchMore }); + } else if (this._useInputButton) { + this.setState({ selectedActionType: SuggestionActionType.useInputText }); + } + } + + public focusBelowSuggestions(): void { + if (this._useInputButton) { + this.setState({ selectedActionType: SuggestionActionType.useInputText }); + } else if (this._searchForMoreButton) { + this.setState({ selectedActionType: SuggestionActionType.searchMore }); + } + } + public focusSearchForMoreButton() { if (this._searchForMoreButton) { this._searchForMoreButton.focus(); @@ -218,6 +338,18 @@ export class Suggestions extends BaseComponent, {}> { } } + @autobind + private _useInput() { + if (this.props.createGenericItem) { + this.props.createGenericItem(); + } + } + + @autobind + private _isTextValid() { + return this.props.isTextValid ? this.props.isTextValid() : false; + } + @autobind private _onClickTypedSuggestionsItem(item: T, index: number): (ev: React.MouseEvent) => void { return (ev: React.MouseEvent): void => { @@ -226,9 +358,9 @@ export class Suggestions extends BaseComponent, {}> { } @autobind - private _onKeyDown(ev: React.KeyboardEvent) { - if ((ev.keyCode === KeyCodes.up || ev.keyCode === KeyCodes.down) && typeof this.props.refocusSuggestions === 'function') { - this.props.refocusSuggestions(ev.keyCode); + private _refocusOnSuggestions(keyCode: number): void { + if (typeof this.props.refocusSuggestions === 'function') { + this.props.refocusSuggestions(keyCode); } } diff --git a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.types.ts b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.types.ts index 7874e3626641d4..5d97d250e071e2 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.types.ts +++ b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.types.ts @@ -41,6 +41,18 @@ export interface ISuggestionsProps extends React.Props { * The callback that should be called when the user attempts to get more results */ onGetMoreResults?: () => void; + /** + * The text that appears indicated to the user that they can use the input text as an item + */ + useInputText?: string; + /** + * The callback that should be called to see if the input text is valid + */ + isTextValid?: () => boolean; + /** + * The callback that should be called when the user attempts to use the input text as as item + */ + createGenericItem?: () => void; /** * The CSS classname of the suggestions list. */ 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 d35720a8a6c712..14b30cd849f8d8 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 @@ -97,8 +97,10 @@ export class SuggestionsController { } public deselectAllSuggestions(): void { - this.suggestions[this.currentIndex].selected = false; - this.currentIndex = -1; + if (this.currentIndex > -1) { + this.suggestions[this.currentIndex].selected = false; + this.currentIndex = -1; + } } public setSelectedSuggestion(index: number): void { From 6d1c676bce62ed84feca2bce82800876864b2344 Mon Sep 17 00:00:00 2001 From: Amy Nguyen Date: Thu, 8 Feb 2018 13:26:45 -0800 Subject: [PATCH 2/9] update experiments to use new stuff in suggestions --- .../ExtendedPeoplePicker.Basic.Example.tsx | 1 + .../FloatingPicker/BaseFloatingPicker.tsx | 84 ++++++++++++------- .../BaseFloatingPicker.types.ts | 2 +- 3 files changed, 55 insertions(+), 32 deletions(-) diff --git a/packages/experiments/src/components/ExtendedPicker/examples/ExtendedPeoplePicker.Basic.Example.tsx b/packages/experiments/src/components/ExtendedPicker/examples/ExtendedPeoplePicker.Basic.Example.tsx index f7e13e84bba915..1b42e3a93dad12 100644 --- a/packages/experiments/src/components/ExtendedPicker/examples/ExtendedPeoplePicker.Basic.Example.tsx +++ b/packages/experiments/src/components/ExtendedPicker/examples/ExtendedPeoplePicker.Basic.Example.tsx @@ -31,6 +31,7 @@ const suggestionProps: IBasePickerSuggestionsProps = { suggestionsAvailableAlertText: 'People Picker Suggestions available', suggestionsContainerAriaLabel: 'Suggested contacts', searchForMoreText: 'Search more', + useInputText: 'Use this name', }; // tslint:disable-next-line:no-any diff --git a/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.tsx b/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.tsx index a7da08048a00ac..3bdfe35a0a890d 100644 --- a/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.tsx +++ b/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.tsx @@ -129,12 +129,14 @@ export class BaseFloatingPicker> extend @autobind public refocusSuggestions(keyCode: KeyCodes): void { - if (keyCode === KeyCodes.up) { - this.suggestionStore.setSelectedSuggestion( - this.suggestionStore.suggestions.length - 1 - ); - } else if (keyCode === KeyCodes.down) { - this.suggestionStore.setSelectedSuggestion(0); + if (this.suggestionStore.suggestions && this.suggestionStore.suggestions.length > 0) { + if (keyCode === KeyCodes.up) { + this.suggestionStore.setSelectedSuggestion( + this.suggestionStore.suggestions.length - 1 + ); + } else if (keyCode === KeyCodes.down) { + this.suggestionStore.setSelectedSuggestion(0); + } } } @@ -169,6 +171,8 @@ export class BaseFloatingPicker> extend calloutWidth={ this.props.calloutWidth ? this.props.calloutWidth : 0 } > > extend !(this.props.inputElement as HTMLElement).contains(ev.target as HTMLElement))) { return; } - switch (ev.which) { + let keyCode = ev.which; + switch (keyCode) { case KeyCodes.escape: this.setState({ suggestionsVisible: false }); ev.preventDefault(); @@ -350,8 +355,9 @@ export class BaseFloatingPicker> extend case KeyCodes.tab: case KeyCodes.enter: - if ( - !ev.shiftKey && + if (this.suggestionElement.hasSuggestedActionSelected()) { + this.suggestionElement.executeSelectedAction(); + } else if (!ev.shiftKey && !ev.ctrlKey && this.suggestionStore.hasSelectedSuggestion()) { this.completeSuggestion(); @@ -378,38 +384,49 @@ export class BaseFloatingPicker> extend break; case KeyCodes.up: - if ( - this.state.moreSuggestionsAvailable && - this.suggestionElement.props.searchForMoreText && - this.suggestionStore.currentIndex === 0 - ) { - this.suggestionElement.focusSearchForMoreButton(); - this.suggestionStore.deselectAllSuggestions(); - this.forceUpdate(); + if (this.suggestionElement.tryHandleKeyDown(keyCode)) { + ev.preventDefault(); + ev.stopPropagation(); } else { - if (this.suggestionStore.previousSuggestion()) { + if (this.suggestionElement.hasSuggestedAction() && + this.suggestionStore.currentIndex === 0 + ) { ev.preventDefault(); ev.stopPropagation(); - this.onSuggestionSelect(); + this.suggestionElement.focusAboveSuggestions(); + this.suggestionStore.deselectAllSuggestions(); + this.forceUpdate(); + } else { + if (this.suggestionStore.previousSuggestion()) { + ev.preventDefault(); + ev.stopPropagation(); + this.onSuggestionSelect(); + } } } break; case KeyCodes.down: - if ( - this.state.moreSuggestionsAvailable && - this.suggestionElement.props.searchForMoreText && - this.suggestionStore.currentIndex + 1 === - this.suggestionStore.suggestions.length - ) { - this.suggestionElement.focusSearchForMoreButton(); - this.suggestionStore.deselectAllSuggestions(); - this.forceUpdate(); + if (this.suggestionElement.tryHandleKeyDown(keyCode)) { + ev.preventDefault(); + ev.stopPropagation(); } else { - if (this.suggestionStore.nextSuggestion()) { + if ( + this.suggestionElement.hasSuggestedAction() && + this.suggestionStore.currentIndex + 1 === + this.suggestionStore.suggestions.length + ) { ev.preventDefault(); ev.stopPropagation(); - this.onSuggestionSelect(); + this.suggestionElement.focusBelowSuggestions(); + this.suggestionStore.deselectAllSuggestions(); + this.forceUpdate(); + } else { + if (this.suggestionStore.nextSuggestion()) { + ev.preventDefault(); + ev.stopPropagation(); + this.onSuggestionSelect(); + } } } break; @@ -463,10 +480,10 @@ export class BaseFloatingPicker> extend this.updateSuggestionsList(suggestions, updatedValue); } + @autobind private _onValidateInput(): void { if ( this.props.onValidateInput && - (this.props.onValidateInput as ((input: string) => boolean))(this.state.queryString) !== true && this.props.createGenericItem ) { let itemToConvert = (this.props.createGenericItem as (( @@ -481,6 +498,11 @@ export class BaseFloatingPicker> extend } } + @autobind + private _tryValidateInput(): boolean { + return this.props.onValidateInput ? this.props.onValidateInput(this.state.queryString) : false; + } + private _getTextFromItem(item: T, currentValue?: string): string { if (this.props.getTextFromItem) { return (this.props.getTextFromItem as ((item: T, currentValue?: string) => string))(item, currentValue); diff --git a/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.types.ts b/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.types.ts index 88669257e1275e..920dbe0892d613 100644 --- a/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.types.ts +++ b/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.types.ts @@ -113,4 +113,4 @@ export interface IBaseFloatingPickerProps extends React.Props { * Width for the suggestions callout */ calloutWidth?: number; -} +} \ No newline at end of file From af72cc3962d85c82ae92b308c1523b8935959c6d Mon Sep 17 00:00:00 2001 From: Amy Nguyen Date: Thu, 8 Feb 2018 13:29:09 -0800 Subject: [PATCH 3/9] run gulp change --- .../amyngu-newSuggestions_2018-02-08-21-28.json | 11 +++++++++++ .../amyngu-newSuggestions_2018-02-08-21-28.json | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 common/changes/@uifabric/experiments/amyngu-newSuggestions_2018-02-08-21-28.json create mode 100644 common/changes/office-ui-fabric-react/amyngu-newSuggestions_2018-02-08-21-28.json diff --git a/common/changes/@uifabric/experiments/amyngu-newSuggestions_2018-02-08-21-28.json b/common/changes/@uifabric/experiments/amyngu-newSuggestions_2018-02-08-21-28.json new file mode 100644 index 00000000000000..3241f919c49463 --- /dev/null +++ b/common/changes/@uifabric/experiments/amyngu-newSuggestions_2018-02-08-21-28.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@uifabric/experiments", + "comment": "Use new \"use current input\" command in Suggestions", + "type": "minor" + } + ], + "packageName": "@uifabric/experiments", + "email": "amyngu@microsoft.com" +} \ No newline at end of file diff --git a/common/changes/office-ui-fabric-react/amyngu-newSuggestions_2018-02-08-21-28.json b/common/changes/office-ui-fabric-react/amyngu-newSuggestions_2018-02-08-21-28.json new file mode 100644 index 00000000000000..b9bd42d5e19a41 --- /dev/null +++ b/common/changes/office-ui-fabric-react/amyngu-newSuggestions_2018-02-08-21-28.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "office-ui-fabric-react", + "comment": "Add \"use current input command\" and remove need to explicity call focus when moving between suggestions and commands", + "type": "minor" + } + ], + "packageName": "office-ui-fabric-react", + "email": "amyngu@microsoft.com" +} \ No newline at end of file From 9d175bc79629b9428935c54e91c6dac52ec0d461 Mon Sep 17 00:00:00 2001 From: Amy Nguyen Date: Thu, 8 Feb 2018 13:45:50 -0800 Subject: [PATCH 4/9] fix up basepicker keydown --- .../src/components/pickers/BasePicker.tsx | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) 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 822455d21e6bbf..f4c493ec97ac74 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/BasePicker.tsx +++ b/packages/office-ui-fabric-react/src/components/pickers/BasePicker.tsx @@ -492,35 +492,48 @@ export class BasePicker> extends BaseComponent< break; case KeyCodes.up: - if (ev.target === this.input.inputElement && this.state.suggestionsVisible && !this.suggestionElement.tryHandleKeyDown(keyCode)) { - if (this.state.moreSuggestionsAvailable && this.suggestionElement.props.searchForMoreText && this.suggestionStore.currentIndex === 0) { - this.suggestionElement.focusSearchForMoreButton(); - this.suggestionStore.deselectAllSuggestions(); - this.forceUpdate(); + if (ev.target === this.input.inputElement && this.state.suggestionsVisible) { + if (this.suggestionElement.tryHandleKeyDown(keyCode)) { + ev.preventDefault(); + ev.stopPropagation(); } else { - if (this.suggestionStore.previousSuggestion()) { + if (this.suggestionElement.hasSuggestedAction() && this.suggestionStore.currentIndex === 0) { ev.preventDefault(); ev.stopPropagation(); - this.onSuggestionSelect(); + this.suggestionElement.focusSearchForMoreButton(); + this.suggestionStore.deselectAllSuggestions(); + this.forceUpdate(); + } else { + if (this.suggestionStore.previousSuggestion()) { + ev.preventDefault(); + ev.stopPropagation(); + this.onSuggestionSelect(); + } } } } break; case KeyCodes.down: - if (ev.target === this.input.inputElement && this.state.suggestionsVisible && !this.suggestionElement.tryHandleKeyDown(keyCode)) { - if (this.state.moreSuggestionsAvailable && this.suggestionElement.props.searchForMoreText && (this.suggestionStore.currentIndex + 1) === this.suggestionStore.suggestions.length) { - this.suggestionElement.focusSearchForMoreButton(); - this.suggestionStore.deselectAllSuggestions(); - this.forceUpdate(); + if (ev.target === this.input.inputElement && this.state.suggestionsVisible) { + if (this.suggestionElement.tryHandleKeyDown(keyCode)) { + ev.preventDefault(); + ev.stopPropagation(); } else { - if (this.suggestionStore.nextSuggestion()) { + if (this.suggestionElement.hasSuggestedAction() && (this.suggestionStore.currentIndex + 1) === this.suggestionStore.suggestions.length) { ev.preventDefault(); ev.stopPropagation(); - this.onSuggestionSelect(); + this.suggestionElement.focusSearchForMoreButton(); + this.suggestionStore.deselectAllSuggestions(); + this.forceUpdate(); + } else { + if (this.suggestionStore.nextSuggestion()) { + ev.preventDefault(); + ev.stopPropagation(); + this.onSuggestionSelect(); + } } } - } break; } From 6398c3c31fcab633a01200d4aa86a855ced93009 Mon Sep 17 00:00:00 2001 From: Amy Nguyen Date: Mon, 12 Feb 2018 14:09:14 -0800 Subject: [PATCH 5/9] move use text input command to before suggestions --- .../ExtendedPeoplePicker.Basic.Example.tsx | 34 +++-- .../FloatingPicker/BaseFloatingPicker.tsx | 19 ++- .../BaseFloatingPicker.types.ts | 5 + .../src/components/pickers/BasePicker.tsx | 8 +- .../pickers/Suggestions/Suggestions.tsx | 123 ++++++++++-------- .../pickers/Suggestions/Suggestions.types.ts | 4 +- 6 files changed, 118 insertions(+), 75 deletions(-) diff --git a/packages/experiments/src/components/ExtendedPicker/examples/ExtendedPeoplePicker.Basic.Example.tsx b/packages/experiments/src/components/ExtendedPicker/examples/ExtendedPeoplePicker.Basic.Example.tsx index 1b42e3a93dad12..28d91b2580a020 100644 --- a/packages/experiments/src/components/ExtendedPicker/examples/ExtendedPeoplePicker.Basic.Example.tsx +++ b/packages/experiments/src/components/ExtendedPicker/examples/ExtendedPeoplePicker.Basic.Example.tsx @@ -22,23 +22,12 @@ export interface IPeoplePickerExampleState { mostRecentlyUsed: IPersonaProps[]; } -const suggestionProps: IBasePickerSuggestionsProps = { - suggestionsHeaderText: 'Suggested People', - mostRecentlyUsedHeaderText: 'Suggested Contacts', - noResultsFoundText: 'No results found', - loadingText: 'Loading', - showRemoveButtons: true, - suggestionsAvailableAlertText: 'People Picker Suggestions available', - suggestionsContainerAriaLabel: 'Suggested contacts', - searchForMoreText: 'Search more', - useInputText: 'Use this name', -}; - // tslint:disable-next-line:no-any export class ExtendedPeoplePickerTypesExample extends BaseComponent<{}, IPeoplePickerExampleState> { private _picker: ExtendedPeoplePicker; private _floatingPickerProps: IBaseFloatingPickerProps; private _selectedItemsListProps: ISelectedPeopleProps; + private _suggestionProps: IBasePickerSuggestionsProps; constructor(props: {}) { super(props); @@ -55,15 +44,28 @@ export class ExtendedPeoplePickerTypesExample extends BaseComponent<{}, IPeopleP mostRecentlyUsed: mru, }; + this._suggestionProps = { + suggestionsHeaderText: 'Suggested People', + mostRecentlyUsedHeaderText: 'Suggested Contacts', + noResultsFoundText: 'No results found', + loadingText: 'Loading', + showRemoveButtons: true, + suggestionsAvailableAlertText: 'People Picker Suggestions available', + suggestionsContainerAriaLabel: 'Suggested contacts', + searchForMoreText: 'Search more', + useInputText: 'Use this name', + }; + this._floatingPickerProps = { suggestionsController: new SuggestionsController(), onResolveSuggestions: this._onFilterChanged, getTextFromItem: this._getTextFromItem, - pickerSuggestionsProps: suggestionProps, + pickerSuggestionsProps: this._suggestionProps, key: 'normal', onRemoveSuggestion: this._onRemoveSuggestion, onValidateInput: this._validateInput, onZeroQuerySuggestion: this._returnMostRecentlyUsed, + showUseInput: this._shouldShowUseInput, }; this._selectedItemsListProps = { @@ -194,6 +196,12 @@ export class ExtendedPeoplePickerTypesExample extends BaseComponent<{}, IPeopleP return copyText; } + @autobind + private _shouldShowUseInput(): boolean { + return this._validateInput(this._picker.floatingPicker.inputText) + && this._picker.floatingPicker.suggestions.length === 0; + } + private _listContainsPersona(persona: IPersonaProps, personas: IPersonaProps[]): boolean { if (!personas || !personas.length || personas.length === 0) { return false; diff --git a/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.tsx b/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.tsx index 3bdfe35a0a890d..9d7d3c5f1af3f0 100644 --- a/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.tsx +++ b/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.tsx @@ -54,6 +54,15 @@ export class BaseFloatingPicker> extend }; } + public get inputText(): string { + return this.state.queryString; + } + + // tslint:disable-next-line:no-any + public get suggestions(): any[] { + return this.suggestionStore.suggestions; + } + public forceResolveSuggestion(): void { if (this.suggestionStore.hasSelectedSuggestion()) { this.completeSuggestion(); @@ -171,7 +180,7 @@ export class BaseFloatingPicker> extend calloutWidth={ this.props.calloutWidth ? this.props.calloutWidth : 0 } > > extend break; case KeyCodes.up: - if (this.suggestionElement.tryHandleKeyDown(keyCode)) { + if (this.suggestionElement.tryHandleKeyDown(keyCode, this.suggestionStore.currentIndex)) { ev.preventDefault(); ev.stopPropagation(); } else { @@ -407,7 +416,7 @@ export class BaseFloatingPicker> extend break; case KeyCodes.down: - if (this.suggestionElement.tryHandleKeyDown(keyCode)) { + if (this.suggestionElement.tryHandleKeyDown(keyCode, this.suggestionStore.currentIndex)) { ev.preventDefault(); ev.stopPropagation(); } else { @@ -499,8 +508,8 @@ export class BaseFloatingPicker> extend } @autobind - private _tryValidateInput(): boolean { - return this.props.onValidateInput ? this.props.onValidateInput(this.state.queryString) : false; + private _shouldShowUseInput(): boolean { + return this.props.showUseInput ? this.props.showUseInput() : false; } private _getTextFromItem(item: T, currentValue?: string): string { diff --git a/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.types.ts b/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.types.ts index 920dbe0892d613..8b595f0bc80fd8 100644 --- a/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.types.ts +++ b/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.types.ts @@ -98,6 +98,11 @@ export interface IBaseFloatingPickerProps extends React.Props { isValid: boolean ) => ISuggestionModel; + /** + * The callback that should be called to see if the use input text command should be shown + */ + showUseInput?: () => boolean; + /** * The items that the base picker should currently display as selected. If this is provided then the picker will act as a controlled * component. 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 f4c493ec97ac74..649e214b2e89a8 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/BasePicker.tsx +++ b/packages/office-ui-fabric-react/src/components/pickers/BasePicker.tsx @@ -493,14 +493,14 @@ export class BasePicker> extends BaseComponent< case KeyCodes.up: if (ev.target === this.input.inputElement && this.state.suggestionsVisible) { - if (this.suggestionElement.tryHandleKeyDown(keyCode)) { + if (this.suggestionElement.tryHandleKeyDown(keyCode, this.suggestionStore.currentIndex)) { ev.preventDefault(); ev.stopPropagation(); } else { if (this.suggestionElement.hasSuggestedAction() && this.suggestionStore.currentIndex === 0) { ev.preventDefault(); ev.stopPropagation(); - this.suggestionElement.focusSearchForMoreButton(); + this.suggestionElement.focusAboveSuggestions(); this.suggestionStore.deselectAllSuggestions(); this.forceUpdate(); } else { @@ -516,14 +516,14 @@ export class BasePicker> extends BaseComponent< case KeyCodes.down: if (ev.target === this.input.inputElement && this.state.suggestionsVisible) { - if (this.suggestionElement.tryHandleKeyDown(keyCode)) { + if (this.suggestionElement.tryHandleKeyDown(keyCode, this.suggestionStore.currentIndex)) { ev.preventDefault(); ev.stopPropagation(); } else { if (this.suggestionElement.hasSuggestedAction() && (this.suggestionStore.currentIndex + 1) === this.suggestionStore.suggestions.length) { ev.preventDefault(); ev.stopPropagation(); - this.suggestionElement.focusSearchForMoreButton(); + this.suggestionElement.focusBelowSuggestions(); this.suggestionStore.deselectAllSuggestions(); this.forceUpdate(); } else { diff --git a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx index 9ebd00d051b465..dd70c634418a5d 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx +++ b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx @@ -83,7 +83,7 @@ export class Suggestions extends BaseComponent, ISuggest let { useInputText, createGenericItem, - isTextValid, + showUseInput, mostRecentlyUsedHeaderText, searchForMoreText, className, @@ -129,20 +129,11 @@ export class Suggestions extends BaseComponent, ISuggest (
{ headerText }
) : (null) } - { isLoading && ( - ) } - { hasNoSuggestions ? - (onRenderNoResultFound ? onRenderNoResultFound(undefined, noResults) : noResults()) : - this._renderSuggestions() - } - { useInputText && !moreSuggestionsAvailable && hasNoSuggestions && this._isTextValid() && ( + { useInputText && this._shouldShowUseInput() && ( extends BaseComponent, ISuggest { useInputText } ) } + { isLoading && ( + ) } + { hasNoSuggestions ? + (onRenderNoResultFound ? onRenderNoResultFound(undefined, noResults) : noResults()) : + this._renderSuggestions() + } { searchForMoreText && moreSuggestionsAvailable && ( extends BaseComponent, ISuggest } @autobind - public tryHandleKeyDown(keyCode: number): boolean { + public tryHandleKeyDown(keyCode: number, currentSuggestionIndex: number): boolean { let isEventHandled = false; let newSelectedActionType = null; let currentSelectedAction = this.state.selectedActionType; - if (currentSelectedAction !== SuggestionActionType.none) { - if (keyCode === KeyCodes.down) { - switch (currentSelectedAction) { - case SuggestionActionType.useInputText: - if (this._searchForMoreButton) { - newSelectedActionType = SuggestionActionType.searchMore; - } else { - this._refocusOnSuggestions(keyCode); - newSelectedActionType = SuggestionActionType.none; - } - break; - case SuggestionActionType.searchMore: + let suggestionLength = this.props.suggestions.length; + if (keyCode === KeyCodes.down) { + switch (currentSelectedAction) { + case SuggestionActionType.useInputText: + if (suggestionLength > 0) { this._refocusOnSuggestions(keyCode); newSelectedActionType = SuggestionActionType.none; - break; - } - } else if (keyCode === KeyCodes.up) { - switch (currentSelectedAction) { - case SuggestionActionType.useInputText: + } else if (this._searchForMoreButton) { + newSelectedActionType = SuggestionActionType.searchMore; + } else { + newSelectedActionType = SuggestionActionType.useInputText; + } + break; + case SuggestionActionType.searchMore: + if (this._useInputButton) { + newSelectedActionType = SuggestionActionType.useInputText; + } else if (suggestionLength > 0) { + this._refocusOnSuggestions(keyCode); + newSelectedActionType = SuggestionActionType.none; + } else { + newSelectedActionType = SuggestionActionType.searchMore; + } + break; + case SuggestionActionType.none: + if (currentSuggestionIndex === -1 && this._useInputButton) { + newSelectedActionType = SuggestionActionType.useInputText; + } + break; + } + } else if (keyCode === KeyCodes.up) { + switch (currentSelectedAction) { + case SuggestionActionType.useInputText: + if (this._searchForMoreButton) { + newSelectedActionType = SuggestionActionType.searchMore; + } else if (suggestionLength > 0) { this._refocusOnSuggestions(keyCode); newSelectedActionType = SuggestionActionType.none; break; - case SuggestionActionType.searchMore: - if (this._useInputButton) { - newSelectedActionType = SuggestionActionType.useInputText; - } else { - this._refocusOnSuggestions(keyCode); - newSelectedActionType = SuggestionActionType.none; - } - break; - } + } + case SuggestionActionType.searchMore: + if (suggestionLength > 0) { + this._refocusOnSuggestions(keyCode); + newSelectedActionType = SuggestionActionType.none; + } else if (this._useInputButton) { + newSelectedActionType = SuggestionActionType.useInputText; + } + break; + case SuggestionActionType.none: + if (currentSuggestionIndex === -1 && this._searchForMoreButton) { + newSelectedActionType = SuggestionActionType.searchMore; + } + break; } + } - if (newSelectedActionType !== null) { - this.setState({ selectedActionType: newSelectedActionType }); - isEventHandled = true; - } + if (newSelectedActionType !== null) { + this.setState({ selectedActionType: newSelectedActionType }); + isEventHandled = true; } return isEventHandled; @@ -260,18 +281,18 @@ export class Suggestions extends BaseComponent, ISuggest public focusAboveSuggestions(): void { let newSelectedActionType = null; - if (this._searchForMoreButton) { - this.setState({ selectedActionType: SuggestionActionType.searchMore }); - } else if (this._useInputButton) { + if (this._useInputButton) { this.setState({ selectedActionType: SuggestionActionType.useInputText }); + } else if (this._searchForMoreButton) { + this.setState({ selectedActionType: SuggestionActionType.searchMore }); } } public focusBelowSuggestions(): void { - if (this._useInputButton) { - this.setState({ selectedActionType: SuggestionActionType.useInputText }); - } else if (this._searchForMoreButton) { + if (this._searchForMoreButton) { this.setState({ selectedActionType: SuggestionActionType.searchMore }); + } else if (this._useInputButton) { + this.setState({ selectedActionType: SuggestionActionType.useInputText }); } } @@ -346,8 +367,8 @@ export class Suggestions extends BaseComponent, ISuggest } @autobind - private _isTextValid() { - return this.props.isTextValid ? this.props.isTextValid() : false; + private _shouldShowUseInput() { + return this.props.showUseInput ? this.props.showUseInput() : false; } @autobind diff --git a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.types.ts b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.types.ts index 5d97d250e071e2..c324c7ccb3a733 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.types.ts +++ b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.types.ts @@ -46,9 +46,9 @@ export interface ISuggestionsProps extends React.Props { */ useInputText?: string; /** - * The callback that should be called to see if the input text is valid + * The callback that should be called to see if the use input text command should be shown */ - isTextValid?: () => boolean; + showUseInput?: () => boolean; /** * The callback that should be called when the user attempts to use the input text as as item */ From 71ddcee0f0a02fc489c12bf4c97219134b97d3a6 Mon Sep 17 00:00:00 2001 From: Amy Nguyen Date: Mon, 12 Feb 2018 15:48:24 -0800 Subject: [PATCH 6/9] change name to forceResolve --- .../examples/ExtendedPeoplePicker.Basic.Example.tsx | 6 +++--- .../components/FloatingPicker/BaseFloatingPicker.tsx | 7 +++---- .../FloatingPicker/BaseFloatingPicker.types.ts | 4 ++-- .../src/components/pickers/BasePicker.types.ts | 4 ++-- .../components/pickers/Suggestions/Suggestions.tsx | 12 ++++++------ .../pickers/Suggestions/Suggestions.types.ts | 8 ++++---- 6 files changed, 20 insertions(+), 21 deletions(-) diff --git a/packages/experiments/src/components/ExtendedPicker/examples/ExtendedPeoplePicker.Basic.Example.tsx b/packages/experiments/src/components/ExtendedPicker/examples/ExtendedPeoplePicker.Basic.Example.tsx index 28d91b2580a020..36cdd40ed5eb94 100644 --- a/packages/experiments/src/components/ExtendedPicker/examples/ExtendedPeoplePicker.Basic.Example.tsx +++ b/packages/experiments/src/components/ExtendedPicker/examples/ExtendedPeoplePicker.Basic.Example.tsx @@ -53,7 +53,7 @@ export class ExtendedPeoplePickerTypesExample extends BaseComponent<{}, IPeopleP suggestionsAvailableAlertText: 'People Picker Suggestions available', suggestionsContainerAriaLabel: 'Suggested contacts', searchForMoreText: 'Search more', - useInputText: 'Use this name', + forceResolveText: 'Use this name', }; this._floatingPickerProps = { @@ -65,7 +65,7 @@ export class ExtendedPeoplePickerTypesExample extends BaseComponent<{}, IPeopleP onRemoveSuggestion: this._onRemoveSuggestion, onValidateInput: this._validateInput, onZeroQuerySuggestion: this._returnMostRecentlyUsed, - showUseInput: this._shouldShowUseInput, + showForceResolve: this._shouldShowForceResolve, }; this._selectedItemsListProps = { @@ -197,7 +197,7 @@ export class ExtendedPeoplePickerTypesExample extends BaseComponent<{}, IPeopleP } @autobind - private _shouldShowUseInput(): boolean { + private _shouldShowForceResolve(): boolean { return this._validateInput(this._picker.floatingPicker.inputText) && this._picker.floatingPicker.suggestions.length === 0; } diff --git a/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.tsx b/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.tsx index 9d7d3c5f1af3f0..d682d8dc5dd574 100644 --- a/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.tsx +++ b/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.tsx @@ -96,7 +96,6 @@ export class BaseFloatingPicker> extend this.setState({ suggestionsVisible: false, }); - console.log('hidepicker'); } public showPicker(): void { @@ -180,7 +179,7 @@ export class BaseFloatingPicker> extend calloutWidth={ this.props.calloutWidth ? this.props.calloutWidth : 0 } > > extend } @autobind - private _shouldShowUseInput(): boolean { - return this.props.showUseInput ? this.props.showUseInput() : false; + private _showForceResolve(): boolean { + return this.props.showForceResolve ? this.props.showForceResolve() : false; } private _getTextFromItem(item: T, currentValue?: string): string { diff --git a/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.types.ts b/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.types.ts index 8b595f0bc80fd8..72612318643564 100644 --- a/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.types.ts +++ b/packages/experiments/src/components/FloatingPicker/BaseFloatingPicker.types.ts @@ -99,9 +99,9 @@ export interface IBaseFloatingPickerProps extends React.Props { ) => ISuggestionModel; /** - * The callback that should be called to see if the use input text command should be shown + * The callback that should be called to see if the force resolve command should be shown */ - showUseInput?: () => boolean; + showForceResolve?: () => boolean; /** * The items that the base picker should currently display as selected. If this is provided then the picker will act as a controlled 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 07fb3dcab7e8eb..d8841b5265c0fa 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 @@ -163,9 +163,9 @@ export interface IBasePickerSuggestionsProps { */ searchForMoreText?: string; /** - * The text that appears indicated to the user that they can use the inputed text as an item + * The text that appears indicating to the use to force resolve the input */ - useInputText?: string; + forceResolveText?: string; /** * The text to display while the results are loading. */ diff --git a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx index dd70c634418a5d..955c98762a1e2e 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx +++ b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx @@ -81,9 +81,9 @@ export class Suggestions extends BaseComponent, ISuggest public render() { let { - useInputText, + forceResolveText, createGenericItem, - showUseInput, + showForceResolve, mostRecentlyUsedHeaderText, searchForMoreText, className, @@ -129,7 +129,7 @@ export class Suggestions extends BaseComponent, ISuggest (
{ headerText }
) : (null) } - { useInputText && this._shouldShowUseInput() && ( + { forceResolveText && this._shouldShowForceResolve() && ( extends BaseComponent, ISuggest }) } onClick={ this._useInput } > - { useInputText } + { forceResolveText } ) } { isLoading && ( @@ -367,8 +367,8 @@ export class Suggestions extends BaseComponent, ISuggest } @autobind - private _shouldShowUseInput() { - return this.props.showUseInput ? this.props.showUseInput() : false; + private _shouldShowForceResolve() { + return this.props.showForceResolve ? this.props.showForceResolve() : false; } @autobind diff --git a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.types.ts b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.types.ts index c324c7ccb3a733..10f711966da78f 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.types.ts +++ b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.types.ts @@ -42,13 +42,13 @@ export interface ISuggestionsProps extends React.Props { */ onGetMoreResults?: () => void; /** - * The text that appears indicated to the user that they can use the input text as an item + * The text that appears indicating to the use to force resolve the input */ - useInputText?: string; + forceResolveText?: string; /** - * The callback that should be called to see if the use input text command should be shown + * The callback that should be called to see if the force resolve command should be shown */ - showUseInput?: () => boolean; + showForceResolve?: () => boolean; /** * The callback that should be called when the user attempts to use the input text as as item */ From 676b8df8590c156451296b8bd27d8afb39346c8f Mon Sep 17 00:00:00 2001 From: Amy Nguyen Date: Tue, 13 Feb 2018 15:47:45 -0800 Subject: [PATCH 7/9] add comment for return --- .../src/components/pickers/Suggestions/Suggestions.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx index 955c98762a1e2e..901f8fc908f105 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx +++ b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx @@ -192,6 +192,9 @@ export class Suggestions extends BaseComponent, ISuggest ); } + /** + * Returns true if the event was handled, false otherwise + */ @autobind public tryHandleKeyDown(keyCode: number, currentSuggestionIndex: number): boolean { let isEventHandled = false; From dbbe1e836d47393ec143ea5c98f28521935a5084 Mon Sep 17 00:00:00 2001 From: Amy Nguyen Date: Tue, 13 Feb 2018 15:54:46 -0800 Subject: [PATCH 8/9] rename more vars to forceResolve --- .../pickers/Suggestions/Suggestions.tsx | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx index 901f8fc908f105..4506ced14c9746 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx +++ b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx @@ -13,7 +13,7 @@ const styles: any = stylesImport; export enum SuggestionActionType { none, - useInputText, + forceResolve, searchMore, } @@ -63,7 +63,7 @@ export class SuggestionsItem extends BaseComponent, { export class Suggestions extends BaseComponent, ISuggestionsState> { - protected _useInputButton: IButton; + protected _forceResolveButton: IButton; protected _searchForMoreButton: IButton; protected _selectedElement: HTMLDivElement; private SuggestionsItemOfProperType = SuggestionsItem as new (props: ISuggestionItemProps) => SuggestionsItem; @@ -131,15 +131,15 @@ export class Suggestions extends BaseComponent, ISuggest
) : (null) } { forceResolveText && this._shouldShowForceResolve() && ( { forceResolveText } @@ -203,19 +203,19 @@ export class Suggestions extends BaseComponent, ISuggest let suggestionLength = this.props.suggestions.length; if (keyCode === KeyCodes.down) { switch (currentSelectedAction) { - case SuggestionActionType.useInputText: + case SuggestionActionType.forceResolve: if (suggestionLength > 0) { this._refocusOnSuggestions(keyCode); newSelectedActionType = SuggestionActionType.none; } else if (this._searchForMoreButton) { newSelectedActionType = SuggestionActionType.searchMore; } else { - newSelectedActionType = SuggestionActionType.useInputText; + newSelectedActionType = SuggestionActionType.forceResolve; } break; case SuggestionActionType.searchMore: - if (this._useInputButton) { - newSelectedActionType = SuggestionActionType.useInputText; + if (this._forceResolveButton) { + newSelectedActionType = SuggestionActionType.forceResolve; } else if (suggestionLength > 0) { this._refocusOnSuggestions(keyCode); newSelectedActionType = SuggestionActionType.none; @@ -224,14 +224,14 @@ export class Suggestions extends BaseComponent, ISuggest } break; case SuggestionActionType.none: - if (currentSuggestionIndex === -1 && this._useInputButton) { - newSelectedActionType = SuggestionActionType.useInputText; + if (currentSuggestionIndex === -1 && this._forceResolveButton) { + newSelectedActionType = SuggestionActionType.forceResolve; } break; } } else if (keyCode === KeyCodes.up) { switch (currentSelectedAction) { - case SuggestionActionType.useInputText: + case SuggestionActionType.forceResolve: if (this._searchForMoreButton) { newSelectedActionType = SuggestionActionType.searchMore; } else if (suggestionLength > 0) { @@ -243,8 +243,8 @@ export class Suggestions extends BaseComponent, ISuggest if (suggestionLength > 0) { this._refocusOnSuggestions(keyCode); newSelectedActionType = SuggestionActionType.none; - } else if (this._useInputButton) { - newSelectedActionType = SuggestionActionType.useInputText; + } else if (this._forceResolveButton) { + newSelectedActionType = SuggestionActionType.forceResolve; } break; case SuggestionActionType.none: @@ -264,7 +264,7 @@ export class Suggestions extends BaseComponent, ISuggest } public hasSuggestedAction(): boolean { - return this._searchForMoreButton !== null || this._useInputButton !== null; + return this._searchForMoreButton !== null || this._forceResolveButton !== null; } public hasSuggestedActionSelected(): boolean { @@ -273,8 +273,8 @@ export class Suggestions extends BaseComponent, ISuggest public executeSelectedAction(): void { switch (this.state.selectedActionType) { - case SuggestionActionType.useInputText: - this._useInput(); + case SuggestionActionType.forceResolve: + this._forceResolve(); break; case SuggestionActionType.searchMore: this._getMoreResults(); @@ -284,8 +284,8 @@ export class Suggestions extends BaseComponent, ISuggest public focusAboveSuggestions(): void { let newSelectedActionType = null; - if (this._useInputButton) { - this.setState({ selectedActionType: SuggestionActionType.useInputText }); + if (this._forceResolveButton) { + this.setState({ selectedActionType: SuggestionActionType.forceResolve }); } else if (this._searchForMoreButton) { this.setState({ selectedActionType: SuggestionActionType.searchMore }); } @@ -294,8 +294,8 @@ export class Suggestions extends BaseComponent, ISuggest public focusBelowSuggestions(): void { if (this._searchForMoreButton) { this.setState({ selectedActionType: SuggestionActionType.searchMore }); - } else if (this._useInputButton) { - this.setState({ selectedActionType: SuggestionActionType.useInputText }); + } else if (this._forceResolveButton) { + this.setState({ selectedActionType: SuggestionActionType.forceResolve }); } } @@ -363,7 +363,7 @@ export class Suggestions extends BaseComponent, ISuggest } @autobind - private _useInput() { + private _forceResolve() { if (this.props.createGenericItem) { this.props.createGenericItem(); } From d74020d2546cddc8792798fd86c10f2c7a977937 Mon Sep 17 00:00:00 2001 From: Amy Nguyen Date: Tue, 13 Feb 2018 16:48:06 -0800 Subject: [PATCH 9/9] fix break inside else if statement --- .../src/components/pickers/Suggestions/Suggestions.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx index 4506ced14c9746..229057ebde17ac 100644 --- a/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx +++ b/packages/office-ui-fabric-react/src/components/pickers/Suggestions/Suggestions.tsx @@ -237,8 +237,8 @@ export class Suggestions extends BaseComponent, ISuggest } else if (suggestionLength > 0) { this._refocusOnSuggestions(keyCode); newSelectedActionType = SuggestionActionType.none; - break; } + break; case SuggestionActionType.searchMore: if (suggestionLength > 0) { this._refocusOnSuggestions(keyCode); @@ -264,7 +264,7 @@ export class Suggestions extends BaseComponent, ISuggest } public hasSuggestedAction(): boolean { - return this._searchForMoreButton !== null || this._forceResolveButton !== null; + return this._searchForMoreButton !== undefined || this._forceResolveButton !== undefined; } public hasSuggestedActionSelected(): boolean {