@linktr.ee/messaging-react 1.39.0 → 1.40.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.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { b as a, c as t, C as i, d as n, e as o, f as g, F as r, g as M, L as m, M as l, h as u, i as h, j as d, k as v, r as C, l as L, u as c, m as A, n as F } from "./index-j4j9UfK1.js";
1
+ import { b as a, c as t, C as i, d as n, e as o, f as g, F as r, g as M, L as m, M as l, h as u, i as h, j as d, k as v, r as C, l as L, u as c, m as A, n as F } from "./index-8ZuHtwFb.js";
2
2
  export {
3
3
  a 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": "1.39.0",
3
+ "version": "1.40.1",
4
4
  "description": "React messaging components built on messaging-core for web applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -54,7 +54,7 @@ export const Avatar = ({
54
54
  <img
55
55
  src={image}
56
56
  alt=""
57
- className="aspect-square h-full w-full object-cover"
57
+ className="h-full w-full object-cover"
58
58
  />
59
59
  ) : (
60
60
  <div
@@ -77,9 +77,10 @@ export const Avatar = ({
77
77
  className
78
78
  )}
79
79
  style={{
80
+ '--str-chat__avatar-size': `${size}px`,
80
81
  width: `${size}px`,
81
82
  height: `${size}px`,
82
- }}
83
+ } as React.CSSProperties}
83
84
  >
84
85
  {starred && (
85
86
  <div
@@ -0,0 +1,86 @@
1
+ import type { Meta, StoryFn } from '@storybook/react'
2
+ import React, { useState } from 'react'
3
+
4
+ import type { VoteSelection } from '../../hooks/useMessageVote'
5
+
6
+ import { MessageVoteButtons } from './MessageVoteButtons'
7
+
8
+ type ComponentProps = React.ComponentProps<typeof MessageVoteButtons>
9
+
10
+ const meta: Meta<ComponentProps> = {
11
+ title: 'MessageVoteButtons',
12
+ component: MessageVoteButtons,
13
+ parameters: {
14
+ layout: 'centered',
15
+ },
16
+ }
17
+ export default meta
18
+
19
+ const Template: StoryFn<ComponentProps> = (args) => (
20
+ <div className="p-12">
21
+ <MessageVoteButtons {...args} />
22
+ </div>
23
+ )
24
+
25
+ export const Unselected: StoryFn<ComponentProps> = Template.bind({})
26
+ Unselected.args = {
27
+ selected: null,
28
+ onVoteUp: () => {},
29
+ onVoteDown: () => {},
30
+ }
31
+
32
+ export const GoodResponse: StoryFn<ComponentProps> = Template.bind({})
33
+ GoodResponse.args = {
34
+ selected: 'up',
35
+ onVoteUp: () => {},
36
+ onVoteDown: () => {},
37
+ }
38
+
39
+ export const BadResponse: StoryFn<ComponentProps> = Template.bind({})
40
+ BadResponse.args = {
41
+ selected: 'down',
42
+ onVoteUp: () => {},
43
+ onVoteDown: () => {},
44
+ }
45
+
46
+ export const Interactive: StoryFn = () => {
47
+ const [selected, setSelected] = useState<VoteSelection>(null)
48
+ return (
49
+ <div className="p-12">
50
+ <MessageVoteButtons
51
+ selected={selected}
52
+ onVoteUp={() => setSelected(selected === 'up' ? null : 'up')}
53
+ onVoteDown={() => setSelected(selected === 'down' ? null : 'down')}
54
+ />
55
+ </div>
56
+ )
57
+ }
58
+
59
+ export const AllVariants: StoryFn = () => (
60
+ <div className="p-12 flex flex-col gap-6">
61
+ <div className="flex items-center gap-4">
62
+ <span className="text-sm w-32">Unselected:</span>
63
+ <MessageVoteButtons
64
+ selected={null}
65
+ onVoteUp={() => {}}
66
+ onVoteDown={() => {}}
67
+ />
68
+ </div>
69
+ <div className="flex items-center gap-4">
70
+ <span className="text-sm w-32">Good response:</span>
71
+ <MessageVoteButtons
72
+ selected="up"
73
+ onVoteUp={() => {}}
74
+ onVoteDown={() => {}}
75
+ />
76
+ </div>
77
+ <div className="flex items-center gap-4">
78
+ <span className="text-sm w-32">Bad response:</span>
79
+ <MessageVoteButtons
80
+ selected="down"
81
+ onVoteUp={() => {}}
82
+ onVoteDown={() => {}}
83
+ />
84
+ </div>
85
+ </div>
86
+ )
@@ -1,3 +1,5 @@
1
+ import { ThumbsUpIcon, ThumbsDownIcon } from '@phosphor-icons/react'
2
+ import classNames from 'classnames'
1
3
  import React from 'react'
2
4
 
3
5
  import type { VoteSelection } from '../../hooks/useMessageVote'
@@ -8,32 +10,6 @@ interface MessageVoteButtonsProps {
8
10
  onVoteDown: () => void
9
11
  }
10
12
 
11
- const ThumbUpIcon: React.FC<{ filled: boolean }> = ({ filled }) => (
12
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
13
- <path
14
- d="M4.667 7.333l2.666-6A1.333 1.333 0 018.667 2v2.667a.667.667 0 00.666.666h3.764a1.334 1.334 0 011.192 1.93l-2.333 4.666a1.333 1.333 0 01-1.193.738H4.667m0-5.334v5.334m0-5.334H2.667a1.333 1.333 0 00-1.334 1.334v2.666a1.333 1.333 0 001.334 1.334h2"
15
- stroke="currentColor"
16
- strokeWidth="1.33"
17
- strokeLinecap="round"
18
- strokeLinejoin="round"
19
- fill={filled ? 'currentColor' : 'none'}
20
- />
21
- </svg>
22
- )
23
-
24
- const ThumbDownIcon: React.FC<{ filled: boolean }> = ({ filled }) => (
25
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
26
- <path
27
- d="M11.333 8.667l-2.666 6A1.333 1.333 0 017.333 14v-2.667a.667.667 0 00-.666-.666H2.903a1.334 1.334 0 01-1.192-1.93l2.333-4.666a1.333 1.333 0 011.193-.738h6.096m0 5.334V3.333m0 5.334h2a1.333 1.333 0 001.334-1.334V4.667a1.333 1.333 0 00-1.334-1.334h-2"
28
- stroke="currentColor"
29
- strokeWidth="1.33"
30
- strokeLinecap="round"
31
- strokeLinejoin="round"
32
- fill={filled ? 'currentColor' : 'none'}
33
- />
34
- </svg>
35
- )
36
-
37
13
  export const MessageVoteButtons: React.FC<MessageVoteButtonsProps> = ({
38
14
  selected,
39
15
  onVoteUp,
@@ -42,21 +18,27 @@ export const MessageVoteButtons: React.FC<MessageVoteButtonsProps> = ({
42
18
  <div className="message-vote-buttons">
43
19
  <button
44
20
  type="button"
45
- className={`message-vote-button${selected === 'up' ? ' message-vote-button--selected' : ''} focus-ring`}
21
+ className={classNames('message-vote-button focus-ring', {
22
+ 'message-vote-button--selected': selected === 'up',
23
+ })}
46
24
  onClick={onVoteUp}
47
- aria-label="Helpful"
25
+ aria-label="Good response"
48
26
  aria-pressed={selected === 'up'}
27
+ data-tooltip="Good response"
49
28
  >
50
- <ThumbUpIcon filled={selected === 'up'} />
29
+ <ThumbsUpIcon size={16} weight={selected === 'up' ? 'fill' : 'regular'} />
51
30
  </button>
52
31
  <button
53
32
  type="button"
54
- className={`message-vote-button${selected === 'down' ? ' message-vote-button--selected' : ''} focus-ring`}
33
+ className={classNames('message-vote-button focus-ring', {
34
+ 'message-vote-button--selected': selected === 'down',
35
+ })}
55
36
  onClick={onVoteDown}
56
- aria-label="Not helpful"
37
+ aria-label="Bad response"
57
38
  aria-pressed={selected === 'down'}
39
+ data-tooltip="Bad response"
58
40
  >
59
- <ThumbDownIcon filled={selected === 'down'} />
41
+ <ThumbsDownIcon size={16} weight={selected === 'down' ? 'fill' : 'regular'} />
60
42
  </button>
61
43
  </div>
62
44
  )
@@ -188,6 +188,9 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
188
188
  id={message.user.id}
189
189
  image={message.user.image}
190
190
  name={message.user.name || message.user.id}
191
+ size={isChatbot ? 24 : 28}
192
+ shape="circle"
193
+ dmAgentEnabled={isChatbot}
191
194
  />
192
195
  )}
193
196
  {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
package/src/styles.css CHANGED
@@ -169,7 +169,7 @@
169
169
 
170
170
  .str-chat__li .str-chat__message--other {
171
171
  position: relative;
172
- grid-template-columns: 40px 1fr;
172
+ grid-template-columns: 28px 1fr;
173
173
  }
174
174
 
175
175
  .str-chat__li .str-chat__message--other .str-chat__message-bubble-wrapper {
@@ -280,6 +280,7 @@
280
280
  }
281
281
 
282
282
  .message-vote-button {
283
+ position: relative;
283
284
  display: flex;
284
285
  align-items: center;
285
286
  justify-content: center;
@@ -289,7 +290,7 @@
289
290
  border: none;
290
291
  border-radius: 50%;
291
292
  background-color: transparent;
292
- color: rgba(0, 0, 0, 0.35);
293
+ color: #737373;
293
294
  cursor: pointer;
294
295
  transition:
295
296
  background-color 0.15s,
@@ -297,16 +298,91 @@
297
298
  }
298
299
 
299
300
  .message-vote-button:hover {
300
- background-color: rgba(0, 0, 0, 0.06);
301
- color: rgba(0, 0, 0, 0.55);
301
+ background-color: rgba(0, 0, 0, 0.05);
302
+ color: #737373;
302
303
  }
303
304
 
304
- .message-vote-button--selected {
305
- color: rgba(0, 0, 0, 0.7);
305
+ .message-vote-button[data-tooltip]::after {
306
+ content: attr(data-tooltip);
307
+ position: absolute;
308
+ bottom: calc(100% + 6px);
309
+ left: 50%;
310
+ transform: translateX(-50%);
311
+ background-color: rgba(0, 0, 0, 0.85);
312
+ color: #fff;
313
+ font-size: 12px;
314
+ line-height: 1;
315
+ padding: 4px 8px;
316
+ border-radius: 4px;
317
+ white-space: nowrap;
318
+ pointer-events: none;
319
+ opacity: 0;
320
+ transition: opacity 0.15s 0s;
306
321
  }
307
322
 
308
- .message-vote-button--selected:hover {
309
- color: rgba(0, 0, 0, 0.7);
323
+ .message-vote-button[data-tooltip]:hover::after,
324
+ .message-vote-button[data-tooltip]:focus-visible::after {
325
+ opacity: 1;
326
+ transition-delay: 300ms;
327
+ }
328
+
329
+ /* Chatbot reply markdown — restore semantics that consumer Tailwind preflight
330
+ (or other resets) strip from the body of `.str-chat__message-text-inner`. */
331
+ .str-chat__message-text-inner :where(h1, h2, h3, h4, h5, h6) {
332
+ font-weight: 600;
333
+ margin: 0.5rem 0 0.25rem;
334
+ line-height: 1.3;
335
+ text-wrap: balance;
336
+ }
337
+ .str-chat__message-text-inner h1 {
338
+ font-size: 1.5rem;
339
+ }
340
+ .str-chat__message-text-inner h2 {
341
+ font-size: 1.25rem;
342
+ }
343
+ .str-chat__message-text-inner h3 {
344
+ font-size: 1.0625rem;
345
+ }
346
+ .str-chat__message-text-inner :where(h1, h2, h3, h4, h5, h6):first-child {
347
+ margin-top: 0;
348
+ }
349
+
350
+ .str-chat__message-text-inner ul {
351
+ list-style-type: disc;
352
+ padding-inline-start: 1.25rem;
353
+ margin: 0.25rem 0;
354
+ }
355
+ .str-chat__message-text-inner ol {
356
+ list-style-type: decimal;
357
+ padding-inline-start: 1.25rem;
358
+ margin: 0.25rem 0;
359
+ }
360
+ .str-chat__message-text-inner li {
361
+ display: list-item;
362
+ margin: 0.125rem 0;
363
+ }
364
+ .str-chat__message-text-inner ul ul,
365
+ .str-chat__message-text-inner ol ol,
366
+ .str-chat__message-text-inner ul ol,
367
+ .str-chat__message-text-inner ol ul {
368
+ margin: 0;
369
+ }
370
+
371
+ .str-chat__message-text-inner a {
372
+ text-decoration: underline;
373
+ text-underline-offset: 0.15em;
374
+ word-break: break-word;
375
+ }
376
+
377
+ .str-chat__message-text-inner p {
378
+ margin: 0.25rem 0;
379
+ text-wrap: pretty;
380
+ }
381
+ .str-chat__message-text-inner > :first-child {
382
+ margin-top: 0;
383
+ }
384
+ .str-chat__message-text-inner > :last-child {
385
+ margin-bottom: 0;
310
386
  }
311
387
 
312
388
  /* Standalone tip message (tip without text) */