@linktr.ee/messaging-react 4.4.7 → 4.5.0-rc-1788297811
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/assets/index.css +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +58 -43
- package/dist/index.js +1167 -1033
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/AttachmentCard/MediaPlayer.test.tsx +9 -5
- package/src/components/AttachmentCard/Thumbnail.test.tsx +4 -0
- package/src/components/ChannelActionsMenu/ChannelActionsMenu.test.tsx +18 -10
- package/src/components/ChannelList/ChannelListContext.test.tsx +7 -5
- package/src/components/ChannelList/CustomChannelPreview.test.tsx +7 -5
- package/src/components/ChannelList/index.test.tsx +1 -0
- package/src/components/ChannelView.test.tsx +20 -13
- package/src/components/CustomLinkPreviewList/CustomLinkPreviewList.test.tsx +4 -3
- package/src/components/CustomMessage/CustomMessage.test.tsx +6 -5
- package/src/components/CustomMessage/MessageTag.test.tsx +6 -0
- package/src/components/CustomMessage/SentMessageDeliveryStatus.test.tsx +19 -9
- package/src/components/CustomMessage/StreamAttachmentMessage.test.tsx +45 -5
- package/src/components/CustomMessage/StreamAttachmentMessage.tsx +6 -0
- package/src/components/CustomMessage/TipMessage/TipMessage.test.tsx +3 -0
- package/src/components/CustomMessageInput/CustomMessageInput.test.tsx +16 -7
- package/src/components/FaqList/FaqList.test.tsx +20 -12
- package/src/components/LinkAttachment/LinkAttachment.test.tsx +27 -14
- package/src/components/LinkAttachment/components/_shared/BubbleTail.test.tsx +1 -0
- package/src/components/LinkAttachment/components/_shared/CardBody.test.tsx +6 -6
- package/src/components/LinkAttachment/components/_shared/CardCta.test.tsx +8 -5
- package/src/components/LinkAttachment/components/_shared/CardShell.test.tsx +7 -5
- package/src/components/LinkAttachment/components/_shared/CardThumbnail.test.tsx +3 -8
- package/src/components/MessageAttachment/Audio/AudioAttachment.stories.tsx +165 -58
- package/src/components/MessageAttachment/Audio/WaveformAudioRow.test.tsx +155 -0
- package/src/components/MessageAttachment/Audio/WaveformAudioRow.tsx +455 -0
- package/src/components/MessageAttachment/Audio/audioRowRequester.test.ts +24 -0
- package/src/components/MessageAttachment/Audio/audioRowRequester.ts +16 -0
- package/src/components/MessageAttachment/Audio/index.tsx +83 -79
- package/src/components/MessageAttachment/MessageAttachment.behavior.test.tsx +22 -15
- package/src/components/MessageAttachment/MessageAttachment.test.tsx +279 -134
- package/src/components/MessageAttachment/_shared/Bubble.test.tsx +2 -0
- package/src/components/MessageAttachment/_shared/CarouselNav.test.tsx +5 -4
- package/src/components/MessageAttachment/_shared/CompactDocumentRow.test.tsx +4 -3
- package/src/components/MessageAttachment/_shared/DismissButton.test.tsx +4 -3
- package/src/components/MessageAttachment/_shared/DownloadAction.test.tsx +8 -5
- package/src/components/MessageAttachment/_shared/ImageViewer.test.tsx +6 -3
- package/src/components/MessageAttachment/_shared/MediaStackGrid.test.tsx +11 -4
- package/src/components/MessageAttachment/_shared/PdfViewer.test.tsx +5 -3
- package/src/components/MessageAttachment/_shared/VideoViewer.test.tsx +12 -3
- package/src/components/MessageAttachment/_shared/ViewerShell.test.tsx +13 -6
- package/src/components/MessageAttachment/_shared/useCarousel.test.tsx +10 -4
- package/src/components/MessageAttachment/_shared/useIsClient.ts +23 -0
- package/src/components/MessageAttachment/index.tsx +25 -9
- package/src/components/MessageAttachment/types.ts +19 -9
- package/src/components/MessageBubble/MessageBubble.test.tsx +8 -0
- package/src/components/RichCard/RichCard.test.tsx +10 -2
- package/src/styles.css +120 -0
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { describe, expect, it, vi } from 'vitest'
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
userEvent,
|
|
6
|
+
renderWithProviders,
|
|
7
|
+
screen,
|
|
8
|
+
fireEvent,
|
|
9
|
+
} from '../../test/utils'
|
|
5
10
|
|
|
6
11
|
import RichCard from '.'
|
|
7
12
|
|
|
@@ -41,6 +46,7 @@ describe('RichCard', () => {
|
|
|
41
46
|
expect(card).toHaveTextContent('👋 Say hello as people arrive')
|
|
42
47
|
expect(card).toHaveTextContent('✨ Spark conversations')
|
|
43
48
|
expect(card).toHaveTextContent('💬 Add automated FAQs')
|
|
49
|
+
// eslint-disable-next-line testing-library/no-node-access -- media or rendered-markup internals have no user-facing query.
|
|
44
50
|
expect(card.querySelectorAll('br')).toHaveLength(2)
|
|
45
51
|
})
|
|
46
52
|
|
|
@@ -57,6 +63,7 @@ describe('RichCard', () => {
|
|
|
57
63
|
)
|
|
58
64
|
|
|
59
65
|
const card = await screen.findByTestId('rich-card')
|
|
66
|
+
// eslint-disable-next-line testing-library/no-node-access -- media or rendered-markup internals have no user-facing query.
|
|
60
67
|
expect(card.querySelectorAll('br')).toHaveLength(0)
|
|
61
68
|
expect(screen.getByText(/Say hello as people arrive/)).toHaveClass(
|
|
62
69
|
'truncate'
|
|
@@ -197,6 +204,7 @@ describe('RichCard', () => {
|
|
|
197
204
|
})
|
|
198
205
|
|
|
199
206
|
it('renders a url action as an external anchor, others as buttons', async () => {
|
|
207
|
+
const user = userEvent.setup()
|
|
200
208
|
const onClick = vi.fn()
|
|
201
209
|
renderWithProviders(
|
|
202
210
|
<RichCard.Received
|
|
@@ -212,7 +220,7 @@ describe('RichCard', () => {
|
|
|
212
220
|
expect(link).toHaveAttribute('href', 'https://tr.ee/x')
|
|
213
221
|
expect(link).toHaveAttribute('target', '_blank')
|
|
214
222
|
|
|
215
|
-
|
|
223
|
+
await user.click(screen.getByRole('button', { name: 'Set up' }))
|
|
216
224
|
expect(onClick).toHaveBeenCalledTimes(1)
|
|
217
225
|
})
|
|
218
226
|
|
package/src/styles.css
CHANGED
|
@@ -908,3 +908,123 @@
|
|
|
908
908
|
.message-locked-attachment-text .str-chat__message-text-inner {
|
|
909
909
|
color: inherit;
|
|
910
910
|
}
|
|
911
|
+
|
|
912
|
+
/* Audio attachment waveform — `MessageAttachment.Audio` (MES-1360).
|
|
913
|
+
|
|
914
|
+
Plain CSS rather than Tailwind utilities for two reasons: the per-bar
|
|
915
|
+
height is a floored custom property that has to be authored once
|
|
916
|
+
rather than repeated on 35 elements, and the played / unplayed fills
|
|
917
|
+
are the one design decision Figma left open (it draws the idle state
|
|
918
|
+
only), so keeping them in a single place is what makes them reviewable.
|
|
919
|
+
Follows the existing `.mes-media-viewer*` / `.mes-dialog` convention:
|
|
920
|
+
the package's shipped stylesheet is enough, with no Tailwind
|
|
921
|
+
dependency in the consumer.
|
|
922
|
+
|
|
923
|
+
Geometry is Figma `2754:17710` → `sound-wave` (`…;2754:8065`): a
|
|
924
|
+
138×30 track holding 35 bars at 2px with 2px gaps
|
|
925
|
+
(35 x 2 + 34 x 2 = 138). Bars flex from a zero basis, so the exact
|
|
926
|
+
2px falls out of the 138px track and a narrower container degrades
|
|
927
|
+
proportionally instead of clipping. */
|
|
928
|
+
.mes-audio-wave {
|
|
929
|
+
position: relative;
|
|
930
|
+
display: flex;
|
|
931
|
+
flex: 1 1 0;
|
|
932
|
+
min-width: 0;
|
|
933
|
+
align-items: center;
|
|
934
|
+
height: 30px;
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
.mes-audio-wave__track {
|
|
938
|
+
display: flex;
|
|
939
|
+
width: 100%;
|
|
940
|
+
height: 100%;
|
|
941
|
+
align-items: center;
|
|
942
|
+
gap: 2px;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
/* Figma's bars run 4px..30px on a 30px track, so the amplitude
|
|
946
|
+
percentage is floored at that 4px minimum: a silent sample — or the
|
|
947
|
+
all-zero fallback used when no waveform could be produced — still
|
|
948
|
+
draws the shortest bar the design already contains, keeping the
|
|
949
|
+
card's silhouette identical instead of collapsing it. */
|
|
950
|
+
.mes-audio-wave__bar {
|
|
951
|
+
flex: 1 1 0;
|
|
952
|
+
min-width: 0;
|
|
953
|
+
height: max(4px, var(--mes-audio-wave-bar, 0%));
|
|
954
|
+
border-radius: 9999px;
|
|
955
|
+
background: rgb(255 255 255 / 0.4);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
.mes-audio-wave__bar--played {
|
|
959
|
+
background: #ffffff;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
.mes-audio-wave--light .mes-audio-wave__bar {
|
|
963
|
+
background: rgb(4 4 3 / 0.5);
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
.mes-audio-wave--light .mes-audio-wave__bar--played {
|
|
967
|
+
background: #040403;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/* Seek is a real `<input type="range">` stretched over the bars, which
|
|
971
|
+
supplies click, drag, arrow keys, Home / End and a screen-reader
|
|
972
|
+
slider role natively. The bars are the visible track, so the input
|
|
973
|
+
itself must not paint — but it must stay focusable, which is why the
|
|
974
|
+
thumb and track are cleared individually rather than the whole input
|
|
975
|
+
being given `opacity: 0`. */
|
|
976
|
+
.mes-audio-wave__seek {
|
|
977
|
+
position: absolute;
|
|
978
|
+
inset: 0;
|
|
979
|
+
width: 100%;
|
|
980
|
+
height: 100%;
|
|
981
|
+
margin: 0;
|
|
982
|
+
padding: 0;
|
|
983
|
+
cursor: pointer;
|
|
984
|
+
background: transparent;
|
|
985
|
+
-webkit-appearance: none;
|
|
986
|
+
appearance: none;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
.mes-audio-wave__seek:disabled {
|
|
990
|
+
cursor: default;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
.mes-audio-wave__seek::-webkit-slider-runnable-track {
|
|
994
|
+
background: transparent;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
.mes-audio-wave__seek::-webkit-slider-thumb {
|
|
998
|
+
-webkit-appearance: none;
|
|
999
|
+
appearance: none;
|
|
1000
|
+
width: 1px;
|
|
1001
|
+
height: 100%;
|
|
1002
|
+
opacity: 0;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
.mes-audio-wave__seek::-moz-range-track {
|
|
1006
|
+
background: transparent;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
.mes-audio-wave__seek::-moz-range-thumb {
|
|
1010
|
+
width: 1px;
|
|
1011
|
+
height: 100%;
|
|
1012
|
+
border: 0;
|
|
1013
|
+
opacity: 0;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
.mes-audio-wave__seek:focus {
|
|
1017
|
+
outline: none;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
/* The input is transparent, so the focus ring has to render on the
|
|
1021
|
+
wrapper that actually has pixels. */
|
|
1022
|
+
.mes-audio-wave:has(.mes-audio-wave__seek:focus-visible) {
|
|
1023
|
+
outline: 2px solid rgb(255 255 255 / 0.6);
|
|
1024
|
+
outline-offset: 4px;
|
|
1025
|
+
border-radius: 4px;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
.mes-audio-wave--light:has(.mes-audio-wave__seek:focus-visible) {
|
|
1029
|
+
outline-color: rgb(4 4 3 / 0.6);
|
|
1030
|
+
}
|