@linktr.ee/messaging-react 4.1.0-rc-1786608731 → 4.1.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/{Card-NbyEZmLk.cjs → Card-B5ZGxDcH.cjs} +2 -2
- package/dist/{Card-NbyEZmLk.cjs.map → Card-B5ZGxDcH.cjs.map} +1 -1
- package/dist/{Card-ClyBNKoW.js → Card-LPAZ4FjL.js} +2 -2
- package/dist/{Card-ClyBNKoW.js.map → Card-LPAZ4FjL.js.map} +1 -1
- package/dist/index-B88BeZjY.cjs +3 -0
- package/dist/index-B88BeZjY.cjs.map +1 -0
- package/dist/{index-CH6y1lmh.js → index-Cxj0F8aQ.js} +924 -917
- package/dist/index-Cxj0F8aQ.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/src/components/ChannelView.test.tsx +22 -0
- package/src/components/ChannelView.tsx +10 -0
- package/src/components/LinkAttachment/components/_shared/CardShell.tsx +6 -1
- package/src/components/MessagingShell/MessagingShell.test.tsx +0 -20
- package/src/components/MessagingShell/index.tsx +0 -2
- package/src/components/RichCard/RichCard.test.tsx +16 -0
- package/src/components/RichCard/RichCardBody.tsx +1 -0
- package/src/types.ts +0 -1
- package/dist/index-CH6y1lmh.js.map +0 -1
- package/dist/index-D1x28quP.cjs +0 -3
- package/dist/index-D1x28quP.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-B88BeZjY.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.MessagingProvider=e.MessagingProvider;exports.MessagingShell=e.MessagingShell;exports.RichCard=e.RichCard;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.useMessaging=e.useMessaging;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.d.ts
CHANGED
|
@@ -208,7 +208,7 @@ export declare const ChannelView: default_2.NamedExoticComponent<ChannelViewProp
|
|
|
208
208
|
* Props that MessagingShell passes through to ChannelView.
|
|
209
209
|
* ChannelViewProps is the source of truth for these props.
|
|
210
210
|
*/
|
|
211
|
-
declare type ChannelViewPassthroughProps = Pick<ChannelViewProps, 'renderMessageInputActions' | '
|
|
211
|
+
declare type ChannelViewPassthroughProps = Pick<ChannelViewProps, 'renderMessageInputActions' | 'renderConversationFooter' | 'CustomChannelEmptyState' | 'onBlockParticipantClick' | 'onReportParticipantClick' | 'dmAgentEnabled' | 'onMessageSent' | 'viewerLanguage' | 'renderChannelBanner' | 'customChannelActions' | 'renderChannelActions' | 'onParticipantNameClick' | 'renderMessage' | 'onMessageLinkClick' | 'onOutboundClick' | 'resolveOutbound' | 'showChannelInfo' | 'composerInput'>;
|
|
212
212
|
|
|
213
213
|
/**
|
|
214
214
|
* ChannelView component props
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e, b as t, C as i, c as n, d as o, e as m, F as r, f as l, L as g, h as c, M, i as h, j as L, k as u, l as d, R as p, m as C, n as v, p as A, q as k, s as F, t as b, u as P, v as f, w as x, o as y, x as z, y as S, z as q, B, D, E, G as R } from "./index-
|
|
1
|
+
import { a as e, b as t, C as i, c as n, d as o, e as m, F as r, f as l, L as g, h as c, M, i as h, j as L, k as u, l as d, R as p, m as C, n as v, p as A, q as k, s as F, t as b, u as P, v as f, w as x, o as y, x as z, y as S, z as q, B, D, E, G as R } from "./index-Cxj0F8aQ.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": "4.1.0
|
|
3
|
+
"version": "4.1.0",
|
|
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
|
"chromatic:local": "yarn storybook:build && chromatic"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@linktr.ee/messaging-core": "2.4.0
|
|
53
|
+
"@linktr.ee/messaging-core": "^2.4.0",
|
|
54
54
|
"@linktr.ee/messaging-taxonomy": "^0.10.0",
|
|
55
55
|
"@phosphor-icons/react": "^2.1.10"
|
|
56
56
|
},
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { OFFICIAL_CHANNEL_TYPE } from '@linktr.ee/messaging-taxonomy'
|
|
1
2
|
import React from 'react'
|
|
2
3
|
import type { Channel } from 'stream-chat'
|
|
3
4
|
import { describe, expect, it, vi, beforeEach } from 'vitest'
|
|
@@ -131,6 +132,7 @@ vi.mock('../hooks/useChannelStar', () => ({
|
|
|
131
132
|
const createChannel = ({
|
|
132
133
|
currentUserId = 'visitor-1',
|
|
133
134
|
currentUserRole = 'owner',
|
|
135
|
+
channelType,
|
|
134
136
|
messages = [],
|
|
135
137
|
otherUser = {
|
|
136
138
|
id: 'linker-1' as const,
|
|
@@ -143,6 +145,7 @@ const createChannel = ({
|
|
|
143
145
|
}: {
|
|
144
146
|
currentUserId?: 'visitor-1' | 'linker-1'
|
|
145
147
|
currentUserRole?: 'owner' | 'member'
|
|
148
|
+
channelType?: string
|
|
146
149
|
messages?: Channel['state']['messages']
|
|
147
150
|
channelCustomerTag?: string
|
|
148
151
|
otherMemberIsFollower?: boolean
|
|
@@ -156,6 +159,7 @@ const createChannel = ({
|
|
|
156
159
|
({
|
|
157
160
|
id: 'channel-1',
|
|
158
161
|
cid: 'messaging:channel-1',
|
|
162
|
+
type: channelType,
|
|
159
163
|
data: {
|
|
160
164
|
customer_tag: channelCustomerTag,
|
|
161
165
|
},
|
|
@@ -217,6 +221,24 @@ describe('ChannelView', () => {
|
|
|
217
221
|
expect(lastActionsMenuProps().showReportParticipant).not.toBe(false)
|
|
218
222
|
})
|
|
219
223
|
|
|
224
|
+
it('widens the content column in the official (read-only) channel via the width var', () => {
|
|
225
|
+
const { container } = renderWithProviders(
|
|
226
|
+
<ChannelView channel={createChannel({ channelType: OFFICIAL_CHANNEL_TYPE })} />
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
const root = container.querySelector('.messaging-channel-view') as HTMLElement
|
|
230
|
+
expect(root.style.getPropertyValue('--lt-msg-card-width')).toBe('368px')
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
it('leaves the card-width var unset in a regular channel (default widths)', () => {
|
|
234
|
+
const { container } = renderWithProviders(
|
|
235
|
+
<ChannelView channel={createChannel({ channelType: 'messaging' })} />
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
const root = container.querySelector('.messaging-channel-view') as HTMLElement
|
|
239
|
+
expect(root.style.getPropertyValue('--lt-msg-card-width')).toBe('')
|
|
240
|
+
})
|
|
241
|
+
|
|
220
242
|
it('hides block and report in the actions menu when restricted', () => {
|
|
221
243
|
renderWithProviders(
|
|
222
244
|
<ChannelView
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isOfficialChannel } from '@linktr.ee/messaging-taxonomy'
|
|
1
2
|
import classNames from 'classnames'
|
|
2
3
|
import React, { useCallback, useEffect, useRef } from 'react'
|
|
3
4
|
import { Channel as ChannelType } from 'stream-chat'
|
|
@@ -379,6 +380,14 @@ export const ChannelView = React.memo<ChannelViewProps>(
|
|
|
379
380
|
return () => container.removeEventListener('click', handler)
|
|
380
381
|
}, [onMessageLinkClick, channel])
|
|
381
382
|
|
|
383
|
+
// The official channel is read-only (no composer), so the design gives its content a
|
|
384
|
+
// wider column. Publish the width as a CSS var on the channel root; every card/bubble
|
|
385
|
+
// inside reads `w-[var(--lt-msg-card-width,…)]` and widens. Other channels leave the var
|
|
386
|
+
// unset and keep their default widths.
|
|
387
|
+
const messageCardWidthStyle = isOfficialChannel(channel.type)
|
|
388
|
+
? ({ '--lt-msg-card-width': '368px' } as React.CSSProperties)
|
|
389
|
+
: undefined
|
|
390
|
+
|
|
382
391
|
return (
|
|
383
392
|
<div
|
|
384
393
|
ref={containerRef}
|
|
@@ -386,6 +395,7 @@ export const ChannelView = React.memo<ChannelViewProps>(
|
|
|
386
395
|
'messaging-channel-view h-full flex flex-col',
|
|
387
396
|
className
|
|
388
397
|
)}
|
|
398
|
+
style={messageCardWidthStyle}
|
|
389
399
|
>
|
|
390
400
|
<DmAgentEnabledContext.Provider value={dmAgentEnabled ?? false}>
|
|
391
401
|
<Channel
|
|
@@ -65,7 +65,12 @@ export interface CardShellProps {
|
|
|
65
65
|
export const LOADING_LABEL = 'Loading link preview'
|
|
66
66
|
|
|
67
67
|
const SHELL_CLASS = classNames(
|
|
68
|
-
|
|
68
|
+
// Width is a channel-scoped token: default 290px, but a read-only surface with no
|
|
69
|
+
// composer (the official channel) sets `--lt-msg-card-width` on its root to widen the
|
|
70
|
+
// content column (see ChannelView). Consumers that don't set the var keep 290px.
|
|
71
|
+
// `max-w-full` caps the card to its container so a widened value can never overflow
|
|
72
|
+
// horizontally on a narrow (sub-393px) viewport — it shrinks to fit instead.
|
|
73
|
+
'relative w-[var(--lt-msg-card-width,290px)] max-w-full select-none overflow-hidden',
|
|
69
74
|
// 20px corners — no token exists for it in the component-library preset,
|
|
70
75
|
// whose radius scale is sm .5rem / md 1rem / lg 1.5rem / xl 4rem.
|
|
71
76
|
'rounded-[20px]'
|
|
@@ -169,26 +169,6 @@ describe('MessagingShell', () => {
|
|
|
169
169
|
)
|
|
170
170
|
})
|
|
171
171
|
|
|
172
|
-
it('forwards renderMessageInputFooter through to ChannelView', async () => {
|
|
173
|
-
queryChannelsMock.mockResolvedValue([makeChannel('existing-1')])
|
|
174
|
-
const renderMessageInputFooter = vi.fn()
|
|
175
|
-
|
|
176
|
-
renderWithProviders(
|
|
177
|
-
<MessagingShell
|
|
178
|
-
initialParticipantFilter="other-1"
|
|
179
|
-
renderMessageInputFooter={renderMessageInputFooter}
|
|
180
|
-
/>
|
|
181
|
-
)
|
|
182
|
-
|
|
183
|
-
await waitFor(() => {
|
|
184
|
-
expect(screen.getByTestId('channel-view')).toBeInTheDocument()
|
|
185
|
-
})
|
|
186
|
-
|
|
187
|
-
expect(capturedChannelViewProps.renderMessageInputFooter).toBe(
|
|
188
|
-
renderMessageInputFooter
|
|
189
|
-
)
|
|
190
|
-
})
|
|
191
|
-
|
|
192
172
|
it('does not create the channel again when the load effect re-runs for the same pair (e.g. service identity settles during connect)', async () => {
|
|
193
173
|
queryChannelsMock.mockResolvedValue([])
|
|
194
174
|
startChannelWithParticipantMock.mockResolvedValue(makeChannel('created-1'))
|
|
@@ -22,7 +22,6 @@ import { LoadingState } from './LoadingState'
|
|
|
22
22
|
export const MessagingShell: React.FC<MessagingShellProps> = ({
|
|
23
23
|
capabilities = {},
|
|
24
24
|
renderMessageInputActions,
|
|
25
|
-
renderMessageInputFooter,
|
|
26
25
|
renderConversationFooter,
|
|
27
26
|
onChannelSelect,
|
|
28
27
|
onExitConversation,
|
|
@@ -250,7 +249,6 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
|
|
|
250
249
|
channel={selectedChannel}
|
|
251
250
|
key={selectedChannel.id}
|
|
252
251
|
renderMessageInputActions={renderMessageInputActions}
|
|
253
|
-
renderMessageInputFooter={renderMessageInputFooter}
|
|
254
252
|
renderConversationFooter={renderConversationFooter}
|
|
255
253
|
renderChannelBanner={renderChannelBanner}
|
|
256
254
|
onLeaveConversation={handleExitConversation}
|
|
@@ -25,6 +25,22 @@ describe('RichCard', () => {
|
|
|
25
25
|
).toBeInTheDocument()
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
+
it('renders multiline bullet copy as separate lines', async () => {
|
|
29
|
+
renderWithProviders(
|
|
30
|
+
<RichCard.Received
|
|
31
|
+
title="Welcome"
|
|
32
|
+
subtitle={'👋 Say hello as people arrive\n✨ Spark conversations\n💬 Add automated FAQs'}
|
|
33
|
+
subtitleLines={6}
|
|
34
|
+
images={[HERO]}
|
|
35
|
+
/>
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
const card = await screen.findByTestId('rich-card')
|
|
39
|
+
expect(card).toHaveTextContent('👋 Say hello as people arrive')
|
|
40
|
+
expect(card).toHaveTextContent('✨ Spark conversations')
|
|
41
|
+
expect(card).toHaveTextContent('💬 Add automated FAQs')
|
|
42
|
+
})
|
|
43
|
+
|
|
28
44
|
it('renders a single hero image for the hero presentation', async () => {
|
|
29
45
|
renderWithProviders(
|
|
30
46
|
<RichCard.Received
|
package/src/types.ts
CHANGED
|
@@ -436,7 +436,6 @@ export interface ChannelViewProps {
|
|
|
436
436
|
export type ChannelViewPassthroughProps = Pick<
|
|
437
437
|
ChannelViewProps,
|
|
438
438
|
| 'renderMessageInputActions'
|
|
439
|
-
| 'renderMessageInputFooter'
|
|
440
439
|
| 'renderConversationFooter'
|
|
441
440
|
| 'CustomChannelEmptyState'
|
|
442
441
|
| 'onBlockParticipantClick'
|