stream-chat-react 13.9.0 → 13.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ChannelPreview/hooks/useMessageDeliveryStatus.js +8 -3
- package/dist/components/Chat/hooks/useChat.js +1 -1
- package/dist/components/Dialog/ButtonWithSubmenu.d.ts +2 -2
- package/dist/components/Dialog/ButtonWithSubmenu.js +6 -6
- package/dist/components/Dialog/DialogAnchor.d.ts +5 -11
- package/dist/components/Dialog/DialogAnchor.js +22 -26
- package/dist/components/Dialog/DialogPortal.d.ts +2 -1
- package/dist/components/Dialog/DialogPortal.js +23 -7
- package/dist/components/Dialog/hooks/index.d.ts +1 -0
- package/dist/components/Dialog/hooks/useDialog.d.ts +4 -0
- package/dist/components/Dialog/hooks/useDialog.js +9 -1
- package/dist/components/Dialog/hooks/usePopoverPosition.d.ts +68 -0
- package/dist/components/Dialog/hooks/usePopoverPosition.js +54 -0
- package/dist/components/Form/Dropdown.d.ts +2 -2
- package/dist/components/Message/MessageRepliesCountButton.js +3 -1
- package/dist/components/Message/renderText/remarkPlugins/index.d.ts +1 -0
- package/dist/components/Message/renderText/remarkPlugins/index.js +1 -0
- package/dist/components/Message/renderText/remarkPlugins/keepLineBreaksPlugin.d.ts +10 -2
- package/dist/components/Message/renderText/remarkPlugins/keepLineBreaksPlugin.js +46 -26
- package/dist/components/Message/renderText/remarkPlugins/remarkIgnoreMarkdown.d.ts +8 -0
- package/dist/components/Message/renderText/remarkPlugins/remarkIgnoreMarkdown.js +11 -0
- package/dist/components/MessageActions/MessageActions.js +4 -4
- package/dist/components/MessageInput/AttachmentSelector.d.ts +1 -1
- package/dist/components/MessageInput/AttachmentSelector.js +9 -4
- package/dist/components/MessageList/hooks/useLastDeliveredData.js +5 -2
- package/dist/components/Modal/GlobalModal.js +2 -2
- package/dist/components/Reactions/ReactionSelectorWithButton.js +4 -4
- package/dist/components/Tooltip/Tooltip.d.ts +2 -2
- package/dist/components/Tooltip/Tooltip.js +11 -12
- package/dist/context/DialogManagerContext.d.ts +1 -0
- package/dist/context/DialogManagerContext.js +1 -0
- package/dist/css/v2/index.css +1 -1
- package/dist/css/v2/index.layout.css +1 -1
- package/dist/experimental/MessageActions/MessageActions.js +5 -5
- package/dist/experimental/index.browser.cjs +307 -238
- package/dist/experimental/index.browser.cjs.map +4 -4
- package/dist/experimental/index.node.cjs +307 -238
- package/dist/experimental/index.node.cjs.map +4 -4
- package/dist/index.browser.cjs +1415 -1307
- package/dist/index.browser.cjs.map +4 -4
- package/dist/index.node.cjs +1418 -1307
- package/dist/index.node.cjs.map +4 -4
- package/dist/plugins/Emojis/EmojiPicker.d.ts +9 -4
- package/dist/plugins/Emojis/EmojiPicker.js +10 -5
- package/dist/plugins/Emojis/index.browser.cjs +89 -29
- package/dist/plugins/Emojis/index.browser.cjs.map +4 -4
- package/dist/plugins/Emojis/index.node.cjs +89 -29
- package/dist/plugins/Emojis/index.node.cjs.map +4 -4
- package/dist/scss/v2/Message/Message-layout.scss +4 -0
- package/dist/scss/v2/MessageActionsBox/MessageActionsBox-layout.scss +1 -0
- package/package.json +7 -8
- package/dist/components/MessageActions/hooks/index.d.ts +0 -1
- package/dist/components/MessageActions/hooks/index.js +0 -1
- package/dist/components/MessageActions/hooks/useMessageActionsBoxPopper.d.ts +0 -18
- package/dist/components/MessageActions/hooks/useMessageActionsBoxPopper.js +0 -31
|
@@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
import { UploadIcon as DefaultUploadIcon } from './icons';
|
|
3
3
|
import { useAttachmentManagerState } from './hooks/useAttachmentManagerState';
|
|
4
4
|
import { CHANNEL_CONTAINER_ID } from '../Channel/constants';
|
|
5
|
-
import { DialogAnchor,
|
|
5
|
+
import { DialogAnchor, useDialogIsOpen, useDialogOnNearestManager } from '../Dialog';
|
|
6
6
|
import { DialogMenuButton } from '../Dialog/DialogMenu';
|
|
7
7
|
import { Modal as DefaultModal } from '../Modal';
|
|
8
8
|
import { ShareLocationDialog as DefaultLocationDialog } from '../Location';
|
|
@@ -16,6 +16,7 @@ import clsx from 'clsx';
|
|
|
16
16
|
import { useMessageComposer } from './hooks';
|
|
17
17
|
export const SimpleAttachmentSelector = () => {
|
|
18
18
|
const { AttachmentSelectorInitiationButtonContents, FileUploadIcon = DefaultUploadIcon, } = useComponentContext();
|
|
19
|
+
const { channelCapabilities } = useChannelStateContext();
|
|
19
20
|
const inputRef = useRef(null);
|
|
20
21
|
const [labelElement, setLabelElement] = useState(null);
|
|
21
22
|
const id = useStableId();
|
|
@@ -33,6 +34,8 @@ export const SimpleAttachmentSelector = () => {
|
|
|
33
34
|
labelElement.removeEventListener('keyup', handleKeyUp);
|
|
34
35
|
};
|
|
35
36
|
}, [labelElement]);
|
|
37
|
+
if (!channelCapabilities['upload-file'])
|
|
38
|
+
return null;
|
|
36
39
|
return (React.createElement("div", { className: 'str-chat__file-input-container', "data-testid": 'file-upload-button' },
|
|
37
40
|
React.createElement(UploadFileInput, { id: id, ref: inputRef }),
|
|
38
41
|
React.createElement("label", { className: 'str-chat__file-input-label', htmlFor: id, ref: setLabelElement, tabIndex: 0 }, AttachmentSelectorInitiationButtonContents ? (React.createElement(AttachmentSelectorInitiationButtonContents, null)) : (React.createElement(FileUploadIcon, null)))));
|
|
@@ -119,8 +122,10 @@ export const AttachmentSelector = ({ attachmentSelectorActionSet = defaultAttach
|
|
|
119
122
|
const messageComposer = useMessageComposer();
|
|
120
123
|
const actions = useAttachmentSelectorActionsFiltered(attachmentSelectorActionSet);
|
|
121
124
|
const menuDialogId = `attachment-actions-menu${messageComposer.threadId ? '-thread' : ''}`;
|
|
122
|
-
const menuDialog =
|
|
123
|
-
|
|
125
|
+
const { dialog: menuDialog, dialogManager } = useDialogOnNearestManager({
|
|
126
|
+
id: menuDialogId,
|
|
127
|
+
});
|
|
128
|
+
const menuDialogIsOpen = useDialogIsOpen(menuDialogId, dialogManager?.id);
|
|
124
129
|
const [modalContentAction, setModalContentActionAction] = useState();
|
|
125
130
|
const openModal = useCallback((actionType) => {
|
|
126
131
|
const action = actions.find((a) => a.type === actionType);
|
|
@@ -143,7 +148,7 @@ export const AttachmentSelector = ({ attachmentSelectorActionSet = defaultAttach
|
|
|
143
148
|
channelCapabilities['upload-file'] && React.createElement(UploadFileInput, { ref: setFileInput }),
|
|
144
149
|
React.createElement("button", { "aria-expanded": menuDialogIsOpen, "aria-haspopup": 'true', "aria-label": t('aria/Open Attachment Selector'), className: 'str-chat__attachment-selector__menu-button', "data-testid": 'invoke-attachment-selector-button', onClick: () => menuDialog?.toggle(), ref: menuButtonRef },
|
|
145
150
|
React.createElement(AttachmentSelectorMenuInitButtonIcon, null)),
|
|
146
|
-
React.createElement(DialogAnchor, { id: menuDialogId, placement: 'top-start', referenceElement: menuButtonRef.current, tabIndex: -1, trapFocus: true },
|
|
151
|
+
React.createElement(DialogAnchor, { dialogManagerId: dialogManager?.id, id: menuDialogId, placement: 'top-start', referenceElement: menuButtonRef.current, tabIndex: -1, trapFocus: true },
|
|
147
152
|
React.createElement("div", { className: 'str-chat__attachment-selector-actions-menu str-chat__dialog-menu', "data-testid": 'attachment-selector-actions-menu' }, actions.map(({ ActionButton, type }) => (React.createElement(ActionButton, { closeMenu: menuDialog.close, key: `attachment-selector-item-${type}`, openModalForAction: openModal }))))),
|
|
148
153
|
React.createElement(Portal, { getPortalDestination: getModalPortalDestination ?? getDefaultPortalDestination, isOpen: modalIsOpen },
|
|
149
154
|
React.createElement(Modal, { className: clsx({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
2
2
|
export const useLastDeliveredData = (props) => {
|
|
3
3
|
const { channel, messages, returnAllReadData } = props;
|
|
4
|
-
|
|
4
|
+
const calculate = useCallback(() => returnAllReadData
|
|
5
5
|
? messages.reduce((acc, msg) => {
|
|
6
6
|
acc[msg.id] = channel.messageReceiptsTracker.deliveredForMessage({
|
|
7
7
|
msgId: msg.id,
|
|
@@ -10,4 +10,7 @@ export const useLastDeliveredData = (props) => {
|
|
|
10
10
|
return acc;
|
|
11
11
|
}, {})
|
|
12
12
|
: channel.messageReceiptsTracker.groupUsersByLastDeliveredMessage(), [channel, messages, returnAllReadData]);
|
|
13
|
+
const [deliveredTo, setDeliveredTo] = useState(calculate);
|
|
14
|
+
useEffect(() => channel.on('message.delivered', () => setDeliveredTo(calculate)).unsubscribe, [channel, calculate]);
|
|
15
|
+
return deliveredTo;
|
|
13
16
|
};
|
|
@@ -3,7 +3,7 @@ import { useCallback } from 'react';
|
|
|
3
3
|
import React, { useEffect, useRef } from 'react';
|
|
4
4
|
import { FocusScope } from '@react-aria/focus';
|
|
5
5
|
import { CloseIconRound } from './icons';
|
|
6
|
-
import { useTranslationContext } from '../../context';
|
|
6
|
+
import { modalDialogManagerId, useTranslationContext } from '../../context';
|
|
7
7
|
import { DialogPortalEntry, modalDialogId, useModalDialog, useModalDialogIsOpen, } from '../Dialog';
|
|
8
8
|
export const GlobalModal = ({ children, className, onClose, onCloseAttempt, open, }) => {
|
|
9
9
|
const { t } = useTranslationContext('Modal');
|
|
@@ -48,7 +48,7 @@ export const GlobalModal = ({ children, className, onClose, onCloseAttempt, open
|
|
|
48
48
|
}, [dialog, open]);
|
|
49
49
|
if (!open || !isOpen)
|
|
50
50
|
return null;
|
|
51
|
-
return (React.createElement(DialogPortalEntry, { dialogId: modalDialogId },
|
|
51
|
+
return (React.createElement(DialogPortalEntry, { dialogId: modalDialogId, dialogManagerId: modalDialogManagerId },
|
|
52
52
|
React.createElement("div", { className: clsx('str-chat str-chat__modal str-chat-react__modal str-chat__modal--open', className), onClick: handleClick },
|
|
53
53
|
React.createElement(FocusScope, { autoFocus: true, contain: true },
|
|
54
54
|
React.createElement("button", { className: 'str-chat__modal__close-button', ref: closeButtonRef, title: t('Close'), type: 'button' },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useRef } from 'react';
|
|
2
2
|
import { ReactionSelector as DefaultReactionSelector } from './ReactionSelector';
|
|
3
|
-
import { DialogAnchor,
|
|
3
|
+
import { DialogAnchor, useDialogIsOpen, useDialogOnNearestManager } from '../Dialog';
|
|
4
4
|
import { useComponentContext, useMessageContext, useTranslationContext, } from '../../context';
|
|
5
5
|
/**
|
|
6
6
|
* Internal convenience component - not to be exported. It just groups the button and the dialog anchor and thus prevents
|
|
@@ -13,10 +13,10 @@ export const ReactionSelectorWithButton = ({ ReactionIcon, }) => {
|
|
|
13
13
|
const buttonRef = useRef(null);
|
|
14
14
|
const dialogIdNamespace = threadList ? '-thread-' : '';
|
|
15
15
|
const dialogId = `reaction-selector${dialogIdNamespace}--${message.id}`;
|
|
16
|
-
const dialog =
|
|
17
|
-
const dialogIsOpen = useDialogIsOpen(dialogId);
|
|
16
|
+
const { dialog, dialogManager } = useDialogOnNearestManager({ id: dialogId });
|
|
17
|
+
const dialogIsOpen = useDialogIsOpen(dialogId, dialogManager?.id);
|
|
18
18
|
return (React.createElement(React.Fragment, null,
|
|
19
|
-
React.createElement(DialogAnchor, { id: dialogId, placement: isMyMessage() ? 'top-end' : 'top-start', referenceElement: buttonRef.current, trapFocus: true },
|
|
19
|
+
React.createElement(DialogAnchor, { dialogManagerId: dialogManager?.id, id: dialogId, placement: isMyMessage() ? 'top-end' : 'top-start', referenceElement: buttonRef.current, trapFocus: true },
|
|
20
20
|
React.createElement(ReactionSelector, null)),
|
|
21
21
|
React.createElement("button", { "aria-expanded": dialogIsOpen, "aria-label": t('aria/Open Reaction Selector'), className: 'str-chat__message-reactions-button', "data-testid": 'message-reaction-action', onClick: () => dialog?.toggle(), ref: buttonRef },
|
|
22
22
|
React.createElement(ReactionIcon, { className: 'str-chat__message-action-icon' }))));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ComponentProps } from 'react';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import type {
|
|
3
|
+
import type { PopperLikePlacement } from '../Dialog';
|
|
4
4
|
export declare const Tooltip: ({ children, ...rest }: ComponentProps<'div'>) => React.JSX.Element;
|
|
5
5
|
export type PopperTooltipProps<T extends HTMLElement> = React.PropsWithChildren<{
|
|
6
6
|
/** Reference element to which the tooltip should attach to */
|
|
@@ -8,7 +8,7 @@ export type PopperTooltipProps<T extends HTMLElement> = React.PropsWithChildren<
|
|
|
8
8
|
/** Popper's modifier (offset) property - [xAxis offset, yAxis offset], default [0, 10] */
|
|
9
9
|
offset?: [number, number];
|
|
10
10
|
/** Popper's placement property defining default position of the tooltip, default 'top' */
|
|
11
|
-
placement?:
|
|
11
|
+
placement?: PopperLikePlacement;
|
|
12
12
|
/** Tells component whether to render its contents */
|
|
13
13
|
visible?: boolean;
|
|
14
14
|
}>;
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import {
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { usePopoverPosition } from '../Dialog/hooks/usePopoverPosition';
|
|
3
3
|
export const Tooltip = ({ children, ...rest }) => (React.createElement("div", { className: 'str-chat__tooltip', ...rest }, children));
|
|
4
4
|
export const PopperTooltip = ({ children, offset = [0, 10], placement = 'top', referenceElement, visible = false, }) => {
|
|
5
5
|
const [popperElement, setPopperElement] = useState(null);
|
|
6
|
-
const {
|
|
7
|
-
|
|
8
|
-
{
|
|
9
|
-
name: 'offset',
|
|
10
|
-
options: {
|
|
11
|
-
offset,
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
],
|
|
6
|
+
const { placement: resolvedPlacement, refs, strategy, x, y, } = usePopoverPosition({
|
|
7
|
+
offset,
|
|
15
8
|
placement,
|
|
16
9
|
});
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
refs.setReference(referenceElement);
|
|
12
|
+
}, [referenceElement, refs]);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
refs.setFloating(popperElement);
|
|
15
|
+
}, [popperElement, refs]);
|
|
17
16
|
if (!visible)
|
|
18
17
|
return null;
|
|
19
|
-
return (React.createElement("div", { className: 'str-chat__tooltip', ref: setPopperElement, style:
|
|
18
|
+
return (React.createElement("div", { className: 'str-chat__tooltip', "data-placement": resolvedPlacement, ref: setPopperElement, style: { left: x ?? 0, position: strategy, top: y ?? 0 } }, children));
|
|
20
19
|
};
|
|
@@ -25,4 +25,5 @@ export declare const useDialogManager: ({ dialogId, dialogManagerId, }?: UseDial
|
|
|
25
25
|
export declare const modalDialogManagerId: "modal-dialog-manager";
|
|
26
26
|
export declare const ModalDialogManagerProvider: ({ children }: PropsWithChildrenOnly) => React.JSX.Element;
|
|
27
27
|
export declare const useModalDialogManager: () => DialogManager | undefined;
|
|
28
|
+
export declare const useNearestDialogManagerContext: () => DialogManagerProviderContextValue | undefined;
|
|
28
29
|
export {};
|
|
@@ -121,3 +121,4 @@ export const useDialogManager = ({ dialogId, dialogManagerId, } = {}) => {
|
|
|
121
121
|
export const modalDialogManagerId = 'modal-dialog-manager';
|
|
122
122
|
export const ModalDialogManagerProvider = ({ children }) => (React.createElement(DialogManagerProvider, { id: modalDialogManagerId }, children));
|
|
123
123
|
export const useModalDialogManager = () => useMemo(() => getDialogManager(modalDialogManagerId), []);
|
|
124
|
+
export const useNearestDialogManagerContext = () => useContext(DialogManagerProviderContext);
|