stream-chat-react
Version:
React components to create chat conversations or livestream style chat
106 lines (105 loc) • 5.59 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import clsx from 'clsx';
import { useComponentContext } from '../../context/ComponentContext';
import { useChatContext } from '../../context/ChatContext';
import { escapeRegExp } from '../../utils';
import { Item } from './Item';
import { DefaultSuggestionListHeader } from './Header';
export var List = function (_a) {
var className = _a.className, component = _a.component, currentTrigger = _a.currentTrigger, dropdownScroll = _a.dropdownScroll, getSelectedItem = _a.getSelectedItem, getTextToReplace = _a.getTextToReplace, PropHeader = _a.Header, itemClassName = _a.itemClassName, itemStyle = _a.itemStyle, onSelect = _a.onSelect, selectionEnd = _a.selectionEnd, style = _a.style, PropSuggestionItem = _a.SuggestionItem, propValue = _a.value, values = _a.values;
var _b = useComponentContext('SuggestionList'), AutocompleteSuggestionHeader = _b.AutocompleteSuggestionHeader, AutocompleteSuggestionItem = _b.AutocompleteSuggestionItem;
var themeVersion = useChatContext('SuggestionList').themeVersion;
var SuggestionItem = PropSuggestionItem || AutocompleteSuggestionItem || Item;
var SuggestionHeader = PropHeader || AutocompleteSuggestionHeader || DefaultSuggestionListHeader;
var _c = useState(undefined), selectedItem = _c[0], setSelectedItem = _c[1];
var itemsRef = [];
var isSelected = function (item) {
return selectedItem === values.findIndex(function (value) { return getId(value) === getId(item); });
};
var getId = function (item) {
var textToReplace = getTextToReplace(item);
if (textToReplace.key) {
return textToReplace.key;
}
if (typeof item === 'string' || !item.key) {
return textToReplace.text;
}
return item.key;
};
var modifyText = function (value) {
if (!value)
return;
onSelect(getTextToReplace(value));
if (getSelectedItem)
getSelectedItem(value);
};
var handleClick = function (e) {
e === null || e === void 0 ? void 0 : e.preventDefault();
modifyText(values[selectedItem]);
};
var selectItem = useCallback(function (item) {
var index = values.findIndex(function (value) {
return value.id ? value.id === item.id : value.name === item.name;
});
setSelectedItem(index);
}, [values]);
var handleKeyDown = useCallback(function (event) {
if (event.key === 'ArrowUp') {
setSelectedItem(function (prevSelected) {
if (prevSelected === undefined)
return 0;
var newID = prevSelected === 0 ? values.length - 1 : prevSelected - 1;
dropdownScroll(itemsRef[newID]);
return newID;
});
}
if (event.key === 'ArrowDown') {
setSelectedItem(function (prevSelected) {
if (prevSelected === undefined)
return 0;
var newID = prevSelected === values.length - 1 ? 0 : prevSelected + 1;
dropdownScroll(itemsRef[newID]);
return newID;
});
}
if ((event.key === 'Enter' || event.key === 'Tab') && selectedItem !== undefined) {
handleClick(event);
}
return null;
}, [selectedItem, values]);
useEffect(function () {
document.addEventListener('keydown', handleKeyDown, false);
return function () { return document.removeEventListener('keydown', handleKeyDown); };
}, [handleKeyDown]);
useEffect(function () {
if (values === null || values === void 0 ? void 0 : values.length)
selectItem(values[0]);
}, [values]); // eslint-disable-line
var restructureItem = useCallback(function (item) {
var matched = item.name || item.id;
var textBeforeCursor = propValue.slice(0, selectionEnd);
var triggerIndex = textBeforeCursor.lastIndexOf(currentTrigger);
var editedPropValue = escapeRegExp(textBeforeCursor.slice(triggerIndex + 1));
var parts = matched.split(new RegExp("(".concat(editedPropValue, ")"), 'gi'));
var itemNameParts = { match: editedPropValue, parts: parts };
return __assign(__assign({}, item), { itemNameParts: itemNameParts });
}, [propValue, selectionEnd, currentTrigger]);
var restructuredValues = useMemo(function () { return values.map(restructureItem); }, [values, restructureItem]);
return (React.createElement("ul", { className: clsx('rta__list', className), style: style },
themeVersion === '1' && (React.createElement("li", { className: 'rta__list-header' },
React.createElement(SuggestionHeader, { currentTrigger: currentTrigger, value: propValue }))),
restructuredValues.map(function (item, i) { return (React.createElement(SuggestionItem, { className: itemClassName, component: component, item: item, key: getId(item), onClickHandler: handleClick, onSelectHandler: selectItem, ref: function (ref) {
itemsRef[i] = ref;
}, selected: isSelected(item), style: itemStyle, value: propValue })); })));
};