UNPKG

@openshift-assisted/ui-lib

Version:

React component library for the Assisted Installer UI

170 lines 9.84 kB
"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