@openshift-assisted/ui-lib
Version:
React component library for the Assisted Installer UI
170 lines • 9.84 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenShiftSelectWithSearch = void 0;
const tslib_1 = require("tslib");
const react_1 = tslib_1.__importDefault(require("react"));
const react_core_1 = require("@patternfly/react-core");
const times_icon_1 = tslib_1.__importDefault(require("@patternfly/react-icons/dist/esm/icons/times-icon"));
const use_translation_wrapper_1 = require("../../hooks/use-translation-wrapper");
const OpenShiftSelectWithSearch = ({ versions, getHelperText, setCustomOpenshiftSelect, }) => {
const initialSelectOptions = react_1.default.useMemo(() => versions.map((version) => ({
children: version.supportLevel === 'beta'
? version.label + ' - ' + 'Developer preview release'
: version.label,
value: version.value,
})), [versions]);
const [isOpen, setIsOpen] = react_1.default.useState(false);
const [selected, setSelected] = react_1.default.useState('');
const [inputValue, setInputValue] = react_1.default.useState('');
const [filterValue, setFilterValue] = react_1.default.useState('');
const [selectOptions, setSelectOptions] = react_1.default.useState(initialSelectOptions);
const [focusedItemIndex, setFocusedItemIndex] = react_1.default.useState(null);
const [activeItem, setActiveItem] = react_1.default.useState(null);
const textInputRef = react_1.default.useRef();
const { t } = (0, use_translation_wrapper_1.useTranslation)();
react_1.default.useEffect(() => {
if (textInputRef.current) {
textInputRef.current.maxLength = 30;
}
}, []);
react_1.default.useEffect(() => {
let newSelectOptions = initialSelectOptions;
// Filter menu items based on the text input value when one exists
if (filterValue) {
newSelectOptions = initialSelectOptions.filter((menuItem) => String(menuItem.children).toLowerCase().includes(filterValue.toLowerCase()));
// When no options are found after filtering, display 'No results found'
if (!newSelectOptions.length) {
newSelectOptions = [
{
isDisabled: true,
children: `No results found for "${filterValue}"`,
value: 'no results',
},
];
}
// Open the menu when the input value changes and the new value is not empty
if (!isOpen) {
setIsOpen(true);
}
}
setSelectOptions(newSelectOptions);
setActiveItem(null);
setFocusedItemIndex(null);
}, [filterValue, initialSelectOptions, isOpen]);
const onToggleClick = () => {
setIsOpen(!isOpen);
};
const onSelect = (_event, value) => {
// Check if the specific value exists in newSelectOptions
const foundItem = selectOptions.find((menuItem) => String(menuItem.value) === String(value));
const newLabel = foundItem === null || foundItem === void 0 ? void 0 : foundItem.children;
if (value && value !== 'no results') {
setInputValue(newLabel);
setFilterValue('');
setSelected(value);
const filteredVersions = versions.filter((version) => version.value === value);
setCustomOpenshiftSelect({
label: filteredVersions[0].supportLevel === 'beta'
? filteredVersions[0].label + ' - ' + t('ai:Developer preview release')
: filteredVersions[0].label,
value: filteredVersions[0].value,
version: filteredVersions[0].version,
default: filteredVersions[0].default,
supportLevel: filteredVersions[0].supportLevel,
});
}
setIsOpen(false);
setFocusedItemIndex(null);
setActiveItem(null);
};
const onTextInputChange = (_event, value) => {
setInputValue(value);
setFilterValue(value);
};
const handleMenuArrowKeys = (key) => {
let indexToFocus;
if (isOpen) {
if (key === 'ArrowUp') {
// When no index is set or at the first index, focus to the last, otherwise decrement focus index
if (focusedItemIndex === null || focusedItemIndex === 0) {
indexToFocus = selectOptions.length - 1;
}
else {
indexToFocus = focusedItemIndex - 1;
}
}
if (key === 'ArrowDown') {
// When no index is set or at the last index, focus to the first, otherwise increment focus index
if (focusedItemIndex === null || focusedItemIndex === selectOptions.length - 1) {
indexToFocus = 0;
}
else {
indexToFocus = focusedItemIndex + 1;
}
}
setFocusedItemIndex(indexToFocus !== null && indexToFocus !== void 0 ? indexToFocus : 0);
const focusedItem = selectOptions.filter((option) => !option.isDisabled)[indexToFocus !== null && indexToFocus !== void 0 ? indexToFocus : 0];
setActiveItem(`select-typeahead-${focusedItem.value.replace(' ', '-')}`);
}
};
const onInputKeyDown = (event) => {
const enabledMenuItems = selectOptions.filter((option) => !option.isDisabled);
const [firstMenuItem] = enabledMenuItems;
const focusedItem = focusedItemIndex ? enabledMenuItems[focusedItemIndex] : firstMenuItem;
switch (event.key) {
// Select the first available option
case 'Enter':
if (isOpen && focusedItem.value !== 'no results') {
setInputValue(String(focusedItem.children));
setFilterValue('');
setSelected(String(focusedItem.children));
}
setIsOpen((prevIsOpen) => !prevIsOpen);
setFocusedItemIndex(null);
setActiveItem(null);
break;
case 'Tab':
case 'Escape':
setIsOpen(false);
setActiveItem(null);
break;
case 'ArrowUp':
case 'ArrowDown':
event.preventDefault();
handleMenuArrowKeys(event.key);
break;
}
};
const toggle = (toggleRef) => (react_1.default.createElement(react_core_1.MenuToggle, { ref: toggleRef, variant: "typeahead", onClick: onToggleClick, isExpanded: isOpen, isFullWidth: true },
react_1.default.createElement(react_core_1.TextInputGroup, { isPlain: true },
react_1.default.createElement(react_core_1.TextInputGroupMain, Object.assign({ value: inputValue, onClick: onToggleClick, onChange: onTextInputChange, onKeyDown: onInputKeyDown, id: "typeahead-select-input", autoComplete: "off", innerRef: textInputRef, placeholder: "" }, (activeItem && { 'aria-activedescendant': activeItem }), { role: "combobox", isExpanded: isOpen, "aria-controls": "select-typeahead-listbox" })),
react_1.default.createElement(react_core_1.TextInputGroupUtilities, null, !!inputValue && (react_1.default.createElement(react_core_1.Button, { variant: "plain", onClick: () => {
var _a;
setSelected('');
setInputValue('');
setFilterValue('');
(_a = textInputRef === null || textInputRef === void 0 ? void 0 : textInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
}, "aria-label": "Clear input value" },
react_1.default.createElement(times_icon_1.default, { "aria-hidden": true })))))));
const helperText = getHelperText && getHelperText(selected, true);
return (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement(react_core_1.Select, { id: "customOpenshiftSelect", isOpen: isOpen, selected: selected, onSelect: onSelect, onOpenChange: () => {
setIsOpen(false);
}, toggle: toggle, isScrollable: true },
react_1.default.createElement(react_core_1.SelectList, { id: "select-typeahead-listbox" }, selectOptions.reverse().map((option, index) => {
const match = option.value.match(/\d+\.(\d+)\.\d+/);
const y = match ? match[1] : null;
const previousY = index > 0
? (selectOptions[index - 1].value.match(/\d+\.(\d+)\.\d+/) || [])[1]
: null;
const showDivider = previousY !== null && y !== previousY;
return (react_1.default.createElement(react_1.default.Fragment, { key: index },
showDivider && (react_1.default.createElement(react_core_1.Divider, { component: "li", id: `divider-${option.value}`, key: `divider-${option.value}` })),
react_1.default.createElement(react_core_1.SelectOption, Object.assign({ key: option.value, isFocused: focusedItemIndex === index, className: option.className, onClick: () => setSelected(option.value), id: `select-typeahead-${option.value.replace(' ', '-')}` }, option, { ref: null }))));
}))),
react_1.default.createElement(react_core_1.FormHelperText, null,
react_1.default.createElement(react_core_1.HelperText, null,
react_1.default.createElement(react_core_1.HelperTextItem, { variant: "default" }, helperText !== null && helperText !== void 0 ? helperText : 'Select an OpenShift version from the list or use the type ahead to narrow down the list.')))));
};
exports.OpenShiftSelectWithSearch = OpenShiftSelectWithSearch;
//# sourceMappingURL=OpenShiftSelectWithSearch.js.map