@linktr.ee/messaging-react 4.1.1 → 4.1.3-rc-1786778288
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-Bxat0g1O.cjs → Card-DKP7SMTp.cjs} +2 -2
- package/dist/{Card-Bxat0g1O.cjs.map → Card-DKP7SMTp.cjs.map} +1 -1
- package/dist/{Card-xYcNcZC_.js → Card-avnlyzrl.js} +2 -2
- package/dist/{Card-xYcNcZC_.js.map → Card-avnlyzrl.js.map} +1 -1
- package/dist/index-Bq5DM1Lm.cjs +3 -0
- package/dist/index-Bq5DM1Lm.cjs.map +1 -0
- package/dist/{index-t0Okjl1p.js → index-DFykbijs.js} +1257 -1302
- package/dist/index-DFykbijs.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/src/components/ActionButton/ActionButton.stories.tsx +1 -0
- package/src/components/AttachmentCard/MediaPlayer.tsx +10 -8
- package/src/components/Avatar/Avatar.stories.tsx +44 -5
- package/src/components/ChannelList/CustomChannelPreview.stories.tsx +332 -1
- package/src/components/CloseButton/CloseButton.stories.tsx +1 -1
- package/src/components/CustomDateSeparator/CustomDateSeparator.stories.tsx +1 -1
- package/src/components/CustomMessage/CustomMessage.stories.tsx +5 -0
- package/src/components/CustomMessage/MessageTag.stories.tsx +4 -6
- package/src/components/CustomMessage/StreamAttachmentMessage.tsx +21 -54
- package/src/components/CustomMessageInput/index.tsx +13 -16
- package/src/components/FaqList/FaqList.stories.tsx +204 -0
- package/src/components/FaqList/FaqListItem.stories.tsx +1 -0
- package/src/components/IconButton/IconButton.stories.tsx +1 -0
- package/src/components/Loading/Loading.stories.tsx +1 -0
- package/src/components/MessagingShell/ErrorState.stories.tsx +1 -0
- package/src/components/MessagingShell/LoadingState.stories.tsx +1 -0
- package/src/components/SearchInput/SearchInput.stories.tsx +1 -0
- package/src/testing/createMockMessagingClient.stories.tsx +1 -1
- package/dist/index-CAD8AXBg.cjs +0 -3
- package/dist/index-CAD8AXBg.cjs.map +0 -1
- package/dist/index-t0Okjl1p.js.map +0 -1
|
@@ -195,62 +195,13 @@ function messageAttachmentNamespaceForKind(kind: StreamMediaKind) {
|
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
|
|
198
|
+
// Per-attachment render props for a single media kind. Both the single-item and
|
|
199
|
+
// multi-item (cluster) paths shape each attachment the same way, so they share
|
|
200
|
+
// this builder.
|
|
201
|
+
function mediaItemForKind(
|
|
199
202
|
kind: StreamMediaKind,
|
|
200
|
-
|
|
203
|
+
attachment: Attachment
|
|
201
204
|
): Record<string, unknown> {
|
|
202
|
-
if (attachments.length > 1) {
|
|
203
|
-
switch (kind) {
|
|
204
|
-
case 'image':
|
|
205
|
-
return {
|
|
206
|
-
items: attachments.map((attachment) => ({
|
|
207
|
-
src: imageSrcFromAttachment(attachment),
|
|
208
|
-
alt: trimToUndefined((attachment as { title?: string }).title),
|
|
209
|
-
})),
|
|
210
|
-
}
|
|
211
|
-
case 'video':
|
|
212
|
-
return {
|
|
213
|
-
items: attachments.map((attachment) => ({
|
|
214
|
-
src: trimToUndefined(attachment.asset_url) ?? '',
|
|
215
|
-
poster: trimToUndefined(
|
|
216
|
-
(attachment as { thumb_url?: string }).thumb_url
|
|
217
|
-
),
|
|
218
|
-
mimeType: trimToUndefined(attachment.mime_type),
|
|
219
|
-
})),
|
|
220
|
-
}
|
|
221
|
-
case 'audio':
|
|
222
|
-
return {
|
|
223
|
-
items: attachments.map((attachment) => ({
|
|
224
|
-
src: trimToUndefined(attachment.asset_url) ?? '',
|
|
225
|
-
mimeType: trimToUndefined(attachment.mime_type) ?? 'audio/mpeg',
|
|
226
|
-
filename: trimToUndefined((attachment as { title?: string }).title),
|
|
227
|
-
})),
|
|
228
|
-
}
|
|
229
|
-
case 'pdf':
|
|
230
|
-
return {
|
|
231
|
-
items: attachments.map((attachment) => ({
|
|
232
|
-
src: trimToUndefined(attachment.asset_url) ?? '',
|
|
233
|
-
filename: trimToUndefined((attachment as { title?: string }).title),
|
|
234
|
-
fileSize: (attachment as { file_size?: number }).file_size,
|
|
235
|
-
})),
|
|
236
|
-
}
|
|
237
|
-
case 'file':
|
|
238
|
-
return {
|
|
239
|
-
items: attachments.map((attachment) => ({
|
|
240
|
-
src: trimToUndefined(attachment.asset_url) ?? '',
|
|
241
|
-
filename: trimToUndefined((attachment as { title?: string }).title),
|
|
242
|
-
fileSize: (attachment as { file_size?: number }).file_size,
|
|
243
|
-
mimeType:
|
|
244
|
-
trimToUndefined(attachment.mime_type) ??
|
|
245
|
-
'application/octet-stream',
|
|
246
|
-
})),
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const attachment = attachments[0]
|
|
252
|
-
if (!attachment) return {}
|
|
253
|
-
|
|
254
205
|
switch (kind) {
|
|
255
206
|
case 'image':
|
|
256
207
|
return {
|
|
@@ -288,6 +239,22 @@ function buildMediaClusterRenderProps(
|
|
|
288
239
|
}
|
|
289
240
|
}
|
|
290
241
|
|
|
242
|
+
function buildMediaClusterRenderProps(
|
|
243
|
+
kind: StreamMediaKind,
|
|
244
|
+
attachments: Attachment[]
|
|
245
|
+
): Record<string, unknown> {
|
|
246
|
+
if (attachments.length > 1) {
|
|
247
|
+
return {
|
|
248
|
+
items: attachments.map((attachment) => mediaItemForKind(kind, attachment)),
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const attachment = attachments[0]
|
|
253
|
+
if (!attachment) return {}
|
|
254
|
+
|
|
255
|
+
return mediaItemForKind(kind, attachment)
|
|
256
|
+
}
|
|
257
|
+
|
|
291
258
|
function MediaClusterBubble({
|
|
292
259
|
groupPosition,
|
|
293
260
|
isMyMessage,
|
|
@@ -327,6 +327,17 @@ export interface CustomMessageInputProps {
|
|
|
327
327
|
composerInput?: React.ComponentType
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
+
const ComposerBackdrop: React.FC = () => (
|
|
331
|
+
<div className="messaging-composer-backdrop" aria-hidden="true">
|
|
332
|
+
<div className="messaging-composer-backdrop-blur" />
|
|
333
|
+
<div className="messaging-composer-backdrop-blur" />
|
|
334
|
+
<div className="messaging-composer-backdrop-blur" />
|
|
335
|
+
<div className="messaging-composer-backdrop-blur" />
|
|
336
|
+
<div className="messaging-composer-backdrop-blur" />
|
|
337
|
+
<div className="messaging-composer-backdrop-gradient" />
|
|
338
|
+
</div>
|
|
339
|
+
)
|
|
340
|
+
|
|
330
341
|
export const CustomMessageInput: React.FC<CustomMessageInputProps> = ({
|
|
331
342
|
renderActions,
|
|
332
343
|
renderHeader,
|
|
@@ -436,14 +447,7 @@ export const CustomMessageInput: React.FC<CustomMessageInputProps> = ({
|
|
|
436
447
|
ref={composerRef}
|
|
437
448
|
className="messaging-composer-chrome messaging-composer-chrome--floating"
|
|
438
449
|
>
|
|
439
|
-
<
|
|
440
|
-
<div className="messaging-composer-backdrop-blur" />
|
|
441
|
-
<div className="messaging-composer-backdrop-blur" />
|
|
442
|
-
<div className="messaging-composer-backdrop-blur" />
|
|
443
|
-
<div className="messaging-composer-backdrop-blur" />
|
|
444
|
-
<div className="messaging-composer-backdrop-blur" />
|
|
445
|
-
<div className="messaging-composer-backdrop-gradient" />
|
|
446
|
-
</div>
|
|
450
|
+
<ComposerBackdrop />
|
|
447
451
|
<div className="relative z-10 flex flex-col">
|
|
448
452
|
{renderHeader?.()}
|
|
449
453
|
<div className="messaging-composer-locked-panel flex w-full flex-col items-center justify-center gap-3 px-6 py-4">
|
|
@@ -488,14 +492,7 @@ export const CustomMessageInput: React.FC<CustomMessageInputProps> = ({
|
|
|
488
492
|
ref={composerRef}
|
|
489
493
|
className="messaging-composer-chrome messaging-composer-chrome--floating"
|
|
490
494
|
>
|
|
491
|
-
<
|
|
492
|
-
<div className="messaging-composer-backdrop-blur" />
|
|
493
|
-
<div className="messaging-composer-backdrop-blur" />
|
|
494
|
-
<div className="messaging-composer-backdrop-blur" />
|
|
495
|
-
<div className="messaging-composer-backdrop-blur" />
|
|
496
|
-
<div className="messaging-composer-backdrop-blur" />
|
|
497
|
-
<div className="messaging-composer-backdrop-gradient" />
|
|
498
|
-
</div>
|
|
495
|
+
<ComposerBackdrop />
|
|
499
496
|
|
|
500
497
|
<div className="relative z-10 flex min-h-0 flex-col">
|
|
501
498
|
{renderHeader?.()}
|
|
@@ -22,6 +22,15 @@ const Template: StoryFn<ComponentProps> = (args) => {
|
|
|
22
22
|
)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
// Per-variant stories stay in Storybook for browsing/design review but are
|
|
26
|
+
// individually covered by cells in AllStates — skip in Chromatic.
|
|
27
|
+
const skipInChromatic = { chromatic: { disableSnapshot: true } }
|
|
28
|
+
|
|
29
|
+
// Deterministic local avatar for the grid so a pravatar network flake can't
|
|
30
|
+
// diff the whole AllStates snapshot. Individual stories keep their remote
|
|
31
|
+
// images (they're skipped in Chromatic anyway).
|
|
32
|
+
const LOCAL_AVATAR = '/image-thumbnail.jpg'
|
|
33
|
+
|
|
25
34
|
export const Default: StoryFn<ComponentProps> = Template.bind({})
|
|
26
35
|
Default.args = {
|
|
27
36
|
faqs: [
|
|
@@ -52,6 +61,7 @@ Default.args = {
|
|
|
52
61
|
avatarName: 'Brie Parson',
|
|
53
62
|
avatarImage: 'https://i.pravatar.cc/150?img=47',
|
|
54
63
|
}
|
|
64
|
+
Default.parameters = skipInChromatic
|
|
55
65
|
|
|
56
66
|
export const WithoutHeader: StoryFn<ComponentProps> = Template.bind({})
|
|
57
67
|
WithoutHeader.args = {
|
|
@@ -73,6 +83,7 @@ WithoutHeader.args = {
|
|
|
73
83
|
],
|
|
74
84
|
onFaqClick: (id) => console.log('FAQ clicked:', id),
|
|
75
85
|
}
|
|
86
|
+
WithoutHeader.parameters = skipInChromatic
|
|
76
87
|
|
|
77
88
|
export const WithDisabledFaq: StoryFn<ComponentProps> = Template.bind({})
|
|
78
89
|
WithDisabledFaq.args = {
|
|
@@ -101,6 +112,7 @@ WithDisabledFaq.args = {
|
|
|
101
112
|
],
|
|
102
113
|
onFaqClick: (id) => console.log('FAQ clicked:', id),
|
|
103
114
|
}
|
|
115
|
+
WithDisabledFaq.parameters = skipInChromatic
|
|
104
116
|
|
|
105
117
|
export const WithLoading: StoryFn<ComponentProps> = Template.bind({})
|
|
106
118
|
WithLoading.args = {
|
|
@@ -131,12 +143,14 @@ WithLoading.args = {
|
|
|
131
143
|
loadingFaqId: '2',
|
|
132
144
|
headerText: 'Tap to send a suggested question:',
|
|
133
145
|
}
|
|
146
|
+
WithLoading.parameters = skipInChromatic
|
|
134
147
|
|
|
135
148
|
export const Empty: StoryFn<ComponentProps> = Template.bind({})
|
|
136
149
|
Empty.args = {
|
|
137
150
|
faqs: [],
|
|
138
151
|
onFaqClick: (id) => console.log('FAQ clicked:', id),
|
|
139
152
|
}
|
|
153
|
+
Empty.parameters = skipInChromatic
|
|
140
154
|
|
|
141
155
|
export const WithAvatarOnly: StoryFn<ComponentProps> = Template.bind({})
|
|
142
156
|
WithAvatarOnly.args = {
|
|
@@ -160,6 +174,7 @@ WithAvatarOnly.args = {
|
|
|
160
174
|
headerText: 'Frequently Asked Questions',
|
|
161
175
|
avatarName: 'Account Owner',
|
|
162
176
|
}
|
|
177
|
+
WithAvatarOnly.parameters = skipInChromatic
|
|
163
178
|
|
|
164
179
|
export const WithAvatarAndImage: StoryFn<ComponentProps> = Template.bind({})
|
|
165
180
|
WithAvatarAndImage.args = {
|
|
@@ -184,3 +199,192 @@ WithAvatarAndImage.args = {
|
|
|
184
199
|
avatarName: 'Sarah Johnson',
|
|
185
200
|
avatarImage: 'https://i.pravatar.cc/150?img=28',
|
|
186
201
|
}
|
|
202
|
+
WithAvatarAndImage.parameters = skipInChromatic
|
|
203
|
+
|
|
204
|
+
export const AllStates: StoryFn = () => {
|
|
205
|
+
const states: { label: string; props: ComponentProps }[] = [
|
|
206
|
+
{
|
|
207
|
+
label: 'Default (header + avatar + image)',
|
|
208
|
+
props: {
|
|
209
|
+
faqs: [
|
|
210
|
+
{
|
|
211
|
+
id: '1',
|
|
212
|
+
question: 'Book club slots',
|
|
213
|
+
answer: 'We ship worldwide...',
|
|
214
|
+
enabled: true,
|
|
215
|
+
order: 1,
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
id: '2',
|
|
219
|
+
question: 'Refunds',
|
|
220
|
+
answer: 'You can track...',
|
|
221
|
+
enabled: true,
|
|
222
|
+
order: 2,
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
id: '3',
|
|
226
|
+
question: 'Brand collabs',
|
|
227
|
+
answer: 'Returns are accepted...',
|
|
228
|
+
enabled: true,
|
|
229
|
+
order: 3,
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
onFaqClick: (id) => console.log('FAQ clicked:', id),
|
|
233
|
+
headerText: 'Tap to send a suggested question by Brie Parson:',
|
|
234
|
+
avatarName: 'Brie Parson',
|
|
235
|
+
avatarImage: LOCAL_AVATAR,
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
label: 'Without header',
|
|
240
|
+
props: {
|
|
241
|
+
faqs: [
|
|
242
|
+
{
|
|
243
|
+
id: '1',
|
|
244
|
+
question: 'Book club slots',
|
|
245
|
+
answer: 'We ship worldwide...',
|
|
246
|
+
enabled: true,
|
|
247
|
+
order: 1,
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
id: '2',
|
|
251
|
+
question: 'Refunds',
|
|
252
|
+
answer: 'You can track...',
|
|
253
|
+
enabled: true,
|
|
254
|
+
order: 2,
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
onFaqClick: (id) => console.log('FAQ clicked:', id),
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
label: 'With avatar only',
|
|
262
|
+
props: {
|
|
263
|
+
faqs: [
|
|
264
|
+
{
|
|
265
|
+
id: '1',
|
|
266
|
+
question: 'Book club slots',
|
|
267
|
+
answer: 'We ship worldwide...',
|
|
268
|
+
enabled: true,
|
|
269
|
+
order: 1,
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
id: '2',
|
|
273
|
+
question: 'Refunds',
|
|
274
|
+
answer: 'You can track...',
|
|
275
|
+
enabled: true,
|
|
276
|
+
order: 2,
|
|
277
|
+
},
|
|
278
|
+
],
|
|
279
|
+
onFaqClick: (id) => console.log('FAQ clicked:', id),
|
|
280
|
+
headerText: 'Frequently Asked Questions',
|
|
281
|
+
avatarName: 'Account Owner',
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
label: 'With avatar and image',
|
|
286
|
+
props: {
|
|
287
|
+
faqs: [
|
|
288
|
+
{
|
|
289
|
+
id: '1',
|
|
290
|
+
question: 'How do I contact support?',
|
|
291
|
+
answer: 'You can reach us...',
|
|
292
|
+
enabled: true,
|
|
293
|
+
order: 1,
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
id: '2',
|
|
297
|
+
question: 'What are your hours?',
|
|
298
|
+
answer: 'We are available...',
|
|
299
|
+
enabled: true,
|
|
300
|
+
order: 2,
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
onFaqClick: (id) => console.log('FAQ clicked:', id),
|
|
304
|
+
headerText: 'Questions for Sarah',
|
|
305
|
+
avatarName: 'Sarah Johnson',
|
|
306
|
+
avatarImage: LOCAL_AVATAR,
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
label: 'With disabled FAQ',
|
|
311
|
+
props: {
|
|
312
|
+
faqs: [
|
|
313
|
+
{
|
|
314
|
+
id: '1',
|
|
315
|
+
question: 'Enabled question',
|
|
316
|
+
answer: 'Answer...',
|
|
317
|
+
enabled: true,
|
|
318
|
+
order: 1,
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
id: '2',
|
|
322
|
+
question: 'Disabled question',
|
|
323
|
+
answer: 'Answer...',
|
|
324
|
+
enabled: false,
|
|
325
|
+
order: 2,
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
id: '3',
|
|
329
|
+
question: 'Another enabled',
|
|
330
|
+
answer: 'Answer...',
|
|
331
|
+
enabled: true,
|
|
332
|
+
order: 3,
|
|
333
|
+
},
|
|
334
|
+
],
|
|
335
|
+
onFaqClick: (id) => console.log('FAQ clicked:', id),
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
label: 'With loading',
|
|
340
|
+
props: {
|
|
341
|
+
faqs: [
|
|
342
|
+
{
|
|
343
|
+
id: '1',
|
|
344
|
+
question: 'Book club slots',
|
|
345
|
+
answer: 'We ship worldwide...',
|
|
346
|
+
enabled: true,
|
|
347
|
+
order: 1,
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
id: '2',
|
|
351
|
+
question: 'Refunds',
|
|
352
|
+
answer: 'You can track...',
|
|
353
|
+
enabled: true,
|
|
354
|
+
order: 2,
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
id: '3',
|
|
358
|
+
question: 'Brand collabs',
|
|
359
|
+
answer: 'Returns are accepted...',
|
|
360
|
+
enabled: true,
|
|
361
|
+
order: 3,
|
|
362
|
+
},
|
|
363
|
+
],
|
|
364
|
+
onFaqClick: (id) => console.log('FAQ clicked:', id),
|
|
365
|
+
loadingFaqId: '2',
|
|
366
|
+
headerText: 'Tap to send a suggested question:',
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
label: 'Empty (renders nothing)',
|
|
371
|
+
props: {
|
|
372
|
+
faqs: [],
|
|
373
|
+
onFaqClick: (id) => console.log('FAQ clicked:', id),
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
]
|
|
377
|
+
|
|
378
|
+
return (
|
|
379
|
+
<div className="flex flex-col gap-6 bg-white p-6">
|
|
380
|
+
{states.map(({ label, props }) => (
|
|
381
|
+
<div key={label} className="flex flex-col gap-1">
|
|
382
|
+
<span className="text-xs text-stone">{label}</span>
|
|
383
|
+
<div className="w-96">
|
|
384
|
+
<FaqList {...props} />
|
|
385
|
+
</div>
|
|
386
|
+
</div>
|
|
387
|
+
))}
|
|
388
|
+
</div>
|
|
389
|
+
)
|
|
390
|
+
}
|
|
@@ -14,7 +14,7 @@ import { createMockMessagingClient } from './createMockMessagingClient'
|
|
|
14
14
|
*/
|
|
15
15
|
const meta: Meta = {
|
|
16
16
|
title: 'testing/createMockMessagingClient',
|
|
17
|
-
parameters: { layout: 'fullscreen' },
|
|
17
|
+
parameters: { layout: 'fullscreen', chromatic: { disableSnapshot: true } },
|
|
18
18
|
}
|
|
19
19
|
export default meta
|
|
20
20
|
|