@linktr.ee/messaging-react 3.15.0 → 3.15.1-rc-1784866764

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/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-NcnnPWrl.cjs");exports.ActionButton=e.ActionButton;exports.Avatar=e.Avatar;exports.ChannelEmptyState=e.ChannelEmptyState;exports.ChannelList=e.ChannelList;exports.ChannelView=e.ChannelView;exports.CustomMessageProvider=e.CustomMessageProvider;exports.FaqList=e.FaqList;exports.FaqListItem=e.FaqListItem;exports.LinkAttachment=e.LinkAttachment;exports.LockedAttachment=e.LockedAttachment;exports.MediaMessage=e.MediaMessage;exports.MessageAttachment=e.MessageAttachment;exports.MessageBubble=e.MessageBubble;exports.MessageVoteButtons=e.MessageVoteButtons;exports.MessagingProvider=e.MessagingProvider;exports.MessagingShell=e.MessagingShell;exports.buildCompactMetaLabel=e.buildCompactMetaLabel;exports.formatFileSize=e.formatFileSize;exports.formatRelativeTime=e.formatRelativeTime;exports.getFileExtensionLabel=e.getFileExtensionLabel;exports.getMessageDisplayText=e.getMessageDisplayText;exports.isLinkAttachment=e.isLinkAttachment;exports.isUuidLike=e.isUuidLike;exports.messageAttachmentGroupPositionFromStream=e.bubbleGroupPositionFromStream;exports.normalizeLanguageCode=e.normalizeLanguageCode;exports.optimizeMessagingAttachmentUrl=e.optimizeMessagingAttachmentUrl;exports.resolveConversationParticipant=e.resolveConversationParticipant;exports.resolveLinkAttachment=e.resolveLinkAttachment;exports.resolveMediaFromMessage=e.resolveMediaFromMessage;exports.resolveParticipantDisplayName=e.resolveParticipantDisplayName;exports.useComposerLocked=e.useComposerLocked;exports.useCustomMessage=e.useCustomMessage;exports.useMessageVote=e.useMessageVote;exports.useMessaging=e.useMessaging;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-ftxF5ams.cjs");exports.ActionButton=e.ActionButton;exports.Avatar=e.Avatar;exports.ChannelEmptyState=e.ChannelEmptyState;exports.ChannelList=e.ChannelList;exports.ChannelView=e.ChannelView;exports.CustomMessageProvider=e.CustomMessageProvider;exports.FaqList=e.FaqList;exports.FaqListItem=e.FaqListItem;exports.LinkAttachment=e.LinkAttachment;exports.LockedAttachment=e.LockedAttachment;exports.MediaMessage=e.MediaMessage;exports.MessageAttachment=e.MessageAttachment;exports.MessageBubble=e.MessageBubble;exports.MessageVoteButtons=e.MessageVoteButtons;exports.MessagingProvider=e.MessagingProvider;exports.MessagingShell=e.MessagingShell;exports.buildCompactMetaLabel=e.buildCompactMetaLabel;exports.formatFileSize=e.formatFileSize;exports.formatRelativeTime=e.formatRelativeTime;exports.getFileExtensionLabel=e.getFileExtensionLabel;exports.getMessageDisplayText=e.getMessageDisplayText;exports.isLinkAttachment=e.isLinkAttachment;exports.isUuidLike=e.isUuidLike;exports.messageAttachmentGroupPositionFromStream=e.bubbleGroupPositionFromStream;exports.normalizeLanguageCode=e.normalizeLanguageCode;exports.optimizeMessagingAttachmentUrl=e.optimizeMessagingAttachmentUrl;exports.resolveConversationParticipant=e.resolveConversationParticipant;exports.resolveLinkAttachment=e.resolveLinkAttachment;exports.resolveMediaFromMessage=e.resolveMediaFromMessage;exports.resolveParticipantDisplayName=e.resolveParticipantDisplayName;exports.useComposerLocked=e.useComposerLocked;exports.useCustomMessage=e.useCustomMessage;exports.useMessageVote=e.useMessageVote;exports.useMessaging=e.useMessaging;
2
2
  //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as e, b as t, C as i, c as o, d as n, e as m, F as r, f as g, L as l, h as M, M as c, i as u, j as L, k as h, l as p, m as d, n as v, p as C, q as A, s as k, t as F, u as b, v as P, w as f, x, o as y, y as z, z as B, B as S, D as q, E as D, G as E, H as V, I as w } from "./index-DdVzOymJ.js";
1
+ import { a as e, b as t, C as i, c as o, d as n, e as m, F as r, f as g, L as l, h as M, M as c, i as u, j as L, k as h, l as p, m as d, n as v, p as C, q as A, s as k, t as F, u as b, v as P, w as f, x, o as y, y as z, z as B, B as S, D as q, E as D, G as E, H as V, I as w } from "./index-BdRJRNr3.js";
2
2
  export {
3
3
  e as ActionButton,
4
4
  t as Avatar,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linktr.ee/messaging-react",
3
- "version": "3.15.0",
3
+ "version": "3.15.1-rc-1784866764",
4
4
  "description": "React messaging components built on messaging-core for web applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@linktr.ee/component-library": "11.8.6",
53
- "@linktr.ee/messaging-core": "^2.2.0",
53
+ "@linktr.ee/messaging-core": "2.3.0-rc-1784866764",
54
54
  "@phosphor-icons/react": "^2.1.10"
55
55
  },
56
56
  "devDependencies": {
@@ -1,12 +1,21 @@
1
1
  import React from 'react'
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
3
3
 
4
- import { renderWithProviders, screen } from '../../test/utils'
4
+ import { fireEvent, renderWithProviders, screen } from '../../test/utils'
5
5
 
6
6
  import { CustomMessageInput } from '.'
7
7
 
8
8
  let mockChannelData: Record<string, unknown> = {}
9
9
 
10
+ // Controls whether the composer treats the input as sendable, which in turn
11
+ // enables/disables the send button. Defaults to false to match the existing
12
+ // suite; individual tests flip it to true when they need an enabled button.
13
+ let mockHasSendableData = false
14
+
15
+ // Stable submit spy so a test can assert the send button still fires it on
16
+ // click (a new vi.fn() per render would be unassertable).
17
+ const mockHandleSubmit = vi.fn()
18
+
10
19
  let mockContextSendButton:
11
20
  | React.ComponentType<{
12
21
  sendMessage: (...args: unknown[]) => unknown
@@ -40,9 +49,9 @@ vi.mock('stream-chat-react', () => ({
40
49
  channel: { data: mockChannelData },
41
50
  }),
42
51
  useMessageInputContext: () => ({
43
- handleSubmit: vi.fn(),
52
+ handleSubmit: mockHandleSubmit,
44
53
  }),
45
- useMessageComposerHasSendableData: () => false,
54
+ useMessageComposerHasSendableData: () => mockHasSendableData,
46
55
  useComponentContext: () => ({
47
56
  SendButton: mockContextSendButton,
48
57
  }),
@@ -54,6 +63,8 @@ vi.mock('../CustomLinkPreviewList', () => ({
54
63
 
55
64
  describe('CustomMessageInput', () => {
56
65
  beforeEach(() => {
66
+ mockHasSendableData = false
67
+ mockHandleSubmit.mockClear()
57
68
  mockContextSendButton = ({ sendMessage, disabled }) => (
58
69
  <button
59
70
  type="button"
@@ -168,6 +179,38 @@ describe('CustomMessageInput', () => {
168
179
  ).not.toBeInTheDocument()
169
180
  })
170
181
 
182
+ // MES-1320: tapping the default send button must not blur the composer, or
183
+ // the mobile soft keyboard closes after every sent message. The button
184
+ // prevents the default pointerdown focus shift while leaving the click (and
185
+ // therefore the send) intact.
186
+ describe('keeps the composer focused when tapping the default send button (MES-1320)', () => {
187
+ it('prevents the default pointerdown so focus stays in the textarea', () => {
188
+ mockChannelData = {}
189
+ mockContextSendButton = undefined
190
+ mockHasSendableData = true
191
+
192
+ renderWithProviders(<CustomMessageInput />)
193
+
194
+ const sendButton = screen.getByTestId('send-button')
195
+ // fireEvent returns false when the dispatched event was cancelled
196
+ // (preventDefault was called on a cancelable event).
197
+ const notCancelled = fireEvent.pointerDown(sendButton)
198
+ expect(notCancelled).toBe(false)
199
+ })
200
+
201
+ it('still submits on click', () => {
202
+ mockChannelData = {}
203
+ mockContextSendButton = undefined
204
+ mockHasSendableData = true
205
+
206
+ renderWithProviders(<CustomMessageInput />)
207
+
208
+ const sendButton = screen.getByTestId('send-button')
209
+ fireEvent.click(sendButton)
210
+ expect(mockHandleSubmit).toHaveBeenCalledTimes(1)
211
+ })
212
+ })
213
+
171
214
  it('preserves disabled state on the send button when there is no sendable data', () => {
172
215
  mockChannelData = {}
173
216
 
@@ -189,9 +232,7 @@ describe('CustomMessageInput', () => {
189
232
  )
190
233
 
191
234
  // The interactive input is gone entirely — no textarea, no send button.
192
- expect(
193
- screen.queryByTestId('stream-message-input')
194
- ).not.toBeInTheDocument()
235
+ expect(screen.queryByTestId('stream-message-input')).not.toBeInTheDocument()
195
236
  expect(screen.queryByTestId('textarea-composer')).not.toBeInTheDocument()
196
237
  expect(container.querySelector('.message-input')).not.toBeInTheDocument()
197
238
 
@@ -52,6 +52,15 @@ const DefaultSendButton: React.FC<{
52
52
  type="button"
53
53
  aria-label="Send"
54
54
  disabled={disabled}
55
+ // Keep the soft keyboard open after tapping send (MES-1320). Pressing a
56
+ // button moves focus to it, blurring the textarea — on mobile that
57
+ // dismisses the on-screen keyboard, forcing the visitor to re-tap the
58
+ // composer for every message. preventDefault on pointerdown suppresses that
59
+ // focus shift so the textarea stays focused; the click still fires (click is
60
+ // derived from pointerup, not pointerdown), so `sendMessage` runs as normal.
61
+ // pointerdown covers both touch and mouse, and keyboard activation (Enter/
62
+ // Space → click) is unaffected.
63
+ onPointerDown={(e) => e.preventDefault()}
55
64
  onClick={sendMessage}
56
65
  >
57
66
  <ArrowUpIcon weight="bold" className="size-4" />