Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "ComboBox adding onPendingValueChanged 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
Expand Up @@ -122,6 +122,8 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> {

private _isScrollIdle: boolean;

private _hasPendingValue: boolean;

private readonly _scrollIdleDelay: number = 250 /* ms */;

private _scrollIdleTimeoutId: number | undefined;
Expand Down Expand Up @@ -233,6 +235,8 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> {
this._select();
}

this._notifyPendingValueChanged(prevState);

if (isOpen && !prevState.isOpen && onMenuOpen) {
onMenuOpen();
}
Expand Down Expand Up @@ -688,7 +692,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, onPendingValueChanged } = this.props;
const { selectedIndex, currentOptions } = this.state;

// Find the next selectable index, if searchDirection is none
Expand All @@ -709,6 +713,12 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> {
selectedIndex: index
});

// If ComboBox value is changed, revert preview first
if (this._hasPendingValue && onPendingValueChanged) {
onPendingValueChanged();
this._hasPendingValue = false;
}

// Did the creator give us an onChanged callback?
if (onChanged) {
onChanged(option, index);
Expand Down Expand Up @@ -1233,6 +1243,41 @@ export class ComboBox extends BaseComponent<IComboBoxProps, IComboBoxState> {
}
}

private _notifyPendingValueChanged(prevState: IComboBoxState) {
const { onPendingValueChanged } = this.props;

if (!onPendingValueChanged) {
return;
}

const {
currentPendingValue,
currentOptions,
currentPendingValueValidIndex,
currentPendingValueValidIndexOnHover
} = this.state;

let newPendingIndex: number | undefined = undefined;
let newPendingValue: string | undefined = undefined;

if (currentPendingValueValidIndexOnHover !== prevState.currentPendingValueValidIndexOnHover && this._indexWithinBounds(currentOptions, currentPendingValueValidIndexOnHover)) {
// Set new pending index if hover index was changed
newPendingIndex = currentPendingValueValidIndexOnHover;
} else if (currentPendingValueValidIndex !== prevState.currentPendingValueValidIndex && this._indexWithinBounds(currentOptions, currentPendingValueValidIndex)) {
// Set new pending index if currentPendingValueValidIndex was changed
newPendingIndex = currentPendingValueValidIndex;
} else if (currentPendingValue !== prevState.currentPendingValue && currentPendingValue !== '') {
// Set pendingValue in the case it was changed and no index was changed
newPendingValue = currentPendingValue;
}

// Notify when there is a new pending index/value. Also, if there is a pending value, it needs to send undefined.
if (newPendingIndex !== undefined || newPendingValue || this._hasPendingValue) {
onPendingValueChanged(newPendingIndex ? currentOptions[newPendingIndex] : undefined, newPendingIndex, newPendingValue);
this._hasPendingValue = newPendingIndex !== undefined || newPendingValue !== undefined;
}
}

/**
* Sets the isOpen state and updates focusInputAfterClose
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ export interface IComboBoxProps extends ISelectableDroppableTextProps<IComboBox>
*/
onChanged?: (option?: IComboBoxOption, index?: number, value?: string) => void;

/**
* Callback issued when the user changes the pending value in ComboBox
*/
onPendingValueChanged?: (option?: IComboBoxOption, index?: number, value?: string) => void;

/**
* Function that gets invoked when the ComboBox menu is launched
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ export class ComboBoxBasicExample extends React.Component<{}, {
value?: string;
}> {
private _testOptions =
[{ key: 'Header', text: 'Theme Fonts', itemType: SelectableOptionMenuItemType.Header },
{ key: 'A', text: 'Arial Black' },
{ key: 'B', text: 'Times New Roman' },
{ key: 'C', text: 'Comic Sans MS' },
{ key: 'divider_2', text: '-', itemType: SelectableOptionMenuItemType.Divider },
{ key: 'Header1', text: 'Other Options', itemType: SelectableOptionMenuItemType.Header },
{ key: 'D', text: 'Option d' },
{ key: 'E', text: 'Option e' },
{ key: 'F', text: 'Option f' },
{ key: 'G', text: 'Option g' },
{ key: 'H', text: 'Option h' },
{ key: 'I', text: 'Option i' },
{ key: 'J', text: 'Option j', disabled: true },
];
[{ key: 'Header', text: 'Theme Fonts', itemType: SelectableOptionMenuItemType.Header },
{ key: 'A', text: 'Arial Black' },
{ key: 'B', text: 'Times New Roman' },
{ key: 'C', text: 'Comic Sans MS' },
{ key: 'divider_2', text: '-', itemType: SelectableOptionMenuItemType.Divider },
{ key: 'Header1', text: 'Other Options', itemType: SelectableOptionMenuItemType.Header },
{ key: 'D', text: 'Option d' },
{ key: 'E', text: 'Option e' },
{ key: 'F', text: 'Option f' },
{ key: 'G', text: 'Option g' },
{ key: 'H', text: 'Option h' },
{ key: 'I', text: 'Option i' },
{ key: 'J', text: 'Option j', disabled: true },
];

private _fontMapping: { [key: string]: string } = {
['Arial Black']: '"Arial Black", "Arial Black_MSFontService", sans-serif',
Expand Down Expand Up @@ -80,6 +80,7 @@ export class ComboBoxBasicExample extends React.Component<{}, {
onFocus={ () => console.log('onFocus called') }
onBlur={ () => console.log('onBlur called') }
onMenuOpen={ () => console.log('ComboBox menu opened') }
onPendingValueChanged={ (option, pendingIndex, pendingValue) => console.log('Preview value was changed. Pending index: ' + pendingIndex + '. Pending value: ' + pendingValue) }
// tslint:enable:jsx-no-lambda
/>

Expand Down Expand Up @@ -132,6 +133,7 @@ export class ComboBoxBasicExample extends React.Component<{}, {
onFocus={ () => console.log('onFocus called') }
onBlur={ () => console.log('onBlur called') }
onMenuOpen={ () => console.log('ComboBox menu opened') }
onPendingValueChanged={ (option, pendingIndex, pendingValue) => console.log('Preview value was changed. Pending index: ' + pendingIndex + '. Pending value: ' + pendingValue) }
// tslint:enable:jsx-no-lambda
/>

Expand Down