@activecollab/components
Version:
ActiveCollab Components
589 lines (588 loc) • 24.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Autocomplete = void 0;
exports.isOptionGroup = isOptionGroup;
var _styledComponents = _interopRequireDefault(require("styled-components"));
var _react = _interopRequireWildcard(require("react"));
var _reactVirtual = require("@tanstack/react-virtual");
var _HandleKeyboard = require("./HandleKeyboard");
var _Styles = require("./Styles");
var _useHighlightText = _interopRequireDefault(require("../../hooks/useHighlightText"));
var _Option = require("../Select/Option");
var _Styles2 = require("../Select/Option/Styles");
var _OptionGroup = require("../Select/OptionGroup");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
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; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function isOptionGroup(item) {
return item.options !== undefined;
}
var Autocomplete = exports.Autocomplete = function Autocomplete(_ref) {
var type = _ref.type,
_ref$options = _ref.options,
options = _ref$options === void 0 ? [] : _ref$options,
inputEl = _ref.inputEl,
_ref$selected = _ref.selected,
selected = _ref$selected === void 0 ? [] : _ref$selected,
emptyValue = _ref.emptyValue,
noResultText = _ref.noResultText,
_ref$renderOption = _ref.renderOption,
renderOption = _ref$renderOption === void 0 ? function (option) {
return option === null || option === void 0 ? void 0 : option.name;
} : _ref$renderOption,
defaultValue = _ref.defaultValue,
_ref$sortDirection = _ref.sortDirection,
sortDirection = _ref$sortDirection === void 0 ? "asc" : _ref$sortDirection,
handleChange = _ref.handleChange,
optionClassName = _ref.optionClassName,
handleEmptyAction = _ref.handleEmptyAction,
disabledInternalSort = _ref.disabledInternalSort,
AutocompleteClassName = _ref.AutocompleteClassName,
handleDefaultOptionChange = _ref.handleDefaultOptionChange,
preselectDefaultValue = _ref.preselectDefaultValue,
_ref$keepSameOptionsO = _ref.keepSameOptionsOrder,
keepSameOptionsOrder = _ref$keepSameOptionsO === void 0 ? false : _ref$keepSameOptionsO,
_ref$autoHeightMax = _ref.autoHeightMax,
autoHeightMax = _ref$autoHeightMax === void 0 ? 340 : _ref$autoHeightMax,
clearInputOnSelect = _ref.clearInputOnSelect,
_ref$mixedOptions = _ref.mixedOptions,
mixedOptions = _ref$mixedOptions === void 0 ? [] : _ref$mixedOptions,
filterCriteria = _ref.filterCriteria,
disableVirtualization = _ref.disableVirtualization;
var listContainerRef = (0, _react.useRef)(null);
var itemRef = (0, _react.useRef)(null);
var selectedOptions = (0, _react.useMemo)(function () {
if (Array.isArray(selected)) {
return selected;
}
return [selected];
}, [selected]);
var handleSort = (0, _react.useCallback)(function (opts) {
var _opts$;
if (keepSameOptionsOrder) {
return opts;
}
var isGrouped = Array.isArray((_opts$ = opts[0]) === null || _opts$ === void 0 ? void 0 : _opts$.options);
var sortOptions = function sortOptions(a, b) {
var aSelected = selectedOptions.includes(a.id);
var bSelected = selectedOptions.includes(b.id);
var aMixed = mixedOptions.includes(a.id);
var bMixed = mixedOptions.includes(b.id);
if (aSelected && !bSelected) {
return -1;
}
if (!aSelected && bSelected) {
return 1;
}
if (aMixed && !bMixed) {
return -1;
}
if (!aMixed && bMixed) {
return 1;
}
return 0;
};
if (isGrouped) {
return opts.map(function (group) {
var sortedGroupOptions = group.options.sort(sortOptions);
return _objectSpread(_objectSpread({}, group), {}, {
options: sortedGroupOptions
});
});
} else {
return opts.sort(sortOptions);
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[mixedOptions, selectedOptions]);
var sortList = (0, _react.useCallback)(function (options) {
var _options$;
if (disabledInternalSort) {
return handleSort([...options]);
}
var isGrouped = Array.isArray((_options$ = options[0]) === null || _options$ === void 0 ? void 0 : _options$.options);
if (isGrouped) {
var sortedOptions = options.map(function (group) {
var sortedGroupOptions = group.options.sort(function (a, b) {
return sortDirection === "asc" ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name);
});
return _objectSpread(_objectSpread({}, group), {}, {
options: handleSort(sortedGroupOptions)
});
});
return handleSort(sortedOptions);
} else {
var _sortedOptions = options.sort(function (a, b) {
return sortDirection === "asc" ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name);
});
return handleSort(_sortedOptions);
}
}, [sortDirection, disabledInternalSort, handleSort]);
var _useState = (0, _react.useState)(function () {
return sortList(options);
}),
_useState2 = _slicedToArray(_useState, 2),
sortedList = _useState2[0],
setSortedList = _useState2[1];
(0, _react.useEffect)(function () {
setSortedList(sortList(options));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [options]);
var _useState3 = (0, _react.useState)({
item: undefined,
by: undefined
}),
_useState4 = _slicedToArray(_useState3, 2),
hover = _useState4[0],
setHover = _useState4[1];
var _useState5 = (0, _react.useState)(""),
_useState6 = _slicedToArray(_useState5, 2),
filter = _useState6[0],
setFilter = _useState6[1];
var handleEmpty = (0, _react.useCallback)(function (e) {
if (e && e.button !== 0) {
return;
}
if (handleEmptyAction) {
var _inputEl$current;
inputEl === null || inputEl === void 0 || (_inputEl$current = inputEl.current) === null || _inputEl$current === void 0 || _inputEl$current.focus();
setFilter("");
handleEmptyAction(filter);
}
}, [filter, handleEmptyAction, inputEl]);
var onAddNewMouseEnter = (0, _react.useCallback)(function () {
return setHover({
item: "addNew",
by: "mouse"
});
}, []);
var showAddNew = (0, _react.useMemo)(function () {
return !!(emptyValue && filter.trim() && options.every(function (option) {
if (isOptionGroup(option)) {
return option.options.every(function (v) {
return v.name.toLowerCase() !== filter.trim().toLowerCase();
});
}
return option.name.toLowerCase() !== filter.trim().toLowerCase();
}));
}, [emptyValue, filter, options]);
var filterOptions = (0, _react.useCallback)(function (options, filter) {
var trimmedFilter = filter.trim();
var isGrouped = options[0] && isOptionGroup(options[0]);
var matchesFilter = function matchesFilter(option) {
var nameMatch = option.name.toLowerCase().includes(trimmedFilter.toLowerCase());
if (filterCriteria && trimmedFilter) {
return nameMatch || filterCriteria(option, trimmedFilter);
}
return nameMatch;
};
if (isGrouped) {
var hovered = false;
return options.reduce(function (acc, groupedOption) {
var filteredOptions = groupedOption.options.filter(matchesFilter);
if (filteredOptions.length > 0) {
if (!hovered && filter) {
setHover({
item: filteredOptions[0].id,
by: "keyboard"
});
}
hovered = true;
return [...acc, _objectSpread(_objectSpread({}, groupedOption), {}, {
options: filteredOptions
})];
}
return [...acc];
}, []);
} else {
var filteredOptions = options.filter(matchesFilter);
if (filter && filteredOptions.length > 0) {
setHover({
item: filteredOptions[0].id,
by: "keyboard"
});
}
if (filteredOptions.length === 0 && emptyValue) {
setHover({
item: "addNew",
by: "keyboard"
});
}
return filteredOptions;
}
}, [emptyValue, filterCriteria]);
var list = (0, _react.useMemo)(function () {
return filterOptions(sortedList, filter);
}, [filter, filterOptions, sortedList]);
var showDefaultOption = (0, _react.useMemo)(function () {
return !!defaultValue && !filter;
}, [defaultValue, filter]);
var flatOptions = (0, _react.useMemo)(function () {
var options = list.reduce(function (acc, option) {
if (!isOptionGroup(option)) {
return [...acc, option];
}
return [...acc, ...option.options];
}, []);
return filterOptions(options, filter);
}, [filter, filterOptions, list]);
var showNoResultCondition = (0, _react.useMemo)(function () {
return noResultText && !showAddNew && list.length < 1 && (defaultValue && filter || !defaultValue);
}, [noResultText, showAddNew, list.length, defaultValue, filter]);
var virtualItems = (0, _react.useMemo)(function () {
var items = [];
if (showDefaultOption) {
items.push({
type: "default",
id: "default"
});
}
list.forEach(function (item, index) {
if (isOptionGroup(item)) {
items.push({
type: "group",
id: item.id,
item
});
item.options.forEach(function (option) {
items.push({
type: "option",
id: option.id,
item: option,
index
});
});
} else {
items.push({
type: "option",
id: item.id,
item,
index
});
}
});
if (showNoResultCondition) {
items.push({
type: "noResult",
id: "noResult"
});
}
if (showAddNew) {
items.push({
type: "addNew",
id: "addNew"
});
}
return items;
}, [list, showDefaultOption, showNoResultCondition, showAddNew]);
var shouldUseVirtualization = !disableVirtualization && virtualItems.length > 40;
var rowVirtualizer = (0, _reactVirtual.useVirtualizer)({
count: virtualItems.length,
getScrollElement: function getScrollElement() {
return listContainerRef.current;
},
estimateSize: function estimateSize() {
return 28;
},
overscan: 5,
gap: 4
});
var handleInputChange = (0, _react.useCallback)(function (e) {
if (e.target && !(e.key === "ArrowDown") && !(e.key === "ArrowUp") && !(e.key === "Enter")) {
setFilter(e.target.value);
}
}, []);
var handleHoverCallback = (0, _react.useCallback)(function (e) {
setHover({
item: e,
by: "mouse"
});
}, []);
var toggleSelected = (0, _react.useCallback)(function (id) {
var result;
if (id !== null) {
if (type === "multiple") {
if (selectedOptions.includes(id)) {
result = selectedOptions.filter(function (_id) {
return _id !== id;
});
} else {
result = [...selectedOptions, id];
}
} else {
result = id;
}
if (clearInputOnSelect && inputEl !== null && inputEl !== void 0 && inputEl.current) {
inputEl.current.value = "";
inputEl.current.dispatchEvent(new Event("change", {
bubbles: true
}));
}
setFilter("");
} else {
if (typeof handleDefaultOptionChange === "function") {
handleDefaultOptionChange();
return;
}
}
if (typeof handleChange === "function") {
handleChange(result);
}
}, [clearInputOnSelect, handleChange, handleDefaultOptionChange, inputEl, selectedOptions, type]);
var handleMouseEnter = (0, _react.useCallback)(function (e) {
if (e === undefined || e === null) {
return setHover({
item: null,
by: "mouse"
});
}
setHover({
item: e,
by: "mouse"
});
}, []);
var handleClick = (0, _react.useCallback)(function (e) {
e.preventDefault();
toggleSelected(hover.item);
}, [toggleSelected, hover]);
var handleRenderOption = (0, _react.useCallback)(function (item, index) {
if (isOptionGroup(item)) {
return /*#__PURE__*/_react.default.createElement(_OptionGroup.OptionGroup, {
checked: selectedOptions,
name: item.name,
tooltip: item.tooltip,
key: item.id,
setHover: handleHoverCallback,
id: item.id,
hover: hover.item,
options: item.options,
renderOptions: handleRenderOption,
type: type,
onChange: handleChange,
filter: filter,
mixedOptions: mixedOptions
});
}
return /*#__PURE__*/_react.default.createElement(_Option.Option, {
name: item.name,
ref: hover.item === item.id ? itemRef : null,
key: index,
tooltip: item.tooltip,
onMouseEnter: handleMouseEnter,
onClick: handleClick,
id: item.id,
hover: item.id === hover.item,
className: optionClassName,
renderOption: renderOption(_objectSpread(_objectSpread({}, item), {}, {
name: (0, _useHighlightText.default)(item.name, filter)
}), {
id: "option_".concat(item.id),
checked: selectedOptions && selectedOptions.includes(item.id),
hover: hover.item === item.id,
onChange: function onChange() {
return null;
}
})
});
}, [handleClick, handleMouseEnter, hover.item, optionClassName, renderOption, filter, selectedOptions, handleHoverCallback, type, handleChange, mixedOptions]);
var handleOnMouseLeave = (0, _react.useCallback)(function () {
setHover({
item: undefined,
by: "mouse"
});
}, []);
(0, _react.useEffect)(function () {
if (hover.by === "keyboard" && hover.item !== undefined) {
var index = virtualItems.findIndex(function (item) {
return item.id === hover.item;
});
if (index !== -1) {
rowVirtualizer.scrollToIndex(index, {
align: "center"
});
}
}
}, [hover, rowVirtualizer, virtualItems]);
var handleOnKeyDown = (0, _react.useCallback)(function (e) {
if (e.key === "Enter") {
e.preventDefault();
if (hover.item === undefined && filter === "") {
return;
}
if (hover.item === "addNew") {
handleEmpty(null);
return;
}
if (hover.item === null && handleDefaultOptionChange) {
handleDefaultOptionChange();
return;
}
if (typeof hover.item !== "undefined" || hover.item !== null) {
toggleSelected(hover.item);
setFilter("");
}
return;
}
setHover({
item: (0, _HandleKeyboard.handleKeyboardMovement)(e, hover.item, flatOptions, showAddNew, showDefaultOption),
by: "keyboard"
});
}, [filter, flatOptions, toggleSelected, handleDefaultOptionChange, handleEmpty, hover, showAddNew, showDefaultOption]);
(0, _react.useEffect)(function () {
var _inputEl$current2;
var listenerTarget = (_inputEl$current2 = inputEl === null || inputEl === void 0 ? void 0 : inputEl.current) !== null && _inputEl$current2 !== void 0 ? _inputEl$current2 : document;
listenerTarget.addEventListener("input", handleInputChange);
listenerTarget.addEventListener("keydown", handleOnKeyDown);
return function () {
listenerTarget.removeEventListener("input", handleInputChange);
listenerTarget.removeEventListener("keydown", handleOnKeyDown);
};
}, [handleInputChange, handleOnKeyDown, inputEl]);
var isDefaultOptionSelected = (0, _react.useCallback)(function () {
if (preselectDefaultValue) {
return selectedOptions.length < 1 || selectedOptions[0] === "";
} else {
return selectedOptions[0] === null || selectedOptions.length === flatOptions.length;
}
}, [flatOptions.length, preselectDefaultValue, selectedOptions]);
var renderVirtualItem = (0, _react.useCallback)(function (virtualItem, index) {
switch (virtualItem.type) {
case "default":
return /*#__PURE__*/_react.default.createElement(_Option.Option, {
name: String(defaultValue),
ref: hover.item === null ? itemRef : null,
hover: hover.item === null,
onMouseEnter: handleMouseEnter,
onClick: function onClick(e) {
e.preventDefault();
toggleSelected(null);
},
renderOption: renderOption({
name: defaultValue,
id: null
}, {
checked: isDefaultOptionSelected(),
hover: hover.item === null,
onChange: function onChange() {
return null;
}
})
});
case "group":
if (!virtualItem.item || !isOptionGroup(virtualItem.item)) return null;
return /*#__PURE__*/_react.default.createElement(_OptionGroup.OptionGroup, {
checked: selectedOptions,
name: virtualItem.item.name,
tooltip: virtualItem.item.tooltip,
key: virtualItem.item.id,
setHover: handleHoverCallback,
id: virtualItem.item.id,
hover: hover.item,
options: virtualItem.item.options,
renderOptions: handleRenderOption,
type: type,
onChange: handleChange,
filter: filter,
mixedOptions: mixedOptions
});
case "option":
if (!virtualItem.item || isOptionGroup(virtualItem.item)) return null;
return /*#__PURE__*/_react.default.createElement(_Option.Option, {
name: virtualItem.item.name,
ref: hover.item === virtualItem.id ? itemRef : null,
key: index,
tooltip: virtualItem.item.tooltip,
onMouseEnter: function onMouseEnter() {
return handleMouseEnter(virtualItem.id);
},
onClick: handleClick,
id: virtualItem.id,
hover: virtualItem.id === hover.item,
className: optionClassName,
renderOption: renderOption(_objectSpread(_objectSpread({}, virtualItem.item), {}, {
name: (0, _useHighlightText.default)(virtualItem.item.name, filter)
}), {
id: "option_".concat(virtualItem.id),
checked: selectedOptions && selectedOptions.includes(virtualItem.id),
hover: hover.item === virtualItem.id,
onChange: function onChange() {
return null;
}
})
});
case "noResult":
return /*#__PURE__*/_react.default.createElement(_StyledStyledOption, null, noResultText);
case "addNew":
return /*#__PURE__*/_react.default.createElement(_Styles.StyledAutocompleteNewItem, {
ref: hover.item === "addNew" ? itemRef : null,
key: "emptyValue",
hover: hover.item === "addNew",
onMouseDown: handleEmpty,
onMouseEnter: onAddNewMouseEnter
}, emptyValue);
default:
return null;
}
}, [defaultValue, hover.item, handleMouseEnter, renderOption, isDefaultOptionSelected, selectedOptions, handleHoverCallback, handleRenderOption, type, handleChange, filter, mixedOptions, handleClick, optionClassName, noResultText, handleEmpty, onAddNewMouseEnter, emptyValue, toggleSelected]);
return /*#__PURE__*/_react.default.createElement(_Styles.StyledAutocompleteScrollShadow, {
className: AutocompleteClassName,
$isHidden: !defaultValue && !emptyValue && !noResultText && list.length < 1
}, function (_ref2) {
var _onScroll = _ref2.onScroll;
return /*#__PURE__*/_react.default.createElement(_Styles.StyledAutocompleteBody, {
key: "body",
onMouseLeave: handleOnMouseLeave
}, /*#__PURE__*/_react.default.createElement("div", {
ref: listContainerRef,
style: {
height: "".concat(Math.min(rowVirtualizer.getTotalSize() + 12, autoHeightMax), "px"),
overflow: "auto"
},
onScroll: function onScroll(e) {
if (_onScroll) _onScroll(e);
}
}, /*#__PURE__*/_react.default.createElement("div", {
style: {
height: "".concat(rowVirtualizer.getTotalSize(), "px"),
width: "100%",
position: "relative"
}
}, shouldUseVirtualization ? rowVirtualizer.getVirtualItems().map(function (virtualRow) {
var item = virtualItems[virtualRow.index];
return /*#__PURE__*/_react.default.createElement("div", {
key: virtualRow.index,
"data-index": virtualRow.index,
style: {
position: "absolute",
top: 0,
left: 0,
width: "100%",
transform: "translateY(".concat(virtualRow.start, "px)")
}
}, renderVirtualItem(item, virtualRow.index));
}) : virtualItems.map(function (item, index) {
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, {
key: index
}, renderVirtualItem(item, index));
}))));
});
};
Autocomplete.displayName = "Autocomplete";
var _StyledStyledOption = (0, _styledComponents.default)(_Styles2.StyledOption).withConfig({
displayName: "Autocomplete___StyledStyledOption",
componentId: "sc-9x4q7e-0"
})(["cursor:auto"]);
//# sourceMappingURL=Autocomplete.js.map