stream-chat-react
Version:
React components to create chat conversations or livestream style chat
48 lines (47 loc) • 3.61 kB
JavaScript
import clsx from 'clsx';
import React, { useState } from 'react';
import { useChatContext, useMessageContext, useTranslationContext } from '../../context';
import { ActionsIcon } from '../../components/Message/icons';
import { DialogAnchor, useDialog, useDialogIsOpen } from '../../components/Dialog';
import { MessageActionsWrapper } from '../../components/MessageActions/MessageActions';
import { useBaseMessageActionSetFilter, useSplitMessageActionSet } from './hooks';
import { defaultMessageActionSet } from './defaults';
// TODO: allow passing down customWrapperClass
/**
* A new actions component to replace current `MessageOptions` component.
* Exports from `stream-chat-react/experimental` __MIGHT__ change - use with caution
* and follow release notes in case you notice unexpected behavior.
*/
export const MessageActions = ({ disableBaseMessageActionSetFilter = false, messageActionSet = defaultMessageActionSet, }) => {
const { theme } = useChatContext();
const { isMyMessage, message } = useMessageContext();
const { t } = useTranslationContext();
const [actionsBoxButtonElement, setActionsBoxButtonElement] = useState(null);
const filteredMessageActionSet = useBaseMessageActionSetFilter(messageActionSet, disableBaseMessageActionSetFilter);
const { dropdownActionSet, quickActionSet } = useSplitMessageActionSet(filteredMessageActionSet);
const dropdownDialogId = `message-actions--${message.id}`;
const reactionSelectorDialogId = `reaction-selector--${message.id}`;
const dialog = useDialog({ id: dropdownDialogId });
const dropdownDialogIsOpen = useDialogIsOpen(dropdownDialogId);
const reactionSelectorDialogIsOpen = useDialogIsOpen(reactionSelectorDialogId);
// do not render anything if total action count is zero
if (dropdownActionSet.length + quickActionSet.length === 0) {
return null;
}
return (React.createElement("div", { className: clsx(`str-chat__message-${theme}__actions str-chat__message-options`, {
'str-chat__message-options--active': dropdownDialogIsOpen || reactionSelectorDialogIsOpen,
}) },
dropdownActionSet.length > 0 && (React.createElement(MessageActionsWrapper, { inline: false, toggleOpen: dialog?.toggle },
React.createElement("button", { "aria-expanded": dropdownDialogIsOpen, "aria-haspopup": 'true', "aria-label": t('aria/Open Message Actions Menu'), className: 'str-chat__message-actions-box-button', "data-testid": 'message-actions-toggle-button', ref: setActionsBoxButtonElement },
React.createElement(ActionsIcon, { className: 'str-chat__message-action-icon' })),
React.createElement(DialogAnchor, { id: dropdownDialogId, placement: isMyMessage() ? 'top-end' : 'top-start', referenceElement: actionsBoxButtonElement, tabIndex: -1, trapFocus: true },
React.createElement(DropdownBox, { open: dropdownDialogIsOpen }, dropdownActionSet.map(({ Component: DropdownActionComponent, type }) => (React.createElement(DropdownActionComponent, { key: type }))))))),
quickActionSet.map(({ Component: QuickActionComponent, type }) => (React.createElement(QuickActionComponent, { key: type })))));
};
const DropdownBox = ({ children, open }) => {
const { t } = useTranslationContext();
return (React.createElement("div", { className: clsx('str-chat__message-actions-box', {
'str-chat__message-actions-box--open': open,
}) },
React.createElement("div", { "aria-label": t('aria/Message Options'), className: 'str-chat__message-actions-list', role: 'listbox' }, children)));
};