@scaleflex/ui
Advanced tools
Comparing version 2.5.0 to 2.6.0
import _extends from "@babel/runtime/helpers/extends"; | ||
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; | ||
import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; | ||
import _typeof from "@babel/runtime/helpers/typeof"; | ||
import _defineProperty from "@babel/runtime/helpers/defineProperty"; | ||
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; | ||
var _excluded = ["children", "MenuProps", "LabelProps", "InputProps", "error", "label", "hint", "value", "noOptionsText", "focusOnOpen", "onChange", "onOpen", "onClose", "getOptionDisabled", "getOptionValue", "getOptionLabel", "multiple", "size", "disabled", "scroll", "readOnly", "options", "placeholder", "fullWidth", "sortAlphabetically", "submitOnBlur"]; | ||
import React, { useRef, useEffect, useState } from 'react'; | ||
var _excluded = ["children", "MenuProps", "LabelProps", "InputProps", "error", "label", "hint", "value", "noOptionsText", "focusOnOpen", "onChange", "onOpen", "onClose", "getOptionDisabled", "getOptionValue", "getOptionLabel", "multiple", "size", "disabled", "scroll", "readOnly", "options", "placeholder", "fullWidth", "sortAlphabetically", "submitOnBlur", "maxMenuHeight", "showClearIcon", "renderLabelIconEnd", "renderOptionLabel", "renderSearchEmptyMenuItem", "renderGroup", "groupBy"]; | ||
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } | ||
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } | ||
import React from 'react'; | ||
import PT from 'prop-types'; | ||
@@ -13,7 +14,4 @@ import Tick from '@scaleflex/icons/tick'; | ||
import { propTypes as inputPropTypes } from '../input/input.component'; | ||
import Label from '../label'; | ||
import FormHint from '../form-hint'; | ||
import ArrowTick from '../arrow-tick'; | ||
import Input from '../input'; | ||
import Menu from '../menu'; | ||
import Tag from '../tag'; | ||
@@ -24,447 +22,78 @@ import MenuItem, { MenuItemActions } from '../menu-item'; | ||
import Styled from './autocomplete.styles'; | ||
var Autocomplete = intrinsicComponent(function (_ref, ref) { | ||
var children = _ref.children, | ||
MenuProps = _ref.MenuProps, | ||
LabelPropsData = _ref.LabelProps, | ||
InputPropsData = _ref.InputProps, | ||
error = _ref.error, | ||
label = _ref.label, | ||
hint = _ref.hint, | ||
value = _ref.value, | ||
_ref$noOptionsText = _ref.noOptionsText, | ||
noOptionsText = _ref$noOptionsText === void 0 ? 'No options' : _ref$noOptionsText, | ||
focusOnOpen = _ref.focusOnOpen, | ||
onChange = _ref.onChange, | ||
onOpen = _ref.onOpen, | ||
onClose = _ref.onClose, | ||
_ref$getOptionDisable = _ref.getOptionDisabled, | ||
getOptionDisabled = _ref$getOptionDisable === void 0 ? function () { | ||
import { renderLabel, renderHint, defaultGetOptionValue, defaultGetOptionLabel } from './autocomplete.utils'; | ||
import { useAutocomplete } from './autocomplete.hook'; | ||
var Autocomplete = intrinsicComponent(function (props, ref) { | ||
var children = props.children, | ||
MenuProps = props.MenuProps, | ||
LabelPropsData = props.LabelProps, | ||
InputPropsData = props.InputProps, | ||
error = props.error, | ||
label = props.label, | ||
hint = props.hint, | ||
value = props.value, | ||
noOptionsText = props.noOptionsText, | ||
focusOnOpen = props.focusOnOpen, | ||
onChange = props.onChange, | ||
onOpen = props.onOpen, | ||
onClose = props.onClose, | ||
_props$getOptionDisab = props.getOptionDisabled, | ||
getOptionDisabled = _props$getOptionDisab === void 0 ? function () { | ||
return false; | ||
} : _ref$getOptionDisable, | ||
getOptionValue = _ref.getOptionValue, | ||
getOptionLabel = _ref.getOptionLabel, | ||
multiple = _ref.multiple, | ||
size = _ref.size, | ||
disabled = _ref.disabled, | ||
scroll = _ref.scroll, | ||
readOnly = _ref.readOnly, | ||
_ref$options = _ref.options, | ||
options = _ref$options === void 0 ? [] : _ref$options, | ||
placeholder = _ref.placeholder, | ||
fullWidth = _ref.fullWidth, | ||
sortAlphabetically = _ref.sortAlphabetically, | ||
submitOnBlur = _ref.submitOnBlur, | ||
rest = _objectWithoutProperties(_ref, _excluded); | ||
var inputRef = useRef(null); | ||
var getNextOptionLabel = function getNextOptionLabel(option) { | ||
if (getOptionLabel) { | ||
return getOptionLabel(option); | ||
} | ||
return option.label; | ||
}; | ||
var getNextOptionValue = function getNextOptionValue(option) { | ||
if (getOptionValue) { | ||
return getOptionValue(option); | ||
} | ||
return option.id; | ||
}; | ||
var getFilteredItems = function getFilteredItems(items, callBackFun) { | ||
var filteredItems = []; | ||
items.forEach(function (item, index, array) { | ||
return callBackFun(item, index, array) && filteredItems.push(item); | ||
}); | ||
return filteredItems; | ||
}; | ||
var isObjectOptions = _typeof(options[0]) === 'object'; | ||
var getSortedOptions = function getSortedOptions() { | ||
if (isObjectOptions && sortAlphabetically) { | ||
return options.sort(function (a, b) { | ||
return getNextOptionLabel(a).localeCompare(getNextOptionLabel(b)); | ||
}); | ||
} | ||
if (sortAlphabetically) { | ||
return options.sort(); | ||
} | ||
return options; | ||
}; | ||
var removedDuplicatedOptions = getFilteredItems(getSortedOptions(), function (option, index, array) { | ||
if (array.findIndex(function (item) { | ||
return getNextOptionLabel(item) === getNextOptionLabel(option); | ||
}) === index) { | ||
return true; | ||
} | ||
return false; | ||
}); | ||
var _useState = useState(multiple ? [] : ''), | ||
_useState2 = _slicedToArray(_useState, 2), | ||
selected = _useState2[0], | ||
setSelected = _useState2[1]; | ||
var _useState3 = useState(removedDuplicatedOptions), | ||
_useState4 = _slicedToArray(_useState3, 2), | ||
filteredOptions = _useState4[0], | ||
setFilteredOptions = _useState4[1]; | ||
var _useState5 = useState(undefined), | ||
_useState6 = _slicedToArray(_useState5, 2), | ||
anchorEl = _useState6[0], | ||
setAnchorEl = _useState6[1]; | ||
var _useState7 = useState(-1), | ||
_useState8 = _slicedToArray(_useState7, 2), | ||
currentItemIndex = _useState8[0], | ||
setCurrentItemIndex = _useState8[1]; | ||
var _useState9 = useState(''), | ||
_useState10 = _slicedToArray(_useState9, 2), | ||
renderedValue = _useState10[0], | ||
setRenderedValue = _useState10[1]; | ||
var _useState11 = useState([]), | ||
_useState12 = _slicedToArray(_useState11, 2), | ||
selectedItemsIndex = _useState12[0], | ||
setSelectedIemsIndex = _useState12[1]; | ||
var open = Boolean(anchorEl); | ||
var isItemSelected = (multiple ? (selected || []).length > 0 : !!selected) || selectedItemsIndex.length > 0; | ||
var hasDuplicatedLabels = removedDuplicatedOptions.length !== options.length; | ||
var convertToLower = function convertToLower(val) { | ||
return (val || '').toString().toLowerCase(); | ||
}; | ||
var onBlurHandler = function onBlurHandler() { | ||
if (submitOnBlur) { | ||
submitOnBlur(); | ||
} | ||
setAnchorEl(undefined); | ||
}; | ||
var handleOnChange = function handleOnChange(event, val, id) { | ||
if (multiple) { | ||
if (onChange) { | ||
if (isObjectOptions && id) { | ||
onChange(event, [].concat(_toConsumableArray(selected), _toConsumableArray(id))); | ||
} else if (!isObjectOptions) { | ||
onChange(event, [].concat(_toConsumableArray(selected), _toConsumableArray(val))); | ||
} | ||
} | ||
} else { | ||
if (onChange) { | ||
if (isObjectOptions && id) { | ||
onChange(event, id); | ||
} else if (!isObjectOptions) { | ||
onChange(event, val); | ||
} | ||
} | ||
setSelected(''); | ||
setCurrentItemIndex(-1); | ||
} | ||
}; | ||
var handleOnRemoveItem = function handleOnRemoveItem(event, itemIndex, index) { | ||
event.stopPropagation(); | ||
var updatedSelectedItems = Array.isArray(selected) ? selected.filter(function (_, nextIndex) { | ||
return nextIndex !== index; | ||
}) : ''; | ||
var updatedSelectedIndex = selectedItemsIndex.filter(function (nextIndex) { | ||
return nextIndex !== itemIndex; | ||
}); | ||
setSelected(updatedSelectedItems); | ||
setSelectedIemsIndex(updatedSelectedIndex); | ||
if (onChange) { | ||
if (isObjectOptions) { | ||
onChange(event, _toConsumableArray(updatedSelectedItems)); | ||
} else if (!multiple) { | ||
onChange(event, [].concat(_toConsumableArray(updatedSelectedItems), [''])); | ||
} | ||
} | ||
if (submitOnBlur) { | ||
submitOnBlur(); | ||
} | ||
}; | ||
var handleOpenClick = function handleOpenClick(event) { | ||
setAnchorEl(inputRef.current); | ||
if (onOpen) { | ||
onOpen(event); | ||
} | ||
}; | ||
var handleCloseClick = function handleCloseClick(event) { | ||
setAnchorEl(undefined); | ||
setCurrentItemIndex(-1); | ||
if (onClose) { | ||
onClose(event); | ||
} | ||
}; | ||
var handleClearIconClick = function handleClearIconClick(event) { | ||
event === null || event === void 0 || event.stopPropagation(); | ||
if (multiple) { | ||
if (onChange) { | ||
onChange(event, []); | ||
} | ||
setSelected([]); | ||
} else { | ||
if (onChange) { | ||
onChange(event, ''); | ||
} | ||
setSelected(''); | ||
} | ||
setCurrentItemIndex(-1); | ||
setSelectedIemsIndex([]); | ||
}; | ||
var handleSelectedItem = function handleSelectedItem(event, item, id, index) { | ||
// make sure this item isn't already selected | ||
if (!multiple && (selected !== item || isObjectOptions && selected !== id)) { | ||
handleOnChange(event, item, id); | ||
if (isObjectOptions) { | ||
var nextOptionId = getNextOptionValue(removedDuplicatedOptions[index]); | ||
setSelectedIemsIndex([index]); | ||
setSelected(nextOptionId); | ||
} else { | ||
setSelected(item); | ||
} | ||
} else if (multiple) { | ||
if (Array.isArray(selected) && (selected.includes(item) || isObjectOptions && selected.includes(id) && selectedItemsIndex.includes(index))) { | ||
var updatedSelectedItems = selected; | ||
if (isObjectOptions) { | ||
var removedIndex = selected.findIndex(function (selectedId) { | ||
return selectedId === id; | ||
}); | ||
if (removedIndex !== -1) { | ||
updatedSelectedItems.splice(removedIndex, 1); | ||
} | ||
} else { | ||
updatedSelectedItems = selected.filter(function (selectedItem) { | ||
return selectedItem !== item; | ||
}); | ||
} | ||
var updatedSelectedIndex = selectedItemsIndex.filter(function (nextIndex) { | ||
return nextIndex !== index; | ||
}); | ||
setSelected(updatedSelectedItems); | ||
setSelectedIemsIndex(updatedSelectedIndex); | ||
if (onChange) { | ||
onChange(event, _toConsumableArray(updatedSelectedItems)); | ||
} | ||
} else if (isObjectOptions) { | ||
handleOnChange(event, null, [id]); | ||
setSelectedIemsIndex(function (prev) { | ||
return [].concat(_toConsumableArray(prev), [index]); | ||
}); | ||
setSelected(function (prev) { | ||
return [].concat(_toConsumableArray(prev), [id]); | ||
}); | ||
} else { | ||
handleOnChange(event, [item], null); | ||
setSelected(function (prev) { | ||
return [].concat(_toConsumableArray(prev), [item]); | ||
}); | ||
setSelectedIemsIndex(function (prev) { | ||
return [].concat(_toConsumableArray(prev), [index]); | ||
}); | ||
} | ||
} | ||
setRenderedValue(''); | ||
handleCloseClick(event); | ||
}; | ||
var handleMenuItemClick = function handleMenuItemClick(event, item, index, id) { | ||
// menu item shouldn't be clickable if it's disabled or = 'No options' | ||
if (item === noOptionsText || getOptionDisabled && getOptionDisabled(item, index)) { | ||
return null; | ||
} | ||
return handleSelectedItem(event, item, id, index); | ||
}; | ||
var getObjectOptionLabel = function getObjectOptionLabel(optionValue, optionIndex) { | ||
var selectedOptionIndex = removedDuplicatedOptions.findIndex(function (option, index) { | ||
return getNextOptionValue(option) === optionValue && index === optionIndex; | ||
}); | ||
return (getOptionLabel ? getOptionLabel(removedDuplicatedOptions[selectedOptionIndex]) : removedDuplicatedOptions[selectedOptionIndex]) || optionValue; | ||
}; | ||
var getValue = function getValue() { | ||
if (isObjectOptions && !multiple && selected.length > 0) return getObjectOptionLabel(value, selectedItemsIndex[0]); | ||
if (!isObjectOptions && !multiple) return value; | ||
return renderedValue; | ||
}; | ||
var handleInputChange = function handleInputChange(event) { | ||
var inputValue = event.currentTarget.value; | ||
setRenderedValue(inputValue); | ||
if (!multiple) handleOnChange(event, [inputValue], null); | ||
setAnchorEl(inputRef.current); | ||
}; | ||
var getOptionIndex = function getOptionIndex(option) { | ||
var optionIndex = -1; | ||
if (isObjectOptions) { | ||
var optionObject = Object.entries(removedDuplicatedOptions).find(function (_ref2) { | ||
var _ref3 = _slicedToArray(_ref2, 2), | ||
_ = _ref3[0], | ||
optObject = _ref3[1]; | ||
return getNextOptionLabel(optObject) === option; | ||
}); | ||
if (optionObject) { | ||
optionIndex = Number(optionObject[0]); | ||
} | ||
} else { | ||
optionIndex = removedDuplicatedOptions.indexOf(option); | ||
} | ||
return optionIndex; | ||
}; | ||
var isMenuItemsAvailable = function isMenuItemsAvailable() { | ||
var validMenuItems = getFilteredItems(filteredOptions, function (option) { | ||
var filteredOptionLabel = getNextOptionLabel(option); | ||
var filteredOptionItem = isObjectOptions ? filteredOptionLabel : option; | ||
var filteredOptionIndex = getOptionIndex(filteredOptionItem); | ||
if (option !== noOptionsText && getOptionDisabled && !getOptionDisabled(filteredOptionItem, filteredOptionIndex)) return true; | ||
return false; | ||
}); | ||
return !!validMenuItems.length; | ||
}; | ||
var getNextAvailableOption = function getNextAvailableOption(currentIndex, direction) { | ||
if (!isMenuItemsAvailable()) return; | ||
while (currentIndex !== currentItemIndex) { | ||
var filteredItemLabel = getNextOptionLabel(filteredOptions[currentIndex]); | ||
var selectedOption = isObjectOptions ? filteredItemLabel : filteredOptions[currentIndex]; | ||
var optionIndex = getOptionIndex(selectedOption); | ||
var isDisabled = false; | ||
if (getOptionDisabled && typeof selectedOption === 'string') { | ||
isDisabled = getOptionDisabled(selectedOption, optionIndex); | ||
} | ||
if (!isDisabled) { | ||
setCurrentItemIndex(currentIndex); | ||
break; | ||
} | ||
if (direction === 'ArrowUp') { | ||
if (currentIndex === 0) { | ||
currentIndex = filteredOptions.length; | ||
} | ||
currentIndex -= 1; | ||
} | ||
if (direction === 'ArrowDown') { | ||
if (currentIndex === filteredOptions.length - 1) { | ||
currentIndex = -1; | ||
} | ||
currentIndex += 1; | ||
} | ||
} | ||
}; | ||
var handleKeyDown = function handleKeyDown(event) { | ||
if (open) { | ||
if (event.key === 'ArrowUp') { | ||
if (currentItemIndex > 0) { | ||
getNextAvailableOption(currentItemIndex - 1, event.key); | ||
} else { | ||
getNextAvailableOption(filteredOptions.length - 1, event.key); | ||
} | ||
} | ||
if (event.key === 'ArrowDown') { | ||
if (currentItemIndex < filteredOptions.length - 1) { | ||
getNextAvailableOption(currentItemIndex + 1, event.key); | ||
} else { | ||
getNextAvailableOption(0, event.key); | ||
} | ||
} | ||
if (event.key === 'Enter' && currentItemIndex >= 0) { | ||
var selectedOption = filteredOptions[currentItemIndex]; | ||
if (typeof selectedOption === 'string') { | ||
handleSelectedItem(event, selectedOption, -1, getOptionIndex(selectedOption)); | ||
} else { | ||
handleSelectedItem(event, getNextOptionLabel(selectedOption), getNextOptionValue(selectedOption), getOptionIndex(getNextOptionLabel(selectedOption))); | ||
} | ||
} | ||
if (event.key === 'Escape') { | ||
handleCloseClick(event); | ||
} | ||
} | ||
}; | ||
var getMultipleFilteredItems = function getMultipleFilteredItems(item, val) { | ||
if (isObjectOptions) { | ||
if (getOptionLabel ? convertToLower(getOptionLabel(item)).includes(convertToLower(val) || '') : convertToLower(item.label).includes(convertToLower(val) || '')) return true; | ||
} else if (convertToLower(item).includes(convertToLower(val) || '')) return true; | ||
return false; | ||
}; | ||
var getMultipleFilteredOptions = function getMultipleFilteredOptions() { | ||
var filteredMenuOptions = []; | ||
if (isObjectOptions || multiple) { | ||
filteredMenuOptions = getFilteredItems(removedDuplicatedOptions, function (item) { | ||
return getMultipleFilteredItems(item, renderedValue); | ||
}); | ||
} else { | ||
// filter menu options based on the value[0] as it's an array in multiple mode | ||
filteredMenuOptions = getFilteredItems(removedDuplicatedOptions, function (item) { | ||
return getMultipleFilteredItems(item, value[0] || ''); | ||
}); | ||
} | ||
setFilteredOptions(filteredMenuOptions); | ||
}; | ||
var getFilteredOptions = function getFilteredOptions() { | ||
var filteredMenuOptions = removedDuplicatedOptions; | ||
if (isObjectOptions) { | ||
filteredMenuOptions = getFilteredItems(filteredMenuOptions, function (option) { | ||
var _convertToLower; | ||
return getOptionLabel ? (_convertToLower = convertToLower(getOptionLabel(option))) === null || _convertToLower === void 0 ? void 0 : _convertToLower.includes(convertToLower(renderedValue)) : convertToLower(option.label).includes(convertToLower(renderedValue)); | ||
}); | ||
} else if (value) { | ||
filteredMenuOptions = getFilteredItems(filteredMenuOptions, function (option) { | ||
return convertToLower(option).includes(convertToLower(value[0])); | ||
}); | ||
} | ||
setFilteredOptions(filteredMenuOptions || []); | ||
}; | ||
var isActiveMenuItem = function isActiveMenuItem(item, index, id) { | ||
if (item === selected || index === currentItemIndex || multiple && selected.includes(item) || isObjectOptions && Array.isArray(selected) && selected.includes(id) && selectedItemsIndex.includes(index) || isObjectOptions && selected === id && selectedItemsIndex.includes(index)) return true; | ||
return false; | ||
}; | ||
var showMiActions = function showMiActions(item, id, index) { | ||
if (selected === id || item === selected || multiple && selected.includes(item) || isObjectOptions && selected.includes(id) && selectedItemsIndex.includes(index)) return true; | ||
return false; | ||
}; | ||
var renderLabel = function renderLabel() { | ||
if (label) { | ||
if (typeof label === 'function') { | ||
return label({ | ||
error: error | ||
}); | ||
} | ||
if (_typeof(label) === 'object') { | ||
return label; | ||
} | ||
return /*#__PURE__*/React.createElement(Label, _extends({ | ||
size: size, | ||
error: error | ||
}, LabelPropsData || {}), label); | ||
} | ||
return null; | ||
}; | ||
var renderTags = function renderTags() { | ||
if (multiple && isItemSelected && Array.isArray(selected)) { | ||
return selectedItemsIndex.map(function (itemIndex, index) { | ||
var itemId = getNextOptionValue(removedDuplicatedOptions[itemIndex]); | ||
var item = isObjectOptions ? getObjectOptionLabel(itemId, itemIndex) : removedDuplicatedOptions[itemIndex]; | ||
var title = isObjectOptions ? getObjectOptionLabel(itemId, itemIndex) : item; | ||
return /*#__PURE__*/React.createElement(Tag, { | ||
key: index, | ||
tagIndex: index, | ||
crossIcon: true, | ||
onRemove: function onRemove(_, event) { | ||
return handleOnRemoveItem(event, itemIndex, index); | ||
}, | ||
title: title | ||
}, item); | ||
}); | ||
} | ||
}; | ||
var renderHint = function renderHint() { | ||
if (hint) { | ||
if (typeof hint === 'function') { | ||
return hint({ | ||
error: error | ||
}); | ||
} | ||
if (_typeof(hint) === 'object') { | ||
return hint; | ||
} | ||
return /*#__PURE__*/React.createElement(FormHint, { | ||
size: size, | ||
error: error | ||
}, hint); | ||
} | ||
return null; | ||
}; | ||
var renderMenuItem = function renderMenuItem(item, index, id) { | ||
var optionIndex = getOptionIndex(item); | ||
var miActions = /*#__PURE__*/React.createElement(MenuItemActions, null, /*#__PURE__*/React.createElement(Styled.TickIcon, null, /*#__PURE__*/React.createElement(Tick, { | ||
size: 12 | ||
}))); | ||
} : _props$getOptionDisab, | ||
_props$getOptionValue = props.getOptionValue, | ||
getOptionValue = _props$getOptionValue === void 0 ? defaultGetOptionValue : _props$getOptionValue, | ||
_props$getOptionLabel = props.getOptionLabel, | ||
getOptionLabel = _props$getOptionLabel === void 0 ? defaultGetOptionLabel : _props$getOptionLabel, | ||
multiple = props.multiple, | ||
size = props.size, | ||
disabled = props.disabled, | ||
scroll = props.scroll, | ||
readOnly = props.readOnly, | ||
options = props.options, | ||
placeholder = props.placeholder, | ||
fullWidth = props.fullWidth, | ||
sortAlphabetically = props.sortAlphabetically, | ||
submitOnBlur = props.submitOnBlur, | ||
_props$maxMenuHeight = props.maxMenuHeight, | ||
maxMenuHeight = _props$maxMenuHeight === void 0 ? 250 : _props$maxMenuHeight, | ||
_props$showClearIcon = props.showClearIcon, | ||
showClearIcon = _props$showClearIcon === void 0 ? false : _props$showClearIcon, | ||
renderLabelIconEnd = props.renderLabelIconEnd, | ||
renderOptionLabel = props.renderOptionLabel, | ||
renderSearchEmptyMenuItem = props.renderSearchEmptyMenuItem, | ||
renderGroup = props.renderGroup, | ||
groupBy = props.groupBy, | ||
rest = _objectWithoutProperties(props, _excluded); | ||
var _useAutocomplete = useAutocomplete(_objectSpread(_objectSpread({}, props), {}, { | ||
getOptionValue: getOptionValue, | ||
getOptionLabel: getOptionLabel, | ||
getOptionDisabled: getOptionDisabled | ||
})), | ||
formattedValue = _useAutocomplete.formattedValue, | ||
filteredOptions = _useAutocomplete.filteredOptions, | ||
groupedFilteredOptions = _useAutocomplete.groupedFilteredOptions, | ||
optionsList = _useAutocomplete.optionsList, | ||
inputRef = _useAutocomplete.inputRef, | ||
inputValue = _useAutocomplete.inputValue, | ||
isValueSelected = _useAutocomplete.isValueSelected, | ||
open = _useAutocomplete.open, | ||
anchorEl = _useAutocomplete.anchorEl, | ||
handleMenuItemClick = _useAutocomplete.handleMenuItemClick, | ||
handleOpenMenuClick = _useAutocomplete.handleOpenMenuClick, | ||
handleChangeSearchTerm = _useAutocomplete.handleChangeSearchTerm, | ||
handleCloseMenuClick = _useAutocomplete.handleCloseMenuClick, | ||
handleOnRemoveItem = _useAutocomplete.handleOnRemoveItem, | ||
handleOnBlur = _useAutocomplete.handleOnBlur, | ||
handleKeyDown = _useAutocomplete.handleKeyDown, | ||
handleClearIconClick = _useAutocomplete.handleClearIconClick, | ||
checkIsIdSelected = _useAutocomplete.checkIsIdSelected, | ||
getOptionById = _useAutocomplete.getOptionById; | ||
var isMultiple = Boolean(multiple) && Array.isArray(formattedValue); | ||
var renderMenuItem = function renderMenuItem(option) { | ||
var optionId = getOptionValue(option); | ||
var optionLabel = getOptionLabel(option); | ||
var isActive = checkIsIdSelected(optionId); | ||
return /*#__PURE__*/React.createElement(MenuItem, { | ||
key: optionIndex, | ||
value: item, | ||
key: optionId, | ||
value: optionId, | ||
size: size, | ||
@@ -474,85 +103,69 @@ onMouseDown: function onMouseDown(e) { | ||
}, | ||
noOptionsText: item === noOptionsText, | ||
disabled: getOptionDisabled && getOptionDisabled(item, optionIndex), | ||
active: isActiveMenuItem(item, index, id), | ||
onClick: function onClick(event) { | ||
return handleMenuItemClick(event, item, optionIndex, id); | ||
}, | ||
disabled: getOptionDisabled(option), | ||
active: isActive, | ||
onClick: handleMenuItemClick(option), | ||
enableScrollIntoView: true | ||
}, item, showMiActions(item, id, index) && miActions); | ||
}, renderOptionLabel ? renderOptionLabel(option) : optionLabel, isActive && !renderOptionLabel && /*#__PURE__*/React.createElement(MenuItemActions, null, /*#__PURE__*/React.createElement(Styled.TickIcon, null, /*#__PURE__*/React.createElement(Tick, { | ||
size: 12 | ||
})))); | ||
}; | ||
useEffect(function () { | ||
if (focusOnOpen) setAnchorEl(inputRef.current); | ||
}, [focusOnOpen]); | ||
useEffect(function () { | ||
if (isItemSelected) { | ||
filteredOptions.map(function (option, index) { | ||
if (option === selected) { | ||
setCurrentItemIndex(index); | ||
} | ||
return null; | ||
}); | ||
} | ||
}, [anchorEl]); | ||
useEffect(function () { | ||
if (multiple) { | ||
getMultipleFilteredOptions(); | ||
} else { | ||
getFilteredOptions(); | ||
} | ||
}, [value, renderedValue, anchorEl]); | ||
useEffect(function () { | ||
if ((filteredOptions === null || filteredOptions === void 0 ? void 0 : filteredOptions.length) === 0) { | ||
setFilteredOptions([noOptionsText]); | ||
} | ||
}, [filteredOptions, value]); | ||
useEffect(function () { | ||
setFilteredOptions(removedDuplicatedOptions); | ||
}, [options]); | ||
useEffect(function () { | ||
var filteredMenuOptions = isObjectOptions ? removedDuplicatedOptions.map(function (option) { | ||
return getNextOptionLabel(option); | ||
}) : removedDuplicatedOptions; | ||
if (multiple) { | ||
var nextOptionIndex = (value === null || value === void 0 ? void 0 : value.map(function (item) { | ||
return removedDuplicatedOptions.findIndex(function (option) { | ||
return getNextOptionValue(option) === item; | ||
var renderTags = function renderTags() { | ||
return isMultiple && formattedValue.map(function (optionId, index) { | ||
var option = getOptionById(optionId); | ||
var optionLabel = option ? getOptionLabel(option) : optionId; | ||
return /*#__PURE__*/React.createElement(Tag, { | ||
key: optionId, | ||
tagIndex: index, | ||
crossIcon: true, | ||
onRemove: function onRemove(_, event) { | ||
return handleOnRemoveItem(event, optionId); | ||
}, | ||
title: optionLabel, | ||
size: size | ||
}, optionLabel); | ||
}); | ||
}; | ||
var renderMenuContent = function renderMenuContent() { | ||
if (filteredOptions.length > 0) { | ||
if (groupBy) { | ||
return groupedFilteredOptions.map(function (_ref, index) { | ||
var groupOptions = _ref.options, | ||
groupedByValue = _ref.groupedByValue; | ||
var groupKey = ['string', 'number'].includes(_typeof(groupedByValue)) ? groupedByValue : index; | ||
var groupChildren = groupOptions.map(renderMenuItem); | ||
return renderGroup ? renderGroup({ | ||
key: groupKey, | ||
group: groupedByValue, | ||
children: groupChildren | ||
}) : /*#__PURE__*/React.createElement(Styled.OptionGroup, { | ||
key: groupKey | ||
}, groupChildren); | ||
}); | ||
})) || []; | ||
var nextOptionId = nextOptionIndex.map(function (item) { | ||
return getNextOptionValue(removedDuplicatedOptions[item]); | ||
}); | ||
setSelected(nextOptionId); | ||
setSelectedIemsIndex(nextOptionIndex); | ||
} else { | ||
var _nextOptionIndex = removedDuplicatedOptions.findIndex(function (option) { | ||
return getNextOptionValue(option) === value; | ||
}); | ||
var _nextOptionId = getNextOptionValue(removedDuplicatedOptions[_nextOptionIndex]); | ||
if (_nextOptionIndex !== -1) setSelectedIemsIndex([_nextOptionIndex]);else setSelectedIemsIndex([]); | ||
setSelected(_nextOptionId || ''); | ||
} | ||
if (!multiple && (value === null || value === void 0 ? void 0 : value.length) !== 0) { | ||
var valueOptionIndex = filteredMenuOptions.findIndex(function (option) { | ||
return option === value; | ||
}); | ||
if (valueOptionIndex !== -1) { | ||
setCurrentItemIndex(valueOptionIndex); | ||
setSelected(value); | ||
} | ||
return filteredOptions.map(renderMenuItem); | ||
} | ||
if (hasDuplicatedLabels) { | ||
console.warn('options have duplicate Labels'); | ||
if (optionsList.length > 0 && renderSearchEmptyMenuItem) { | ||
return renderSearchEmptyMenuItem(); | ||
} | ||
}, [value]); | ||
return /*#__PURE__*/React.createElement(MenuItem, { | ||
noOptionsText: true, | ||
size: size | ||
}, noOptionsText); | ||
}; | ||
return /*#__PURE__*/React.createElement(Styled.Autocomplete, _extends({ | ||
ref: ref | ||
}, rest), renderLabel(), /*#__PURE__*/React.createElement(Styled.AutocompleteContainer, { | ||
onClick: disabled || readOnly ? undefined : handleOpenClick | ||
}, /*#__PURE__*/React.createElement(Input, _extends({}, InputPropsData || {}, { | ||
}, rest), renderLabel({ | ||
label: label, | ||
error: error, | ||
size: size, | ||
LabelProps: LabelPropsData | ||
}), /*#__PURE__*/React.createElement(Styled.AutocompleteContainer, { | ||
onClick: disabled || readOnly ? undefined : handleOpenMenuClick | ||
}, /*#__PURE__*/React.createElement(Input, _extends({}, isMultiple ? { | ||
renderTags: renderTags, | ||
selectedItems: formattedValue | ||
} : {}, InputPropsData || {}, { | ||
ref: inputRef, | ||
size: size, | ||
value: getValue() || '', | ||
renderTags: renderTags, | ||
selectedItems: selected, | ||
value: inputValue, | ||
readOnly: readOnly, | ||
@@ -562,4 +175,4 @@ error: error, | ||
onKeyDown: handleKeyDown, | ||
onChange: handleInputChange, | ||
onBlur: onBlurHandler, | ||
onChange: handleChangeSearchTerm, | ||
onBlur: handleOnBlur, | ||
disabled: disabled, | ||
@@ -570,4 +183,8 @@ placeholder: placeholder, | ||
iconEnd: function iconEnd() { | ||
return /*#__PURE__*/React.createElement(ArrowTick, { | ||
onClick: disabled || readOnly ? undefined : handleOpenClick, | ||
return /*#__PURE__*/React.createElement(Styled.InputIconEndContainer, null, renderLabelIconEnd && renderLabelIconEnd({ | ||
isMultiple: isMultiple, | ||
option: !isMultiple && formattedValue && typeof formattedValue === 'string' ? getOptionById(formattedValue) : null | ||
}), /*#__PURE__*/React.createElement(ArrowTick, _extends({}, !disabled && !readOnly ? { | ||
onClick: handleOpenMenuClick | ||
} : {}, { | ||
type: open ? 'top' : 'bottom', | ||
@@ -577,21 +194,20 @@ IconProps: { | ||
} | ||
}); | ||
}, | ||
clearIcon: isItemSelected && /*#__PURE__*/React.createElement(Styled.CrossIcon, { | ||
}))); | ||
} | ||
}, showClearIcon ? { | ||
clearIcon: isValueSelected && /*#__PURE__*/React.createElement(Styled.CrossIcon, { | ||
size: size === 'md' ? 11 : 10 | ||
}), | ||
clearIconClick: handleClearIconClick | ||
}))), /*#__PURE__*/React.createElement(Menu, _extends({ | ||
onClose: handleCloseClick, | ||
} : {}))), /*#__PURE__*/React.createElement(Styled.Menu, _extends({ | ||
onClose: handleCloseMenuClick, | ||
open: open, | ||
scroll: scroll, | ||
anchorEl: anchorEl, | ||
style: { | ||
maxHeight: '250px' | ||
} | ||
}, MenuProps), _typeof(filteredOptions[0]) === 'object' ? Object.values(filteredOptions).map(function (option, index) { | ||
return renderMenuItem(getNextOptionLabel(option), index, getNextOptionValue(option)); | ||
}) : filteredOptions === null || filteredOptions === void 0 ? void 0 : filteredOptions.map(function (item, index) { | ||
return renderMenuItem(item, index, null); | ||
})), renderHint()); | ||
maxMenuHeight: maxMenuHeight | ||
}, MenuProps), renderMenuContent()), renderHint({ | ||
hint: hint, | ||
error: error, | ||
size: size | ||
})); | ||
}); | ||
@@ -603,3 +219,6 @@ Autocomplete.defaultProps = { | ||
scroll: true, | ||
readOnly: false | ||
readOnly: false, | ||
sortAlphabetically: false, | ||
options: [], | ||
noOptionsText: 'No options' | ||
}; | ||
@@ -630,4 +249,11 @@ Autocomplete.propTypes = { | ||
getOptionLabel: PT.func, | ||
submitOnBlur: PT.func | ||
submitOnBlur: PT.func, | ||
sortAlphabetically: PT.bool, | ||
showClearIcon: PT.bool, | ||
maxMenuHeight: PT.oneOfType([PT.string, PT.number]), | ||
renderLabelIconEnd: PT.func, | ||
renderOptionLabel: PT.func, | ||
renderSearchEmptyMenuItem: PT.func, | ||
groupBy: PT.func | ||
}; | ||
export default Autocomplete; |
@@ -6,11 +6,19 @@ import type { Values } from '../../utils/types'; | ||
import { InputBackgroundColor, InputSize } from '../../utils/types'; | ||
import { AnchorElType } from '../menu/menu.props'; | ||
export type AutocompleteBackgroundType = Values<typeof InputBackgroundColor>; | ||
export type AutocompleteSizeType = Values<typeof InputSize>; | ||
export type AutocompleteOptionType = string | AutocompleteObjectOptionstype; | ||
export type AutocompleteObjectOptionstype = { | ||
id: number; | ||
label: string; | ||
export type AutocompleteOptionIdType = string; | ||
export type AutocompleteOptionLabelType = string; | ||
export type AutocompleteOptionObjectType = { | ||
[key: string]: any; | ||
}; | ||
export type AutocompleteOptionType = AutocompleteOptionIdType | AutocompleteOptionObjectType; | ||
export type AutocompleteValueType = AutocompleteOptionIdType | AutocompleteOptionIdType[]; | ||
export type AutocompleteOptionsGroupType = { | ||
options: AutocompleteOptionType[]; | ||
groupedByValue?: any | ||
}; | ||
export interface AutocompleteProps extends React.HTMLAttributes<HTMLDivElement> { | ||
@@ -21,4 +29,4 @@ children?: React.ReactElementLike; | ||
hint?: React.ReactNode; | ||
value?: any; | ||
options: string[] | AutocompleteObjectOptionstype[]; | ||
value?: AutocompleteValueType; | ||
options: AutocompleteOptionType[]; | ||
noOptionsText?: string; | ||
@@ -34,10 +42,9 @@ placeholder?: string; | ||
focusOnOpen?: boolean; | ||
onChange?: (event: React.SyntheticEvent<HTMLInputElement>, value: string | AutocompleteValueType[]) => void; | ||
onOpen?: (event) => void; | ||
onClose?: (event: React.SyntheticEvent<HTMLInputElement> | React.KeyboardEvent<HTMLInputElement>) => void; | ||
getOptionDisabled?: (item: string, index: number) => boolean; | ||
getOptionValue?: ( | ||
value: string | AutocompleteObjectOptionstype | any | ||
) => string | AutocompleteObjectOptionstype[] | any; | ||
getOptionLabel?: (value: string | AutocompleteObjectOptionstype | any) => string | any; | ||
onChange?: (newValue: AutocompleteValueType) => void; | ||
onOpen?: (event: React.SyntheticEvent<HTMLElement>) => void; | ||
onClose?: (event: React.SyntheticEvent<HTMLElement> | React.KeyboardEvent<HTMLElement> | undefined) => void; | ||
getOptionDisabled?: (option: AutocompleteOptionType) => boolean; | ||
getOptionValue?: (option: AutocompleteOptionType) => AutocompleteOptionIdType; | ||
getOptionLabel?: (option: AutocompleteOptionType) => AutocompleteOptionLabelType; | ||
groupBy?: (option: AutocompleteOptionType) => any; | ||
submitOnBlur?: () => void; | ||
@@ -48,2 +55,59 @@ MenuProps?: MenuProps; | ||
background?: AutocompleteBackgroundType; | ||
maxMenuHeight?: string | number; | ||
showClearIcon?: boolean; | ||
renderLabelIconEnd?: ({ | ||
option, | ||
isMultiple, | ||
}: { | ||
option?: AutocompleteOptionType | null | undefined; | ||
isMultiple: boolean; | ||
}) => React.ReactNode; | ||
renderOptionLabel?: (option: AutocompleteOptionType) => React.ReactNode; | ||
renderSearchEmptyMenuItem?: () => React.ReactNode; | ||
renderGroup?: ({ | ||
key, | ||
group, | ||
children, | ||
}: { | ||
key: string | number; | ||
group: any; | ||
children: React.ReactNode; | ||
}) => React.ReactNode; | ||
} | ||
export interface RenderLabelProps { | ||
label?: React.ReactNode; | ||
error?: boolean; | ||
size?: AutocompleteSizeType; | ||
LabelProps?: LabelProps; | ||
} | ||
export interface RenderHintProps { | ||
hint?: React.ReactNode; | ||
error?: boolean; | ||
size?: AutocompleteSizeType; | ||
} | ||
export interface AutocompleteHookReturn { | ||
formattedValue: AutocompleteValueType; | ||
filteredOptions: AutocompleteOptionType[]; | ||
groupedFilteredOptions: AutocompleteOptionsGroupType[]; | ||
optionsList: AutocompleteOptionType[]; | ||
inputRef: React.Ref; | ||
inputValue: string; | ||
isValueSelected?: boolean; | ||
open: boolean; | ||
anchorEl: AnchorElType; | ||
handleMenuItemClick: (option: AutocompleteOptionType) => () => void; | ||
handleOpenMenuClick: (event: React.SyntheticEvent<HTMLSpanElement>) => void; | ||
handleChangeSearchTerm: (event: React.SyntheticEvent<HTMLInputElement>) => void; | ||
handleCloseMenuClick: ( | ||
event?: React.SyntheticEvent<HTMLInputElement> | React.KeyboardEvent<HTMLInputElement> | ||
) => void; | ||
checkIsIdSelected: (optionId: AutocompleteOptionIdType) => boolean; | ||
getOptionById: (optionId: AutocompleteOptionIdType) => AutocompleteOptionType | undefined | null; | ||
handleOnRemoveItem: (event: React.SyntheticEvent<HTMLElement>, optionId: AutocompleteOptionIdType) => void; | ||
handleOnBlur: () => void; | ||
handleKeyDown: (event: React.KeyboardEvent<HTMLInputElement>) => void; | ||
handleClearIconClick: () => void; | ||
} |
@@ -5,2 +5,3 @@ import styled, { css } from 'styled-components'; | ||
import StyledFormHint from '../form-hint/form-hint.styles'; | ||
import SfxMenu from '../menu'; | ||
import { generateClassNames, applyDisplayNames } from '../../utils/functions'; | ||
@@ -34,2 +35,23 @@ import { Color as PColor } from '../../utils/types/palette'; | ||
})([""]); | ||
var InputIconEndContainer = /*#__PURE__*/styled.div.attrs({ | ||
className: generateClassNames(baseClassName, 'inputIconEndContainer') | ||
}).withConfig({ | ||
componentId: "sc-uyc6rp-4" | ||
})(["display:flex;align-items:center;gap:16px;"]); | ||
var Menu = /*#__PURE__*/styled(SfxMenu).attrs({ | ||
className: generateClassNames(baseClassName, 'menu') | ||
}).withConfig({ | ||
componentId: "sc-uyc6rp-5" | ||
})(["max-height:", ";background:#ffffff;"], function (_ref3) { | ||
var maxMenuHeight = _ref3.maxMenuHeight; | ||
return +maxMenuHeight ? "".concat(+maxMenuHeight, "px") : maxMenuHeight; | ||
}); | ||
var OptionGroup = /*#__PURE__*/styled.div.attrs({ | ||
className: generateClassNames(baseClassName, 'optionGroup') | ||
}).withConfig({ | ||
componentId: "sc-uyc6rp-6" | ||
})(["&:not(:last-child){padding-bottom:8px;margin-bottom:8px;border-bottom:1px solid ", ";}"], function (_ref4) { | ||
var palette = _ref4.theme.palette; | ||
return palette[PColor.BordersSecondary]; | ||
}); | ||
var Styled = applyDisplayNames({ | ||
@@ -39,4 +61,7 @@ Autocomplete: Autocomplete, | ||
TickIcon: TickIcon, | ||
CrossIcon: CrossIcon | ||
CrossIcon: CrossIcon, | ||
InputIconEndContainer: InputIconEndContainer, | ||
Menu: Menu, | ||
OptionGroup: OptionGroup | ||
}); | ||
export default Styled; |
{ | ||
"name": "@scaleflex/ui", | ||
"version": "2.5.0", | ||
"version": "2.6.0", | ||
"author": "scaleflex", | ||
@@ -5,0 +5,0 @@ "repository": "github:scaleflex/ui", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
637116
507
13977