@revikornmann/muka-ui 0.11.0 → 0.13.0

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 (150) hide show
  1. package/build/manifest.json +30 -0
  2. package/dist/cjs/components/AgentTaskList/AgentTaskList.css +22 -3
  3. package/dist/cjs/components/AgentTaskList/AgentTaskList.js +1 -1
  4. package/dist/cjs/components/BadgeNumber/BadgeNumber.css +105 -0
  5. package/dist/cjs/components/BadgeNumber/BadgeNumber.js +19 -0
  6. package/dist/cjs/components/BadgeNumber/BadgeNumber.js.map +1 -0
  7. package/dist/cjs/components/BadgeNumber/index.js +11 -0
  8. package/dist/cjs/components/BadgeNumber/index.js.map +1 -0
  9. package/dist/cjs/components/BottomBar/BottomBar.css +8 -5
  10. package/dist/cjs/components/Button/Button.css +13 -6
  11. package/dist/cjs/components/Button/Button.js +1 -1
  12. package/dist/cjs/components/ChatComposer/ChatComposer.css +13 -1
  13. package/dist/cjs/components/ChatMessage/ChatMessage.css +328 -0
  14. package/dist/cjs/components/ChatMessage/ChatMessage.js +141 -0
  15. package/dist/cjs/components/ChatMessage/ChatMessage.js.map +1 -0
  16. package/dist/cjs/components/ChatMessage/index.js +7 -0
  17. package/dist/cjs/components/ChatMessage/index.js.map +1 -0
  18. package/dist/cjs/components/ChatMessageList/ChatMessageList.css +17 -1
  19. package/dist/cjs/components/ChatMessageList/ChatMessageList.js +1 -1
  20. package/dist/cjs/components/ChatMessageStack/ChatMessageStack.css +51 -0
  21. package/dist/cjs/components/ChatMessageStack/ChatMessageStack.js +49 -0
  22. package/dist/cjs/components/ChatMessageStack/ChatMessageStack.js.map +1 -0
  23. package/dist/cjs/components/ChatMessageStack/index.js +6 -0
  24. package/dist/cjs/components/ChatMessageStack/index.js.map +1 -0
  25. package/dist/cjs/components/ChatPhotoGrid/ChatPhotoGrid.css +119 -0
  26. package/dist/cjs/components/ChatPhotoGrid/ChatPhotoGrid.js +47 -0
  27. package/dist/cjs/components/ChatPhotoGrid/ChatPhotoGrid.js.map +1 -0
  28. package/dist/cjs/components/ChatPhotoGrid/index.js +11 -0
  29. package/dist/cjs/components/ChatPhotoGrid/index.js.map +1 -0
  30. package/dist/cjs/components/Menu/Menu.js +5 -4
  31. package/dist/cjs/components/Menu/Menu.js.map +1 -1
  32. package/dist/cjs/components/index.js +11 -5
  33. package/dist/cjs/components/index.js.map +1 -1
  34. package/dist/cjs/utils/useLongPress.js +71 -0
  35. package/dist/cjs/utils/useLongPress.js.map +1 -0
  36. package/dist/esm/components/AgentTaskList/AgentTaskList.css +22 -3
  37. package/dist/esm/components/AgentTaskList/AgentTaskList.js +1 -1
  38. package/dist/esm/components/BadgeNumber/BadgeNumber.css +105 -0
  39. package/dist/esm/components/BadgeNumber/BadgeNumber.js +15 -0
  40. package/dist/esm/components/BadgeNumber/BadgeNumber.js.map +1 -0
  41. package/dist/esm/components/BadgeNumber/index.js +3 -0
  42. package/dist/esm/components/BadgeNumber/index.js.map +1 -0
  43. package/dist/esm/components/BottomBar/BottomBar.css +8 -5
  44. package/dist/esm/components/Button/Button.css +13 -6
  45. package/dist/esm/components/Button/Button.js +1 -1
  46. package/dist/esm/components/ChatComposer/ChatComposer.css +13 -1
  47. package/dist/esm/components/ChatMessage/ChatMessage.css +328 -0
  48. package/dist/esm/components/ChatMessage/ChatMessage.js +137 -0
  49. package/dist/esm/components/ChatMessage/ChatMessage.js.map +1 -0
  50. package/dist/esm/components/ChatMessage/index.js +2 -0
  51. package/dist/esm/components/ChatMessage/index.js.map +1 -0
  52. package/dist/esm/components/ChatMessageList/ChatMessageList.css +17 -1
  53. package/dist/esm/components/ChatMessageList/ChatMessageList.js +1 -1
  54. package/dist/esm/components/ChatMessageStack/ChatMessageStack.css +51 -0
  55. package/dist/esm/components/ChatMessageStack/ChatMessageStack.js +42 -0
  56. package/dist/esm/components/ChatMessageStack/ChatMessageStack.js.map +1 -0
  57. package/dist/esm/components/ChatMessageStack/index.js +2 -0
  58. package/dist/esm/components/ChatMessageStack/index.js.map +1 -0
  59. package/dist/esm/components/ChatPhotoGrid/ChatPhotoGrid.css +119 -0
  60. package/dist/esm/components/ChatPhotoGrid/ChatPhotoGrid.js +43 -0
  61. package/dist/esm/components/ChatPhotoGrid/ChatPhotoGrid.js.map +1 -0
  62. package/dist/esm/components/ChatPhotoGrid/index.js +3 -0
  63. package/dist/esm/components/ChatPhotoGrid/index.js.map +1 -0
  64. package/dist/esm/components/Menu/Menu.js +5 -4
  65. package/dist/esm/components/Menu/Menu.js.map +1 -1
  66. package/dist/esm/components/index.js +4 -1
  67. package/dist/esm/components/index.js.map +1 -1
  68. package/dist/esm/utils/useLongPress.js +68 -0
  69. package/dist/esm/utils/useLongPress.js.map +1 -0
  70. package/dist/styles/components/AgentTaskList.css +22 -3
  71. package/dist/styles/components/BadgeNumber.css +105 -0
  72. package/dist/styles/components/BottomBar.css +8 -5
  73. package/dist/styles/components/Button.css +13 -6
  74. package/dist/styles/components/ChatComposer.css +13 -1
  75. package/dist/styles/components/ChatMessage.css +328 -0
  76. package/dist/styles/components/ChatMessageList.css +17 -1
  77. package/dist/styles/components/ChatMessageStack.css +51 -0
  78. package/dist/styles/components/ChatPhotoGrid.css +119 -0
  79. package/dist/styles/index.css +2615 -1941
  80. package/dist/styles/muka-dark.css +2615 -1941
  81. package/dist/styles/muka-light.css +2615 -1941
  82. package/dist/styles/tokens-bouwplan-dark.css +85 -0
  83. package/dist/styles/tokens-bouwplan-light.css +85 -0
  84. package/dist/styles/tokens-fscl-dark.css +85 -0
  85. package/dist/styles/tokens-fscl-light.css +85 -0
  86. package/dist/styles/tokens-grip-dark.css +85 -0
  87. package/dist/styles/tokens-grip-light.css +85 -0
  88. package/dist/styles/tokens-muka-dark.css +85 -0
  89. package/dist/styles/tokens-muka-light.css +85 -0
  90. package/dist/styles/tokens-wireframe-dark.css +85 -0
  91. package/dist/styles/tokens-wireframe-light.css +85 -0
  92. package/dist/styles/wireframe-dark.css +2615 -1941
  93. package/dist/styles/wireframe-light.css +2615 -1941
  94. package/dist/types/components/AgentTaskList/AgentTaskList.d.ts +1 -1
  95. package/dist/types/components/BadgeNumber/BadgeNumber.d.ts +17 -0
  96. package/dist/types/components/BadgeNumber/BadgeNumber.d.ts.map +1 -0
  97. package/dist/types/components/BadgeNumber/index.d.ts +3 -0
  98. package/dist/types/components/BadgeNumber/index.d.ts.map +1 -0
  99. package/dist/types/components/Button/Button.d.ts +1 -1
  100. package/dist/types/components/ChatMessage/ChatMessage.d.ts +130 -0
  101. package/dist/types/components/ChatMessage/ChatMessage.d.ts.map +1 -0
  102. package/dist/types/components/ChatMessage/index.d.ts +2 -0
  103. package/dist/types/components/ChatMessage/index.d.ts.map +1 -0
  104. package/dist/types/components/ChatMessageList/ChatMessageList.d.ts +2 -2
  105. package/dist/types/components/ChatMessageList/ChatMessageList.d.ts.map +1 -1
  106. package/dist/types/components/ChatMessageStack/ChatMessageStack.d.ts +46 -0
  107. package/dist/types/components/ChatMessageStack/ChatMessageStack.d.ts.map +1 -0
  108. package/dist/types/components/ChatMessageStack/index.d.ts +2 -0
  109. package/dist/types/components/ChatMessageStack/index.d.ts.map +1 -0
  110. package/dist/types/components/ChatPhotoGrid/ChatPhotoGrid.d.ts +44 -0
  111. package/dist/types/components/ChatPhotoGrid/ChatPhotoGrid.d.ts.map +1 -0
  112. package/dist/types/components/ChatPhotoGrid/index.d.ts +3 -0
  113. package/dist/types/components/ChatPhotoGrid/index.d.ts.map +1 -0
  114. package/dist/types/components/Menu/Menu.d.ts +12 -0
  115. package/dist/types/components/Menu/Menu.d.ts.map +1 -1
  116. package/dist/types/components/index.d.ts +4 -1
  117. package/dist/types/components/index.d.ts.map +1 -1
  118. package/dist/types/utils/useLongPress.d.ts +28 -0
  119. package/dist/types/utils/useLongPress.d.ts.map +1 -0
  120. package/package.json +1 -1
  121. package/tokens/README.md +14 -0
  122. package/tokens/t2-alias/brand/bouwplan/dark.json +24 -0
  123. package/tokens/t2-alias/brand/bouwplan/light.json +24 -0
  124. package/tokens/t2-alias/brand/fscl/dark.json +24 -0
  125. package/tokens/t2-alias/brand/fscl/light.json +24 -0
  126. package/tokens/t2-alias/brand/grip/dark.json +54 -0
  127. package/tokens/t2-alias/brand/grip/light.json +54 -0
  128. package/tokens/t2-alias/brand/muka/dark.json +54 -0
  129. package/tokens/t2-alias/brand/muka/light.json +54 -0
  130. package/tokens/t2-alias/brand/wireframe/dark.json +54 -0
  131. package/tokens/t2-alias/brand/wireframe/light.json +54 -0
  132. package/tokens/t3-semantics/ui.json +219 -0
  133. package/tokens/t4-components/badge-number.json +48 -0
  134. package/tokens/t4-components/chatbubble.json +180 -0
  135. package/tokens/t4-components/chatphotogrid.json +32 -0
  136. package/dist/cjs/components/ChatBubble/ChatBubble.css +0 -80
  137. package/dist/cjs/components/ChatBubble/ChatBubble.js +0 -24
  138. package/dist/cjs/components/ChatBubble/ChatBubble.js.map +0 -1
  139. package/dist/cjs/components/ChatBubble/index.js +0 -6
  140. package/dist/cjs/components/ChatBubble/index.js.map +0 -1
  141. package/dist/esm/components/ChatBubble/ChatBubble.css +0 -80
  142. package/dist/esm/components/ChatBubble/ChatBubble.js +0 -20
  143. package/dist/esm/components/ChatBubble/ChatBubble.js.map +0 -1
  144. package/dist/esm/components/ChatBubble/index.js +0 -2
  145. package/dist/esm/components/ChatBubble/index.js.map +0 -1
  146. package/dist/styles/components/ChatBubble.css +0 -80
  147. package/dist/types/components/ChatBubble/ChatBubble.d.ts +0 -30
  148. package/dist/types/components/ChatBubble/ChatBubble.d.ts.map +0 -1
  149. package/dist/types/components/ChatBubble/index.d.ts +0 -2
  150. package/dist/types/components/ChatBubble/index.d.ts.map +0 -1
@@ -0,0 +1,328 @@
1
+ /* ChatMessage Component Styles */
2
+
3
+ .muka-chat-message {
4
+ display: flex;
5
+ flex-direction: column;
6
+ width: 100%;
7
+ max-width: 100%;
8
+ }
9
+
10
+ /* ─── Row: avatar rail + bubble ────────────────────────── */
11
+
12
+ .muka-chat-message__row {
13
+ display: grid;
14
+ grid-template-columns: minmax(0, 1fr);
15
+ grid-template-areas: 'bubble';
16
+ column-gap: var(--chatbubble-row-gap);
17
+ width: 100%;
18
+ }
19
+
20
+ .muka-chat-message--has-avatar .muka-chat-message__row {
21
+ grid-template-columns: auto minmax(0, 1fr);
22
+ grid-template-areas: 'rail bubble';
23
+ }
24
+
25
+ .muka-chat-message--own.muka-chat-message--has-avatar .muka-chat-message__row {
26
+ grid-template-columns: minmax(0, 1fr) auto;
27
+ grid-template-areas: 'bubble rail';
28
+ }
29
+
30
+ .muka-chat-message__rail {
31
+ grid-area: rail;
32
+ /* Sits on the bubble's baseline (Figma 5355:44091) */
33
+ align-self: end;
34
+ display: flex;
35
+ justify-content: center;
36
+ min-width: var(--chatbubble-avatar-size);
37
+ }
38
+
39
+ /*
40
+ * The Small size in Figma (5373:44702) halves the avatar to 32px and tightens
41
+ * the gap to the bubble. Size the avatar itself, not just the rail, so the
42
+ * bubbles keep their alignment. The header row keeps its own gap.
43
+ */
44
+ @media (max-width: 1023px) {
45
+ .muka-chat-message__row {
46
+ column-gap: var(--chatbubble-row-gap-compact);
47
+ }
48
+
49
+ .muka-chat-message__rail {
50
+ min-width: var(--chatbubble-avatar-size-compact);
51
+ }
52
+
53
+ /* Outweighs the avatar's own size class, which sets width/height directly */
54
+ .muka-chat-message .muka-chat-message__rail > * {
55
+ width: var(--chatbubble-avatar-size-compact);
56
+ height: var(--chatbubble-avatar-size-compact);
57
+ }
58
+ }
59
+
60
+ /* ─── Bubble surface ───────────────────────────────────── */
61
+
62
+ .muka-chat-message__bubble {
63
+ grid-area: bubble;
64
+ max-width: var(--chatbubble-max-width);
65
+ position: relative;
66
+ display: flex;
67
+ flex-direction: column;
68
+ gap: var(--chatbubble-gap);
69
+ padding: var(--chatbubble-padding-block) var(--chatbubble-padding-inline);
70
+ border-radius: var(--chatbubble-radius);
71
+ border: var(--border-width-regular) solid transparent;
72
+ box-shadow: var(--shadow-level2);
73
+ word-break: break-word;
74
+ }
75
+
76
+ /*
77
+ * Length axis (Figma `Text length` on 5355:44091): short messages hug their
78
+ * content, long ones fill the row up to the shared max width.
79
+ */
80
+ .muka-chat-message--long .muka-chat-message__bubble {
81
+ width: 100%;
82
+ }
83
+
84
+ .muka-chat-message--short .muka-chat-message__bubble {
85
+ width: fit-content;
86
+ }
87
+
88
+ .muka-chat-message--own .muka-chat-message__bubble {
89
+ justify-self: end;
90
+ }
91
+
92
+ .muka-chat-message--own .muka-chat-message__bubble {
93
+ background-color: var(--chatbubble-color-own-background);
94
+ border-color: var(--chatbubble-color-own-border);
95
+ color: var(--chatbubble-color-own-foreground);
96
+ }
97
+
98
+ .muka-chat-message--peer .muka-chat-message__bubble {
99
+ background-color: var(--chatbubble-color-peer-background);
100
+ border-color: var(--chatbubble-color-peer-border);
101
+ color: var(--chatbubble-color-peer-foreground);
102
+ }
103
+
104
+ .muka-chat-message--agent .muka-chat-message__bubble {
105
+ background-color: var(--chatbubble-color-agent-background);
106
+ border-color: var(--chatbubble-color-agent-border);
107
+ color: var(--chatbubble-color-agent-foreground);
108
+ }
109
+
110
+ /* ─── Header row (author · meta · time · badge) ────────── */
111
+
112
+ .muka-chat-message__header {
113
+ display: flex;
114
+ flex-flow: row wrap;
115
+ align-items: center;
116
+ gap: var(--chatbubble-row-gap);
117
+ }
118
+
119
+ .muka-chat-message__author {
120
+ font-family: var(--text-body-base-bold-fontFamily);
121
+ font-weight: var(--text-body-base-bold-fontWeight);
122
+ font-size: var(--text-body-base-bold-fontSize);
123
+ line-height: var(--text-body-base-bold-lineHeight);
124
+ }
125
+
126
+ .muka-chat-message__author-meta {
127
+ /* Inherits the variant's body colour from the bubble */
128
+ color: inherit;
129
+ font-family: var(--text-body-base-regular-fontFamily);
130
+ font-weight: var(--text-body-base-regular-fontWeight);
131
+ font-size: var(--text-body-base-regular-fontSize);
132
+ line-height: var(--text-body-base-regular-lineHeight);
133
+ }
134
+
135
+ .muka-chat-message__badge {
136
+ display: inline-flex;
137
+ align-items: center;
138
+ }
139
+
140
+ /*
141
+ * Keep the first line of content clear of the absolutely positioned menu
142
+ * button in the bubble's top-right corner.
143
+ */
144
+ .muka-chat-message--has-menu .muka-chat-message__header,
145
+ .muka-chat-message--has-menu.muka-chat-message--no-header .muka-chat-message__message {
146
+ padding-right: var(--spacing-10);
147
+ }
148
+
149
+ /* …and the last line clear of the inset timestamp in the bottom-right corner */
150
+ .muka-chat-message--has-timestamp .muka-chat-message__message {
151
+ padding-right: var(--spacing-10);
152
+ }
153
+
154
+ /* ─── Body ─────────────────────────────────────────────── */
155
+
156
+ .muka-chat-message__body {
157
+ display: flex;
158
+ flex-direction: column;
159
+ gap: var(--chatbubble-gap);
160
+ min-width: 0;
161
+ }
162
+
163
+ .muka-chat-message__media {
164
+ min-width: 0;
165
+ }
166
+
167
+ .muka-chat-message__message {
168
+ font-family: var(--text-body-base-regular-fontFamily);
169
+ font-weight: var(--text-body-base-regular-fontWeight);
170
+ font-size: var(--text-body-base-regular-fontSize);
171
+ line-height: var(--text-body-base-regular-lineHeight);
172
+ white-space: pre-wrap;
173
+ word-break: break-word;
174
+ }
175
+
176
+ /* Empty message block should not add a gap of its own */
177
+ .muka-chat-message__message:empty {
178
+ display: none;
179
+ }
180
+
181
+ /* ─── Embedded card ────────────────────────────────────── */
182
+
183
+ .muka-chat-message__embed {
184
+ position: relative;
185
+ display: flex;
186
+ flex-direction: column;
187
+ gap: var(--chatbubble-embed-gap);
188
+ /* The card is inset from the blocks above and below it (Figma 5289:40562) */
189
+ margin-block: var(--chatbubble-embed-margin-block);
190
+ padding: var(--chatbubble-embed-padding-block) var(--chatbubble-embed-padding-inline);
191
+ border-radius: var(--chatbubble-embed-radius);
192
+ border: var(--border-width-regular) solid transparent;
193
+ }
194
+
195
+ /*
196
+ * The embed sits on the raised surface of its author's role, one step apart
197
+ * from the bubble it is nested in, and reuses that role's border colour.
198
+ */
199
+ .muka-chat-message--own .muka-chat-message__embed {
200
+ background-color: var(--chatbubble-embed-color-own-background);
201
+ border-color: var(--chatbubble-embed-color-own-border);
202
+ color: var(--chatbubble-embed-color-own-foreground);
203
+ }
204
+
205
+ .muka-chat-message--peer .muka-chat-message__embed {
206
+ background-color: var(--chatbubble-embed-color-peer-background);
207
+ border-color: var(--chatbubble-embed-color-peer-border);
208
+ color: var(--chatbubble-embed-color-peer-foreground);
209
+ }
210
+
211
+ .muka-chat-message--agent .muka-chat-message__embed {
212
+ background-color: var(--chatbubble-embed-color-agent-background);
213
+ border-color: var(--chatbubble-embed-color-agent-border);
214
+ color: var(--chatbubble-embed-color-agent-foreground);
215
+ }
216
+
217
+ .muka-chat-message__embed-content {
218
+ display: flex;
219
+ flex-direction: column;
220
+ gap: var(--chatbubble-embed-gap);
221
+ min-width: 0;
222
+ }
223
+
224
+ .muka-chat-message__embed-copy {
225
+ position: absolute;
226
+ top: var(--chatbubble-embed-padding-block);
227
+ right: var(--chatbubble-embed-padding-inline);
228
+ }
229
+
230
+ /* ─── Stacked full-width action buttons ────────────────── */
231
+
232
+ .muka-chat-message__action-stack {
233
+ display: flex;
234
+ flex-direction: column;
235
+ gap: var(--chatbubble-action-stack-gap);
236
+ }
237
+
238
+ /* ─── Inset timestamp ──────────────────────────────────── */
239
+
240
+ /*
241
+ * Every author puts its timestamp in the bubble's bottom-right corner, below
242
+ * the message — never in the header row (Figma 5355:44091).
243
+ */
244
+
245
+ .muka-chat-message__timestamp {
246
+ color: var(--chatbubble-color-timestamp);
247
+ font-family: var(--text-body-xs-regular-fontFamily);
248
+ font-weight: var(--text-body-xs-regular-fontWeight);
249
+ font-size: var(--text-body-xs-regular-fontSize);
250
+ line-height: var(--text-body-xs-regular-lineHeight);
251
+ white-space: nowrap;
252
+ }
253
+
254
+ /*
255
+ * Pinned to the corner rather than stacked below the message, so a one-line
256
+ * message stays one line tall. The message reserves the width it needs.
257
+ */
258
+ .muka-chat-message__timestamp--inset {
259
+ position: absolute;
260
+ right: var(--spacing-2);
261
+ bottom: var(--spacing-1);
262
+ }
263
+
264
+ /*
265
+ * Media, an embed or an action stack run the full width of the bubble, so the
266
+ * corner the timestamp sits in has to be cleared for it.
267
+ */
268
+ .muka-chat-message--has-timestamp.muka-chat-message--has-blocks .muka-chat-message__body {
269
+ padding-bottom: var(--text-body-xs-regular-lineHeight);
270
+ }
271
+
272
+ /* ─── Menu affordance ──────────────────────────────────── */
273
+
274
+ /*
275
+ * Hidden at rest. Revealed on hover on pointer devices, on keyboard focus
276
+ * everywhere, and pinned while its menu is open. On touch the equivalent
277
+ * affordance is a long-press on the bubble, which opens an ActionSheet.
278
+ */
279
+ .muka-chat-message__menu {
280
+ position: absolute;
281
+ top: var(--spacing-1);
282
+ right: var(--spacing-1);
283
+ opacity: 0;
284
+ pointer-events: none;
285
+ }
286
+
287
+ .muka-chat-message__menu:focus-within,
288
+ .muka-chat-message--menu-open .muka-chat-message__menu {
289
+ opacity: 1;
290
+ pointer-events: auto;
291
+ }
292
+
293
+ @media (hover: hover) and (pointer: fine) and (min-width: 1024px) {
294
+ .muka-chat-message__bubble:hover .muka-chat-message__menu {
295
+ opacity: 1;
296
+ pointer-events: auto;
297
+ }
298
+ }
299
+
300
+ /* Suppress iOS Safari's own callout so the long-press sheet can take over */
301
+ @media (pointer: coarse) {
302
+ .muka-chat-message--has-menu .muka-chat-message__bubble {
303
+ -webkit-touch-callout: none;
304
+ }
305
+ }
306
+
307
+ /* ─── Print ────────────────────────────────────────────── */
308
+
309
+ @media print {
310
+ .muka-chat-message__bubble {
311
+ box-shadow: none;
312
+ break-inside: avoid;
313
+ print-color-adjust: exact;
314
+ -webkit-print-color-adjust: exact;
315
+ }
316
+
317
+ .muka-chat-message__embed {
318
+ break-inside: avoid;
319
+ print-color-adjust: exact;
320
+ -webkit-print-color-adjust: exact;
321
+ }
322
+
323
+ .muka-chat-message__menu,
324
+ .muka-chat-message__embed-copy,
325
+ .muka-chat-message__action-stack {
326
+ display: none;
327
+ }
328
+ }
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ChatMessage = exports.ChatMessageVariantContext = void 0;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const Button_1 = require("../Button");
8
+ const Icon_1 = require("../Icon");
9
+ const Menu_1 = require("../Menu");
10
+ const ActionSheet_1 = require("../ActionSheet");
11
+ const useLongPress_1 = require("../../utils/useLongPress");
12
+ require("./ChatMessage.css");
13
+ /**
14
+ * Messages at or below this many characters hug their content; longer ones fill
15
+ * the available width (Figma `Text length` axis on `5355:44091`).
16
+ */
17
+ const SHORT_MESSAGE_MAX_LENGTH = 100;
18
+ /**
19
+ * Set by `ChatMessageStack` so its children inherit the author without every
20
+ * message repeating it. Exported for the stack; not part of the public API.
21
+ */
22
+ exports.ChatMessageVariantContext = (0, react_1.createContext)(null);
23
+ /**
24
+ * ChatMessage — a single chat message.
25
+ *
26
+ * Composes with `ChatMessageList`, and with `ChatMessageStack` for consecutive
27
+ * messages from one author. Pass `<ChatPhotoGrid />` to `media`, an
28
+ * `<AgentTaskList />` above the bubble for tool progress, and a `<Badge />` to
29
+ * `badge` for visibility scope.
30
+ *
31
+ * Secondary actions (copy, feedback, regenerate, plus anything in `menuItems`)
32
+ * live behind one options menu: a dropdown revealed on hover on pointer
33
+ * devices, and a bottom sheet opened by long-pressing the bubble on touch.
34
+ */
35
+ const ChatMessage = ({ variant, children, length = 'auto', avatar, reserveAvatar = false, author, authorMeta, badge, timestamp, media, embed, onEmbedCopy, embedCopyLabel = 'Copy', actionStack, onCopy, copyLabel = 'Copy', onFeedback, feedback = null, feedbackUpLabel = 'Helpful', feedbackDownLabel = 'Not helpful', onRefresh, refreshLabel = 'Regenerate', menuItems, menuLabel = 'Message options', menuCancelLabel = 'Cancel', className = '', }) => {
36
+ const [menuOpen, setMenuOpen] = (0, react_1.useState)(false);
37
+ const [sheetOpen, setSheetOpen] = (0, react_1.useState)(false);
38
+ // The trigger is revealed on hover, so focus must not linger on it after a
39
+ // pointer-driven close — Radix restores focus on close, and the browser marks
40
+ // that programmatic focus `:focus-visible`, which would pin the button open.
41
+ // Keyboard users still get focus back, since for them the reveal is correct.
42
+ const openedWithKeyboard = (0, react_1.useRef)(false);
43
+ const stackVariant = (0, react_1.useContext)(exports.ChatMessageVariantContext);
44
+ const resolvedVariant = variant ?? stackVariant ?? 'peer';
45
+ // The visibility badge hangs off the author line, so it goes when the author does.
46
+ const showBadge = Boolean(author && badge);
47
+ const hasHeader = Boolean(author || authorMeta || showBadge);
48
+ const hasRail = Boolean(avatar || reserveAvatar);
49
+ const hasBlocks = Boolean(media || embed || actionStack);
50
+ const resolvedLength = length !== 'auto'
51
+ ? length
52
+ : hasBlocks || typeof children !== 'string' || children.length > SHORT_MESSAGE_MAX_LENGTH
53
+ ? 'long'
54
+ : 'short';
55
+ const items = (0, react_1.useMemo)(() => {
56
+ const resolved = [];
57
+ if (onCopy) {
58
+ resolved.push({
59
+ id: 'copy',
60
+ label: copyLabel,
61
+ icon: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "file-copy", size: "sm" }),
62
+ onSelect: onCopy,
63
+ });
64
+ }
65
+ if (onFeedback) {
66
+ resolved.push({
67
+ id: 'feedback-up',
68
+ label: feedbackUpLabel,
69
+ icon: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "thumb-up", size: "sm" }),
70
+ checked: feedback === 'up',
71
+ onSelect: () => onFeedback(feedback === 'up' ? null : 'up'),
72
+ }, {
73
+ id: 'feedback-down',
74
+ label: feedbackDownLabel,
75
+ icon: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "thumb-down", size: "sm" }),
76
+ checked: feedback === 'down',
77
+ onSelect: () => onFeedback(feedback === 'down' ? null : 'down'),
78
+ });
79
+ }
80
+ if (onRefresh) {
81
+ resolved.push({
82
+ id: 'refresh',
83
+ label: refreshLabel,
84
+ icon: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "restart", size: "sm" }),
85
+ onSelect: onRefresh,
86
+ });
87
+ }
88
+ if (menuItems)
89
+ resolved.push(...menuItems);
90
+ return resolved;
91
+ }, [
92
+ onCopy,
93
+ copyLabel,
94
+ onFeedback,
95
+ feedback,
96
+ feedbackUpLabel,
97
+ feedbackDownLabel,
98
+ onRefresh,
99
+ refreshLabel,
100
+ menuItems,
101
+ ]);
102
+ const hasMenu = items.length > 0;
103
+ const longPress = (0, useLongPress_1.useLongPress)({
104
+ enabled: hasMenu,
105
+ onLongPress: () => setSheetOpen(true),
106
+ });
107
+ const classes = [
108
+ 'muka-chat-message',
109
+ `muka-chat-message--${resolvedVariant}`,
110
+ `muka-chat-message--${resolvedLength}`,
111
+ hasRail && 'muka-chat-message--has-avatar',
112
+ hasMenu && 'muka-chat-message--has-menu',
113
+ timestamp && 'muka-chat-message--has-timestamp',
114
+ hasBlocks && 'muka-chat-message--has-blocks',
115
+ menuOpen && 'muka-chat-message--menu-open',
116
+ !hasHeader && 'muka-chat-message--no-header',
117
+ className,
118
+ ]
119
+ .filter(Boolean)
120
+ .join(' ');
121
+ // Grouped messages set `reserveAvatar` to keep the rail — and so the bubbles —
122
+ // aligned with the one message in the stack that draws the avatar.
123
+ const rail = hasRail ? ((0, jsx_runtime_1.jsx)("div", { className: "muka-chat-message__rail", children: avatar })) : null;
124
+ return ((0, jsx_runtime_1.jsxs)("div", { className: classes, "data-variant": resolvedVariant, "data-length": resolvedLength, children: [(0, jsx_runtime_1.jsxs)("div", { className: "muka-chat-message__row", children: [resolvedVariant !== 'own' ? rail : null, (0, jsx_runtime_1.jsxs)("div", { className: "muka-chat-message__bubble", ...(hasMenu ? longPress : {}), children: [hasHeader && ((0, jsx_runtime_1.jsxs)("div", { className: "muka-chat-message__header", children: [author && ((0, jsx_runtime_1.jsx)("span", { className: "muka-chat-message__author", children: author })), authorMeta && ((0, jsx_runtime_1.jsx)("span", { className: "muka-chat-message__author-meta", children: authorMeta })), showBadge && (0, jsx_runtime_1.jsx)("span", { className: "muka-chat-message__badge", children: badge })] })), (0, jsx_runtime_1.jsxs)("div", { className: "muka-chat-message__body", children: [media && (0, jsx_runtime_1.jsx)("div", { className: "muka-chat-message__media", children: media }), (0, jsx_runtime_1.jsx)("div", { className: "muka-chat-message__message", children: children }), embed && ((0, jsx_runtime_1.jsxs)("div", { className: "muka-chat-message__embed", children: [(0, jsx_runtime_1.jsx)("div", { className: "muka-chat-message__embed-content", children: embed }), onEmbedCopy && ((0, jsx_runtime_1.jsx)("div", { className: "muka-chat-message__embed-copy", children: (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "muted", size: "md", iconOnly: true, type: "button", "aria-label": embedCopyLabel, onClick: onEmbedCopy, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "file-copy", size: "sm" }) }) }))] })), actionStack && ((0, jsx_runtime_1.jsx)("div", { className: "muka-chat-message__action-stack", children: actionStack }))] }), timestamp && ((0, jsx_runtime_1.jsx)("span", { className: "muka-chat-message__timestamp muka-chat-message__timestamp--inset", children: timestamp })), hasMenu && ((0, jsx_runtime_1.jsx)("div", { className: "muka-chat-message__menu", children: (0, jsx_runtime_1.jsxs)(Menu_1.Menu, { open: menuOpen, onOpenChange: setMenuOpen, children: [(0, jsx_runtime_1.jsx)(Menu_1.MenuTrigger, { asChild: true, children: (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "secondary", size: "sm", iconOnly: true, type: "button", "aria-label": menuLabel, onPointerDown: () => {
125
+ openedWithKeyboard.current = false;
126
+ }, onKeyDown: () => {
127
+ openedWithKeyboard.current = true;
128
+ }, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "arrow-down-s", size: "xs" }) }) }), (0, jsx_runtime_1.jsx)(Menu_1.MenuContent, { align: "end", onCloseAutoFocus: (event) => {
129
+ if (!openedWithKeyboard.current)
130
+ event.preventDefault();
131
+ }, children: items.map((item) => item.checked === undefined ? ((0, jsx_runtime_1.jsx)(Menu_1.MenuItem, { icon: item.icon, destructive: item.destructive, disabled: item.disabled, onSelect: item.onSelect, children: item.label }, item.id)) : ((0, jsx_runtime_1.jsx)(Menu_1.MenuCheckboxItem, { checked: item.checked, disabled: item.disabled, icon: item.icon, onCheckedChange: item.onSelect, children: item.label }, item.id))) })] }) }))] }), resolvedVariant === 'own' ? rail : null] }), hasMenu && ((0, jsx_runtime_1.jsx)(ActionSheet_1.ActionSheet, { open: sheetOpen, onOpenChange: setSheetOpen, title: menuLabel, cancel: { label: menuCancelLabel }, actions: items.map((item) => ({
132
+ label: item.label,
133
+ icon: item.icon,
134
+ onClick: item.onSelect,
135
+ destructive: item.destructive,
136
+ disabled: item.disabled,
137
+ })) }))] }));
138
+ };
139
+ exports.ChatMessage = ChatMessage;
140
+ exports.default = exports.ChatMessage;
141
+ //# sourceMappingURL=ChatMessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatMessage.js","sourceRoot":"","sources":["../../../../components/ChatMessage/ChatMessage.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChatMessageVariantContext = exports.ChatMessage = void 0;
4
+ var ChatMessage_1 = require("./ChatMessage");
5
+ Object.defineProperty(exports, "ChatMessage", { enumerable: true, get: function () { return ChatMessage_1.ChatMessage; } });
6
+ Object.defineProperty(exports, "ChatMessageVariantContext", { enumerable: true, get: function () { return ChatMessage_1.ChatMessageVariantContext; } });
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../components/ChatMessage/index.ts"],"names":[],"mappings":";;;AAAA,6CAMuB;AALrB,0GAAA,WAAW,OAAA;AACX,wHAAA,yBAAyB,OAAA"}
@@ -19,6 +19,22 @@
19
19
  align-items: stretch;
20
20
  gap: var(--spacing-8);
21
21
  width: 100%;
22
- max-width: 640px;
22
+ max-width: var(--container-max-width-sm);
23
23
  margin: 0 auto;
24
24
  }
25
+
26
+ /* ─── Print ────────────────────────────────────────────── */
27
+
28
+ @media print {
29
+ .muka-chat-message-list {
30
+ overflow: visible;
31
+ height: auto;
32
+ max-height: none;
33
+ background: none;
34
+ padding: 0;
35
+ }
36
+
37
+ .muka-chat-message-list__inner {
38
+ max-width: 100%;
39
+ }
40
+ }
@@ -11,7 +11,7 @@ require("./ChatMessageList.css");
11
11
  * Auto-scrolls to bottom when content changes. Pin the list to the bottom of
12
12
  * the conversation so new messages stay in view as they arrive.
13
13
  *
14
- * Composes with `ChatBubble` and `TypingIndicator`.
14
+ * Composes with `ChatMessage` and `TypingIndicator`.
15
15
  */
16
16
  const ChatMessageList = ({ children, autoScroll = true, className = '', 'aria-label': ariaLabel = 'Chat messages', }) => {
17
17
  const ref = (0, react_1.useRef)(null);
@@ -0,0 +1,51 @@
1
+ /* ChatMessageStack Component Styles */
2
+
3
+ .muka-chat-message-stack {
4
+ display: flex;
5
+ flex-direction: column;
6
+ gap: var(--chatbubble-stack-gap);
7
+ width: 100%;
8
+ max-width: 100%;
9
+ }
10
+
11
+ .muka-chat-message-stack__messages {
12
+ display: flex;
13
+ flex-direction: column;
14
+ gap: var(--chatbubble-stack-gap);
15
+ width: 100%;
16
+ }
17
+
18
+ /*
19
+ * Reasoning sits above the stack, indented past the avatar rail so it lines up
20
+ * with the bubbles rather than with the avatar (Figma 5379:47300).
21
+ */
22
+ .muka-chat-message-stack__reasoning {
23
+ min-width: 0;
24
+ }
25
+
26
+ .muka-chat-message-stack--has-avatar .muka-chat-message-stack__reasoning {
27
+ padding-left: calc(var(--chatbubble-avatar-size) + var(--chatbubble-row-gap));
28
+ }
29
+
30
+ .muka-chat-message-stack--own.muka-chat-message-stack--has-avatar
31
+ .muka-chat-message-stack__reasoning {
32
+ padding-left: 0;
33
+ padding-right: calc(var(--chatbubble-avatar-size) + var(--chatbubble-row-gap));
34
+ }
35
+
36
+ /* Follow the message's compact rail and gap below the desktop breakpoint */
37
+ @media (max-width: 1023px) {
38
+ .muka-chat-message-stack--has-avatar .muka-chat-message-stack__reasoning {
39
+ padding-left: calc(
40
+ var(--chatbubble-avatar-size-compact) + var(--chatbubble-row-gap-compact)
41
+ );
42
+ }
43
+
44
+ .muka-chat-message-stack--own.muka-chat-message-stack--has-avatar
45
+ .muka-chat-message-stack__reasoning {
46
+ padding-left: 0;
47
+ padding-right: calc(
48
+ var(--chatbubble-avatar-size-compact) + var(--chatbubble-row-gap-compact)
49
+ );
50
+ }
51
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ChatMessageStack = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = __importDefault(require("react"));
9
+ const ChatMessage_1 = require("../ChatMessage");
10
+ require("./ChatMessageStack.css");
11
+ /**
12
+ * ChatMessageStack — consecutive messages from one author.
13
+ *
14
+ * Only the first message carries the author line and only the last carries the
15
+ * avatar; the messages in between reserve the rail so the bubbles stay aligned.
16
+ * Pass plain `<ChatMessage>` children and let the stack place those parts.
17
+ *
18
+ * Compose inside a `ChatMessageList`.
19
+ */
20
+ const ChatMessageStack = ({ variant, children, avatar, author, authorMeta, badge, reasoning, className = '', }) => {
21
+ const messages = react_1.default.Children.toArray(children).filter(react_1.default.isValidElement);
22
+ const lastIndex = messages.length - 1;
23
+ const classes = [
24
+ 'muka-chat-message-stack',
25
+ `muka-chat-message-stack--${variant}`,
26
+ avatar && 'muka-chat-message-stack--has-avatar',
27
+ className,
28
+ ]
29
+ .filter(Boolean)
30
+ .join(' ');
31
+ return ((0, jsx_runtime_1.jsx)(ChatMessage_1.ChatMessageVariantContext.Provider, { value: variant, children: (0, jsx_runtime_1.jsxs)("div", { className: classes, "data-variant": variant, children: [reasoning && ((0, jsx_runtime_1.jsx)("div", { className: "muka-chat-message-stack__reasoning", children: reasoning })), (0, jsx_runtime_1.jsx)("div", { className: "muka-chat-message-stack__messages", children: messages.map((message, index) => {
32
+ const isLast = index === lastIndex;
33
+ const isFirst = index === 0;
34
+ // Only the first message carries the author line and only the last
35
+ // carries the avatar; the rest reserve the rail so the bubbles line
36
+ // up (Figma 5379:47050).
37
+ const overrides = {
38
+ author: isFirst ? author : undefined,
39
+ authorMeta: isFirst ? authorMeta : undefined,
40
+ badge: isFirst ? badge : undefined,
41
+ avatar: isLast ? avatar : undefined,
42
+ reserveAvatar: Boolean(avatar) && !isLast,
43
+ };
44
+ return react_1.default.cloneElement(message, overrides);
45
+ }) })] }) }));
46
+ };
47
+ exports.ChatMessageStack = ChatMessageStack;
48
+ exports.default = exports.ChatMessageStack;
49
+ //# sourceMappingURL=ChatMessageStack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatMessageStack.js","sourceRoot":"","sources":["../../../../components/ChatMessageStack/ChatMessageStack.tsx"],"names":[],"mappings":";;;;;;;AAAA,kDAA0B;AAC1B,gDAIwB;AACxB,kCAAgC;AAyChC;;;;;;;;GAQG;AACI,MAAM,gBAAgB,GAAoC,CAAC,EAChE,OAAO,EACP,QAAQ,EACR,MAAM,EACN,MAAM,EACN,UAAU,EACV,KAAK,EACL,SAAS,EACT,SAAS,GAAG,EAAE,GACf,EAAE,EAAE;IACH,MAAM,QAAQ,GAAG,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,eAAK,CAAC,cAAc,CAAC,CAAC;IAC/E,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAEtC,MAAM,OAAO,GAAG;QACd,yBAAyB;QACzB,4BAA4B,OAAO,EAAE;QACrC,MAAM,IAAI,qCAAqC;QAC/C,SAAS;KACV;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,OAAO,CACL,uBAAC,uCAAyB,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YAChD,iCAAK,SAAS,EAAE,OAAO,kBAAgB,OAAO,aAC3C,SAAS,IAAI,CACZ,gCAAK,SAAS,EAAC,oCAAoC,YAAE,SAAS,GAAO,CACtE,EAED,gCAAK,SAAS,EAAC,mCAAmC,YAC/C,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;wBAC/B,MAAM,MAAM,GAAG,KAAK,KAAK,SAAS,CAAC;wBACnC,MAAM,OAAO,GAAG,KAAK,KAAK,CAAC,CAAC;wBAE5B,mEAAmE;wBACnE,oEAAoE;wBACpE,yBAAyB;wBACzB,MAAM,SAAS,GAA8B;4BAC3C,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;4BACpC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;4BAC5C,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;4BAClC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;4BACnC,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM;yBAC1C,CAAC;wBAEF,OAAO,eAAK,CAAC,YAAY,CACvB,OAA+C,EAC/C,SAAS,CACV,CAAC;oBACJ,CAAC,CAAC,GACE,IACF,GAC6B,CACtC,CAAC;AACJ,CAAC,CAAC;AAtDW,QAAA,gBAAgB,oBAsD3B;AAEF,kBAAe,wBAAgB,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChatMessageStack = void 0;
4
+ var ChatMessageStack_1 = require("./ChatMessageStack");
5
+ Object.defineProperty(exports, "ChatMessageStack", { enumerable: true, get: function () { return ChatMessageStack_1.ChatMessageStack; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../components/ChatMessageStack/index.ts"],"names":[],"mappings":";;;AAAA,uDAAkF;AAAzE,oHAAA,gBAAgB,OAAA"}