-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Adding onPendingValueChanged callback #4105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
ebe922e
d1c5014
51f3aa8
c9626cd
edb9901
22bf253
6c72b47
d38795d
df4f4ef
b03155c
ff7d2e6
215d6f1
33f7e26
1acb059
46d2fd4
b58225b
d98eb23
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "changes": [ | ||
| { | ||
| "packageName": "office-ui-fabric-react", | ||
| "comment": "ComboBox adding onPendingValueSet callback prop to run when pending value is changed", | ||
| "type": "patch" | ||
| } | ||
| ], | ||
| "packageName": "office-ui-fabric-react", | ||
| "email": "madosal@microsoft.com" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -125,6 +125,8 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> { | |
|
|
||
| private _isScrollIdle: boolean; | ||
|
|
||
| private _isInPreview: boolean; | ||
|
|
||
| private readonly _scrollIdleDelay: number = 250 /* ms */; | ||
|
|
||
| private _scrollIdleTimeoutId: number | undefined; | ||
|
|
@@ -197,6 +199,7 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> { | |
| const { | ||
| isOpen, | ||
| focused, | ||
| currentOptions, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removing this that I don't need it anymore |
||
| selectedIndex, | ||
| currentPendingValueValidIndex | ||
| } = this.state; | ||
|
|
@@ -236,6 +239,8 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> { | |
| this._select(); | ||
| } | ||
|
|
||
| this._notifyPreviewChanged(prevState); | ||
|
|
||
| if (isOpen && !prevState.isOpen && onMenuOpen) { | ||
| onMenuOpen(); | ||
| } | ||
|
|
@@ -347,7 +352,7 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> { | |
| styles={ this._getCaretButtonStyles() } | ||
| role='presentation' | ||
| aria-hidden={ isButtonAriaHidden } | ||
| data-is-focusable={false} | ||
| data-is-focusable={ false } | ||
| tabIndex={ -1 } | ||
| onClick={ this._onComboBoxClick } | ||
| iconProps={ buttonIconProps } | ||
|
|
@@ -692,7 +697,7 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> { | |
| * @param searchDirection - the direction to search along the options from the given index | ||
| */ | ||
| private _setSelectedIndex(index: number, searchDirection: SearchDirection = SearchDirection.none) { | ||
| const { onChanged } = this.props; | ||
| const { onChanged, onRevertPreviewExecute } = this.props; | ||
| const { selectedIndex, currentOptions } = this.state; | ||
|
|
||
| // Find the next selectable index, if searchDirection is none | ||
|
|
@@ -713,6 +718,12 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> { | |
| selectedIndex: index | ||
| }); | ||
|
|
||
| // If ComboBox value is changed, revert preview first | ||
| if (this._isInPreview && onRevertPreviewExecute) { | ||
| onRevertPreviewExecute(); | ||
| this._isInPreview = false; | ||
| } | ||
|
|
||
| // Did the creator give us an onChanged callback? | ||
| if (onChanged) { | ||
| onChanged(option, index); | ||
|
|
@@ -1241,6 +1252,48 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> { | |
| } | ||
| } | ||
|
|
||
| private _notifyPreviewChanged(prevState: IComboBoxState) { | ||
| const { onPreviewExecute, onRevertPreviewExecute } = this.props; | ||
| const { | ||
| currentOptions, | ||
| currentPendingValueValidIndex, | ||
| currentPendingValueValidIndexOnHover | ||
| } = this.state; | ||
|
|
||
| if (onPreviewExecute && onRevertPreviewExecute) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider pulling this if check to the top of the function negating it and returning if it's true so the whole function isn't nested inside of the check |
||
| let sendRevert = false; | ||
| let currentPendingIndex = -1; | ||
|
|
||
| if (currentPendingValueValidIndexOnHover !== prevState.currentPendingValueValidIndexOnHover) { | ||
|
|
||
| if (this._indexWithinBounds(currentOptions, currentPendingValueValidIndexOnHover)) { | ||
| currentPendingIndex = currentPendingValueValidIndexOnHover; | ||
| } else { | ||
| sendRevert = true; | ||
| } | ||
| } | ||
|
|
||
| if (currentPendingIndex < 0 && currentPendingValueValidIndex !== prevState.currentPendingValueValidIndex) { | ||
|
|
||
| if (this._indexWithinBounds(currentOptions, currentPendingValueValidIndex)) { | ||
| currentPendingIndex = currentPendingValueValidIndex; | ||
| } else { | ||
| sendRevert = true; | ||
| } | ||
| } | ||
|
|
||
| if (this._isInPreview && (sendRevert || currentPendingIndex >= 0)) { | ||
| onRevertPreviewExecute(); | ||
| this._isInPreview = false; | ||
| } | ||
|
|
||
| if (!this._isInPreview && currentPendingIndex >= 0) { | ||
| onPreviewExecute(currentOptions[currentPendingIndex], currentPendingIndex); | ||
| this._isInPreview = true; | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about the case when a user enters a value that doesn't already exist as an option on the comboBox (when allowFreeform is true)?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That case I'm not sure if it's handled in Excel, so I'm skipping it. In legacy ribbon only available menu items have live preview.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add comments for all of these if checks? This seems overly complex and it could potentially be restructured to be more simple and straight forward. |
||
| } | ||
|
|
||
| /** | ||
| * Sets the isOpen state and updates focusInputAfterClose | ||
| */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,6 +48,17 @@ export interface IComboBoxProps extends ISelectableDroppableTextProps<IComboBox> | |
| */ | ||
| onChanged?: (option?: IComboBoxOption, index?: number, value?: string) => void; | ||
|
|
||
| /** | ||
| * Callback issued when the user changes the pending value index in ComboBox | ||
| * This includes hovering or keyboarding to a menu item | ||
| */ | ||
| onPreviewExecute?: (option?: IComboBoxOption, index?: number) => void; | ||
|
|
||
| /** | ||
| * Callback issued when user leaves the menu item in the ComboBox menu | ||
| */ | ||
| onRevertPreviewExecute?: () => void; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we actually need a revert callback? There's either going to be a new pending value or it's there's no pending value. I think onPendingValueChanged could handle both cases |
||
|
|
||
| /** | ||
| * Function that gets invoked when the ComboBox menu is launched | ||
| */ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is
_isInPreview? Is it true when there's a pending value?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is when the pending values is not undefined