980 lines
56 KiB
JavaScript
980 lines
56 KiB
JavaScript
define(["require", "exports", "tslib", "react", "../../Utilities", "../../Callout", "../../utilities/selection/index", "../../common/DirectionalHint", "./Suggestions/Suggestions", "./Suggestions/Suggestions.styles", "./Suggestions/SuggestionsController", "./BasePicker.types", "../Autofill/index", "./BasePicker.scss", "../../Label", "@fluentui/react-window-provider", "../../utilities/dom"], function (require, exports, tslib_1, React, Utilities_1, Callout_1, index_1, DirectionalHint_1, Suggestions_1, Suggestions_styles_1, SuggestionsController_1, BasePicker_types_1, index_2, stylesImport, Label_1, react_window_provider_1, dom_1) {
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.BasePickerListBelow = exports.BasePicker = void 0;
|
|
var legacyStyles = stylesImport;
|
|
var EXTENDED_LOAD_TIME = 3000;
|
|
var getClassNames = (0, Utilities_1.classNamesFunction)();
|
|
/**
|
|
* Should be removed once new picker without inheritance is created
|
|
*/
|
|
function getStyledSuggestions(suggestionsType) {
|
|
return (0, Utilities_1.styled)(suggestionsType, Suggestions_styles_1.getStyles, undefined, {
|
|
scope: 'Suggestions',
|
|
});
|
|
}
|
|
/**
|
|
* {@docCategory Pickers}
|
|
*/
|
|
var BasePicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BasePicker, _super);
|
|
function BasePicker(basePickerProps) {
|
|
var _this = _super.call(this, basePickerProps) || this;
|
|
// Refs
|
|
_this.root = React.createRef();
|
|
_this.input = React.createRef();
|
|
_this.suggestionElement = React.createRef();
|
|
/**
|
|
* @deprecated this is no longer necessary as typescript now supports generic elements
|
|
*/
|
|
_this.SuggestionOfProperType = Suggestions_1.Suggestions;
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
_this._styledSuggestions = getStyledSuggestions(_this.SuggestionOfProperType);
|
|
_this._isMounted = false;
|
|
_this._overrideScrollDismiss = false;
|
|
_this.dismissSuggestions = function (ev) {
|
|
var selectItemFunction = function () {
|
|
var addItemOnDismiss = true;
|
|
if (_this.props.onDismiss) {
|
|
addItemOnDismiss = _this.props.onDismiss(ev, _this.suggestionStore.currentSuggestion ? _this.suggestionStore.currentSuggestion.item : undefined);
|
|
}
|
|
if (!ev || (ev && !ev.defaultPrevented)) {
|
|
// Select the first suggestion if one is available and permitted by onDismiss when user leaves.
|
|
if (addItemOnDismiss !== false &&
|
|
_this.canAddItems() &&
|
|
_this.suggestionStore.hasSelectedSuggestion() &&
|
|
_this.state.suggestedDisplayValue) {
|
|
_this.addItemByIndex(0);
|
|
}
|
|
}
|
|
};
|
|
if (_this.currentPromise) {
|
|
_this.currentPromise.then(function () { return selectItemFunction(); });
|
|
}
|
|
else {
|
|
selectItemFunction();
|
|
}
|
|
_this.setState({ suggestionsVisible: false });
|
|
};
|
|
_this.refocusSuggestions = function (keyCode) {
|
|
_this.resetFocus();
|
|
if (_this.suggestionStore.suggestions && _this.suggestionStore.suggestions.length > 0) {
|
|
if (keyCode === Utilities_1.KeyCodes.up) {
|
|
_this.suggestionStore.setSelectedSuggestion(_this.suggestionStore.suggestions.length - 1);
|
|
}
|
|
else if (keyCode === Utilities_1.KeyCodes.down) {
|
|
_this.suggestionStore.setSelectedSuggestion(0);
|
|
}
|
|
}
|
|
};
|
|
_this._getDescribedBy = function (items, hasError) {
|
|
var describedBy = '';
|
|
if (items.length > 0) {
|
|
describedBy += _this._ariaMap.selectedItems + ' ';
|
|
}
|
|
if (hasError) {
|
|
describedBy += _this._ariaMap.error;
|
|
}
|
|
return describedBy;
|
|
};
|
|
_this.onInputChange = function (value) {
|
|
_this.updateValue(value);
|
|
_this.setState({
|
|
moreSuggestionsAvailable: true,
|
|
isMostRecentlyUsedVisible: false,
|
|
});
|
|
};
|
|
_this.onSuggestionClick = function (ev, item, index) {
|
|
_this.addItemByIndex(index);
|
|
};
|
|
_this.onSuggestionRemove = function (ev, item, index) {
|
|
if (_this.props.onRemoveSuggestion) {
|
|
_this.props.onRemoveSuggestion(item);
|
|
}
|
|
_this.suggestionStore.removeSuggestion(index);
|
|
};
|
|
_this.onInputFocus = function (ev) {
|
|
_this.selection.setAllSelected(false);
|
|
// Only trigger all of the focus if this component isn't already focused.
|
|
// For example when an item is selected or removed from the selected list it should be treated
|
|
// as though the input is still focused.
|
|
if (!_this.state.isFocused) {
|
|
_this._userTriggeredSuggestions();
|
|
if (_this.props.inputProps && _this.props.inputProps.onFocus) {
|
|
_this.props.inputProps.onFocus(ev);
|
|
}
|
|
}
|
|
};
|
|
_this.onInputBlur = function (ev) {
|
|
if (_this.props.inputProps && _this.props.inputProps.onBlur) {
|
|
_this.props.inputProps.onBlur(ev);
|
|
}
|
|
};
|
|
_this.onBlur = function (ev) {
|
|
if (_this.state.isFocused) {
|
|
// Only blur the entire component if an unrelated element gets focus.
|
|
// Otherwise treat it as though it still has focus.
|
|
// Do nothing if the blur is coming from something
|
|
// inside the comboBox root or the comboBox menu since
|
|
// it we are not really bluring from the whole comboBox
|
|
var relatedTarget = ev.relatedTarget;
|
|
if (ev.relatedTarget === null) {
|
|
// In IE11, due to lack of support, event.relatedTarget is always
|
|
// null making every onBlur call to be "outside" of the ComboBox
|
|
// even when it's not. Using document.activeElement is another way
|
|
// for us to be able to get what the relatedTarget without relying
|
|
// on the event
|
|
relatedTarget = (0, dom_1.getDocumentEx)(_this.context).activeElement;
|
|
}
|
|
if (relatedTarget && !(0, Utilities_1.elementContains)(_this.root.current, relatedTarget)) {
|
|
_this.setState({ isFocused: false });
|
|
if (_this.props.onBlur) {
|
|
_this.props.onBlur(ev);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
/**
|
|
* Resets focus to last element in wrapper div if clicking back into Picker that has hit item limit
|
|
*/
|
|
_this.onWrapperClick = function (ev) {
|
|
if (_this.state.items.length && !_this.canAddItems()) {
|
|
_this.resetFocus(_this.state.items.length - 1);
|
|
}
|
|
};
|
|
/**
|
|
* Reveals suggestions any time the user clicks on the input element
|
|
* without shifting focus.
|
|
*/
|
|
_this.onClick = function (ev) {
|
|
if (_this.props.inputProps !== undefined && _this.props.inputProps.onClick !== undefined) {
|
|
_this.props.inputProps.onClick(ev);
|
|
}
|
|
// Only primary (left) clicks show suggestions.
|
|
if (ev.button === 0) {
|
|
_this._userTriggeredSuggestions();
|
|
}
|
|
};
|
|
_this.onFocus = function () {
|
|
if (!_this.state.isFocused) {
|
|
_this.setState({ isFocused: true });
|
|
}
|
|
};
|
|
_this.onKeyDown = function (ev) {
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
var keyCode = ev.which;
|
|
switch (keyCode) {
|
|
case Utilities_1.KeyCodes.escape:
|
|
if (_this.state.suggestionsVisible) {
|
|
_this.setState({ suggestionsVisible: false });
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
}
|
|
break;
|
|
case Utilities_1.KeyCodes.tab:
|
|
case Utilities_1.KeyCodes.enter:
|
|
if (_this.suggestionElement.current && _this.suggestionElement.current.hasSuggestedActionSelected()) {
|
|
_this.suggestionElement.current.executeSelectedAction();
|
|
}
|
|
else if (!ev.shiftKey && _this.suggestionStore.hasSelectedSuggestion() && _this.state.suggestionsVisible) {
|
|
_this.completeSuggestion();
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
}
|
|
else {
|
|
_this._completeGenericSuggestion();
|
|
}
|
|
break;
|
|
case Utilities_1.KeyCodes.backspace:
|
|
if (!_this.props.disabled) {
|
|
_this.onBackspace(ev);
|
|
}
|
|
ev.stopPropagation();
|
|
break;
|
|
case Utilities_1.KeyCodes.del:
|
|
if (!_this.props.disabled) {
|
|
if (_this.input.current &&
|
|
ev.target === _this.input.current.inputElement &&
|
|
_this.state.suggestionsVisible &&
|
|
_this.suggestionStore.currentIndex !== -1) {
|
|
if (_this.props.onRemoveSuggestion) {
|
|
_this.props.onRemoveSuggestion(_this.suggestionStore.currentSuggestion.item);
|
|
}
|
|
_this.suggestionStore.removeSuggestion(_this.suggestionStore.currentIndex);
|
|
_this.forceUpdate();
|
|
}
|
|
else {
|
|
_this.onBackspace(ev);
|
|
}
|
|
}
|
|
ev.stopPropagation();
|
|
break;
|
|
case Utilities_1.KeyCodes.up:
|
|
if (_this.input.current && ev.target === _this.input.current.inputElement && _this.state.suggestionsVisible) {
|
|
if (_this.suggestionElement.current &&
|
|
_this.suggestionElement.current.tryHandleKeyDown(keyCode, _this.suggestionStore.currentIndex)) {
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
_this.forceUpdate();
|
|
}
|
|
else {
|
|
if (_this.suggestionElement.current &&
|
|
_this.suggestionElement.current.hasSuggestedAction() &&
|
|
_this.suggestionStore.currentIndex === 0) {
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
_this.suggestionElement.current.focusAboveSuggestions();
|
|
_this.suggestionStore.deselectAllSuggestions();
|
|
_this.forceUpdate();
|
|
}
|
|
else {
|
|
if (_this.suggestionStore.previousSuggestion()) {
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
_this.onSuggestionSelect();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case Utilities_1.KeyCodes.down:
|
|
if (_this.input.current && ev.target === _this.input.current.inputElement && _this.state.suggestionsVisible) {
|
|
if (_this.suggestionElement.current &&
|
|
_this.suggestionElement.current.tryHandleKeyDown(keyCode, _this.suggestionStore.currentIndex)) {
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
_this.forceUpdate();
|
|
}
|
|
else {
|
|
if (_this.suggestionElement.current &&
|
|
_this.suggestionElement.current.hasSuggestedAction() &&
|
|
_this.suggestionStore.currentIndex + 1 === _this.suggestionStore.suggestions.length) {
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
_this.suggestionElement.current.focusBelowSuggestions();
|
|
_this.suggestionStore.deselectAllSuggestions();
|
|
_this.forceUpdate();
|
|
}
|
|
else {
|
|
if (_this.suggestionStore.nextSuggestion()) {
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
_this.onSuggestionSelect();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
};
|
|
_this.onItemChange = function (changedItem, index) {
|
|
var items = _this.state.items;
|
|
if (index >= 0) {
|
|
var newItems = items;
|
|
newItems[index] = changedItem;
|
|
_this._updateSelectedItems(newItems);
|
|
}
|
|
};
|
|
_this.onGetMoreResults = function () {
|
|
_this.setState({
|
|
isSearching: true,
|
|
}, function () {
|
|
if (_this.props.onGetMoreResults && _this.input.current) {
|
|
var suggestions = _this.props.onGetMoreResults(_this.input.current.value, _this.state.items);
|
|
var suggestionsArray = suggestions;
|
|
var suggestionsPromiseLike = suggestions;
|
|
if (Array.isArray(suggestionsArray)) {
|
|
_this.updateSuggestions(suggestionsArray);
|
|
_this.setState({ isSearching: false });
|
|
}
|
|
else if (suggestionsPromiseLike.then) {
|
|
suggestionsPromiseLike.then(function (newSuggestions) {
|
|
_this.updateSuggestions(newSuggestions);
|
|
_this.setState({ isSearching: false });
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
_this.setState({ isSearching: false });
|
|
}
|
|
if (_this.input.current) {
|
|
_this.input.current.focus();
|
|
}
|
|
_this.setState({
|
|
moreSuggestionsAvailable: false,
|
|
isResultsFooterVisible: true,
|
|
});
|
|
});
|
|
};
|
|
_this.completeSelection = function (item) {
|
|
_this.addItem(item);
|
|
_this.updateValue('');
|
|
if (_this.input.current) {
|
|
_this.input.current.clear();
|
|
}
|
|
_this.setState({ suggestionsVisible: false });
|
|
};
|
|
_this.addItemByIndex = function (index) {
|
|
_this.completeSelection(_this.suggestionStore.getSuggestionAtIndex(index).item);
|
|
};
|
|
_this.addItem = function (item) {
|
|
var processedItem = _this.props.onItemSelected
|
|
? _this.props.onItemSelected(item)
|
|
: item;
|
|
if (processedItem === null) {
|
|
return;
|
|
}
|
|
var processedItemObject = processedItem;
|
|
var processedItemPromiseLike = processedItem;
|
|
if (processedItemPromiseLike && processedItemPromiseLike.then) {
|
|
processedItemPromiseLike.then(function (resolvedProcessedItem) {
|
|
var newItems = _this.state.items.concat([resolvedProcessedItem]);
|
|
_this._updateSelectedItems(newItems);
|
|
});
|
|
}
|
|
else {
|
|
var newItems = _this.state.items.concat([processedItemObject]);
|
|
_this._updateSelectedItems(newItems);
|
|
}
|
|
_this.setState({ suggestedDisplayValue: '', selectionRemoved: undefined });
|
|
};
|
|
_this.removeItem = function (item) {
|
|
var items = _this.state.items;
|
|
var index = items.indexOf(item);
|
|
if (index >= 0) {
|
|
var newItems = items.slice(0, index).concat(items.slice(index + 1));
|
|
_this.setState({ selectionRemoved: item });
|
|
_this._updateSelectedItems(newItems);
|
|
// reset selection removed text after a timeout so it isn't reached by screen reader virtual cursor.
|
|
// the exact timing isn't important, the live region will fully read even if the text is removed.
|
|
_this._async.setTimeout(function () {
|
|
_this.setState({ selectionRemoved: undefined });
|
|
}, 1000);
|
|
}
|
|
};
|
|
_this.removeItems = function (itemsToRemove) {
|
|
var items = _this.state.items;
|
|
var newItems = items.filter(function (item) { return itemsToRemove.indexOf(item) === -1; });
|
|
_this._updateSelectedItems(newItems);
|
|
};
|
|
/**
|
|
* @deprecated this is no longer necessary as focuszone has been removed
|
|
*/
|
|
_this._shouldFocusZoneEnterInnerZone = function (ev) {
|
|
// If suggestions are shown const up/down keys control them, otherwise allow them through to control the focusZone.
|
|
if (_this.state.suggestionsVisible) {
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
switch (ev.which) {
|
|
case Utilities_1.KeyCodes.up:
|
|
case Utilities_1.KeyCodes.down:
|
|
return true;
|
|
}
|
|
}
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
if (ev.which === Utilities_1.KeyCodes.enter) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
_this._onResolveSuggestions = function (updatedValue) {
|
|
var suggestions = _this.props.onResolveSuggestions(updatedValue, _this.state.items);
|
|
if (suggestions !== null) {
|
|
_this.updateSuggestionsList(suggestions, updatedValue);
|
|
}
|
|
};
|
|
_this._completeGenericSuggestion = function () {
|
|
if (_this.props.onValidateInput &&
|
|
_this.input.current &&
|
|
_this.props.onValidateInput(_this.input.current.value) !== BasePicker_types_1.ValidationState.invalid &&
|
|
_this.props.createGenericItem) {
|
|
var itemToConvert = _this.props.createGenericItem(_this.input.current.value, _this.props.onValidateInput(_this.input.current.value));
|
|
_this.suggestionStore.createGenericSuggestion(itemToConvert);
|
|
_this.completeSuggestion();
|
|
}
|
|
};
|
|
/**
|
|
* This should be called when the user does something other than use text entry to trigger suggestions.
|
|
*
|
|
*/
|
|
_this._userTriggeredSuggestions = function () {
|
|
if (!_this.state.suggestionsVisible) {
|
|
var input = _this.input.current ? _this.input.current.value : '';
|
|
if (!input) {
|
|
_this.onEmptyInputFocus();
|
|
}
|
|
else {
|
|
if (_this.suggestionStore.suggestions.length === 0) {
|
|
_this._onResolveSuggestionsDebounced(input);
|
|
}
|
|
else {
|
|
_this.setState({
|
|
isMostRecentlyUsedVisible: false,
|
|
suggestionsVisible: true,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
};
|
|
(0, Utilities_1.initializeComponentRef)(_this);
|
|
var items = basePickerProps.selectedItems || basePickerProps.defaultSelectedItems || [];
|
|
_this._id = (0, Utilities_1.getId)();
|
|
_this._ariaMap = {
|
|
selectedItems: "selected-items-".concat(_this._id),
|
|
selectedSuggestionAlert: "selected-suggestion-alert-".concat(_this._id),
|
|
suggestionList: "suggestion-list-".concat(_this._id),
|
|
combobox: "combobox-".concat(_this._id),
|
|
error: "error-".concat(_this._id),
|
|
};
|
|
_this.suggestionStore = new SuggestionsController_1.SuggestionsController();
|
|
_this.selection = new index_1.Selection({ onSelectionChanged: function () { return _this.onSelectionChange(); } });
|
|
_this.selection.setItems(items);
|
|
_this.state = {
|
|
items: items,
|
|
suggestedDisplayValue: '',
|
|
isMostRecentlyUsedVisible: false,
|
|
moreSuggestionsAvailable: false,
|
|
isFocused: false,
|
|
isSearching: false,
|
|
selectedIndices: [],
|
|
selectionRemoved: undefined,
|
|
};
|
|
return _this;
|
|
}
|
|
BasePicker.getDerivedStateFromProps = function (newProps) {
|
|
if (newProps.selectedItems) {
|
|
return { items: newProps.selectedItems };
|
|
}
|
|
return null;
|
|
};
|
|
Object.defineProperty(BasePicker.prototype, "items", {
|
|
get: function () {
|
|
return this.state.items;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
BasePicker.prototype.componentDidMount = function () {
|
|
this._isMounted = true;
|
|
this._async = new Utilities_1.Async(this);
|
|
this._updateErrorMessage(this.state.items);
|
|
this.selection.setItems(this.state.items);
|
|
this._onResolveSuggestionsDebounced = this._async.debounce(this._onResolveSuggestions, this.props.resolveDelay);
|
|
};
|
|
BasePicker.prototype.componentDidUpdate = function (oldProps, oldState) {
|
|
var _this = this;
|
|
if (this.state.items && this.state.items !== oldState.items) {
|
|
var currentSelectedIndex = this.selection.getSelectedIndices()[0];
|
|
this.selection.setItems(this.state.items);
|
|
if (this.state.isFocused) {
|
|
// Reset focus and selection so that selected item stays in sync if something
|
|
// has been removed
|
|
if (this.state.items.length < oldState.items.length) {
|
|
this.selection.setIndexSelected(currentSelectedIndex, false, true);
|
|
this.resetFocus(currentSelectedIndex);
|
|
}
|
|
// Reset focus to last item if the input is removed
|
|
else if (this.state.items.length > oldState.items.length && !this.canAddItems()) {
|
|
this.resetFocus(this.state.items.length - 1);
|
|
}
|
|
}
|
|
}
|
|
this._updateErrorMessage(this.state.items);
|
|
// handle dismiss buffer after suggestions are opened
|
|
if (this.state.suggestionsVisible && !oldState.suggestionsVisible) {
|
|
this._overrideScrollDismiss = true;
|
|
this._async.clearTimeout(this._overrideScrollDimissTimeout);
|
|
this._overrideScrollDimissTimeout = this._async.setTimeout(function () {
|
|
_this._overrideScrollDismiss = false;
|
|
}, 100);
|
|
}
|
|
};
|
|
BasePicker.prototype.componentWillUnmount = function () {
|
|
this._isMounted = false;
|
|
if (this.currentPromise) {
|
|
this.currentPromise = undefined;
|
|
}
|
|
this._async.dispose();
|
|
};
|
|
BasePicker.prototype.focus = function () {
|
|
if (this.input.current) {
|
|
this.input.current.focus();
|
|
}
|
|
};
|
|
BasePicker.prototype.focusInput = function () {
|
|
if (this.input.current) {
|
|
this.input.current.focus();
|
|
}
|
|
};
|
|
BasePicker.prototype.completeSuggestion = function (forceComplete) {
|
|
if (this.suggestionStore.hasSelectedSuggestion() && this.input.current) {
|
|
this.completeSelection(this.suggestionStore.currentSuggestion.item);
|
|
}
|
|
else if (forceComplete) {
|
|
this._completeGenericSuggestion();
|
|
}
|
|
};
|
|
BasePicker.prototype.render = function () {
|
|
var _a, _b, _c, _d;
|
|
var _e = this.state, suggestedDisplayValue = _e.suggestedDisplayValue, isFocused = _e.isFocused, items = _e.items;
|
|
var _f = this.props, className = _f.className, inputProps = _f.inputProps, disabled = _f.disabled, selectionAriaLabel = _f.selectionAriaLabel, _g = _f.selectionRole, selectionRole = _g === void 0 ? 'list' : _g, theme = _f.theme, styles = _f.styles;
|
|
var suggestionsVisible = !!this.state.suggestionsVisible;
|
|
var suggestionsAvailable = suggestionsVisible ? this._ariaMap.suggestionList : undefined;
|
|
var hasError = !!((_a = this.state.errorMessage) !== null && _a !== void 0 ? _a : this.props.errorMessage);
|
|
// TODO
|
|
// Clean this up by leaving only the first part after removing support for SASS.
|
|
// Currently we can not remove the SASS styles from BasePicker class because it
|
|
// might be used by consumers who created custom pickers from extending from
|
|
// this base class and have not used the new 'styles' prop.
|
|
// We check for 'styles' prop which is going to be injected by the 'styled' HOC
|
|
// for every other already existing picker variant (PeoplePicker, TagPicker)
|
|
// so that we can use the CSS-in-JS styles. If the check fails (ex: custom picker),
|
|
// then we just use the old SASS styles instead.
|
|
var classNames = styles
|
|
? getClassNames(styles, {
|
|
theme: theme,
|
|
className: className,
|
|
isFocused: isFocused,
|
|
disabled: disabled,
|
|
hasErrorMessage: hasError,
|
|
inputClassName: inputProps && inputProps.className,
|
|
})
|
|
: {
|
|
root: (0, Utilities_1.css)('ms-BasePicker', className ? className : ''),
|
|
error: 'ms-BasePicker-error',
|
|
text: (0, Utilities_1.css)('ms-BasePicker-text', legacyStyles.pickerText, this.state.isFocused && legacyStyles.inputFocused),
|
|
itemsWrapper: legacyStyles.pickerItems,
|
|
input: (0, Utilities_1.css)('ms-BasePicker-input', legacyStyles.pickerInput, inputProps && inputProps.className),
|
|
screenReaderText: legacyStyles.screenReaderOnly,
|
|
};
|
|
var comboLabel = this.props['aria-label'] || (inputProps === null || inputProps === void 0 ? void 0 : inputProps['aria-label']);
|
|
var inputId = (_b = inputProps === null || inputProps === void 0 ? void 0 : inputProps.id) !== null && _b !== void 0 ? _b : this._ariaMap.combobox;
|
|
// selectionAriaLabel is contained in a separate <span> rather than an aria-label on the items list
|
|
// because if the items list has an aria-label, the aria-describedby on the input will only read
|
|
// that label instead of all the selected items. Using aria-labelledby instead fixes this, since
|
|
// aria-describedby and aria-labelledby will not follow a second aria-labelledby
|
|
return (React.createElement("div", { ref: this.root, className: classNames.root, onKeyDown: this.onKeyDown, onFocus: this.onFocus, onBlur: this.onBlur, onClick: this.onWrapperClick },
|
|
this.renderLabel(inputId, (_c = classNames.subComponentStyles) === null || _c === void 0 ? void 0 : _c.label),
|
|
this.renderCustomAlert(classNames.screenReaderText),
|
|
React.createElement("span", { id: "".concat(this._ariaMap.selectedItems, "-label"), hidden: true }, selectionAriaLabel || comboLabel),
|
|
React.createElement(index_1.SelectionZone, { selection: this.selection, selectionMode: index_1.SelectionMode.multiple },
|
|
React.createElement("div", { className: classNames.text, "aria-owns": suggestionsAvailable },
|
|
items.length > 0 && (React.createElement("span", { id: this._ariaMap.selectedItems, className: classNames.itemsWrapper, role: selectionRole, "aria-labelledby": "".concat(this._ariaMap.selectedItems, "-label") }, this.renderItems())),
|
|
this.canAddItems() && (React.createElement(index_2.Autofill, tslib_1.__assign({ spellCheck: false }, inputProps, { className: classNames.input, componentRef: this.input, id: inputId, onClick: this.onClick, onFocus: this.onInputFocus, onBlur: this.onInputBlur, onInputValueChange: this.onInputChange, suggestedDisplayValue: suggestedDisplayValue, "aria-activedescendant": suggestionsVisible ? this.getActiveDescendant() : undefined, "aria-controls": suggestionsAvailable, "aria-describedby": this._getDescribedBy(items, hasError), "aria-expanded": suggestionsVisible, "aria-haspopup": "listbox", "aria-label": comboLabel, role: "combobox", disabled: disabled,
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
onInputChange: this.props.onInputChange }))))),
|
|
this.renderError(classNames.error),
|
|
this.renderSuggestions((_d = classNames.subComponentStyles) === null || _d === void 0 ? void 0 : _d.callout)));
|
|
};
|
|
BasePicker.prototype.canAddItems = function () {
|
|
var items = this.state.items;
|
|
var itemLimit = this.props.itemLimit;
|
|
return itemLimit === undefined || items.length < itemLimit;
|
|
};
|
|
BasePicker.prototype.renderLabel = function (inputId, styles) {
|
|
var _a = this.props, label = _a.label, disabled = _a.disabled, required = _a.required;
|
|
if (!label) {
|
|
return null;
|
|
}
|
|
return (React.createElement(Label_1.Label, { className: "ms-BasePicker-label", styles: styles, disabled: disabled, required: required, htmlFor: inputId }, label));
|
|
};
|
|
BasePicker.prototype.renderError = function (className) {
|
|
var _a = this.props.errorMessage, errorMessage = _a === void 0 ? this.state.errorMessage : _a;
|
|
if (!errorMessage) {
|
|
return null;
|
|
}
|
|
return (React.createElement("div", { role: "alert", id: this._ariaMap.error, className: className }, errorMessage));
|
|
};
|
|
BasePicker.prototype.renderSuggestions = function (styles) {
|
|
var _this = this;
|
|
var StyledTypedSuggestions = this._styledSuggestions;
|
|
return this.state.suggestionsVisible && this.input ? (React.createElement(Callout_1.Callout, tslib_1.__assign({ isBeakVisible: false, gapSpace: 5, target: this.input.current ? this.input.current.inputElement : undefined, onDismiss: this.dismissSuggestions, directionalHint: DirectionalHint_1.DirectionalHint.bottomLeftEdge, directionalHintForRTL: DirectionalHint_1.DirectionalHint.bottomRightEdge,
|
|
// eslint-disable-next-line react/jsx-no-bind
|
|
preventDismissOnEvent: function (ev) { return _this._preventDismissOnScrollOrResize(ev); }, styles: styles }, this.props.pickerCalloutProps),
|
|
React.createElement(StyledTypedSuggestions
|
|
// Assumed to set in derived component's defaultProps
|
|
, tslib_1.__assign({
|
|
// Assumed to set in derived component's defaultProps
|
|
onRenderSuggestion: this.props.onRenderSuggestionsItem, onSuggestionClick: this.onSuggestionClick, onSuggestionRemove: this.onSuggestionRemove, suggestions: this.suggestionStore.getSuggestions(), componentRef: this.suggestionElement, onGetMoreResults: this.onGetMoreResults, moreSuggestionsAvailable: this.state.moreSuggestionsAvailable, isLoading: this.state.suggestionsLoading, isExtendedLoading: this.state.suggestionsExtendedLoading, isSearching: this.state.isSearching, isMostRecentlyUsedVisible: this.state.isMostRecentlyUsedVisible, isResultsFooterVisible: this.state.isResultsFooterVisible, refocusSuggestions: this.refocusSuggestions, removeSuggestionAriaLabel: this.props.removeButtonAriaLabel, suggestionsListId: this._ariaMap.suggestionList, createGenericItem: this._completeGenericSuggestion }, this.props.pickerSuggestionsProps)))) : null;
|
|
};
|
|
BasePicker.prototype.renderItems = function () {
|
|
var _this = this;
|
|
var _a = this.props, disabled = _a.disabled, removeButtonAriaLabel = _a.removeButtonAriaLabel, removeButtonIconProps = _a.removeButtonIconProps;
|
|
var onRenderItem = this.props.onRenderItem;
|
|
var _b = this.state, items = _b.items, selectedIndices = _b.selectedIndices;
|
|
return items.map(function (item, index) {
|
|
return onRenderItem({
|
|
item: item,
|
|
index: index,
|
|
key: item.key ? item.key : index,
|
|
selected: selectedIndices.indexOf(index) !== -1,
|
|
onRemoveItem: function () { return _this.removeItem(item); },
|
|
disabled: disabled,
|
|
onItemChange: _this.onItemChange,
|
|
removeButtonAriaLabel: removeButtonAriaLabel,
|
|
removeButtonIconProps: removeButtonIconProps,
|
|
});
|
|
});
|
|
};
|
|
BasePicker.prototype.resetFocus = function (index) {
|
|
var items = this.state.items;
|
|
if (items.length) {
|
|
// default to focusing the last item
|
|
index = index !== null && index !== void 0 ? index : items.length - 1;
|
|
var newEl = this.root.current &&
|
|
this.root.current.querySelectorAll('[data-selection-index] > button')[Math.min(index, items.length - 1)];
|
|
if (newEl) {
|
|
newEl.focus();
|
|
}
|
|
}
|
|
else {
|
|
if (this.input.current) {
|
|
this.input.current.focus();
|
|
}
|
|
}
|
|
};
|
|
BasePicker.prototype.onSuggestionSelect = function () {
|
|
if (this.suggestionStore.currentSuggestion) {
|
|
var currentValue = this.input.current ? this.input.current.value : '';
|
|
var itemValue = this._getTextFromItem(this.suggestionStore.currentSuggestion.item, currentValue);
|
|
this.setState({ suggestedDisplayValue: itemValue });
|
|
}
|
|
};
|
|
BasePicker.prototype.onSelectionChange = function () {
|
|
this.setState({
|
|
selectedIndices: this.selection.getSelectedIndices(),
|
|
});
|
|
};
|
|
BasePicker.prototype.updateSuggestions = function (suggestions) {
|
|
var _a;
|
|
var maxSuggestionsCount = (_a = this.props.pickerSuggestionsProps) === null || _a === void 0 ? void 0 : _a.resultsMaximumNumber;
|
|
this.suggestionStore.updateSuggestions(suggestions, 0, maxSuggestionsCount);
|
|
this.forceUpdate();
|
|
};
|
|
/**
|
|
* Only to be called when there is nothing in the input. Checks to see if the consumer has
|
|
* provided a function to resolve suggestions
|
|
*/
|
|
BasePicker.prototype.onEmptyInputFocus = function () {
|
|
var emptyResolveSuggestions = this.props.onEmptyResolveSuggestions
|
|
? this.props.onEmptyResolveSuggestions
|
|
: // eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
this.props.onEmptyInputFocus;
|
|
// Only attempt to resolve suggestions if it exists
|
|
if (emptyResolveSuggestions) {
|
|
var suggestions = emptyResolveSuggestions(this.state.items);
|
|
this.updateSuggestionsList(suggestions);
|
|
this.setState({
|
|
isMostRecentlyUsedVisible: true,
|
|
suggestionsVisible: true,
|
|
moreSuggestionsAvailable: false,
|
|
});
|
|
}
|
|
};
|
|
BasePicker.prototype.updateValue = function (updatedValue) {
|
|
this._onResolveSuggestionsDebounced(updatedValue);
|
|
};
|
|
BasePicker.prototype.updateSuggestionsList = function (suggestions, updatedValue) {
|
|
var _this = this;
|
|
var _a;
|
|
// Check to see if the returned value is an array, if it is then just pass it into the next function .
|
|
// If the returned value is not an array then check to see if it's a promise or PromiseLike.
|
|
// If it is then resolve it asynchronously.
|
|
if (Array.isArray(suggestions)) {
|
|
this._updateAndResolveValue(updatedValue, suggestions);
|
|
}
|
|
else if (suggestions && suggestions.then) {
|
|
this.setState({
|
|
suggestionsLoading: true,
|
|
});
|
|
this._startLoadTimer();
|
|
// Clear suggestions
|
|
this.suggestionStore.updateSuggestions([]);
|
|
if (updatedValue !== undefined) {
|
|
this.setState({
|
|
suggestionsVisible: this._getShowSuggestions(),
|
|
});
|
|
}
|
|
else {
|
|
this.setState({
|
|
suggestionsVisible: this.input.current && this.input.current.inputElement === ((_a = (0, dom_1.getDocumentEx)(this.context)) === null || _a === void 0 ? void 0 : _a.activeElement),
|
|
});
|
|
}
|
|
// Ensure that the promise will only use the callback if it was the most recent one.
|
|
this.currentPromise = suggestions;
|
|
suggestions.then(function (newSuggestions) {
|
|
if (suggestions === _this.currentPromise) {
|
|
_this._updateAndResolveValue(updatedValue, newSuggestions);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
BasePicker.prototype.resolveNewValue = function (updatedValue, suggestions) {
|
|
var _this = this;
|
|
this.updateSuggestions(suggestions);
|
|
var itemValue = undefined;
|
|
if (this.suggestionStore.currentSuggestion) {
|
|
itemValue = this._getTextFromItem(this.suggestionStore.currentSuggestion.item, updatedValue);
|
|
}
|
|
// Only set suggestionloading to false after there has been time for the new suggestions to flow
|
|
// to the suggestions list. This is to ensure that the suggestions are available before aria-activedescendant
|
|
// is set so that screen readers will read out the first selected option.
|
|
this.setState({
|
|
suggestedDisplayValue: itemValue,
|
|
suggestionsVisible: this._getShowSuggestions(),
|
|
}, function () { return _this.setState({ suggestionsLoading: false, suggestionsExtendedLoading: false }); });
|
|
};
|
|
BasePicker.prototype.onChange = function (items) {
|
|
if (this.props.onChange) {
|
|
this.props.onChange(items);
|
|
}
|
|
};
|
|
// This is protected because we may expect the backspace key to work differently in a different kind of picker.
|
|
// This lets the subclass override it and provide it's own onBackspace. For an example see the BasePickerListBelow
|
|
BasePicker.prototype.onBackspace = function (ev) {
|
|
if ((this.state.items.length && !this.input.current) ||
|
|
(this.input.current && !this.input.current.isValueSelected && this.input.current.cursorLocation === 0)) {
|
|
if (this.selection.getSelectedCount() > 0) {
|
|
this.removeItems(this.selection.getSelection());
|
|
}
|
|
else {
|
|
this.removeItem(this.state.items[this.state.items.length - 1]);
|
|
}
|
|
}
|
|
};
|
|
BasePicker.prototype.getActiveDescendant = function () {
|
|
var _a;
|
|
if (this.state.suggestionsLoading) {
|
|
return undefined;
|
|
}
|
|
var currentIndex = this.suggestionStore.currentIndex;
|
|
if (currentIndex < 0) {
|
|
// if the suggestions element has actions and the currentIndex does not point to a suggestion,
|
|
// return the action id
|
|
if ((_a = this.suggestionElement.current) === null || _a === void 0 ? void 0 : _a.hasSuggestedAction()) {
|
|
return 'sug-selectedAction';
|
|
}
|
|
// If there are no suggestions and no action suggested, then return the ID for the no results found.
|
|
if (this.suggestionStore.suggestions.length === 0) {
|
|
return 'sug-noResultsFound';
|
|
}
|
|
return undefined;
|
|
}
|
|
else {
|
|
return "sug-".concat(currentIndex);
|
|
}
|
|
};
|
|
/** @deprecated use renderCustomAlert instead */
|
|
BasePicker.prototype.getSuggestionsAlert = function (suggestionAlertClassName) {
|
|
if (suggestionAlertClassName === void 0) { suggestionAlertClassName = legacyStyles.screenReaderOnly; }
|
|
var currentIndex = this.suggestionStore.currentIndex;
|
|
if (this.props.enableSelectedSuggestionAlert) {
|
|
var selectedSuggestion = currentIndex > -1 ? this.suggestionStore.getSuggestionAtIndex(this.suggestionStore.currentIndex) : undefined;
|
|
var selectedSuggestionAlertText = selectedSuggestion ? selectedSuggestion.ariaLabel : undefined;
|
|
// keeping the id/className here for legacy support
|
|
return (React.createElement("div", { id: this._ariaMap.selectedSuggestionAlert, className: suggestionAlertClassName }, "".concat(selectedSuggestionAlertText, " ")));
|
|
}
|
|
};
|
|
BasePicker.prototype.renderCustomAlert = function (alertClassName) {
|
|
if (alertClassName === void 0) { alertClassName = legacyStyles.screenReaderOnly; }
|
|
var _a = this.props.suggestionRemovedText, suggestionRemovedText = _a === void 0 ? 'removed {0}' : _a;
|
|
var removedItemText = '';
|
|
if (this.state.selectionRemoved) {
|
|
var itemName = this._getTextFromItem(this.state.selectionRemoved, '');
|
|
removedItemText = (0, Utilities_1.format)(suggestionRemovedText, itemName);
|
|
}
|
|
return (React.createElement("div", { className: alertClassName, id: this._ariaMap.selectedSuggestionAlert, "aria-live": "assertive" },
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
this.getSuggestionsAlert(alertClassName),
|
|
removedItemText));
|
|
};
|
|
// do not dismiss if the window resizes or scrolls within 100ms of opening
|
|
// this prevents the Android issue where pickers immediately dismiss on open, because the keyboard appears
|
|
BasePicker.prototype._preventDismissOnScrollOrResize = function (ev) {
|
|
if (this._overrideScrollDismiss && (ev.type === 'scroll' || ev.type === 'resize')) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
/** If suggestions are still loading after a predefined amount of time, set state to show user alert */
|
|
BasePicker.prototype._startLoadTimer = function () {
|
|
var _this = this;
|
|
this._async.setTimeout(function () {
|
|
if (_this.state.suggestionsLoading) {
|
|
_this.setState({ suggestionsExtendedLoading: true });
|
|
}
|
|
}, EXTENDED_LOAD_TIME);
|
|
};
|
|
/**
|
|
* Takes in the current updated value and either resolves it with the new suggestions
|
|
* or if updated value is undefined then it clears out currently suggested items
|
|
*/
|
|
BasePicker.prototype._updateAndResolveValue = function (updatedValue, newSuggestions) {
|
|
var _a;
|
|
if (updatedValue !== undefined) {
|
|
this.resolveNewValue(updatedValue, newSuggestions);
|
|
}
|
|
else {
|
|
var maxSuggestionsCount = (_a = this.props.pickerSuggestionsProps) === null || _a === void 0 ? void 0 : _a.resultsMaximumNumber;
|
|
this.suggestionStore.updateSuggestions(newSuggestions, -1, maxSuggestionsCount);
|
|
if (this.state.suggestionsLoading) {
|
|
this.setState({
|
|
suggestionsLoading: false,
|
|
suggestionsExtendedLoading: false,
|
|
});
|
|
}
|
|
}
|
|
};
|
|
BasePicker.prototype._getErrorMessage = function (items) {
|
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
var errorMessage, err_1;
|
|
return tslib_1.__generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
if (this.props.errorMessage) {
|
|
return [2 /*return*/, this.props.errorMessage];
|
|
}
|
|
if (!this.props.onGetErrorMessage) return [3 /*break*/, 8];
|
|
_a.label = 1;
|
|
case 1:
|
|
_a.trys.push([1, 7, , 8]);
|
|
errorMessage = this.props.onGetErrorMessage(items);
|
|
if (!errorMessage) return [3 /*break*/, 5];
|
|
if (!errorMessage.then) return [3 /*break*/, 3];
|
|
return [4 /*yield*/, errorMessage];
|
|
case 2: return [2 /*return*/, _a.sent()];
|
|
case 3: return [2 /*return*/, errorMessage];
|
|
case 4: return [3 /*break*/, 6];
|
|
case 5: return [2 /*return*/, undefined];
|
|
case 6: return [3 /*break*/, 8];
|
|
case 7:
|
|
err_1 = _a.sent();
|
|
return [3 /*break*/, 8];
|
|
case 8: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
BasePicker.prototype._updateErrorMessage = function (items) {
|
|
var _this = this;
|
|
var newErrorMessage;
|
|
this._getErrorMessage(items)
|
|
.then(function (errorMessage) {
|
|
newErrorMessage = errorMessage;
|
|
})
|
|
.catch(function () {
|
|
/* NO-OP */
|
|
})
|
|
.finally(function () {
|
|
if (_this._isMounted && newErrorMessage !== _this.state.errorMessage) {
|
|
_this.setState({ errorMessage: newErrorMessage });
|
|
}
|
|
});
|
|
};
|
|
/**
|
|
* Controls what happens whenever there is an action that impacts the selected items.
|
|
* If `selectedItems` is provided, this will act as a controlled component and it will not update its own state.
|
|
*/
|
|
BasePicker.prototype._updateSelectedItems = function (items) {
|
|
var _this = this;
|
|
if (this.props.selectedItems) {
|
|
// If the component is a controlled component then the controlling component will need to add or remove the items.
|
|
this.onChange(items);
|
|
}
|
|
else {
|
|
this.setState({ items: items }, function () {
|
|
_this._updateErrorMessage(items);
|
|
_this._onSelectedItemsUpdated(items);
|
|
});
|
|
}
|
|
};
|
|
BasePicker.prototype._onSelectedItemsUpdated = function (items) {
|
|
this.onChange(items);
|
|
};
|
|
/**
|
|
* Suggestions are normally shown after the user updates text and the text
|
|
* is non-empty, but also when the user clicks on the input element.
|
|
* @returns True if suggestions should be shown.
|
|
*/
|
|
BasePicker.prototype._getShowSuggestions = function () {
|
|
var _a;
|
|
var areSuggestionsVisible = this.input.current !== undefined &&
|
|
this.input.current !== null &&
|
|
this.input.current.inputElement === ((_a = (0, dom_1.getDocumentEx)(this.context)) === null || _a === void 0 ? void 0 : _a.activeElement) &&
|
|
this.input.current.value !== '';
|
|
return areSuggestionsVisible;
|
|
};
|
|
BasePicker.prototype._getTextFromItem = function (item, currentValue) {
|
|
if (this.props.getTextFromItem) {
|
|
return this.props.getTextFromItem(item, currentValue);
|
|
}
|
|
else {
|
|
return '';
|
|
}
|
|
};
|
|
BasePicker.contextType = react_window_provider_1.WindowContext;
|
|
return BasePicker;
|
|
}(React.Component));
|
|
exports.BasePicker = BasePicker;
|
|
var BasePickerListBelow = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BasePickerListBelow, _super);
|
|
function BasePickerListBelow() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
BasePickerListBelow.prototype.render = function () {
|
|
var _a, _b, _c, _d;
|
|
var _e = this.state, suggestedDisplayValue = _e.suggestedDisplayValue, isFocused = _e.isFocused, items = _e.items;
|
|
var _f = this.props, className = _f.className, inputProps = _f.inputProps, disabled = _f.disabled, selectionAriaLabel = _f.selectionAriaLabel, _g = _f.selectionRole, selectionRole = _g === void 0 ? 'list' : _g, theme = _f.theme, styles = _f.styles;
|
|
var suggestionsVisible = !!this.state.suggestionsVisible;
|
|
var suggestionsAvailable = suggestionsVisible ? this._ariaMap.suggestionList : undefined;
|
|
var hasError = !!((_a = this.state.errorMessage) !== null && _a !== void 0 ? _a : this.props.errorMessage);
|
|
// TODO
|
|
// Clean this up by leaving only the first part after removing support for SASS.
|
|
// Currently we can not remove the SASS styles from BasePicker class because it
|
|
// might be used by consumers who created custom pickers from extending from
|
|
// this base class and have not used the new 'styles' prop.
|
|
// We check for 'styles' prop which is going to be injected by the 'styled' HOC
|
|
// for every other already existing picker variant (PeoplePicker, TagPicker)
|
|
// so that we can use the CSS-in-JS styles. If the check fails (ex: custom picker),
|
|
// then we just use the old SASS styles instead.
|
|
var classNames = styles
|
|
? getClassNames(styles, {
|
|
theme: theme,
|
|
className: className,
|
|
isFocused: isFocused,
|
|
disabled: disabled,
|
|
hasErrorMessage: hasError,
|
|
inputClassName: inputProps && inputProps.className,
|
|
})
|
|
: {
|
|
root: (0, Utilities_1.css)('ms-BasePicker', legacyStyles.picker, className ? className : ''),
|
|
error: 'ms-BasePicker-error',
|
|
text: (0, Utilities_1.css)('ms-BasePicker-text', legacyStyles.pickerText, this.state.isFocused && legacyStyles.inputFocused, disabled && legacyStyles.inputDisabled),
|
|
itemsWrapper: legacyStyles.pickerItems,
|
|
input: (0, Utilities_1.css)('ms-BasePicker-input', legacyStyles.pickerInput, inputProps && inputProps.className),
|
|
screenReaderText: legacyStyles.screenReaderOnly,
|
|
};
|
|
var comboLabel = this.props['aria-label'] || (inputProps === null || inputProps === void 0 ? void 0 : inputProps['aria-label']);
|
|
var inputId = (_b = inputProps === null || inputProps === void 0 ? void 0 : inputProps.id) !== null && _b !== void 0 ? _b : this._ariaMap.combobox;
|
|
return (React.createElement("div", { ref: this.root, onBlur: this.onBlur, onFocus: this.onFocus },
|
|
this.renderLabel(inputId, (_c = classNames.subComponentStyles) === null || _c === void 0 ? void 0 : _c.label),
|
|
React.createElement("div", { className: classNames.root, onKeyDown: this.onKeyDown },
|
|
this.renderCustomAlert(classNames.screenReaderText),
|
|
React.createElement("span", { id: "".concat(this._ariaMap.selectedItems, "-label"), hidden: true }, selectionAriaLabel || comboLabel),
|
|
React.createElement("div", { className: classNames.text, "aria-owns": suggestionsAvailable },
|
|
React.createElement(index_2.Autofill, tslib_1.__assign({}, inputProps, { className: classNames.input, componentRef: this.input, onFocus: this.onInputFocus, onBlur: this.onInputBlur, onClick: this.onClick, onInputValueChange: this.onInputChange, suggestedDisplayValue: suggestedDisplayValue, "aria-activedescendant": suggestionsVisible ? this.getActiveDescendant() : undefined, "aria-controls": suggestionsAvailable, "aria-expanded": suggestionsVisible, "aria-haspopup": "listbox", "aria-label": comboLabel, "aria-describedby": this._getDescribedBy(items, hasError), role: "combobox", id: inputId, disabled: disabled,
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
onInputChange: this.props.onInputChange })))),
|
|
this.renderSuggestions((_d = classNames.subComponentStyles) === null || _d === void 0 ? void 0 : _d.callout),
|
|
React.createElement(index_1.SelectionZone, { selection: this.selection, selectionMode: index_1.SelectionMode.single },
|
|
React.createElement("div", { id: this._ariaMap.selectedItems, className: "ms-BasePicker-selectedItems" // just a className hook without any styles applied to it.
|
|
, role: selectionRole, "aria-labelledby": "".concat(this._ariaMap.selectedItems, "-label") }, this.renderItems())),
|
|
this.renderError(classNames.error)));
|
|
};
|
|
BasePickerListBelow.prototype.onBackspace = function (ev) {
|
|
// override the existing backspace method to not do anything because the list items appear below.
|
|
};
|
|
return BasePickerListBelow;
|
|
}(BasePicker));
|
|
exports.BasePickerListBelow = BasePickerListBelow;
|
|
});
|
|
//# sourceMappingURL=BasePicker.js.map
|