@revikornmann/muka-ui 0.13.0 → 0.14.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.
- package/dist/cjs/components/ChatMessage/ChatMessage.css +13 -17
- package/dist/cjs/components/ChatMessage/ChatMessage.js +12 -15
- package/dist/cjs/components/ChatMessage/ChatMessage.js.map +1 -1
- package/dist/esm/components/ChatMessage/ChatMessage.css +13 -17
- package/dist/esm/components/ChatMessage/ChatMessage.js +12 -15
- package/dist/esm/components/ChatMessage/ChatMessage.js.map +1 -1
- package/dist/styles/components/ChatMessage.css +13 -17
- package/dist/styles/index.css +1665 -1669
- package/dist/styles/muka-dark.css +1665 -1669
- package/dist/styles/muka-light.css +1665 -1669
- package/dist/styles/wireframe-dark.css +1665 -1669
- package/dist/styles/wireframe-light.css +1665 -1669
- package/dist/types/components/ChatMessage/ChatMessage.d.ts +7 -10
- package/dist/types/components/ChatMessage/ChatMessage.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -22,11 +22,6 @@
|
|
|
22
22
|
grid-template-areas: 'rail bubble';
|
|
23
23
|
}
|
|
24
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
25
|
.muka-chat-message__rail {
|
|
31
26
|
grid-area: rail;
|
|
32
27
|
/* Sits on the bubble's baseline (Figma 5355:44091) */
|
|
@@ -61,6 +56,12 @@
|
|
|
61
56
|
|
|
62
57
|
.muka-chat-message__bubble {
|
|
63
58
|
grid-area: bubble;
|
|
59
|
+
/*
|
|
60
|
+
* Width follows the content: a single line hugs, and once the text wraps the
|
|
61
|
+
* bubble fills to the shared max width. Robust to string or rich children —
|
|
62
|
+
* no length measuring needed (Figma `Text length` on 5355:44091).
|
|
63
|
+
*/
|
|
64
|
+
width: fit-content;
|
|
64
65
|
max-width: var(--chatbubble-max-width);
|
|
65
66
|
position: relative;
|
|
66
67
|
display: flex;
|
|
@@ -73,18 +74,11 @@
|
|
|
73
74
|
word-break: break-word;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
/*
|
|
77
|
-
|
|
78
|
-
* content, long ones fill the row up to the shared max width.
|
|
79
|
-
*/
|
|
80
|
-
.muka-chat-message--long .muka-chat-message__bubble {
|
|
77
|
+
/* Media, an embed or an action stack always run the full bubble width. */
|
|
78
|
+
.muka-chat-message--has-blocks .muka-chat-message__bubble {
|
|
81
79
|
width: 100%;
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
.muka-chat-message--short .muka-chat-message__bubble {
|
|
85
|
-
width: fit-content;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
82
|
.muka-chat-message--own .muka-chat-message__bubble {
|
|
89
83
|
justify-self: end;
|
|
90
84
|
}
|
|
@@ -262,10 +256,12 @@
|
|
|
262
256
|
}
|
|
263
257
|
|
|
264
258
|
/*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
259
|
+
* When the last block in the body is media, an embed or an action stack (not
|
|
260
|
+
* trailing text), it runs the full width, so reserve a line below for the inset
|
|
261
|
+
* timestamp. A message that ends in text clears the corner inline instead (see
|
|
262
|
+
* `__message` padding-right above), so it needs no extra bottom space.
|
|
267
263
|
*/
|
|
268
|
-
.muka-chat-message--has-timestamp.muka-chat-message--
|
|
264
|
+
.muka-chat-message--has-timestamp.muka-chat-message--trailing-block .muka-chat-message__body {
|
|
269
265
|
padding-bottom: var(--text-body-xs-regular-lineHeight);
|
|
270
266
|
}
|
|
271
267
|
|
|
@@ -10,11 +10,6 @@ const Menu_1 = require("../Menu");
|
|
|
10
10
|
const ActionSheet_1 = require("../ActionSheet");
|
|
11
11
|
const useLongPress_1 = require("../../utils/useLongPress");
|
|
12
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
13
|
/**
|
|
19
14
|
* Set by `ChatMessageStack` so its children inherit the author without every
|
|
20
15
|
* message repeating it. Exported for the stack; not part of the public API.
|
|
@@ -32,7 +27,7 @@ exports.ChatMessageVariantContext = (0, react_1.createContext)(null);
|
|
|
32
27
|
* live behind one options menu: a dropdown revealed on hover on pointer
|
|
33
28
|
* devices, and a bottom sheet opened by long-pressing the bubble on touch.
|
|
34
29
|
*/
|
|
35
|
-
const ChatMessage = ({ variant, children,
|
|
30
|
+
const ChatMessage = ({ variant, children, 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
31
|
const [menuOpen, setMenuOpen] = (0, react_1.useState)(false);
|
|
37
32
|
const [sheetOpen, setSheetOpen] = (0, react_1.useState)(false);
|
|
38
33
|
// The trigger is revealed on hover, so focus must not linger on it after a
|
|
@@ -45,13 +40,15 @@ const ChatMessage = ({ variant, children, length = 'auto', avatar, reserveAvatar
|
|
|
45
40
|
// The visibility badge hangs off the author line, so it goes when the author does.
|
|
46
41
|
const showBadge = Boolean(author && badge);
|
|
47
42
|
const hasHeader = Boolean(author || authorMeta || showBadge);
|
|
48
|
-
|
|
43
|
+
// `own` never shows an avatar, so it never reserves the rail either.
|
|
44
|
+
const hasRail = resolvedVariant !== 'own' && Boolean(avatar || reserveAvatar);
|
|
49
45
|
const hasBlocks = Boolean(media || embed || actionStack);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
// The inset timestamp needs a clear bottom-right corner. When the last block
|
|
47
|
+
// in the body is text it reserves that space inline (see `__message`
|
|
48
|
+
// padding-right); when it is media/embed/action-stack, the body reserves a
|
|
49
|
+
// line below instead. Render order is media → text → embed → action-stack.
|
|
50
|
+
const hasText = typeof children === 'string' ? children.trim().length > 0 : Boolean(children);
|
|
51
|
+
const trailingBlock = Boolean(actionStack || embed || (media && !hasText));
|
|
55
52
|
const items = (0, react_1.useMemo)(() => {
|
|
56
53
|
const resolved = [];
|
|
57
54
|
if (onCopy) {
|
|
@@ -107,11 +104,11 @@ const ChatMessage = ({ variant, children, length = 'auto', avatar, reserveAvatar
|
|
|
107
104
|
const classes = [
|
|
108
105
|
'muka-chat-message',
|
|
109
106
|
`muka-chat-message--${resolvedVariant}`,
|
|
110
|
-
`muka-chat-message--${resolvedLength}`,
|
|
111
107
|
hasRail && 'muka-chat-message--has-avatar',
|
|
112
108
|
hasMenu && 'muka-chat-message--has-menu',
|
|
113
109
|
timestamp && 'muka-chat-message--has-timestamp',
|
|
114
110
|
hasBlocks && 'muka-chat-message--has-blocks',
|
|
111
|
+
trailingBlock && 'muka-chat-message--trailing-block',
|
|
115
112
|
menuOpen && 'muka-chat-message--menu-open',
|
|
116
113
|
!hasHeader && 'muka-chat-message--no-header',
|
|
117
114
|
className,
|
|
@@ -121,14 +118,14 @@ const ChatMessage = ({ variant, children, length = 'auto', avatar, reserveAvatar
|
|
|
121
118
|
// Grouped messages set `reserveAvatar` to keep the rail — and so the bubbles —
|
|
122
119
|
// aligned with the one message in the stack that draws the avatar.
|
|
123
120
|
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,
|
|
121
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: classes, "data-variant": resolvedVariant, children: [(0, jsx_runtime_1.jsxs)("div", { className: "muka-chat-message__row", children: [rail, (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
122
|
openedWithKeyboard.current = false;
|
|
126
123
|
}, onKeyDown: () => {
|
|
127
124
|
openedWithKeyboard.current = true;
|
|
128
125
|
}, 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
126
|
if (!openedWithKeyboard.current)
|
|
130
127
|
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))) })] }) }))] })
|
|
128
|
+
}, 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))) })] }) }))] })] }), hasMenu && ((0, jsx_runtime_1.jsx)(ActionSheet_1.ActionSheet, { open: sheetOpen, onOpenChange: setSheetOpen, title: menuLabel, cancel: { label: menuCancelLabel }, actions: items.map((item) => ({
|
|
132
129
|
label: item.label,
|
|
133
130
|
icon: item.icon,
|
|
134
131
|
onClick: item.onSelect,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatMessage.js","sourceRoot":"","sources":["../../../../components/ChatMessage/ChatMessage.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;AAEb,iCAAoF;AACpF,sCAAmC;AACnC,kCAA+B;AAC/B,kCAAqF;AACrF,gDAA6C;AAC7C,2DAAwD;AACxD,6BAA2B;
|
|
1
|
+
{"version":3,"file":"ChatMessage.js","sourceRoot":"","sources":["../../../../components/ChatMessage/ChatMessage.tsx"],"names":[],"mappings":"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"}
|
|
@@ -22,11 +22,6 @@
|
|
|
22
22
|
grid-template-areas: 'rail bubble';
|
|
23
23
|
}
|
|
24
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
25
|
.muka-chat-message__rail {
|
|
31
26
|
grid-area: rail;
|
|
32
27
|
/* Sits on the bubble's baseline (Figma 5355:44091) */
|
|
@@ -61,6 +56,12 @@
|
|
|
61
56
|
|
|
62
57
|
.muka-chat-message__bubble {
|
|
63
58
|
grid-area: bubble;
|
|
59
|
+
/*
|
|
60
|
+
* Width follows the content: a single line hugs, and once the text wraps the
|
|
61
|
+
* bubble fills to the shared max width. Robust to string or rich children —
|
|
62
|
+
* no length measuring needed (Figma `Text length` on 5355:44091).
|
|
63
|
+
*/
|
|
64
|
+
width: fit-content;
|
|
64
65
|
max-width: var(--chatbubble-max-width);
|
|
65
66
|
position: relative;
|
|
66
67
|
display: flex;
|
|
@@ -73,18 +74,11 @@
|
|
|
73
74
|
word-break: break-word;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
/*
|
|
77
|
-
|
|
78
|
-
* content, long ones fill the row up to the shared max width.
|
|
79
|
-
*/
|
|
80
|
-
.muka-chat-message--long .muka-chat-message__bubble {
|
|
77
|
+
/* Media, an embed or an action stack always run the full bubble width. */
|
|
78
|
+
.muka-chat-message--has-blocks .muka-chat-message__bubble {
|
|
81
79
|
width: 100%;
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
.muka-chat-message--short .muka-chat-message__bubble {
|
|
85
|
-
width: fit-content;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
82
|
.muka-chat-message--own .muka-chat-message__bubble {
|
|
89
83
|
justify-self: end;
|
|
90
84
|
}
|
|
@@ -262,10 +256,12 @@
|
|
|
262
256
|
}
|
|
263
257
|
|
|
264
258
|
/*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
259
|
+
* When the last block in the body is media, an embed or an action stack (not
|
|
260
|
+
* trailing text), it runs the full width, so reserve a line below for the inset
|
|
261
|
+
* timestamp. A message that ends in text clears the corner inline instead (see
|
|
262
|
+
* `__message` padding-right above), so it needs no extra bottom space.
|
|
267
263
|
*/
|
|
268
|
-
.muka-chat-message--has-timestamp.muka-chat-message--
|
|
264
|
+
.muka-chat-message--has-timestamp.muka-chat-message--trailing-block .muka-chat-message__body {
|
|
269
265
|
padding-bottom: var(--text-body-xs-regular-lineHeight);
|
|
270
266
|
}
|
|
271
267
|
|
|
@@ -7,11 +7,6 @@ import { Menu, MenuTrigger, MenuContent, MenuItem, MenuCheckboxItem } from '../M
|
|
|
7
7
|
import { ActionSheet } from '../ActionSheet';
|
|
8
8
|
import { useLongPress } from '../../utils/useLongPress';
|
|
9
9
|
import './ChatMessage.css';
|
|
10
|
-
/**
|
|
11
|
-
* Messages at or below this many characters hug their content; longer ones fill
|
|
12
|
-
* the available width (Figma `Text length` axis on `5355:44091`).
|
|
13
|
-
*/
|
|
14
|
-
const SHORT_MESSAGE_MAX_LENGTH = 100;
|
|
15
10
|
/**
|
|
16
11
|
* Set by `ChatMessageStack` so its children inherit the author without every
|
|
17
12
|
* message repeating it. Exported for the stack; not part of the public API.
|
|
@@ -29,7 +24,7 @@ export const ChatMessageVariantContext = createContext(null);
|
|
|
29
24
|
* live behind one options menu: a dropdown revealed on hover on pointer
|
|
30
25
|
* devices, and a bottom sheet opened by long-pressing the bubble on touch.
|
|
31
26
|
*/
|
|
32
|
-
export const ChatMessage = ({ variant, children,
|
|
27
|
+
export const ChatMessage = ({ variant, children, 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 = '', }) => {
|
|
33
28
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
34
29
|
const [sheetOpen, setSheetOpen] = useState(false);
|
|
35
30
|
// The trigger is revealed on hover, so focus must not linger on it after a
|
|
@@ -42,13 +37,15 @@ export const ChatMessage = ({ variant, children, length = 'auto', avatar, reserv
|
|
|
42
37
|
// The visibility badge hangs off the author line, so it goes when the author does.
|
|
43
38
|
const showBadge = Boolean(author && badge);
|
|
44
39
|
const hasHeader = Boolean(author || authorMeta || showBadge);
|
|
45
|
-
|
|
40
|
+
// `own` never shows an avatar, so it never reserves the rail either.
|
|
41
|
+
const hasRail = resolvedVariant !== 'own' && Boolean(avatar || reserveAvatar);
|
|
46
42
|
const hasBlocks = Boolean(media || embed || actionStack);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
// The inset timestamp needs a clear bottom-right corner. When the last block
|
|
44
|
+
// in the body is text it reserves that space inline (see `__message`
|
|
45
|
+
// padding-right); when it is media/embed/action-stack, the body reserves a
|
|
46
|
+
// line below instead. Render order is media → text → embed → action-stack.
|
|
47
|
+
const hasText = typeof children === 'string' ? children.trim().length > 0 : Boolean(children);
|
|
48
|
+
const trailingBlock = Boolean(actionStack || embed || (media && !hasText));
|
|
52
49
|
const items = useMemo(() => {
|
|
53
50
|
const resolved = [];
|
|
54
51
|
if (onCopy) {
|
|
@@ -104,11 +101,11 @@ export const ChatMessage = ({ variant, children, length = 'auto', avatar, reserv
|
|
|
104
101
|
const classes = [
|
|
105
102
|
'muka-chat-message',
|
|
106
103
|
`muka-chat-message--${resolvedVariant}`,
|
|
107
|
-
`muka-chat-message--${resolvedLength}`,
|
|
108
104
|
hasRail && 'muka-chat-message--has-avatar',
|
|
109
105
|
hasMenu && 'muka-chat-message--has-menu',
|
|
110
106
|
timestamp && 'muka-chat-message--has-timestamp',
|
|
111
107
|
hasBlocks && 'muka-chat-message--has-blocks',
|
|
108
|
+
trailingBlock && 'muka-chat-message--trailing-block',
|
|
112
109
|
menuOpen && 'muka-chat-message--menu-open',
|
|
113
110
|
!hasHeader && 'muka-chat-message--no-header',
|
|
114
111
|
className,
|
|
@@ -118,14 +115,14 @@ export const ChatMessage = ({ variant, children, length = 'auto', avatar, reserv
|
|
|
118
115
|
// Grouped messages set `reserveAvatar` to keep the rail — and so the bubbles —
|
|
119
116
|
// aligned with the one message in the stack that draws the avatar.
|
|
120
117
|
const rail = hasRail ? (_jsx("div", { className: "muka-chat-message__rail", children: avatar })) : null;
|
|
121
|
-
return (_jsxs("div", { className: classes, "data-variant": resolvedVariant,
|
|
118
|
+
return (_jsxs("div", { className: classes, "data-variant": resolvedVariant, children: [_jsxs("div", { className: "muka-chat-message__row", children: [rail, _jsxs("div", { className: "muka-chat-message__bubble", ...(hasMenu ? longPress : {}), children: [hasHeader && (_jsxs("div", { className: "muka-chat-message__header", children: [author && (_jsx("span", { className: "muka-chat-message__author", children: author })), authorMeta && (_jsx("span", { className: "muka-chat-message__author-meta", children: authorMeta })), showBadge && _jsx("span", { className: "muka-chat-message__badge", children: badge })] })), _jsxs("div", { className: "muka-chat-message__body", children: [media && _jsx("div", { className: "muka-chat-message__media", children: media }), _jsx("div", { className: "muka-chat-message__message", children: children }), embed && (_jsxs("div", { className: "muka-chat-message__embed", children: [_jsx("div", { className: "muka-chat-message__embed-content", children: embed }), onEmbedCopy && (_jsx("div", { className: "muka-chat-message__embed-copy", children: _jsx(Button, { variant: "muted", size: "md", iconOnly: true, type: "button", "aria-label": embedCopyLabel, onClick: onEmbedCopy, children: _jsx(Icon, { name: "file-copy", size: "sm" }) }) }))] })), actionStack && (_jsx("div", { className: "muka-chat-message__action-stack", children: actionStack }))] }), timestamp && (_jsx("span", { className: "muka-chat-message__timestamp muka-chat-message__timestamp--inset", children: timestamp })), hasMenu && (_jsx("div", { className: "muka-chat-message__menu", children: _jsxs(Menu, { open: menuOpen, onOpenChange: setMenuOpen, children: [_jsx(MenuTrigger, { asChild: true, children: _jsx(Button, { variant: "secondary", size: "sm", iconOnly: true, type: "button", "aria-label": menuLabel, onPointerDown: () => {
|
|
122
119
|
openedWithKeyboard.current = false;
|
|
123
120
|
}, onKeyDown: () => {
|
|
124
121
|
openedWithKeyboard.current = true;
|
|
125
122
|
}, children: _jsx(Icon, { name: "arrow-down-s", size: "xs" }) }) }), _jsx(MenuContent, { align: "end", onCloseAutoFocus: (event) => {
|
|
126
123
|
if (!openedWithKeyboard.current)
|
|
127
124
|
event.preventDefault();
|
|
128
|
-
}, children: items.map((item) => item.checked === undefined ? (_jsx(MenuItem, { icon: item.icon, destructive: item.destructive, disabled: item.disabled, onSelect: item.onSelect, children: item.label }, item.id)) : (_jsx(MenuCheckboxItem, { checked: item.checked, disabled: item.disabled, icon: item.icon, onCheckedChange: item.onSelect, children: item.label }, item.id))) })] }) }))] })
|
|
125
|
+
}, children: items.map((item) => item.checked === undefined ? (_jsx(MenuItem, { icon: item.icon, destructive: item.destructive, disabled: item.disabled, onSelect: item.onSelect, children: item.label }, item.id)) : (_jsx(MenuCheckboxItem, { checked: item.checked, disabled: item.disabled, icon: item.icon, onCheckedChange: item.onSelect, children: item.label }, item.id))) })] }) }))] })] }), hasMenu && (_jsx(ActionSheet, { open: sheetOpen, onOpenChange: setSheetOpen, title: menuLabel, cancel: { label: menuCancelLabel }, actions: items.map((item) => ({
|
|
129
126
|
label: item.label,
|
|
130
127
|
icon: item.icon,
|
|
131
128
|
onClick: item.onSelect,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatMessage.js","sourceRoot":"","sources":["../../../../components/ChatMessage/ChatMessage.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAc,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACpF,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ChatMessage.js","sourceRoot":"","sources":["../../../../components/ChatMessage/ChatMessage.tsx"],"names":[],"mappings":"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"}
|
|
@@ -22,11 +22,6 @@
|
|
|
22
22
|
grid-template-areas: 'rail bubble';
|
|
23
23
|
}
|
|
24
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
25
|
.muka-chat-message__rail {
|
|
31
26
|
grid-area: rail;
|
|
32
27
|
/* Sits on the bubble's baseline (Figma 5355:44091) */
|
|
@@ -61,6 +56,12 @@
|
|
|
61
56
|
|
|
62
57
|
.muka-chat-message__bubble {
|
|
63
58
|
grid-area: bubble;
|
|
59
|
+
/*
|
|
60
|
+
* Width follows the content: a single line hugs, and once the text wraps the
|
|
61
|
+
* bubble fills to the shared max width. Robust to string or rich children —
|
|
62
|
+
* no length measuring needed (Figma `Text length` on 5355:44091).
|
|
63
|
+
*/
|
|
64
|
+
width: fit-content;
|
|
64
65
|
max-width: var(--chatbubble-max-width);
|
|
65
66
|
position: relative;
|
|
66
67
|
display: flex;
|
|
@@ -73,18 +74,11 @@
|
|
|
73
74
|
word-break: break-word;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
/*
|
|
77
|
-
|
|
78
|
-
* content, long ones fill the row up to the shared max width.
|
|
79
|
-
*/
|
|
80
|
-
.muka-chat-message--long .muka-chat-message__bubble {
|
|
77
|
+
/* Media, an embed or an action stack always run the full bubble width. */
|
|
78
|
+
.muka-chat-message--has-blocks .muka-chat-message__bubble {
|
|
81
79
|
width: 100%;
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
.muka-chat-message--short .muka-chat-message__bubble {
|
|
85
|
-
width: fit-content;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
82
|
.muka-chat-message--own .muka-chat-message__bubble {
|
|
89
83
|
justify-self: end;
|
|
90
84
|
}
|
|
@@ -262,10 +256,12 @@
|
|
|
262
256
|
}
|
|
263
257
|
|
|
264
258
|
/*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
259
|
+
* When the last block in the body is media, an embed or an action stack (not
|
|
260
|
+
* trailing text), it runs the full width, so reserve a line below for the inset
|
|
261
|
+
* timestamp. A message that ends in text clears the corner inline instead (see
|
|
262
|
+
* `__message` padding-right above), so it needs no extra bottom space.
|
|
267
263
|
*/
|
|
268
|
-
.muka-chat-message--has-timestamp.muka-chat-message--
|
|
264
|
+
.muka-chat-message--has-timestamp.muka-chat-message--trailing-block .muka-chat-message__body {
|
|
269
265
|
padding-bottom: var(--text-body-xs-regular-lineHeight);
|
|
270
266
|
}
|
|
271
267
|
|