@linktr.ee/messaging-react 3.37.0 → 3.37.1

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 (91) hide show
  1. package/README.md +4 -4
  2. package/dist/Card-415OfRhw.cjs.map +1 -1
  3. package/dist/{Card-D4PPD5qa.js → Card-DVMzYquF.js} +11 -8
  4. package/dist/Card-DVMzYquF.js.map +1 -0
  5. package/dist/{Card-qS17qnN0.js → Card-DaJtDL7m.js} +15 -6
  6. package/dist/Card-DaJtDL7m.js.map +1 -0
  7. package/dist/Card-Dxk_Ggxw.cjs.map +1 -1
  8. package/dist/LoadingDots-Ct3WmVlT.js.map +1 -1
  9. package/dist/LoadingDots-D9GGphgM.cjs.map +1 -1
  10. package/dist/{index-DGmVyxHy.js → index-BOBIiAuD.js} +87 -62
  11. package/dist/index-BOBIiAuD.js.map +1 -0
  12. package/dist/index-D7A8U8GQ.cjs.map +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.js +1 -1
  15. package/package.json +3 -2
  16. package/src/components/ActionButton/ActionButton.stories.tsx +0 -2
  17. package/src/components/ActionButton/ActionButton.test.tsx +60 -55
  18. package/src/components/ActionButton/index.tsx +13 -14
  19. package/src/components/AttachmentCard/AttachmentCard.stories.tsx +1 -3
  20. package/src/components/AttachmentCard/MediaPlayer.tsx +9 -7
  21. package/src/components/AttachmentCard/index.tsx +6 -2
  22. package/src/components/Avatar/Avatar.stories.tsx +17 -5
  23. package/src/components/Avatar/index.tsx +13 -23
  24. package/src/components/ChannelView.test.tsx +6 -10
  25. package/src/components/CustomMessage/CustomMessage.stories.tsx +7 -2
  26. package/src/components/CustomMessage/CustomMessage.test.tsx +5 -3
  27. package/src/components/CustomMessage/LockedAttachment/LockedAttachment.test.tsx +5 -4
  28. package/src/components/CustomMessage/LockedAttachment/components/Text/Card.tsx +2 -4
  29. package/src/components/CustomMessage/LockedAttachment/components/_shared/CardBody.tsx +9 -6
  30. package/src/components/CustomMessage/LockedAttachment/components/_shared/CardThumbnail.tsx +1 -3
  31. package/src/components/CustomMessage/LockedAttachment/components/_shared/GalleryThumbnail.tsx +1 -4
  32. package/src/components/CustomMessage/LockedAttachment/components/_shared/PurchaseStatusBadge.tsx +0 -1
  33. package/src/components/CustomMessage/LockedAttachment/components/_shared/SingleThumbnail.tsx +1 -4
  34. package/src/components/CustomMessage/LockedAttachment/components/_shared/SkeletonTextLines.tsx +7 -2
  35. package/src/components/CustomMessage/LockedAttachment/types.ts +4 -3
  36. package/src/components/CustomMessage/MessageAttachmentConversations.stories.tsx +89 -86
  37. package/src/components/CustomMessage/MessageVoteButtons.tsx +4 -1
  38. package/src/components/CustomMessage/SentMessageDeliveryStatus.test.tsx +13 -10
  39. package/src/components/CustomMessage/SentMessageDeliveryStatus.tsx +1 -4
  40. package/src/components/CustomMessage/StreamAttachmentMessage.stories.tsx +4 -4
  41. package/src/components/CustomMessage/StreamAttachmentMessage.test.tsx +6 -7
  42. package/src/components/CustomMessage/context.tsx +7 -2
  43. package/src/components/CustomMessage/index.tsx +1 -4
  44. package/src/components/CustomMessageInput/CustomMessageInput.stories.tsx +33 -11
  45. package/src/components/CustomMessageInput/CustomMessageInput.test.tsx +3 -3
  46. package/src/components/CustomSystemMessage/CustomSystemMessage.test.tsx +6 -9
  47. package/src/components/CustomTypingIndicator/CustomTypingIndicator.stories.tsx +4 -1
  48. package/src/components/IconButton/index.tsx +21 -17
  49. package/src/components/LinkAttachment/LinkAttachment.test.tsx +4 -1
  50. package/src/components/LinkAttachment/components/_shared/CardCta.tsx +4 -1
  51. package/src/components/Loading/Loading.stories.tsx +1 -4
  52. package/src/components/MediaMessage/MediaMessage.stories.tsx +6 -18
  53. package/src/components/MediaMessage/MediaMessage.test.tsx +30 -16
  54. package/src/components/MediaMessage/index.tsx +51 -14
  55. package/src/components/MessageAttachment/Audio/AudioAttachment.stories.tsx +4 -2
  56. package/src/components/MessageAttachment/File/FileAttachment.stories.tsx +3 -1
  57. package/src/components/MessageAttachment/Image/ImageAttachment.stories.tsx +15 -4
  58. package/src/components/MessageAttachment/Image/index.tsx +6 -12
  59. package/src/components/MessageAttachment/MessageAttachment.test.tsx +59 -27
  60. package/src/components/MessageAttachment/Pdf/PdfAttachment.stories.tsx +3 -1
  61. package/src/components/MessageAttachment/Pdf/index.tsx +2 -3
  62. package/src/components/MessageAttachment/Video/VideoAttachment.stories.tsx +11 -3
  63. package/src/components/MessageAttachment/Video/index.tsx +9 -14
  64. package/src/components/MessageAttachment/_shared/CompactDocumentRow.tsx +1 -3
  65. package/src/components/MessageAttachment/_shared/ImageViewer.tsx +1 -3
  66. package/src/components/MessageAttachment/_shared/MediaStackGrid.tsx +5 -1
  67. package/src/components/MessageAttachment/_shared/PdfViewer.tsx +1 -3
  68. package/src/components/MessageAttachment/_shared/VideoViewer.tsx +1 -3
  69. package/src/components/MessageAttachment/_shared/fileMeta.test.ts +4 -6
  70. package/src/components/MessageAttachment/stories/StoryTable.tsx +1 -3
  71. package/src/components/MessageBubble/MessageBubble.stories.tsx +5 -1
  72. package/src/components/MessageBubble/MessageBubble.test.tsx +1 -3
  73. package/src/components/MessageBubble/components/_shared/bubbleTail.tsx +2 -1
  74. package/src/components/MessagingShell/LoadingState.stories.tsx +0 -1
  75. package/src/components/RichCard/RichCard.stories.tsx +14 -3
  76. package/src/components/RichCard/RichCard.test.tsx +16 -4
  77. package/src/components/RichCard/RichCardBody.tsx +11 -3
  78. package/src/components/RichCard/RichCardCard.tsx +1 -3
  79. package/src/components/RichCard/RichCardImages.tsx +2 -4
  80. package/src/components/SearchInput/SearchInput.stories.tsx +0 -1
  81. package/src/components/SearchInput/SearchInput.test.tsx +94 -65
  82. package/src/hooks/useChannelStar.ts +3 -1
  83. package/src/hooks/useMessaging.ts +4 -4
  84. package/src/stories/decorators/storyUser.tsx +2 -2
  85. package/src/stories/mocks.tsx +4 -1
  86. package/src/styles.css +23 -8
  87. package/src/types.ts +1 -2
  88. package/src/utils/cdnImageUrl.test.ts +3 -1
  89. package/dist/Card-D4PPD5qa.js.map +0 -1
  90. package/dist/Card-qS17qnN0.js.map +0 -1
  91. package/dist/index-DGmVyxHy.js.map +0 -1
@@ -88,7 +88,9 @@ const ChatRow: React.FC<{
88
88
  ) : null}
89
89
  </div>
90
90
  ) : null}
91
- <div className={role === 'sender' ? 'flex justify-end' : 'flex justify-start'}>
91
+ <div
92
+ className={role === 'sender' ? 'flex justify-end' : 'flex justify-start'}
93
+ >
92
94
  {children}
93
95
  </div>
94
96
  </div>
@@ -603,91 +605,92 @@ ConversationWithFiles.parameters = skipInChromatic
603
605
  * and a PDF handoff. Useful for sanity-checking spacing and bubble
604
606
  * rhythm when multiple attachment types coexist.
605
607
  */
606
- export const ConversationWithMixedAttachments: StoryFn<ConversationStoryArgs> =
607
- ({ currentUser }) => {
608
- const isSenderTheCreator = currentUser.id === storyUsers.creator.id
609
- const receiver = isSenderTheCreator ? storyUsers.visitor : storyUsers.creator
610
- return (
611
- <ChatMock
612
- currentUser={currentUser}
613
- receiver={receiver}
614
- messages={[
615
- {
616
- id: 'msg-1',
617
- role: 'receiver',
618
- content: 'Hey! Got a sec to look at the launch package?',
619
- },
620
- {
621
- id: 'msg-2',
622
- role: 'sender',
623
- content: 'Yep, send it over.',
624
- },
625
- {
626
- id: 'msg-3',
627
- role: 'receiver',
628
- content: 'Here is the hero shot for the page',
629
- },
630
- {
631
- id: 'msg-4',
632
- role: 'receiver',
633
- content: (
634
- <MessageAttachment.Image.Received
635
- src={HERO_PHOTO}
636
- alt="Hero shot"
637
- filename="hero.jpg"
638
- />
639
- ),
640
- },
641
- {
642
- id: 'msg-5',
643
- role: 'receiver',
644
- content: (
645
- <MessageAttachment.Video.Received
646
- src={VIDEO_SRC}
647
- poster={VIDEO_POSTER}
648
- mimeType="video/mp4"
649
- filename="trailer.mp4"
650
- text="And the rough trailer"
651
- />
652
- ),
653
- },
654
- {
655
- id: 'msg-6',
656
- role: 'sender',
657
- content: 'Looks great. Quick voice memo with notes ↓',
658
- },
659
- {
660
- id: 'msg-7',
661
- role: 'sender',
662
- content: (
663
- <MessageAttachment.Audio.Sent
664
- src={AUDIO_SRC}
665
- mimeType="audio/mpeg"
666
- filename="notes.mp3"
667
- />
668
- ),
669
- },
670
- {
671
- id: 'msg-8',
672
- role: 'sender',
673
- content: (
674
- <MessageAttachment.Pdf.Sent
675
- src={PDF_SRC}
676
- filename="launch-checklist.pdf"
677
- fileSize={142_336}
678
- text="And the launch checklist for the dry run."
679
- />
680
- ),
681
- },
682
- {
683
- id: 'msg-9',
684
- role: 'receiver',
685
- content: 'Got everything. Will sync back in the morning.',
686
- },
687
- ]}
688
- />
689
- )
690
- }
608
+ export const ConversationWithMixedAttachments: StoryFn<
609
+ ConversationStoryArgs
610
+ > = ({ currentUser }) => {
611
+ const isSenderTheCreator = currentUser.id === storyUsers.creator.id
612
+ const receiver = isSenderTheCreator ? storyUsers.visitor : storyUsers.creator
613
+ return (
614
+ <ChatMock
615
+ currentUser={currentUser}
616
+ receiver={receiver}
617
+ messages={[
618
+ {
619
+ id: 'msg-1',
620
+ role: 'receiver',
621
+ content: 'Hey! Got a sec to look at the launch package?',
622
+ },
623
+ {
624
+ id: 'msg-2',
625
+ role: 'sender',
626
+ content: 'Yep, send it over.',
627
+ },
628
+ {
629
+ id: 'msg-3',
630
+ role: 'receiver',
631
+ content: 'Here is the hero shot for the page',
632
+ },
633
+ {
634
+ id: 'msg-4',
635
+ role: 'receiver',
636
+ content: (
637
+ <MessageAttachment.Image.Received
638
+ src={HERO_PHOTO}
639
+ alt="Hero shot"
640
+ filename="hero.jpg"
641
+ />
642
+ ),
643
+ },
644
+ {
645
+ id: 'msg-5',
646
+ role: 'receiver',
647
+ content: (
648
+ <MessageAttachment.Video.Received
649
+ src={VIDEO_SRC}
650
+ poster={VIDEO_POSTER}
651
+ mimeType="video/mp4"
652
+ filename="trailer.mp4"
653
+ text="And the rough trailer ↑"
654
+ />
655
+ ),
656
+ },
657
+ {
658
+ id: 'msg-6',
659
+ role: 'sender',
660
+ content: 'Looks great. Quick voice memo with notes ↓',
661
+ },
662
+ {
663
+ id: 'msg-7',
664
+ role: 'sender',
665
+ content: (
666
+ <MessageAttachment.Audio.Sent
667
+ src={AUDIO_SRC}
668
+ mimeType="audio/mpeg"
669
+ filename="notes.mp3"
670
+ />
671
+ ),
672
+ },
673
+ {
674
+ id: 'msg-8',
675
+ role: 'sender',
676
+ content: (
677
+ <MessageAttachment.Pdf.Sent
678
+ src={PDF_SRC}
679
+ filename="launch-checklist.pdf"
680
+ fileSize={142_336}
681
+ text="And the launch checklist for the dry run."
682
+ />
683
+ ),
684
+ },
685
+ {
686
+ id: 'msg-9',
687
+ role: 'receiver',
688
+ content: 'Got everything. Will sync back in the morning.',
689
+ },
690
+ ]}
691
+ />
692
+ )
693
+ }
691
694
 
692
695
  /**
693
696
  * Multi-attachment message — audio + PDF.
@@ -38,7 +38,10 @@ export const MessageVoteButtons: React.FC<MessageVoteButtonsProps> = ({
38
38
  aria-pressed={selected === 'down'}
39
39
  data-tooltip="Bad response"
40
40
  >
41
- <ThumbsDownIcon size={16} weight={selected === 'down' ? 'fill' : 'regular'} />
41
+ <ThumbsDownIcon
42
+ size={16}
43
+ weight={selected === 'down' ? 'fill' : 'regular'}
44
+ />
42
45
  </button>
43
46
  </div>
44
47
  )
@@ -260,10 +260,9 @@ describe('SentMessageDeliveryStatus', () => {
260
260
  expect(screen.getAllByText('•')).toHaveLength(1)
261
261
  expect(button).not.toHaveTextContent('•')
262
262
  expect(name).toHaveClass('sent-message-broadcast-name')
263
- expect(button.querySelector('.sent-message-broadcast-badge')).toHaveAttribute(
264
- 'aria-hidden',
265
- 'true'
266
- )
263
+ expect(
264
+ button.querySelector('.sent-message-broadcast-badge')
265
+ ).toHaveAttribute('aria-hidden', 'true')
267
266
  expect(screen.getAllByTestId('sent-message-delivery-status')).toHaveLength(
268
267
  3
269
268
  )
@@ -290,9 +289,11 @@ describe('SentMessageDeliveryStatus', () => {
290
289
  />
291
290
  )
292
291
 
293
- screen.getByRole('button', {
294
- name: 'View broadcast July 9th Class absentee',
295
- }).click()
292
+ screen
293
+ .getByRole('button', {
294
+ name: 'View broadcast July 9th Class absentee',
295
+ })
296
+ .click()
296
297
 
297
298
  expect(onBroadcastClick).toHaveBeenCalledWith({
298
299
  id: 'broadcast-1',
@@ -321,9 +322,11 @@ describe('SentMessageDeliveryStatus', () => {
321
322
  />
322
323
  )
323
324
 
324
- screen.getByRole('button', {
325
- name: 'View broadcast Broadcast',
326
- }).click()
325
+ screen
326
+ .getByRole('button', {
327
+ name: 'View broadcast Broadcast',
328
+ })
329
+ .click()
327
330
 
328
331
  expect(onBroadcastClick).toHaveBeenCalledWith({
329
332
  id: 'broadcast-1',
@@ -219,10 +219,7 @@ export const SentMessageDeliveryStatus = ({
219
219
  <span className="sent-message-status-row">
220
220
  {messageStatus}
221
221
  {isLatestRealMessage && (
222
- <span
223
- className="sent-message-broadcast-separator"
224
- aria-hidden="true"
225
- >
222
+ <span className="sent-message-broadcast-separator" aria-hidden="true">
226
223
 
227
224
  </span>
228
225
  )}
@@ -28,10 +28,10 @@ import StreamAttachmentMessage from './StreamAttachmentMessage'
28
28
  * ancestry that Stream bubble chrome and the MES-1031 tails are scoped under.
29
29
  * ────────────────────────────────────────────────────────────────── */
30
30
 
31
- const Bubbles: React.FC<{ isMyMessage: boolean; children: React.ReactNode }> = ({
32
- isMyMessage,
33
- children,
34
- }) => (
31
+ const Bubbles: React.FC<{
32
+ isMyMessage: boolean
33
+ children: React.ReactNode
34
+ }> = ({ isMyMessage, children }) => (
35
35
  <div className="str-chat mx-auto max-w-2xl p-12">
36
36
  {/* Tail CSS is scoped to `.str-chat__li--single|--bottom`; bubble surface
37
37
  styles need `.str-chat__message--me|other`. */}
@@ -9,10 +9,8 @@ import StreamAttachmentMessage, {
9
9
  linkCardPropsFromStreamAttachment,
10
10
  } from './StreamAttachmentMessage'
11
11
 
12
- const message = (
13
- attachments: Attachment[],
14
- text?: string
15
- ): LocalMessage => ({ attachments, text }) as LocalMessage
12
+ const message = (attachments: Attachment[], text?: string): LocalMessage =>
13
+ ({ attachments, text }) as LocalMessage
16
14
 
17
15
  describe('linkCardPropsFromStreamAttachment', () => {
18
16
  it('uses the featured layout when a thumbnail is present', () => {
@@ -99,9 +97,10 @@ describe('StreamAttachmentMessage', () => {
99
97
  />
100
98
  )
101
99
 
102
- expect(
103
- screen.getByRole('link', { name: /my linktree/i })
104
- ).toHaveAttribute('href', 'https://linktr.ee/someone')
100
+ expect(screen.getByRole('link', { name: /my linktree/i })).toHaveAttribute(
101
+ 'href',
102
+ 'https://linktr.ee/someone'
103
+ )
105
104
  expect(screen.queryByText('https://linktr.ee/someone !')).toBeNull()
106
105
  })
107
106
 
@@ -1,6 +1,9 @@
1
1
  import { createContext, useContext } from 'react'
2
2
 
3
- import { defaultLockedAttachmentContextValue, type LockedAttachmentContextValue } from './LockedAttachment/types'
3
+ import {
4
+ defaultLockedAttachmentContextValue,
5
+ type LockedAttachmentContextValue,
6
+ } from './LockedAttachment/types'
4
7
 
5
8
  export interface CustomMessageRegistry {
6
9
  LockedAttachment: LockedAttachmentContextValue
@@ -14,7 +17,9 @@ const CustomMessageContext = createContext<Partial<CustomMessageRegistry>>({})
14
17
 
15
18
  export const CustomMessageProvider = CustomMessageContext.Provider
16
19
 
17
- export function useCustomMessage<K extends keyof CustomMessageRegistry>(key: K): CustomMessageRegistry[K] {
20
+ export function useCustomMessage<K extends keyof CustomMessageRegistry>(
21
+ key: K
22
+ ): CustomMessageRegistry[K] {
18
23
  const ctx = useContext(CustomMessageContext)
19
24
  return (ctx[key] ?? customMessageDefaults[key]) as CustomMessageRegistry[K]
20
25
  }
@@ -307,10 +307,7 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
307
307
  <div className="flex items-center gap-2">
308
308
  {isMine && MessageActions && <MessageActions />}
309
309
  {isMine ? (
310
- <LockedAttachment
311
- {...sharedLockedTextProps}
312
- isMine={true}
313
- />
310
+ <LockedAttachment {...sharedLockedTextProps} isMine={true} />
314
311
  ) : (
315
312
  <LockedAttachment
316
313
  {...sharedLockedTextProps}
@@ -85,11 +85,20 @@ type WrapperProps = {
85
85
  }
86
86
 
87
87
  const Wrapper: React.FC<WrapperProps> = (props) => {
88
- const { frozen, renderActions, sendButton, attachmentPreviewList, renderFooter, surfaceHeight } = props
88
+ const {
89
+ frozen,
90
+ renderActions,
91
+ sendButton,
92
+ attachmentPreviewList,
93
+ renderFooter,
94
+ surfaceHeight,
95
+ } = props
89
96
 
90
97
  const [client] = React.useState(() => createMockStreamChatClient(mockUser))
91
98
 
92
- const [channel, setChannel] = React.useState<ReturnType<StreamChat['channel']> | null>(null)
99
+ const [channel, setChannel] = React.useState<ReturnType<
100
+ StreamChat['channel']
101
+ > | null>(null)
93
102
 
94
103
  useEffect(() => {
95
104
  createMockChannel(client, { frozen }).then(setChannel)
@@ -102,7 +111,9 @@ const Wrapper: React.FC<WrapperProps> = (props) => {
102
111
  <Channel
103
112
  channel={channel}
104
113
  {...(sendButton ? { SendButton: sendButton } : {})}
105
- {...(attachmentPreviewList ? { AttachmentPreviewList: attachmentPreviewList } : {})}
114
+ {...(attachmentPreviewList
115
+ ? { AttachmentPreviewList: attachmentPreviewList }
116
+ : {})}
106
117
  >
107
118
  <div
108
119
  className="bg-white"
@@ -121,7 +132,10 @@ const Wrapper: React.FC<WrapperProps> = (props) => {
121
132
  } as React.CSSProperties
122
133
  }
123
134
  >
124
- <CustomMessageInput renderActions={renderActions} renderFooter={renderFooter} />
135
+ <CustomMessageInput
136
+ renderActions={renderActions}
137
+ renderFooter={renderFooter}
138
+ />
125
139
  </div>
126
140
  </Channel>
127
141
  </Chat>
@@ -167,7 +181,9 @@ Frozen.parameters = {
167
181
  },
168
182
  }
169
183
 
170
- export const WithCustomActionButton: StoryFn<WrapperProps> = (args) => <Wrapper {...args} />
184
+ export const WithCustomActionButton: StoryFn<WrapperProps> = (args) => (
185
+ <Wrapper {...args} />
186
+ )
171
187
  WithCustomActionButton.args = {
172
188
  renderActions: () => (
173
189
  <button
@@ -207,7 +223,9 @@ const PurpleMediaSendButton: React.FC<SendButtonProps> = (props) => {
207
223
  )
208
224
  }
209
225
 
210
- export const WithCustomSendButton: StoryFn<WrapperProps> = (args) => <Wrapper {...args} />
226
+ export const WithCustomSendButton: StoryFn<WrapperProps> = (args) => (
227
+ <Wrapper {...args} />
228
+ )
211
229
  WithCustomSendButton.args = { sendButton: PurpleMediaSendButton }
212
230
  WithCustomSendButton.parameters = {
213
231
  docs: {
@@ -218,7 +236,9 @@ WithCustomSendButton.parameters = {
218
236
  },
219
237
  }
220
238
 
221
- export const WithAttachments: StoryFn<WrapperProps> = (args) => <Wrapper {...args} />
239
+ export const WithAttachments: StoryFn<WrapperProps> = (args) => (
240
+ <Wrapper {...args} />
241
+ )
222
242
  WithAttachments.args = {
223
243
  attachmentPreviewList: () => (
224
244
  <div className="relative size-20 shrink-0 overflow-hidden rounded-2xl border border-black/8">
@@ -249,9 +269,9 @@ WithAttachments.parameters = {
249
269
  },
250
270
  }
251
271
 
252
- export const WithStagedLinkPreviewUnderKeyboard: StoryFn<WrapperProps> = (args) => (
253
- <Wrapper {...args} />
254
- )
272
+ export const WithStagedLinkPreviewUnderKeyboard: StoryFn<WrapperProps> = (
273
+ args
274
+ ) => <Wrapper {...args} />
255
275
  WithStagedLinkPreviewUnderKeyboard.args = {
256
276
  // Roughly a 393x852 phone with the soft keyboard up, so the 250px staged card
257
277
  // alone outgrows the composer's cap (half of this) and the card scrolls.
@@ -274,7 +294,9 @@ WithStagedLinkPreviewUnderKeyboard.parameters = {
274
294
  },
275
295
  }
276
296
 
277
- export const WithPaidAttachment: StoryFn<WrapperProps> = (args) => <Wrapper {...args} />
297
+ export const WithPaidAttachment: StoryFn<WrapperProps> = (args) => (
298
+ <Wrapper {...args} />
299
+ )
278
300
  WithPaidAttachment.args = {
279
301
  attachmentPreviewList: () => (
280
302
  <LockedAttachment
@@ -375,9 +375,9 @@ describe('CustomMessageInput', () => {
375
375
  // Nothing inside may shrink, or the previews get cropped to make room for
376
376
  // the textarea instead of scrolling with it.
377
377
  expect(card).not.toHaveClass('min-h-0')
378
- expect(card.querySelector('.messaging-composer-previews')).not.toHaveClass(
379
- 'min-h-0'
380
- )
378
+ expect(
379
+ card.querySelector('.messaging-composer-previews')
380
+ ).not.toHaveClass('min-h-0')
381
381
  expect(card.querySelector('.messaging-composer-row')).not.toHaveClass(
382
382
  'shrink-0'
383
383
  )
@@ -51,16 +51,13 @@ describe('CustomSystemMessage', () => {
51
51
  it.each([
52
52
  { metadata: {}, text: 'Unknown system message' },
53
53
  { text: 'Absent system type' },
54
- ])(
55
- 'hides the timestamp for unknown or absent system types',
56
- (overrides) => {
57
- const { container } = renderWithProviders(
58
- <CustomSystemMessage {...createProps(overrides)} />
59
- )
54
+ ])('hides the timestamp for unknown or absent system types', (overrides) => {
55
+ const { container } = renderWithProviders(
56
+ <CustomSystemMessage {...createProps(overrides)} />
57
+ )
60
58
 
61
- expect(container.querySelector('time')).not.toBeInTheDocument()
62
- }
63
- )
59
+ expect(container.querySelector('time')).not.toBeInTheDocument()
60
+ })
64
61
 
65
62
  it('hides the timestamp for legacy dm-agent messages without a custom_type', () => {
66
63
  const { container } = renderWithProviders(
@@ -38,7 +38,10 @@ const defaultTyping: Record<string, Event> = {
38
38
  } as Event,
39
39
  }
40
40
 
41
- type ListenerMap = Record<string, (event: { ai_state: string; cid: string }) => void>
41
+ type ListenerMap = Record<
42
+ string,
43
+ (event: { ai_state: string; cid: string }) => void
44
+ >
42
45
 
43
46
  const createMockChannel = ({ aiState }: { aiState?: string }) => {
44
47
  const listeners: ListenerMap = {}
@@ -1,32 +1,36 @@
1
- import classNames from "classnames";
2
- import React from "react";
1
+ import classNames from 'classnames'
2
+ import React from 'react'
3
3
 
4
- interface IconButtonProps
5
- extends Omit<
6
- React.ButtonHTMLAttributes<HTMLButtonElement>,
7
- "type" | "children"
8
- > {
9
- label: string;
10
- children: React.ReactNode;
11
- className?: string;
4
+ interface IconButtonProps extends Omit<
5
+ React.ButtonHTMLAttributes<HTMLButtonElement>,
6
+ 'type' | 'children'
7
+ > {
8
+ label: string
9
+ children: React.ReactNode
10
+ className?: string
12
11
  }
13
12
 
14
- export function IconButton({ label, className, children, ...rest }: IconButtonProps) {
13
+ export function IconButton({
14
+ label,
15
+ className,
16
+ children,
17
+ ...rest
18
+ }: IconButtonProps) {
15
19
  return (
16
20
  <button
17
21
  type="button"
18
22
  className={classNames(
19
- "inline-flex items-center justify-center rounded-full transition-colors focus-ring p-2",
23
+ 'inline-flex items-center justify-center rounded-full transition-colors focus-ring p-2',
20
24
  {
21
- "cursor-not-allowed opacity-50": rest.disabled,
22
- "hover:bg-sand": !rest.disabled,
25
+ 'cursor-not-allowed opacity-50': rest.disabled,
26
+ 'hover:bg-sand': !rest.disabled,
23
27
  },
24
- className,
28
+ className
25
29
  )}
26
30
  {...rest}
27
31
  >
28
32
  <span className="sr-only">{label}</span>
29
33
  {children}
30
34
  </button>
31
- );
32
- }
35
+ )
36
+ }
@@ -60,7 +60,10 @@ describe('LinkAttachment.Received (link previews)', () => {
60
60
 
61
61
  it('truncates the description to a single line by default', async () => {
62
62
  renderWithProviders(
63
- <LinkAttachment.Received title="Official" description="A longer body of prose that would wrap onto several lines" />
63
+ <LinkAttachment.Received
64
+ title="Official"
65
+ description="A longer body of prose that would wrap onto several lines"
66
+ />
64
67
  )
65
68
  const description = await screen.findByText(
66
69
  'A longer body of prose that would wrap onto several lines'
@@ -32,7 +32,10 @@ type CtaEmphasis = NonNullable<LinkAttachmentCta['variant']>
32
32
  // component-library preset has no neutral button token (`primary` is brand
33
33
  // purple), and the host preset can't retheme arbitrary hex. Align the grey with
34
34
  // the Arbor secondary token when the shared design tokens land.
35
- const BUTTON_CLASS_BY_VARIANT: Record<LinkAttachmentVariant, Record<CtaEmphasis, string>> = {
35
+ const BUTTON_CLASS_BY_VARIANT: Record<
36
+ LinkAttachmentVariant,
37
+ Record<CtaEmphasis, string>
38
+ > = {
36
39
  dark: {
37
40
  primary: 'bg-white text-[#121110] hover:bg-white/90',
38
41
  secondary: 'bg-white/15 text-white hover:bg-white/25',
@@ -15,11 +15,8 @@ const meta: Meta<ComponentProps> = {
15
15
  export default meta
16
16
 
17
17
  const Template: StoryFn<ComponentProps> = (args) => {
18
- return (
19
- <Loading {...args} className='w-10 h-10' />
20
- )
18
+ return <Loading {...args} className="w-10 h-10" />
21
19
  }
22
20
 
23
21
  export const Default: StoryFn<ComponentProps> = Template.bind({})
24
22
  Default.args = {}
25
-
@@ -169,9 +169,7 @@ export const Attachment: StoryFn = () => (
169
169
  <MediaMessage
170
170
  isMyMessage={false}
171
171
  message={base({
172
- attachments: [
173
- attachment as MessageAttachment,
174
- ],
172
+ attachments: [attachment as MessageAttachment],
175
173
  })}
176
174
  />
177
175
  </td>
@@ -186,9 +184,7 @@ export const Attachment: StoryFn = () => (
186
184
  <MediaMessage
187
185
  isMyMessage={true}
188
186
  message={base({
189
- attachments: [
190
- attachment as MessageAttachment,
191
- ],
187
+ attachments: [attachment as MessageAttachment],
192
188
  })}
193
189
  />
194
190
  </td>
@@ -211,9 +207,7 @@ export const Links: StoryFn = () => (
211
207
  <MediaMessage
212
208
  isMyMessage={false}
213
209
  message={base({
214
- attachments: [
215
- attachment as MessageAttachment,
216
- ],
210
+ attachments: [attachment as MessageAttachment],
217
211
  })}
218
212
  />
219
213
  </td>
@@ -228,9 +222,7 @@ export const Links: StoryFn = () => (
228
222
  <MediaMessage
229
223
  isMyMessage={true}
230
224
  message={base({
231
- attachments: [
232
- attachment as MessageAttachment,
233
- ],
225
+ attachments: [attachment as MessageAttachment],
234
226
  })}
235
227
  />
236
228
  </td>
@@ -253,9 +245,7 @@ export const Compound: StoryFn = () => (
253
245
  <td key={label} className="align-top">
254
246
  <MediaMessage.Visitor
255
247
  message={base({
256
- attachments: [
257
- attachment as MessageAttachment,
258
- ],
248
+ attachments: [attachment as MessageAttachment],
259
249
  })}
260
250
  />
261
251
  </td>
@@ -269,9 +259,7 @@ export const Compound: StoryFn = () => (
269
259
  <td key={label} className="align-top">
270
260
  <MediaMessage.Creator
271
261
  message={base({
272
- attachments: [
273
- attachment as MessageAttachment,
274
- ],
262
+ attachments: [attachment as MessageAttachment],
275
263
  })}
276
264
  />
277
265
  </td>