stream-chat-react 14.9.0 → 14.11.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.
Files changed (171) hide show
  1. package/README.md +20 -1
  2. package/dist/cjs/{useNotificationApi.bf76a16b.js → NotificationList.6abbee1c.js} +4935 -1232
  3. package/dist/cjs/NotificationList.6abbee1c.js.map +1 -0
  4. package/dist/cjs/{ReactPlayerWrapper.60a93742.js → ReactPlayerWrapper.a94a0cd1.js} +3 -3
  5. package/dist/cjs/{ReactPlayerWrapper.60a93742.js.map → ReactPlayerWrapper.a94a0cd1.js.map} +1 -1
  6. package/dist/cjs/channel-detail.js +288 -217
  7. package/dist/cjs/channel-detail.js.map +1 -1
  8. package/dist/cjs/emojis.js +31 -15
  9. package/dist/cjs/emojis.js.map +1 -1
  10. package/dist/cjs/index.js +2114 -7670
  11. package/dist/cjs/index.js.map +1 -1
  12. package/dist/cjs/useChannelHeaderOnlineStatus.7e17671e.js +961 -0
  13. package/dist/cjs/useChannelHeaderOnlineStatus.7e17671e.js.map +1 -0
  14. package/dist/cjs/useInertWhenHidden.22151beb.js +6426 -0
  15. package/dist/cjs/useInertWhenHidden.22151beb.js.map +1 -0
  16. package/dist/es/{useNotificationApi.ed6bff88.mjs → NotificationList.db01a56d.mjs} +4556 -1258
  17. package/dist/es/NotificationList.db01a56d.mjs.map +1 -0
  18. package/dist/es/channel-detail.mjs +115 -44
  19. package/dist/es/channel-detail.mjs.map +1 -1
  20. package/dist/es/emojis.mjs +25 -8
  21. package/dist/es/emojis.mjs.map +1 -1
  22. package/dist/es/index.mjs +1056 -6612
  23. package/dist/es/index.mjs.map +1 -1
  24. package/dist/es/useChannelHeaderOnlineStatus.a9357343.mjs +771 -0
  25. package/dist/es/useChannelHeaderOnlineStatus.a9357343.mjs.map +1 -0
  26. package/dist/es/useInertWhenHidden.3d5fbdba.mjs +5765 -0
  27. package/dist/es/useInertWhenHidden.3d5fbdba.mjs.map +1 -0
  28. package/dist/types/components/Attachment/Geolocation.d.ts.map +1 -1
  29. package/dist/types/components/Attachment/LinkPreview/Card.d.ts.map +1 -1
  30. package/dist/types/components/Attachment/LinkPreview/CardAudio.d.ts.map +1 -1
  31. package/dist/types/components/Attachment/ModalGallery.d.ts.map +1 -1
  32. package/dist/types/components/Attachment/UnsupportedAttachment.d.ts.map +1 -1
  33. package/dist/types/components/Attachment/VisibilityDisclaimer.d.ts.map +1 -1
  34. package/dist/types/components/Attachment/components/DownloadButton.d.ts.map +1 -1
  35. package/dist/types/components/Avatar/Avatar.d.ts +12 -3
  36. package/dist/types/components/Avatar/Avatar.d.ts.map +1 -1
  37. package/dist/types/components/Avatar/utils.d.ts +3 -0
  38. package/dist/types/components/Avatar/utils.d.ts.map +1 -0
  39. package/dist/types/components/Badge/Badge.d.ts.map +1 -1
  40. package/dist/types/components/Badge/MediaBadge.d.ts.map +1 -1
  41. package/dist/types/components/BaseImage/ImagePlaceholder.d.ts.map +1 -1
  42. package/dist/types/components/Button/PlayButton.d.ts.map +1 -1
  43. package/dist/types/components/Channel/Channel.d.ts.map +1 -1
  44. package/dist/types/components/ChannelListItem/ChannelListItem.d.ts.map +1 -1
  45. package/dist/types/components/ChannelListItem/ChannelListItemActionButtons.defaults.d.ts.map +1 -1
  46. package/dist/types/components/ChannelListItem/ChannelListItemUI.d.ts.map +1 -1
  47. package/dist/types/components/ChannelListItem/hooks/useMessageDeliveryStatus.d.ts.map +1 -1
  48. package/dist/types/components/ChannelListItem/utils.d.ts.map +1 -1
  49. package/dist/types/components/ChatView/ChatView.d.ts.map +1 -1
  50. package/dist/types/components/Dialog/components/Callout.d.ts.map +1 -1
  51. package/dist/types/components/Dialog/components/ContextMenu.d.ts +4 -0
  52. package/dist/types/components/Dialog/components/ContextMenu.d.ts.map +1 -1
  53. package/dist/types/components/Dialog/components/Prompt.d.ts.map +1 -1
  54. package/dist/types/components/Dialog/components/Viewer.d.ts.map +1 -1
  55. package/dist/types/components/EmptyStateIndicator/EmptyStateIndicator.d.ts.map +1 -1
  56. package/dist/types/components/Form/NumericInput.d.ts.map +1 -1
  57. package/dist/types/components/Form/TextInput.d.ts.map +1 -1
  58. package/dist/types/components/Gallery/GalleryHeader.d.ts.map +1 -1
  59. package/dist/types/components/Gallery/GalleryUI.d.ts.map +1 -1
  60. package/dist/types/components/Icons/index.d.ts +1 -0
  61. package/dist/types/components/Icons/index.d.ts.map +1 -1
  62. package/dist/types/components/Icons/slots.d.ts +10 -0
  63. package/dist/types/components/Icons/slots.d.ts.map +1 -0
  64. package/dist/types/components/Loading/LoadingIndicator.d.ts +2 -2
  65. package/dist/types/components/Loading/LoadingIndicator.d.ts.map +1 -1
  66. package/dist/types/components/Location/ShareLocationDialog.d.ts.map +1 -1
  67. package/dist/types/components/MediaRecorder/AudioRecorder/AudioRecorderRecordingControls.d.ts.map +1 -1
  68. package/dist/types/components/MediaRecorder/AudioRecorder/AudioRecordingButtonWithNotification.d.ts.map +1 -1
  69. package/dist/types/components/MediaRecorder/AudioRecorder/AudioRecordingPlayback.d.ts.map +1 -1
  70. package/dist/types/components/MediaRecorder/AudioRecorder/AudioRecordingPreview.d.ts.map +1 -1
  71. package/dist/types/components/Message/MessageAlsoSentInChannelIndicator.d.ts.map +1 -1
  72. package/dist/types/components/Message/MessageDeletedBubble.d.ts.map +1 -1
  73. package/dist/types/components/Message/MessageRepliesCountButton.d.ts.map +1 -1
  74. package/dist/types/components/Message/MessageStatus.d.ts.map +1 -1
  75. package/dist/types/components/Message/MessageTranslationIndicator.d.ts.map +1 -1
  76. package/dist/types/components/Message/MessageUI.d.ts.map +1 -1
  77. package/dist/types/components/Message/PinIndicator.d.ts.map +1 -1
  78. package/dist/types/components/Message/ReminderNotification.d.ts.map +1 -1
  79. package/dist/types/components/MessageActions/DownloadSubmenu.d.ts.map +1 -1
  80. package/dist/types/components/MessageActions/MessageActions.defaults.d.ts.map +1 -1
  81. package/dist/types/components/MessageActions/RemindMeSubmenu.d.ts.map +1 -1
  82. package/dist/types/components/MessageBounce/MessageBouncePrompt.d.ts.map +1 -1
  83. package/dist/types/components/MessageComposer/AttachmentPreviewList/AudioAttachmentPreview.d.ts.map +1 -1
  84. package/dist/types/components/MessageComposer/AttachmentPreviewList/FileAttachmentPreview.d.ts.map +1 -1
  85. package/dist/types/components/MessageComposer/AttachmentPreviewList/GeolocationPreview.d.ts.map +1 -1
  86. package/dist/types/components/MessageComposer/AttachmentPreviewList/MediaAttachmentPreview.d.ts.map +1 -1
  87. package/dist/types/components/MessageComposer/AttachmentPreviewList/UnsupportedAttachmentPreview.d.ts.map +1 -1
  88. package/dist/types/components/MessageComposer/AttachmentSelector/AttachmentSelector.d.ts.map +1 -1
  89. package/dist/types/components/MessageComposer/AttachmentSelector/CommandsMenu.d.ts.map +1 -1
  90. package/dist/types/components/MessageComposer/CommandChip.d.ts.map +1 -1
  91. package/dist/types/components/MessageComposer/LinkPreviewList.d.ts.map +1 -1
  92. package/dist/types/components/MessageComposer/MessageComposer.d.ts +10 -1
  93. package/dist/types/components/MessageComposer/MessageComposer.d.ts.map +1 -1
  94. package/dist/types/components/MessageComposer/MessageComposerActions.d.ts.map +1 -1
  95. package/dist/types/components/MessageComposer/QuotedMessagePreview.d.ts.map +1 -1
  96. package/dist/types/components/MessageComposer/RemoveAttachmentPreviewButton.d.ts.map +1 -1
  97. package/dist/types/components/MessageComposer/SendButton.d.ts.map +1 -1
  98. package/dist/types/components/MessageComposer/SendToChannelCheckbox.d.ts.map +1 -1
  99. package/dist/types/components/MessageComposer/WithDragAndDropUpload.d.ts.map +1 -1
  100. package/dist/types/components/MessageComposer/hooks/useMessageComposerCommands.d.ts.map +1 -1
  101. package/dist/types/components/MessageComposer/hooks/useMessageComposerController.d.ts.map +1 -1
  102. package/dist/types/components/MessageList/ScrollToLatestMessageButton.d.ts.map +1 -1
  103. package/dist/types/components/MessageList/UnreadMessagesNotification.d.ts.map +1 -1
  104. package/dist/types/components/MessageList/UnreadMessagesSeparator.d.ts.map +1 -1
  105. package/dist/types/components/MessageList/hooks/useMarkRead.d.ts.map +1 -1
  106. package/dist/types/components/Modal/CloseButtonOnModalOverlay.d.ts.map +1 -1
  107. package/dist/types/components/Notifications/Notification.d.ts.map +1 -1
  108. package/dist/types/components/Poll/PollActions/PollResults/PollOptionWithVotesHeader.d.ts.map +1 -1
  109. package/dist/types/components/Poll/PollCreationDialog/OptionFieldSet.d.ts.map +1 -1
  110. package/dist/types/components/Poll/PollCreationDialog/PollCreationDialogControls.d.ts.map +1 -1
  111. package/dist/types/components/Poll/PollCreationDialog/PollOptionReorderHandle.d.ts.map +1 -1
  112. package/dist/types/components/Poll/PollOptionSelector.d.ts.map +1 -1
  113. package/dist/types/components/Poll/PollVote.d.ts.map +1 -1
  114. package/dist/types/components/Reactions/MessageReactionsDetail.d.ts.map +1 -1
  115. package/dist/types/components/Reactions/ReactionSelector.d.ts.map +1 -1
  116. package/dist/types/components/Reactions/ReactionSelectorWithButton.d.ts +6 -1
  117. package/dist/types/components/Reactions/ReactionSelectorWithButton.d.ts.map +1 -1
  118. package/dist/types/components/Search/SearchResults/SearchResultItem.d.ts.map +1 -1
  119. package/dist/types/components/SummarizedMessagePreview/SummarizedMessagePreview.d.ts.map +1 -1
  120. package/dist/types/components/TextareaComposer/SuggestionList/MentionItem/BroadcastMentionItem.d.ts.map +1 -1
  121. package/dist/types/components/TextareaComposer/SuggestionList/MentionItem/RoleItem.d.ts.map +1 -1
  122. package/dist/types/components/TextareaComposer/SuggestionList/MentionItem/UserGroupItem.d.ts.map +1 -1
  123. package/dist/types/components/TextareaComposer/SuggestionList/MentionItem/UserItem.d.ts.map +1 -1
  124. package/dist/types/components/Thread/ThreadHeader.d.ts.map +1 -1
  125. package/dist/types/components/Threads/ThreadList/ThreadListEmptyPlaceholder.d.ts.map +1 -1
  126. package/dist/types/components/Threads/ThreadList/ThreadListItemUI.d.ts.map +1 -1
  127. package/dist/types/components/Threads/ThreadList/ThreadListUnseenThreadsBanner.d.ts.map +1 -1
  128. package/dist/types/components/TypingIndicator/TypingIndicator.d.ts.map +1 -1
  129. package/dist/types/components/TypingIndicator/hooks/useDebouncedTypingActive.d.ts +2 -8
  130. package/dist/types/components/TypingIndicator/hooks/useDebouncedTypingActive.d.ts.map +1 -1
  131. package/dist/types/components/VideoPlayer/VideoThumbnail.d.ts.map +1 -1
  132. package/dist/types/context/ComponentContext.d.ts +7 -0
  133. package/dist/types/context/ComponentContext.d.ts.map +1 -1
  134. package/dist/types/context/WithComponents.d.ts.map +1 -1
  135. package/dist/types/context/index.d.ts +1 -0
  136. package/dist/types/context/index.d.ts.map +1 -1
  137. package/dist/types/context/useComponentContextIcons.d.ts +16 -0
  138. package/dist/types/context/useComponentContextIcons.d.ts.map +1 -0
  139. package/dist/types/plugins/ChannelDetail/ChannelDetail.d.ts.map +1 -1
  140. package/dist/types/plugins/ChannelDetail/ChannelDetailEmptyList.d.ts.map +1 -1
  141. package/dist/types/plugins/ChannelDetail/ChannelDetailSearchInput.d.ts.map +1 -1
  142. package/dist/types/plugins/ChannelDetail/SectionNavigator/SectionNavigatorHeader.d.ts.map +1 -1
  143. package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesEmptyList.d.ts.map +1 -1
  144. package/dist/types/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementActions.defaults.d.ts.map +1 -1
  145. package/dist/types/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementView.d.ts.map +1 -1
  146. package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaEmptyList.d.ts.map +1 -1
  147. package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.d.ts.map +1 -1
  148. package/dist/types/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberActions.defaults.d.ts.map +1 -1
  149. package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersAddView.d.ts.map +1 -1
  150. package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersBrowseView.d.ts.map +1 -1
  151. package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersHeaderActions.defaults.d.ts.map +1 -1
  152. package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesEmptyList.d.ts.map +1 -1
  153. package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesView.d.ts.map +1 -1
  154. package/dist/types/plugins/Emojis/EmojiPicker.d.ts +6 -1
  155. package/dist/types/plugins/Emojis/EmojiPicker.d.ts.map +1 -1
  156. package/dist/types/plugins/Emojis/Picker.d.ts +7 -0
  157. package/dist/types/plugins/Emojis/Picker.d.ts.map +1 -0
  158. package/dist/types/utils/getChannelConfig.d.ts +8 -0
  159. package/dist/types/utils/getChannelConfig.d.ts.map +1 -0
  160. package/package.json +3 -9
  161. package/AI.md +0 -423
  162. package/dist/cjs/useChannelHeaderOnlineStatus.72753090.js +0 -4469
  163. package/dist/cjs/useChannelHeaderOnlineStatus.72753090.js.map +0 -1
  164. package/dist/cjs/useMessageComposerController.f8f20e3d.js +0 -99
  165. package/dist/cjs/useMessageComposerController.f8f20e3d.js.map +0 -1
  166. package/dist/cjs/useNotificationApi.bf76a16b.js.map +0 -1
  167. package/dist/es/useChannelHeaderOnlineStatus.c86db868.mjs +0 -3889
  168. package/dist/es/useChannelHeaderOnlineStatus.c86db868.mjs.map +0 -1
  169. package/dist/es/useMessageComposerController.d50f6168.mjs +0 -69
  170. package/dist/es/useMessageComposerController.d50f6168.mjs.map +0 -1
  171. package/dist/es/useNotificationApi.ed6bff88.mjs.map +0 -1
@@ -1,16 +1,31 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_useNotificationApi = require("./useNotificationApi.bf76a16b.js");
3
- const require_useMessageComposerController = require("./useMessageComposerController.f8f20e3d.js");
2
+ const require_NotificationList = require("./NotificationList.6abbee1c.js");
3
+ const require_useInertWhenHidden = require("./useInertWhenHidden.22151beb.js");
4
4
  let react = require("react");
5
- react = require_useNotificationApi.__toESM(react);
5
+ react = require_NotificationList.__toESM(react);
6
6
  let react_jsx_runtime = require("react/jsx-runtime");
7
7
  let stream_chat = require("stream-chat");
8
8
  let lodash_mergewith = require("lodash.mergewith");
9
- lodash_mergewith = require_useNotificationApi.__toESM(lodash_mergewith);
10
- let _emoji_mart_react = require("@emoji-mart/react");
11
- _emoji_mart_react = require_useNotificationApi.__toESM(_emoji_mart_react);
9
+ lodash_mergewith = require_NotificationList.__toESM(lodash_mergewith);
10
+ let emoji_mart = require("emoji-mart");
11
+ //#region src/plugins/Emojis/Picker.tsx
12
+ var Picker = (props) => {
13
+ const ref = (0, react.useRef)(null);
14
+ const instance = (0, react.useRef)(null);
15
+ if (instance.current) instance.current.update(props);
16
+ (0, react.useEffect)(() => {
17
+ instance.current = new emoji_mart.Picker({
18
+ ...props,
19
+ ref
20
+ });
21
+ return () => {
22
+ instance.current = null;
23
+ };
24
+ }, []);
25
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ref });
26
+ };
27
+ //#endregion
12
28
  //#region src/plugins/Emojis/EmojiPicker.tsx
13
- var Picker = _emoji_mart_react.default.default ?? _emoji_mart_react.default;
14
29
  var isShadowRoot = (node) => !!node.host;
15
30
  var defaultButtonClassName = "str-chat__emoji-picker-button";
16
31
  var classNames = {
@@ -18,14 +33,14 @@ var classNames = {
18
33
  wrapperClassName: "str-chat__message-textarea-emoji-picker"
19
34
  };
20
35
  var EmojiPicker = (props) => {
21
- const { t } = require_useNotificationApi.useTranslationContext("EmojiPicker");
22
- const { textareaRef } = require_useMessageComposerController.useMessageComposerContext("EmojiPicker");
23
- const { textComposer } = require_useMessageComposerController.useMessageComposerController();
24
- const isCooldownActive = require_useMessageComposerController.useIsCooldownActive();
36
+ const { t } = require_NotificationList.useTranslationContext("EmojiPicker");
37
+ const { textareaRef } = require_useInertWhenHidden.useMessageComposerContext("EmojiPicker");
38
+ const { textComposer } = require_useInertWhenHidden.useMessageComposerController();
39
+ const isCooldownActive = require_useInertWhenHidden.useIsCooldownActive();
25
40
  const [displayPicker, setDisplayPicker] = (0, react.useState)(false);
26
41
  const [referenceElement, setReferenceElement] = (0, react.useState)(null);
27
42
  const [popperElement, setPopperElement] = (0, react.useState)(null);
28
- const { refs, strategy, x, y } = require_useNotificationApi.usePopoverPosition({
43
+ const { refs, strategy, x, y } = require_NotificationList.usePopoverPosition({
29
44
  offset: 8,
30
45
  placement: props.placement ?? "top-end"
31
46
  });
@@ -36,7 +51,8 @@ var EmojiPicker = (props) => {
36
51
  refs.setFloating(popperElement);
37
52
  }, [popperElement, refs]);
38
53
  const { pickerContainerClassName, wrapperClassName } = classNames;
39
- const { ButtonIconComponent = require_useNotificationApi.IconEmoji } = props;
54
+ const { IconEmoji } = require_NotificationList.useComponentContextIcons();
55
+ const ResolvedButtonIconComponent = props.ButtonIconComponent ?? IconEmoji;
40
56
  const pickerStyle = props.pickerProps?.style;
41
57
  (0, react.useEffect)(() => {
42
58
  if (!popperElement || !referenceElement) return;
@@ -74,7 +90,7 @@ var EmojiPicker = (props) => {
74
90
  "--shadow": "none"
75
91
  }
76
92
  })
77
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_useNotificationApi.Button, {
93
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_NotificationList.Button, {
78
94
  appearance: "ghost",
79
95
  "aria-expanded": displayPicker,
80
96
  "aria-label": t("aria/Emoji picker"),
@@ -86,7 +102,7 @@ var EmojiPicker = (props) => {
86
102
  size: "sm",
87
103
  type: "button",
88
104
  variant: "secondary",
89
- children: ButtonIconComponent && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ButtonIconComponent, {})
105
+ children: ResolvedButtonIconComponent && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResolvedButtonIconComponent, {})
90
106
  })]
91
107
  });
92
108
  };
@@ -1 +1 @@
1
- {"version":3,"file":"emojis.js","names":[],"sources":["../../src/plugins/Emojis/EmojiPicker.tsx","../../src/plugins/Emojis/middleware/textComposerEmojiMiddleware.ts"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport PickerImport from '@emoji-mart/react';\n\nimport { useMessageComposerContext, useTranslationContext } from '../../context';\nimport {\n Button,\n IconEmoji,\n type PopperLikePlacement,\n useMessageComposerController,\n} from '../../components';\nimport { usePopoverPosition } from '../../components/Dialog/hooks/usePopoverPosition';\nimport { useIsCooldownActive } from '../../components/MessageComposer/hooks/useIsCooldownActive';\n\n// @emoji-mart/react ships as CJS with the component on `exports.default`. Under\n// spec-strict ESM interop (e.g. Vite 8 / Rolldown, native Node ESM) a default\n// import yields the module namespace `{ default }` instead of the component,\n// which makes React throw \"Element type is invalid ... got: object\". Unwrap the\n// default defensively so it works regardless of interop.\nconst Picker =\n (PickerImport as unknown as { default?: typeof PickerImport }).default ?? PickerImport;\n\nconst isShadowRoot = (node: Node): node is ShadowRoot => !!(node as ShadowRoot).host;\n\nexport type EmojiPickerProps = {\n ButtonIconComponent?: React.ComponentType;\n buttonClassName?: string;\n pickerContainerClassName?: string;\n wrapperClassName?: string;\n closeOnEmojiSelect?: boolean;\n /**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) to be\n * passed down to the [emoji-mart `Picker`](https://github.com/missive/emoji-mart/tree/v5.5.2#-picker) component\n */\n pickerProps?: Partial<{ theme: 'auto' | 'light' | 'dark' } & Record<string, unknown>>;\n /**\n * Floating UI placement (default: 'top-end') for the picker popover\n */\n placement?: PopperLikePlacement;\n};\n\nconst defaultButtonClassName = 'str-chat__emoji-picker-button';\n\nconst classNames: Pick<\n EmojiPickerProps,\n 'pickerContainerClassName' | 'wrapperClassName'\n> = {\n pickerContainerClassName: 'str-chat__message-textarea-emoji-picker-container',\n wrapperClassName: 'str-chat__message-textarea-emoji-picker',\n};\n\nexport const EmojiPicker = (props: EmojiPickerProps) => {\n const { t } = useTranslationContext('EmojiPicker');\n const { textareaRef } = useMessageComposerContext('EmojiPicker');\n const { textComposer } = useMessageComposerController();\n const isCooldownActive = useIsCooldownActive();\n const [displayPicker, setDisplayPicker] = useState(false);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n const { refs, strategy, x, y } = usePopoverPosition({\n offset: 8,\n placement: props.placement ?? 'top-end',\n });\n\n useEffect(() => {\n refs.setReference(referenceElement);\n }, [referenceElement, refs]);\n useEffect(() => {\n refs.setFloating(popperElement);\n }, [popperElement, refs]);\n\n const { pickerContainerClassName, wrapperClassName } = classNames;\n\n const { ButtonIconComponent = IconEmoji } = props;\n const pickerStyle = props.pickerProps?.style as React.CSSProperties | undefined;\n\n useEffect(() => {\n if (!popperElement || !referenceElement) return;\n\n const handlePointerDown = (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n\n const rootNode = target.getRootNode();\n\n if (\n popperElement.contains(isShadowRoot(rootNode) ? rootNode.host : target) ||\n referenceElement.contains(target)\n ) {\n return;\n }\n\n setDisplayPicker(false);\n };\n\n window.addEventListener('pointerdown', handlePointerDown);\n return () => window.removeEventListener('pointerdown', handlePointerDown);\n }, [referenceElement, popperElement]);\n\n return (\n <div className={props.wrapperClassName ?? wrapperClassName}>\n {displayPicker && (\n <div\n className={props.pickerContainerClassName ?? pickerContainerClassName}\n ref={setPopperElement}\n style={{ left: x ?? 0, position: strategy, top: y ?? 0 }}\n >\n <Picker\n data={async () => (await import('@emoji-mart/data')).default}\n onEmojiSelect={(e: { native: string }) => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n textComposer.insertText({ text: e.native });\n textarea.focus();\n if (props.closeOnEmojiSelect) {\n setDisplayPicker(false);\n }\n }}\n {...props.pickerProps}\n style={{ ...pickerStyle, '--shadow': 'none' }}\n />\n </div>\n )}\n <Button\n appearance='ghost'\n aria-expanded={displayPicker}\n aria-label={t('aria/Emoji picker')}\n circular\n className={props.buttonClassName ?? defaultButtonClassName}\n disabled={isCooldownActive}\n onClick={() => setDisplayPicker((cv) => !cv)}\n ref={setReferenceElement}\n size='sm'\n type='button'\n variant='secondary'\n >\n {ButtonIconComponent && <ButtonIconComponent />}\n </Button>\n </div>\n );\n};\n","import mergeWith from 'lodash.mergewith';\nimport type {\n Middleware,\n SearchSourceOptions,\n SearchSourceType,\n TextComposerMiddlewareExecutorState,\n TextComposerMiddlewareOptions,\n TextComposerSuggestion,\n} from 'stream-chat';\nimport {\n BaseSearchSource,\n getTokenizedSuggestionDisplayName,\n getTriggerCharWithToken,\n insertItemWithTrigger,\n replaceWordWithEntity,\n} from 'stream-chat';\nimport type {\n EmojiSearchIndex,\n EmojiSearchIndexResult,\n} from '../../../components/MessageComposer';\n\nexport type EmojiSuggestion<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n TextComposerSuggestion<T>;\n\nclass EmojiSearchSource<\n T extends TextComposerSuggestion<EmojiSearchIndexResult>,\n> extends BaseSearchSource<T> {\n readonly type: SearchSourceType = 'emoji';\n private emojiSearchIndex: EmojiSearchIndex;\n\n constructor(emojiSearchIndex: EmojiSearchIndex, options?: SearchSourceOptions) {\n super(options);\n this.emojiSearchIndex = emojiSearchIndex;\n }\n\n async query(searchQuery: string) {\n if (searchQuery.length === 0) {\n return { items: [] as T[], next: null };\n }\n const emojis = (await this.emojiSearchIndex.search(searchQuery)) ?? [];\n\n // emojiIndex.search sometimes returns undefined values, so filter those out first\n return {\n items: emojis\n .filter(Boolean)\n .slice(0, 7)\n .map(({ emoticons = [], id, name, native, skins = [] }) => {\n const [firstSkin] = skins;\n\n return {\n emoticons,\n id,\n name,\n native: native ?? firstSkin.native,\n };\n }) as T[],\n next: null, // todo: generate cursor\n };\n }\n\n protected filterQueryResults(items: T[]): T[] | Promise<T[]> {\n return items.map((item) => ({\n ...item,\n ...getTokenizedSuggestionDisplayName({\n displayName: item.id,\n searchToken: this.searchQuery,\n }),\n }));\n }\n}\n\nconst DEFAULT_OPTIONS: TextComposerMiddlewareOptions = { minChars: 1, trigger: ':' };\n\nexport type EmojiMiddleware<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n Middleware<\n TextComposerMiddlewareExecutorState<EmojiSuggestion<T>>,\n 'onChange' | 'onSuggestionItemSelect'\n >;\n\n/**\n * TextComposer middleware for mentions\n * Usage:\n *\n * const textComposer = new TextComposer(options);\n *\n * textComposer.use(new createTextComposerEmojiMiddleware(emojiSearchIndex, {\n * minChars: 2\n * }));\n *\n * @param emojiSearchIndex\n * @param {{\n * minChars: number;\n * trigger: string;\n * }} options\n * @returns\n */\nexport const createTextComposerEmojiMiddleware = (\n emojiSearchIndex: EmojiSearchIndex,\n options?: Partial<TextComposerMiddlewareOptions>,\n): EmojiMiddleware => {\n const finalOptions = mergeWith(DEFAULT_OPTIONS, options ?? {});\n const emojiSearchSource = new EmojiSearchSource(emojiSearchIndex);\n emojiSearchSource.activate();\n\n return {\n id: 'stream-io/emoji-middleware',\n // eslint-disable-next-line sort-keys\n handlers: {\n onChange: async ({ complete, forward, next, state }) => {\n if (!state.selection) return forward();\n\n const triggerWithToken = getTriggerCharWithToken({\n acceptTrailingSpaces: false,\n text: state.text.slice(0, state.selection.end),\n trigger: finalOptions.trigger,\n });\n\n const triggerWasRemoved =\n !triggerWithToken || triggerWithToken.length < finalOptions.minChars;\n\n if (triggerWasRemoved) {\n const hasSuggestionsForTrigger =\n state.suggestions?.trigger === finalOptions.trigger;\n const newState = { ...state };\n if (hasSuggestionsForTrigger && newState.suggestions) {\n delete newState.suggestions;\n }\n return next(newState);\n }\n\n const newSearchTriggerred =\n triggerWithToken && triggerWithToken === finalOptions.trigger;\n\n if (newSearchTriggerred) {\n emojiSearchSource.resetStateAndActivate();\n }\n\n const textWithReplacedWord = await replaceWordWithEntity({\n caretPosition: state.selection.end,\n getEntityString: async (word: string) => {\n const { items } = await emojiSearchSource.query(word);\n\n const emoji = items\n .filter(Boolean)\n .slice(0, 10)\n .find(({ emoticons }) => !!emoticons?.includes(word));\n\n if (!emoji) return null;\n\n const [firstSkin] = emoji.skins ?? [];\n\n return emoji.native ?? firstSkin.native;\n },\n text: state.text,\n });\n\n if (textWithReplacedWord !== state.text) {\n return complete({\n ...state,\n suggestions: undefined, // to prevent the TextComposerMiddlewareExecutor to run the first page query\n text: textWithReplacedWord,\n });\n }\n\n return complete({\n ...state,\n suggestions: {\n query: triggerWithToken.slice(1),\n searchSource: emojiSearchSource,\n trigger: finalOptions.trigger,\n },\n });\n },\n onSuggestionItemSelect: ({ complete, forward, state }) => {\n const { selectedSuggestion } = state.change ?? {};\n if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)\n return forward();\n\n emojiSearchSource.resetStateAndActivate();\n return complete({\n ...state,\n ...insertItemWithTrigger({\n insertText: `${'native' in selectedSuggestion ? selectedSuggestion.native : ''} `,\n selection: state.selection,\n text: state.text,\n trigger: finalOptions.trigger,\n }),\n suggestions: undefined, // Clear suggestions after selection\n });\n },\n },\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"emojis.js","names":[],"sources":["../../src/plugins/Emojis/Picker.tsx","../../src/plugins/Emojis/EmojiPicker.tsx","../../src/plugins/Emojis/middleware/textComposerEmojiMiddleware.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { Picker as EmojiMartPicker } from 'emoji-mart';\n\n/**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) forwarded\n * to the emoji-mart `Picker` custom element.\n */\nexport type PickerProps = Record<string, unknown>;\n\n// React wrapper around the emoji-mart `Picker` custom element. Taken and adjusted from\n// @emoji-mart/react (MIT, Copyright (c) Missive):\n// https://github.com/missive/emoji-mart/blob/16978d04a766eec6455e2e8bb21cd8dc0b3c7436/packages/emoji-mart-react/react.tsx\n//\n// Vendored rather than depended upon because @emoji-mart/react does not declare React 19 in its\n// peer dependencies, which forces consumers into `package.json` overrides.\nexport const Picker = (props: PickerProps) => {\n const ref = useRef<HTMLDivElement | null>(null);\n const instance = useRef<EmojiMartPicker | null>(null);\n if (instance.current) {\n instance.current.update(props);\n }\n\n useEffect(() => {\n instance.current = new EmojiMartPicker({ ...props, ref });\n return () => {\n instance.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return <div ref={ref} />;\n};\n","import React, { useEffect, useState } from 'react';\nimport { Picker, type PickerProps } from './Picker';\n\nimport {\n useComponentContextIcons,\n useMessageComposerContext,\n useTranslationContext,\n} from '../../context';\nimport {\n Button,\n type PopperLikePlacement,\n useMessageComposerController,\n} from '../../components';\nimport { usePopoverPosition } from '../../components/Dialog/hooks/usePopoverPosition';\nimport { useIsCooldownActive } from '../../components/MessageComposer/hooks/useIsCooldownActive';\n\nconst isShadowRoot = (node: Node): node is ShadowRoot => !!(node as ShadowRoot).host;\n\nexport type EmojiPickerProps = {\n /**\n * @deprecated Use the `icons.IconEmoji` slot on `ComponentContext` (via `<WithComponents overrides={{ icons: { IconEmoji: ... } }}>`) instead.\n * Passing this prop still wins over the context slot for backwards compatibility.\n */\n ButtonIconComponent?: React.ComponentType;\n buttonClassName?: string;\n pickerContainerClassName?: string;\n wrapperClassName?: string;\n closeOnEmojiSelect?: boolean;\n /**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) to be\n * passed down to the [emoji-mart `Picker`](https://github.com/missive/emoji-mart/tree/v5.5.2#-picker) component\n */\n pickerProps?: Partial<{ theme: 'auto' | 'light' | 'dark' } & PickerProps>;\n /**\n * Floating UI placement (default: 'top-end') for the picker popover\n */\n placement?: PopperLikePlacement;\n};\n\nconst defaultButtonClassName = 'str-chat__emoji-picker-button';\n\nconst classNames: Pick<\n EmojiPickerProps,\n 'pickerContainerClassName' | 'wrapperClassName'\n> = {\n pickerContainerClassName: 'str-chat__message-textarea-emoji-picker-container',\n wrapperClassName: 'str-chat__message-textarea-emoji-picker',\n};\n\nexport const EmojiPicker = (props: EmojiPickerProps) => {\n const { t } = useTranslationContext('EmojiPicker');\n const { textareaRef } = useMessageComposerContext('EmojiPicker');\n const { textComposer } = useMessageComposerController();\n const isCooldownActive = useIsCooldownActive();\n const [displayPicker, setDisplayPicker] = useState(false);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n const { refs, strategy, x, y } = usePopoverPosition({\n offset: 8,\n placement: props.placement ?? 'top-end',\n });\n\n useEffect(() => {\n refs.setReference(referenceElement);\n }, [referenceElement, refs]);\n useEffect(() => {\n refs.setFloating(popperElement);\n }, [popperElement, refs]);\n\n const { pickerContainerClassName, wrapperClassName } = classNames;\n\n const { IconEmoji } = useComponentContextIcons();\n const ResolvedButtonIconComponent = props.ButtonIconComponent ?? IconEmoji;\n\n const pickerStyle = props.pickerProps?.style as React.CSSProperties | undefined;\n\n useEffect(() => {\n if (!popperElement || !referenceElement) return;\n\n const handlePointerDown = (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n\n const rootNode = target.getRootNode();\n\n if (\n popperElement.contains(isShadowRoot(rootNode) ? rootNode.host : target) ||\n referenceElement.contains(target)\n ) {\n return;\n }\n\n setDisplayPicker(false);\n };\n\n window.addEventListener('pointerdown', handlePointerDown);\n return () => window.removeEventListener('pointerdown', handlePointerDown);\n }, [referenceElement, popperElement]);\n\n return (\n <div className={props.wrapperClassName ?? wrapperClassName}>\n {displayPicker && (\n <div\n className={props.pickerContainerClassName ?? pickerContainerClassName}\n ref={setPopperElement}\n style={{ left: x ?? 0, position: strategy, top: y ?? 0 }}\n >\n <Picker\n data={async () => (await import('@emoji-mart/data')).default}\n onEmojiSelect={(e: { native: string }) => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n textComposer.insertText({ text: e.native });\n textarea.focus();\n if (props.closeOnEmojiSelect) {\n setDisplayPicker(false);\n }\n }}\n {...props.pickerProps}\n style={{ ...pickerStyle, '--shadow': 'none' }}\n />\n </div>\n )}\n <Button\n appearance='ghost'\n aria-expanded={displayPicker}\n aria-label={t('aria/Emoji picker')}\n circular\n className={props.buttonClassName ?? defaultButtonClassName}\n disabled={isCooldownActive}\n onClick={() => setDisplayPicker((cv) => !cv)}\n ref={setReferenceElement}\n size='sm'\n type='button'\n variant='secondary'\n >\n {ResolvedButtonIconComponent && <ResolvedButtonIconComponent />}\n </Button>\n </div>\n );\n};\n","import mergeWith from 'lodash.mergewith';\nimport type {\n Middleware,\n SearchSourceOptions,\n SearchSourceType,\n TextComposerMiddlewareExecutorState,\n TextComposerMiddlewareOptions,\n TextComposerSuggestion,\n} from 'stream-chat';\nimport {\n BaseSearchSource,\n getTokenizedSuggestionDisplayName,\n getTriggerCharWithToken,\n insertItemWithTrigger,\n replaceWordWithEntity,\n} from 'stream-chat';\nimport type {\n EmojiSearchIndex,\n EmojiSearchIndexResult,\n} from '../../../components/MessageComposer';\n\nexport type EmojiSuggestion<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n TextComposerSuggestion<T>;\n\nclass EmojiSearchSource<\n T extends TextComposerSuggestion<EmojiSearchIndexResult>,\n> extends BaseSearchSource<T> {\n readonly type: SearchSourceType = 'emoji';\n private emojiSearchIndex: EmojiSearchIndex;\n\n constructor(emojiSearchIndex: EmojiSearchIndex, options?: SearchSourceOptions) {\n super(options);\n this.emojiSearchIndex = emojiSearchIndex;\n }\n\n async query(searchQuery: string) {\n if (searchQuery.length === 0) {\n return { items: [] as T[], next: null };\n }\n const emojis = (await this.emojiSearchIndex.search(searchQuery)) ?? [];\n\n // emojiIndex.search sometimes returns undefined values, so filter those out first\n return {\n items: emojis\n .filter(Boolean)\n .slice(0, 7)\n .map(({ emoticons = [], id, name, native, skins = [] }) => {\n const [firstSkin] = skins;\n\n return {\n emoticons,\n id,\n name,\n native: native ?? firstSkin.native,\n };\n }) as T[],\n next: null, // todo: generate cursor\n };\n }\n\n protected filterQueryResults(items: T[]): T[] | Promise<T[]> {\n return items.map((item) => ({\n ...item,\n ...getTokenizedSuggestionDisplayName({\n displayName: item.id,\n searchToken: this.searchQuery,\n }),\n }));\n }\n}\n\nconst DEFAULT_OPTIONS: TextComposerMiddlewareOptions = { minChars: 1, trigger: ':' };\n\nexport type EmojiMiddleware<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n Middleware<\n TextComposerMiddlewareExecutorState<EmojiSuggestion<T>>,\n 'onChange' | 'onSuggestionItemSelect'\n >;\n\n/**\n * TextComposer middleware for mentions\n * Usage:\n *\n * const textComposer = new TextComposer(options);\n *\n * textComposer.use(new createTextComposerEmojiMiddleware(emojiSearchIndex, {\n * minChars: 2\n * }));\n *\n * @param emojiSearchIndex\n * @param {{\n * minChars: number;\n * trigger: string;\n * }} options\n * @returns\n */\nexport const createTextComposerEmojiMiddleware = (\n emojiSearchIndex: EmojiSearchIndex,\n options?: Partial<TextComposerMiddlewareOptions>,\n): EmojiMiddleware => {\n const finalOptions = mergeWith(DEFAULT_OPTIONS, options ?? {});\n const emojiSearchSource = new EmojiSearchSource(emojiSearchIndex);\n emojiSearchSource.activate();\n\n return {\n id: 'stream-io/emoji-middleware',\n // eslint-disable-next-line sort-keys\n handlers: {\n onChange: async ({ complete, forward, next, state }) => {\n if (!state.selection) return forward();\n\n const triggerWithToken = getTriggerCharWithToken({\n acceptTrailingSpaces: false,\n text: state.text.slice(0, state.selection.end),\n trigger: finalOptions.trigger,\n });\n\n const triggerWasRemoved =\n !triggerWithToken || triggerWithToken.length < finalOptions.minChars;\n\n if (triggerWasRemoved) {\n const hasSuggestionsForTrigger =\n state.suggestions?.trigger === finalOptions.trigger;\n const newState = { ...state };\n if (hasSuggestionsForTrigger && newState.suggestions) {\n delete newState.suggestions;\n }\n return next(newState);\n }\n\n const newSearchTriggerred =\n triggerWithToken && triggerWithToken === finalOptions.trigger;\n\n if (newSearchTriggerred) {\n emojiSearchSource.resetStateAndActivate();\n }\n\n const textWithReplacedWord = await replaceWordWithEntity({\n caretPosition: state.selection.end,\n getEntityString: async (word: string) => {\n const { items } = await emojiSearchSource.query(word);\n\n const emoji = items\n .filter(Boolean)\n .slice(0, 10)\n .find(({ emoticons }) => !!emoticons?.includes(word));\n\n if (!emoji) return null;\n\n const [firstSkin] = emoji.skins ?? [];\n\n return emoji.native ?? firstSkin.native;\n },\n text: state.text,\n });\n\n if (textWithReplacedWord !== state.text) {\n return complete({\n ...state,\n suggestions: undefined, // to prevent the TextComposerMiddlewareExecutor to run the first page query\n text: textWithReplacedWord,\n });\n }\n\n return complete({\n ...state,\n suggestions: {\n query: triggerWithToken.slice(1),\n searchSource: emojiSearchSource,\n trigger: finalOptions.trigger,\n },\n });\n },\n onSuggestionItemSelect: ({ complete, forward, state }) => {\n const { selectedSuggestion } = state.change ?? {};\n if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)\n return forward();\n\n emojiSearchSource.resetStateAndActivate();\n return complete({\n ...state,\n ...insertItemWithTrigger({\n insertText: `${'native' in selectedSuggestion ? selectedSuggestion.native : ''} `,\n selection: state.selection,\n text: state.text,\n trigger: finalOptions.trigger,\n }),\n suggestions: undefined, // Clear suggestions after selection\n });\n },\n },\n };\n};\n"],"mappings":"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"}