@happyvertical/smrt-chat 0.34.4 → 0.34.6

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 (41) hide show
  1. package/dist/manifest.json +2 -2
  2. package/dist/smrt-knowledge.json +4 -4
  3. package/dist/svelte/components/agent/AgentChat.svelte +23 -26
  4. package/dist/svelte/components/agent/AgentChat.svelte.d.ts.map +1 -1
  5. package/dist/svelte/components/agent/AgentSelector.svelte +1 -0
  6. package/dist/svelte/components/agent/AgentSelector.svelte.d.ts.map +1 -1
  7. package/dist/svelte/components/agent/AgentSessionPanel.svelte +15 -16
  8. package/dist/svelte/components/agent/AgentSessionPanel.svelte.d.ts.map +1 -1
  9. package/dist/svelte/components/agent/ToolCallDisplay.svelte +1 -0
  10. package/dist/svelte/components/agent/ToolCallDisplay.svelte.d.ts.map +1 -1
  11. package/dist/svelte/components/dialogs/RoomCreateDialog.svelte +9 -44
  12. package/dist/svelte/components/dialogs/RoomCreateDialog.svelte.d.ts.map +1 -1
  13. package/dist/svelte/components/dialogs/SearchMessages.svelte +23 -24
  14. package/dist/svelte/components/dialogs/SearchMessages.svelte.d.ts.map +1 -1
  15. package/dist/svelte/components/layout/ChatLayout.svelte +1 -0
  16. package/dist/svelte/components/layout/ChatLayout.svelte.d.ts.map +1 -1
  17. package/dist/svelte/components/layout/MemberList.svelte +10 -15
  18. package/dist/svelte/components/layout/MemberList.svelte.d.ts.map +1 -1
  19. package/dist/svelte/components/layout/RoomHeader.svelte +13 -16
  20. package/dist/svelte/components/layout/RoomHeader.svelte.d.ts.map +1 -1
  21. package/dist/svelte/components/layout/RoomList.svelte +26 -17
  22. package/dist/svelte/components/layout/RoomList.svelte.d.ts.map +1 -1
  23. package/dist/svelte/components/messages/MessageInput.svelte +17 -20
  24. package/dist/svelte/components/messages/MessageInput.svelte.d.ts.map +1 -1
  25. package/dist/svelte/components/messages/MessageItem.svelte +45 -40
  26. package/dist/svelte/components/messages/MessageItem.svelte.d.ts.map +1 -1
  27. package/dist/svelte/components/messages/ThreadPanel.svelte +9 -9
  28. package/dist/svelte/components/messages/ThreadPanel.svelte.d.ts.map +1 -1
  29. package/dist/svelte/components/shared/FileUpload.svelte +22 -54
  30. package/dist/svelte/components/shared/FileUpload.svelte.d.ts.map +1 -1
  31. package/dist/svelte/components/shared/MentionAutocomplete.svelte +1 -0
  32. package/dist/svelte/components/shared/MentionAutocomplete.svelte.d.ts.map +1 -1
  33. package/dist/svelte/components/shared/ReactionPicker.svelte +8 -21
  34. package/dist/svelte/components/shared/ReactionPicker.svelte.d.ts.map +1 -1
  35. package/dist/svelte/components/tabs/ChatTab.svelte +20 -18
  36. package/dist/svelte/components/tabs/ChatTab.svelte.d.ts.map +1 -1
  37. package/dist/svelte/components/tabs/ChatTabList.svelte +13 -10
  38. package/dist/svelte/components/tabs/ChatTabList.svelte.d.ts.map +1 -1
  39. package/dist/svelte/components/tabs/MiniChat.svelte +11 -17
  40. package/dist/svelte/components/tabs/MiniChat.svelte.d.ts.map +1 -1
  41. package/package.json +9 -8
@@ -4,6 +4,7 @@
4
4
  * Displays room info and provides access to members and search
5
5
  */
6
6
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
7
+ import { Button } from '@happyvertical/smrt-ui/ui';
7
8
  import { M } from '../../i18n.messages.js';
8
9
  import type { ChatRoomData } from '../../types.js';
9
10
 
@@ -78,7 +79,9 @@ const roomTypeLabel = $derived.by(() => {
78
79
 
79
80
  <div class="room-header__actions">
80
81
  {#if onshowmembers}
81
- <button
82
+ <Button
83
+ variant="ghost"
84
+ size="sm"
82
85
  class="header-btn"
83
86
  type="button"
84
87
  onclick={onshowmembers}
@@ -92,11 +95,13 @@ const roomTypeLabel = $derived.by(() => {
92
95
  <path d="M16 3.13a4 4 0 0 1 0 7.75" />
93
96
  </svg>
94
97
  <span class="header-btn__count">{participantCount}</span>
95
- </button>
98
+ </Button>
96
99
  {/if}
97
100
 
98
101
  {#if onshowsearch}
99
- <button
102
+ <Button
103
+ variant="ghost"
104
+ size="sm"
100
105
  class="header-btn"
101
106
  type="button"
102
107
  onclick={onshowsearch}
@@ -107,7 +112,7 @@ const roomTypeLabel = $derived.by(() => {
107
112
  <circle cx="11" cy="11" r="8" />
108
113
  <path d="m21 21-4.35-4.35" />
109
114
  </svg>
110
- </button>
115
+ </Button>
111
116
  {/if}
112
117
  </div>
113
118
  </header>
@@ -201,28 +206,20 @@ const roomTypeLabel = $derived.by(() => {
201
206
  gap: 0.25rem;
202
207
  }
203
208
 
204
- .header-btn {
205
- display: inline-flex;
206
- align-items: center;
209
+ /* :global() pierces into each Button's rendered <button> (see #1589). */
210
+ .room-header__actions :global(.header-btn) {
207
211
  gap: 0.25rem;
208
212
  padding: 0.375rem 0.5rem;
209
- border: none;
210
213
  background: none;
211
214
  border-radius: var(--smrt-radius-medium, 0.5rem);
212
215
  color: var(--smrt-color-on-surface-variant, #43474e);
213
- cursor: pointer;
214
216
  transition: background var(--smrt-duration-short2, 150ms);
215
217
  }
216
218
 
217
- .header-btn:hover {
219
+ .room-header__actions :global(.header-btn:hover) {
218
220
  background: var(--smrt-color-surface-variant, #e1e2ec);
219
221
  }
220
222
 
221
- .header-btn:focus-visible {
222
- outline: 2px solid var(--smrt-color-primary, #005ac1);
223
- outline-offset: -2px;
224
- }
225
-
226
223
  .header-btn__icon {
227
224
  width: 1.25rem;
228
225
  height: 1.25rem;
@@ -234,7 +231,7 @@ const roomTypeLabel = $derived.by(() => {
234
231
  }
235
232
 
236
233
  @media (prefers-reduced-motion: reduce) {
237
- .header-btn {
234
+ .room-header__actions :global(.header-btn) {
238
235
  transition: none;
239
236
  }
240
237
  }
@@ -1 +1 @@
1
- {"version":3,"file":"RoomHeader.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/layout/RoomHeader.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD,MAAM,WAAW,KAAK;IACpB,wBAAwB;IACxB,IAAI,EAAE,YAAY,CAAC;IACnB,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AA8FD,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"RoomHeader.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/layout/RoomHeader.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD,MAAM,WAAW,KAAK;IACpB,wBAAwB;IACxB,IAAI,EAAE,YAAY,CAAC;IACnB,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AA+FD,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -4,6 +4,7 @@
4
4
  * Groups rooms by type: channels, DMs, and agent conversations
5
5
  */
6
6
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
7
+ import { Button } from '@happyvertical/smrt-ui/ui';
7
8
  import { M } from '../../i18n.messages.js';
8
9
  import type { ChatRoomData } from '../../types.js';
9
10
 
@@ -71,19 +72,22 @@ function formatTimestamp(date?: string | Date | null): string {
71
72
  <nav class="room-list" aria-label={t(M['chat.room_list.rooms_label'])}>
72
73
  {#if oncreateroom}
73
74
  <div class="room-list__header">
74
- <button
75
+ <Button
76
+ variant="ghost"
77
+ fullWidth
75
78
  class="create-room-btn"
76
79
  type="button"
77
80
  onclick={oncreateroom}
78
81
  aria-label={t(M['chat.room_list.create_new_room'])}
79
82
  >
80
83
  {t(M['chat.room_list.new_room'])}
81
- </button>
84
+ </Button>
82
85
  </div>
83
86
  {/if}
84
87
 
85
88
  {#if channels.length > 0}
86
89
  <section class="room-group">
90
+ <!-- raw-primitive-allow: section disclosure trigger with aria-expanded toggling a collapsible room list, wrapping rich content (rotating chevron, group label, room count); structural accordion header no Button primitive owns -->
87
91
  <button
88
92
  class="room-group__header"
89
93
  type="button"
@@ -101,6 +105,7 @@ function formatTimestamp(date?: string | Date | null): string {
101
105
  <ul class="room-group__list" role="list">
102
106
  {#each channels as room (room.id)}
103
107
  <li>
108
+ <!-- raw-primitive-allow: pressable room-selection row with active and aria-current state, wrapping rich content (type icon, name, unread badge); no Button primitive owns this structural nav-selection pattern -->
104
109
  <button
105
110
  class="room-item"
106
111
  class:room-item--active={room.id === currentRoomId}
@@ -126,6 +131,7 @@ function formatTimestamp(date?: string | Date | null): string {
126
131
 
127
132
  {#if directMessages.length > 0}
128
133
  <section class="room-group">
134
+ <!-- raw-primitive-allow: section disclosure trigger with aria-expanded toggling a collapsible room list, wrapping rich content (rotating chevron, group label, room count); structural accordion header no Button primitive owns -->
129
135
  <button
130
136
  class="room-group__header"
131
137
  type="button"
@@ -143,6 +149,7 @@ function formatTimestamp(date?: string | Date | null): string {
143
149
  <ul class="room-group__list" role="list">
144
150
  {#each directMessages as room (room.id)}
145
151
  <li>
152
+ <!-- raw-primitive-allow: pressable room-selection row with active and aria-current state, wrapping rich content (avatar, name, last-message preview, timestamp, unread badge); no Button primitive owns this structural nav-selection pattern -->
146
153
  <button
147
154
  class="room-item"
148
155
  class:room-item--active={room.id === currentRoomId}
@@ -184,6 +191,7 @@ function formatTimestamp(date?: string | Date | null): string {
184
191
 
185
192
  {#if agentRooms.length > 0}
186
193
  <section class="room-group">
194
+ <!-- raw-primitive-allow: section disclosure trigger with aria-expanded toggling a collapsible room list, wrapping rich content (rotating chevron, group label, room count); structural accordion header no Button primitive owns -->
187
195
  <button
188
196
  class="room-group__header"
189
197
  type="button"
@@ -201,6 +209,7 @@ function formatTimestamp(date?: string | Date | null): string {
201
209
  <ul class="room-group__list" role="list">
202
210
  {#each agentRooms as room (room.id)}
203
211
  <li>
212
+ <!-- raw-primitive-allow: pressable room-selection row with active and aria-current state, wrapping rich content (agent icon, name, unread badge); no Button primitive owns this structural nav-selection pattern -->
204
213
  <button
205
214
  class="room-item"
206
215
  class:room-item--active={room.id === currentRoomId}
@@ -227,9 +236,9 @@ function formatTimestamp(date?: string | Date | null): string {
227
236
  <div class="room-list__empty">
228
237
  <p>{t(M['chat.room_list.no_rooms'])}</p>
229
238
  {#if oncreateroom}
230
- <button class="create-link" type="button" onclick={oncreateroom}>
239
+ <Button variant="ghost" size="sm" class="create-link" type="button" onclick={oncreateroom}>
231
240
  {t(M['chat.room_list.create_first_room'])}
232
- </button>
241
+ </Button>
233
242
  {/if}
234
243
  </div>
235
244
  {/if}
@@ -247,27 +256,21 @@ function formatTimestamp(date?: string | Date | null): string {
247
256
  padding: 0.5rem 0.75rem;
248
257
  }
249
258
 
250
- .create-room-btn {
251
- width: 100%;
259
+ /* :global() pierces into the Button child's rendered <button> (see #1589). */
260
+ .room-list__header :global(.create-room-btn) {
252
261
  padding: 0.5rem 0.75rem;
253
262
  border: 1px dashed var(--smrt-color-outline, #74777f);
254
263
  border-radius: var(--smrt-radius-medium, 0.5rem);
255
264
  background: transparent;
256
265
  color: var(--smrt-color-primary, #005ac1);
257
266
  font: var(--smrt-typography-label-large-font, 500 0.875rem / 1.25 sans-serif);
258
- cursor: pointer;
259
267
  transition: background var(--smrt-duration-short2, 150ms);
260
268
  }
261
269
 
262
- .create-room-btn:hover {
270
+ .room-list__header :global(.create-room-btn:hover) {
263
271
  background: var(--smrt-color-primary-container, #d6e3ff);
264
272
  }
265
273
 
266
- .create-room-btn:focus-visible {
267
- outline: 2px solid var(--smrt-color-primary, #005ac1);
268
- outline-offset: -2px;
269
- }
270
-
271
274
  .room-group {
272
275
  margin-top: 0.25rem;
273
276
  }
@@ -452,20 +455,26 @@ function formatTimestamp(date?: string | Date | null): string {
452
455
  font: var(--smrt-typography-body-medium-font, 0.875rem / 1.25 sans-serif);
453
456
  }
454
457
 
455
- .create-link {
456
- border: none;
458
+ /* :global() pierces into the Button child's rendered <button> (see #1589). */
459
+ .room-list__empty :global(.create-link) {
457
460
  background: none;
458
461
  color: var(--smrt-color-primary, #005ac1);
459
462
  font: var(--smrt-typography-label-large-font, 500 0.875rem / 1.25 sans-serif);
460
- cursor: pointer;
461
463
  text-decoration: underline;
462
464
  }
463
465
 
466
+ .room-list__empty :global(.create-link:hover) {
467
+ background: none;
468
+ }
469
+
464
470
  @media (prefers-reduced-motion: reduce) {
465
471
  .room-item,
466
- .create-room-btn,
467
472
  .room-group__chevron {
468
473
  transition: none;
469
474
  }
475
+
476
+ .room-list__header :global(.create-room-btn) {
477
+ transition: none;
478
+ }
470
479
  }
471
480
  </style>
@@ -1 +1 @@
1
- {"version":3,"file":"RoomList.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/layout/RoomList.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD,MAAM,WAAW,KAAK;IACpB,2BAA2B;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,iCAAiC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AA6LD,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"RoomList.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/layout/RoomList.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD,MAAM,WAAW,KAAK;IACpB,2BAA2B;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,iCAAiC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAoMD,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
@@ -4,6 +4,7 @@
4
4
  * Text area with send button. Shows reply preview when replying.
5
5
  */
6
6
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
7
+ import { Button } from '@happyvertical/smrt-ui/ui';
7
8
  import { M } from '../../i18n.messages.js';
8
9
 
9
10
  const { t } = useI18n();
@@ -64,14 +65,16 @@ function handleInput() {
64
65
  <span class="message-input__reply-text">{replyTo.content}</span>
65
66
  </div>
66
67
  {#if oncancelreply}
67
- <button
68
+ <Button
69
+ variant="ghost"
70
+ size="sm"
68
71
  class="message-input__reply-close"
69
72
  type="button"
70
73
  onclick={oncancelreply}
71
74
  aria-label={t(M['chat.message_input.cancel_reply'])}
72
75
  >
73
76
  <svg viewBox="0 0 16 16" width="14" height="14"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" /></svg>
74
- </button>
77
+ </Button>
75
78
  {/if}
76
79
  </div>
77
80
  {/if}
@@ -88,7 +91,8 @@ function handleInput() {
88
91
  oninput={handleInput}
89
92
  aria-label={t(M['chat.message_input.input_label'])}
90
93
  ></textarea>
91
- <button
94
+ <Button
95
+ variant="ghost"
92
96
  class="message-input__send"
93
97
  type="button"
94
98
  onclick={handleSend}
@@ -105,7 +109,7 @@ function handleInput() {
105
109
  stroke-linejoin="round"
106
110
  />
107
111
  </svg>
108
- </button>
112
+ </Button>
109
113
  </div>
110
114
  </div>
111
115
 
@@ -155,21 +159,18 @@ function handleInput() {
155
159
  text-overflow: ellipsis;
156
160
  }
157
161
 
158
- .message-input__reply-close {
159
- display: flex;
160
- align-items: center;
161
- justify-content: center;
162
+ /* :global() pierces into the Button child's rendered <button> (see #1589). */
163
+ .message-input__reply :global(.message-input__reply-close) {
162
164
  width: 24px;
163
165
  height: 24px;
164
- border: none;
166
+ padding: 0;
165
167
  border-radius: var(--smrt-radius-small, 0.25rem);
166
168
  background: transparent;
167
169
  color: var(--smrt-color-on-surface-variant, #43474e);
168
- cursor: pointer;
169
170
  flex-shrink: 0;
170
171
  }
171
172
 
172
- .message-input__reply-close:hover {
173
+ .message-input__reply :global(.message-input__reply-close:hover) {
173
174
  background: var(--smrt-color-surface-container-high, #e1e3e8);
174
175
  }
175
176
 
@@ -205,28 +206,24 @@ function handleInput() {
205
206
  color: var(--smrt-color-outline, #74777f);
206
207
  }
207
208
 
208
- .message-input__send {
209
- display: flex;
210
- align-items: center;
211
- justify-content: center;
209
+ /* :global() pierces into the Button child's rendered <button> (see #1589). */
210
+ .message-input__bar :global(.message-input__send) {
212
211
  width: 36px;
213
212
  height: 36px;
214
- border: none;
213
+ padding: 0;
215
214
  border-radius: var(--smrt-radius-full, 9999px);
216
215
  background: var(--smrt-color-primary, #005ac1);
217
216
  color: var(--smrt-color-on-primary, #ffffff);
218
- cursor: pointer;
219
217
  flex-shrink: 0;
220
218
  transition: background var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
221
219
  }
222
220
 
223
- .message-input__send:hover:not(:disabled) {
221
+ .message-input__bar :global(.message-input__send:hover:not(:disabled)) {
224
222
  background: color-mix(in srgb, var(--smrt-color-primary, #005ac1) 85%, var(--smrt-color-shadow, #000));
225
223
  }
226
224
 
227
- .message-input__send:disabled {
225
+ .message-input__bar :global(.message-input__send:disabled) {
228
226
  background: var(--smrt-color-surface-container-high, #e1e3e8);
229
227
  color: var(--smrt-color-outline, #74777f);
230
- cursor: not-allowed;
231
228
  }
232
229
  </style>
@@ -1 +1 @@
1
- {"version":3,"file":"MessageInput.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/messages/MessageInput.svelte.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,KAAK;IACpB,sCAAsC;IACtC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6CAA6C;IAC7C,OAAO,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACrE,4BAA4B;IAC5B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AAyED,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"MessageInput.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/messages/MessageInput.svelte.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,KAAK;IACpB,sCAAsC;IACtC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6CAA6C;IAC7C,OAAO,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACrE,4BAA4B;IAC5B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AA0ED,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
8
+ import { Button } from '@happyvertical/smrt-ui/ui';
8
9
  import { M } from '../../i18n.messages.js';
9
10
  import type { ChatMessageData } from '../../types.js';
10
11
  import Avatar from '../shared/Avatar.svelte';
@@ -172,16 +173,17 @@ function handleEscape(event: KeyboardEvent) {
172
173
  {#if message.reactions.length > 0}
173
174
  <div class="message-item__reactions">
174
175
  {#each message.reactions as reaction}
175
- <button
176
- class="message-item__reaction"
177
- class:message-item__reaction--active={reaction.reacted}
176
+ <Button
177
+ variant="ghost"
178
+ size="sm"
179
+ class="message-item__reaction{reaction.reacted ? ' message-item__reaction--active' : ''}"
178
180
  type="button"
179
181
  onclick={() => onreact?.(message.id, reaction.emoji)}
180
182
  aria-label="{reaction.emoji} {reaction.count}"
181
183
  >
182
184
  <span class="message-item__reaction-emoji">{reaction.emoji}</span>
183
185
  <span class="message-item__reaction-count">{reaction.count}</span>
184
- </button>
186
+ </Button>
185
187
  {/each}
186
188
  </div>
187
189
  {/if}
@@ -195,7 +197,9 @@ function handleEscape(event: KeyboardEvent) {
195
197
  </div>
196
198
 
197
199
  {#if hasActions}
198
- <button
200
+ <Button
201
+ variant="ghost"
202
+ size="sm"
199
203
  class="message-item__more-btn"
200
204
  type="button"
201
205
  onclick={openActions}
@@ -205,7 +209,7 @@ function handleEscape(event: KeyboardEvent) {
205
209
  aria-controls={actionsId}
206
210
  >
207
211
  <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"><circle cx="3" cy="8" r="1.3" fill="currentColor" /><circle cx="8" cy="8" r="1.3" fill="currentColor" /><circle cx="13" cy="8" r="1.3" fill="currentColor" /></svg>
208
- </button>
212
+ </Button>
209
213
  {/if}
210
214
 
211
215
  {#if showActions}
@@ -216,44 +220,52 @@ function handleEscape(event: KeyboardEvent) {
216
220
  aria-label={t(M['chat.message_item.more_actions'])}
217
221
  >
218
222
  {#if onreact}
219
- <button
223
+ <Button
224
+ variant="ghost"
225
+ size="sm"
220
226
  class="message-item__action-btn"
221
227
  type="button"
222
228
  onclick={toggleReactionPicker}
223
229
  aria-label={t(M['chat.message_item.add_reaction'])}
224
230
  >
225
231
  <svg viewBox="0 0 16 16" width="14" height="14"><circle cx="8" cy="8" r="7" fill="none" stroke="currentColor" stroke-width="1.2" /><circle cx="5.5" cy="6.5" r="0.8" fill="currentColor" /><circle cx="10.5" cy="6.5" r="0.8" fill="currentColor" /><path d="M5.5 9.5c.5 1.2 1.5 1.8 2.5 1.8s2-.6 2.5-1.8" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" /></svg>
226
- </button>
232
+ </Button>
227
233
  {/if}
228
234
  {#if onreply}
229
- <button
235
+ <Button
236
+ variant="ghost"
237
+ size="sm"
230
238
  class="message-item__action-btn"
231
239
  type="button"
232
240
  onclick={() => onreply?.(message.id)}
233
241
  aria-label={t(M['chat.message_item.reply'])}
234
242
  >
235
243
  <svg viewBox="0 0 16 16" width="14" height="14"><path d="M6 3L2 7l4 4" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" /><path d="M2 7h8c2.2 0 4 1.8 4 4v1" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" /></svg>
236
- </button>
244
+ </Button>
237
245
  {/if}
238
246
  {#if isOwn && onedit}
239
- <button
247
+ <Button
248
+ variant="ghost"
249
+ size="sm"
240
250
  class="message-item__action-btn"
241
251
  type="button"
242
252
  onclick={() => onedit?.(message.id)}
243
253
  aria-label={t(M['chat.message_item.edit'])}
244
254
  >
245
255
  <svg viewBox="0 0 16 16" width="14" height="14"><path d="M11.5 1.5l3 3L5 14H2v-3z" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" /></svg>
246
- </button>
256
+ </Button>
247
257
  {/if}
248
258
  {#if isOwn && ondelete}
249
- <button
259
+ <Button
260
+ variant="ghost"
261
+ size="sm"
250
262
  class="message-item__action-btn"
251
263
  type="button"
252
264
  onclick={() => ondelete?.(message.id)}
253
265
  aria-label={t(M['chat.message_item.delete'])}
254
266
  >
255
267
  <svg viewBox="0 0 16 16" width="14" height="14"><path d="M2 4h12M5.3 4V2.7A.7.7 0 016 2h4a.7.7 0 01.7.7V4m1.6 0v9.3a1.4 1.4 0 01-1.4 1.4H5.1a1.4 1.4 0 01-1.4-1.4V4" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" /></svg>
256
- </button>
268
+ </Button>
257
269
  {/if}
258
270
  </div>
259
271
 
@@ -391,24 +403,22 @@ function handleEscape(event: KeyboardEvent) {
391
403
  gap: var(--smrt-spacing-1, 0.25rem);
392
404
  }
393
405
 
394
- .message-item__reaction {
395
- display: inline-flex;
396
- align-items: center;
406
+ /* :global() pierces into each Button's rendered <button> (see #1589). */
407
+ .message-item__reactions :global(.message-item__reaction) {
397
408
  gap: var(--smrt-spacing-1, 4px);
398
409
  padding: var(--smrt-spacing-1, 4px) var(--smrt-spacing-2, 8px);
399
410
  border: 1px solid var(--smrt-color-outline-variant, #c4c6cf);
400
411
  border-radius: var(--smrt-radius-full, 9999px);
401
412
  background: var(--smrt-color-surface, #ffffff);
402
- cursor: pointer;
403
413
  font-size: var(--smrt-typography-label-medium-size, 0.75rem);
404
414
  transition: background var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
405
415
  }
406
416
 
407
- .message-item__reaction:hover {
417
+ .message-item__reactions :global(.message-item__reaction:hover) {
408
418
  background: var(--smrt-color-surface-container-high, #e1e3e8);
409
419
  }
410
420
 
411
- .message-item__reaction--active {
421
+ .message-item__reactions :global(.message-item__reaction--active) {
412
422
  border-color: var(--smrt-color-primary, #005ac1);
413
423
  background: var(--smrt-color-primary-container, #d6e3ff);
414
424
  }
@@ -441,12 +451,11 @@ function handleEscape(event: KeyboardEvent) {
441
451
  font-style: italic;
442
452
  }
443
453
 
444
- .message-item__more-btn {
445
- display: flex;
446
- align-items: center;
447
- justify-content: center;
454
+ /* :global() pierces into the Button child's rendered <button> (see #1589). */
455
+ .message-item :global(.message-item__more-btn) {
448
456
  width: 26px;
449
457
  height: 26px;
458
+ padding: 0;
450
459
  position: absolute;
451
460
  top: 0;
452
461
  right: var(--smrt-spacing-4, 1rem);
@@ -454,12 +463,11 @@ function handleEscape(event: KeyboardEvent) {
454
463
  border-radius: var(--smrt-radius-small, 0.25rem);
455
464
  background: var(--smrt-color-surface, #ffffff);
456
465
  color: var(--smrt-color-on-surface-variant, #43474e);
457
- cursor: pointer;
458
466
  opacity: 0;
459
467
  transition: opacity var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
460
468
  }
461
469
 
462
- .message-item--own .message-item__more-btn {
470
+ .message-item--own :global(.message-item__more-btn) {
463
471
  right: auto;
464
472
  left: var(--smrt-spacing-4, 1rem);
465
473
  }
@@ -467,19 +475,19 @@ function handleEscape(event: KeyboardEvent) {
467
475
  /* Reveal the keyboard/touch affordance on hover OR when focus is inside the
468
476
  row, so it is never strictly hover-only (a11y blocker, T2 #1391). Always
469
477
  visible to coarse pointers (touch) which cannot hover. */
470
- .message-item:hover .message-item__more-btn,
471
- .message-item:focus-within .message-item__more-btn {
478
+ .message-item:hover :global(.message-item__more-btn),
479
+ .message-item:focus-within :global(.message-item__more-btn) {
472
480
  opacity: 1;
473
481
  }
474
482
 
475
- .message-item__more-btn:focus-visible {
483
+ .message-item :global(.message-item__more-btn:focus-visible) {
476
484
  opacity: 1;
477
485
  outline: 2px solid var(--smrt-color-primary, #005ac1);
478
486
  outline-offset: 1px;
479
487
  }
480
488
 
481
489
  @media (hover: none) {
482
- .message-item__more-btn {
490
+ .message-item :global(.message-item__more-btn) {
483
491
  opacity: 1;
484
492
  }
485
493
  }
@@ -504,21 +512,18 @@ function handleEscape(event: KeyboardEvent) {
504
512
  left: var(--smrt-spacing-4, 1rem);
505
513
  }
506
514
 
507
- .message-item__action-btn {
508
- display: flex;
509
- align-items: center;
510
- justify-content: center;
515
+ /* :global() pierces into each Button's rendered <button> (see #1589). */
516
+ .message-item__actions :global(.message-item__action-btn) {
511
517
  width: 26px;
512
518
  height: 26px;
513
- border: none;
519
+ padding: 0;
514
520
  border-radius: var(--smrt-radius-small, 0.25rem);
515
521
  background: transparent;
516
522
  color: var(--smrt-color-on-surface-variant, #43474e);
517
- cursor: pointer;
518
523
  transition: background var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
519
524
  }
520
525
 
521
- .message-item__action-btn:hover {
526
+ .message-item__actions :global(.message-item__action-btn:hover) {
522
527
  background: var(--smrt-color-surface-container-high, #e1e3e8);
523
528
  }
524
529
 
@@ -536,9 +541,9 @@ function handleEscape(event: KeyboardEvent) {
536
541
  }
537
542
 
538
543
  @media (prefers-reduced-motion: reduce) {
539
- .message-item__more-btn,
540
- .message-item__action-btn,
541
- .message-item__reaction {
544
+ .message-item :global(.message-item__more-btn),
545
+ .message-item__actions :global(.message-item__action-btn),
546
+ .message-item__reactions :global(.message-item__reaction) {
542
547
  transition: none;
543
548
  }
544
549
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MessageItem.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/messages/MessageItem.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAMtD,MAAM,WAAW,KAAK;IACpB,6BAA6B;IAC7B,OAAO,EAAE,eAAe,CAAC;IACzB,wDAAwD;IACxD,KAAK,EAAE,OAAO,CAAC;IACf,qBAAqB;IACrB,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,qBAAqB;IACrB,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,oBAAoB;IACpB,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,sBAAsB;IACtB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAuMD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"MessageItem.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/messages/MessageItem.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAMtD,MAAM,WAAW,KAAK;IACpB,6BAA6B;IAC7B,OAAO,EAAE,eAAe,CAAC;IACzB,wDAAwD;IACxD,KAAK,EAAE,OAAO,CAAC;IACf,qBAAqB;IACrB,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,qBAAqB;IACrB,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,oBAAoB;IACpB,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,sBAAsB;IACtB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAwMD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
8
+ import { Button } from '@happyvertical/smrt-ui/ui';
8
9
  import { M } from '../../i18n.messages.js';
9
10
  import type { ChatMessageData, ChatThreadData } from '../../types.js';
10
11
  import MessageInput from './MessageInput.svelte';
@@ -47,7 +48,9 @@ const replyCount = $derived(
47
48
  {#if thread.isResolved}
48
49
  <span class="thread-panel__resolved">Resolved</span>
49
50
  {/if}
50
- <button
51
+ <Button
52
+ variant="ghost"
53
+ size="sm"
51
54
  class="thread-panel__close"
52
55
  type="button"
53
56
  onclick={onclose}
@@ -56,7 +59,7 @@ const replyCount = $derived(
56
59
  <svg viewBox="0 0 16 16" width="16" height="16">
57
60
  <path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
58
61
  </svg>
59
- </button>
62
+ </Button>
60
63
  </header>
61
64
 
62
65
  <div class="thread-panel__messages">
@@ -124,22 +127,19 @@ const replyCount = $derived(
124
127
  flex-shrink: 0;
125
128
  }
126
129
 
127
- .thread-panel__close {
128
- display: flex;
129
- align-items: center;
130
- justify-content: center;
130
+ /* :global() pierces into the Button child's rendered <button> (see #1589). */
131
+ .thread-panel__header :global(.thread-panel__close) {
131
132
  width: 32px;
132
133
  height: 32px;
133
- border: none;
134
+ padding: 0;
134
135
  border-radius: var(--smrt-radius-small, 0.25rem);
135
136
  background: transparent;
136
137
  color: var(--smrt-color-on-surface-variant, #43474e);
137
- cursor: pointer;
138
138
  flex-shrink: 0;
139
139
  transition: background var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
140
140
  }
141
141
 
142
- .thread-panel__close:hover {
142
+ .thread-panel__header :global(.thread-panel__close:hover) {
143
143
  background: var(--smrt-color-surface-container-high, #e1e3e8);
144
144
  }
145
145
 
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadPanel.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/messages/ThreadPanel.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKtE,MAAM,WAAW,KAAK;IACpB,sBAAsB;IACtB,MAAM,EAAE,cAAc,CAAC;IACvB,6BAA6B;IAC7B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,gCAAgC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,iCAAiC;IACjC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,6BAA6B;IAC7B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAsDD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ThreadPanel.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/messages/ThreadPanel.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKtE,MAAM,WAAW,KAAK;IACpB,sBAAsB;IACtB,MAAM,EAAE,cAAc,CAAC;IACvB,6BAA6B;IAC7B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,gCAAgC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,iCAAiC;IACjC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,6BAA6B;IAC7B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAuDD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}