UNPKG

stream-chat-react

Version:

React components to create chat conversations or livestream style chat

48 lines (47 loc) 3.61 kB
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))); };