UNPKG

stream-chat-react

Version:

React components to create chat conversations or livestream style chat

106 lines (105 loc) 5.59 kB
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 })); }))); };