@revikornmann/muka-ui 0.9.1 → 0.10.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/ChatComposer/ChatComposer.css +52 -61
- package/dist/cjs/components/ChatComposer/ChatComposer.js +29 -6
- package/dist/cjs/components/ChatComposer/ChatComposer.js.map +1 -1
- package/dist/cjs/components/ChatComposer/index.js +6 -1
- package/dist/cjs/components/ChatComposer/index.js.map +1 -1
- package/dist/cjs/components/ProgressAccordeon/ProgressAccordeon.js +20 -6
- package/dist/cjs/components/ProgressAccordeon/ProgressAccordeon.js.map +1 -1
- package/dist/esm/components/ChatComposer/ChatComposer.css +52 -61
- package/dist/esm/components/ChatComposer/ChatComposer.js +29 -6
- package/dist/esm/components/ChatComposer/ChatComposer.js.map +1 -1
- package/dist/esm/components/ChatComposer/index.js +1 -0
- package/dist/esm/components/ChatComposer/index.js.map +1 -1
- package/dist/esm/components/ProgressAccordeon/ProgressAccordeon.js +17 -6
- package/dist/esm/components/ProgressAccordeon/ProgressAccordeon.js.map +1 -1
- package/dist/styles/components/ChatComposer.css +52 -61
- package/dist/styles/index.css +438 -447
- package/dist/styles/muka-dark.css +438 -447
- package/dist/styles/muka-light.css +438 -447
- package/dist/styles/wireframe-dark.css +438 -447
- package/dist/styles/wireframe-light.css +438 -447
- package/dist/types/components/ChatComposer/ChatComposer.d.ts +50 -18
- package/dist/types/components/ChatComposer/ChatComposer.d.ts.map +1 -1
- package/dist/types/components/ChatComposer/index.d.ts +1 -0
- package/dist/types/components/ChatComposer/index.d.ts.map +1 -1
- package/dist/types/components/ProgressAccordeon/ProgressAccordeon.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -3,15 +3,9 @@
|
|
|
3
3
|
.muka-chat-composer {
|
|
4
4
|
display: flex;
|
|
5
5
|
flex-direction: column;
|
|
6
|
-
gap: var(--spacing-
|
|
6
|
+
gap: var(--spacing-3);
|
|
7
7
|
width: 100%;
|
|
8
8
|
max-width: 768px;
|
|
9
|
-
padding: var(--spacing-3);
|
|
10
|
-
background-color: var(--color-surface-level3);
|
|
11
|
-
border-radius: var(--radius-xl);
|
|
12
|
-
box-shadow:
|
|
13
|
-
0 0 0.5px var(--color-black-alpha-5, rgba(0, 0, 0, 0.09)),
|
|
14
|
-
0 8px 8px var(--color-black-alpha-5, rgba(0, 0, 0, 0.09));
|
|
15
9
|
}
|
|
16
10
|
|
|
17
11
|
.muka-chat-composer--disabled {
|
|
@@ -19,28 +13,33 @@
|
|
|
19
13
|
pointer-events: none;
|
|
20
14
|
}
|
|
21
15
|
|
|
22
|
-
/* ───
|
|
16
|
+
/* ─── Input row ────────────────────────────────────────── */
|
|
23
17
|
|
|
24
|
-
.muka-chat-
|
|
18
|
+
.muka-chat-composer__row {
|
|
25
19
|
display: flex;
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
width: 100%;
|
|
21
|
+
align-items: flex-end;
|
|
22
|
+
gap: var(--spacing-3);
|
|
28
23
|
}
|
|
29
24
|
|
|
30
|
-
/* ───
|
|
25
|
+
/* ─── Text field ───────────────────────────────────────── */
|
|
31
26
|
|
|
32
|
-
.muka-chat-
|
|
27
|
+
.muka-chat-composer__field {
|
|
33
28
|
display: flex;
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
flex: 1 1 auto;
|
|
30
|
+
min-width: 0;
|
|
31
|
+
box-sizing: border-box;
|
|
32
|
+
align-items: center;
|
|
33
|
+
gap: var(--spacing-1);
|
|
34
|
+
min-height: var(--input-field-height-lg, 48px);
|
|
35
|
+
padding: 0 var(--spacing-2);
|
|
36
36
|
border: var(--border-width-regular) solid var(--input-field-color-default-border);
|
|
37
37
|
border-radius: var(--input-field-radius-lg);
|
|
38
38
|
background-color: var(--input-field-color-default-background);
|
|
39
|
-
padding: var(--spacing-2);
|
|
40
39
|
transition: border-color 0.12s ease;
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
.muka-chat-
|
|
42
|
+
.muka-chat-composer__field:focus-within {
|
|
44
43
|
border-color: var(--input-field-color-focus-border, var(--color-action-default));
|
|
45
44
|
}
|
|
46
45
|
|
|
@@ -48,16 +47,17 @@
|
|
|
48
47
|
flex: 1 1 auto;
|
|
49
48
|
min-width: 0;
|
|
50
49
|
width: 100%;
|
|
50
|
+
box-sizing: border-box;
|
|
51
51
|
resize: none;
|
|
52
52
|
border: none;
|
|
53
53
|
background: transparent;
|
|
54
54
|
outline: none;
|
|
55
|
-
padding: var(--spacing-1)
|
|
55
|
+
padding: 0 var(--spacing-1);
|
|
56
56
|
color: var(--color-text-default-default);
|
|
57
|
-
font-family: var(--text-body-
|
|
58
|
-
font-weight: var(--text-body-
|
|
59
|
-
font-size: var(--text-body-
|
|
60
|
-
line-height: var(--text-body-
|
|
57
|
+
font-family: var(--text-body-base-regular-fontFamily);
|
|
58
|
+
font-weight: var(--text-body-base-regular-fontWeight);
|
|
59
|
+
font-size: var(--text-body-base-regular-fontSize);
|
|
60
|
+
line-height: var(--text-body-base-regular-lineHeight);
|
|
61
61
|
appearance: none;
|
|
62
62
|
-webkit-appearance: none;
|
|
63
63
|
}
|
|
@@ -66,57 +66,48 @@
|
|
|
66
66
|
color: var(--color-text-subtle-default);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
/*
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
display: flex;
|
|
73
|
-
align-items: center;
|
|
74
|
-
justify-content: space-between;
|
|
75
|
-
gap: var(--spacing-2);
|
|
69
|
+
/* Keep the in-field emoji button flush to the bottom-right as the field grows */
|
|
70
|
+
.muka-chat-composer__emoji {
|
|
71
|
+
flex-shrink: 0;
|
|
76
72
|
}
|
|
77
73
|
|
|
78
|
-
|
|
79
|
-
display: flex;
|
|
80
|
-
align-items: center;
|
|
81
|
-
gap: var(--spacing-1);
|
|
82
|
-
}
|
|
74
|
+
/* ─── Recording bar ────────────────────────────────────── */
|
|
83
75
|
|
|
84
|
-
.muka-chat-
|
|
76
|
+
.muka-chat-composer__recording {
|
|
85
77
|
display: flex;
|
|
78
|
+
flex: 1 1 auto;
|
|
79
|
+
min-width: 0;
|
|
80
|
+
box-sizing: border-box;
|
|
86
81
|
align-items: center;
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
min-height: var(--input-field-height-lg, 48px);
|
|
83
|
+
padding: var(--card-padding-sm);
|
|
84
|
+
border: var(--border-width-regular) solid var(--card-color-default-border);
|
|
85
|
+
border-radius: var(--radius-lg);
|
|
86
|
+
background-color: var(--card-color-default-background);
|
|
89
87
|
}
|
|
90
88
|
|
|
91
|
-
/* ───
|
|
89
|
+
/* ─── Staged attachments strip ─────────────────────────── */
|
|
92
90
|
|
|
93
|
-
.muka-chat-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
justify-content: center;
|
|
97
|
-
width: var(--size-3xl, 40px);
|
|
98
|
-
height: var(--size-3xl, 40px);
|
|
99
|
-
border: none;
|
|
100
|
-
border-radius: var(--radius-lg);
|
|
101
|
-
background-color: var(--button-color-primary-background-default);
|
|
102
|
-
color: var(--button-color-primary-foreground-default);
|
|
103
|
-
cursor: pointer;
|
|
104
|
-
flex-shrink: 0;
|
|
105
|
-
-webkit-tap-highlight-color: transparent;
|
|
106
|
-
transition: background-color 0.12s ease;
|
|
91
|
+
.muka-chat-composer__attachments-strip {
|
|
92
|
+
position: relative;
|
|
93
|
+
width: 100%;
|
|
107
94
|
}
|
|
108
95
|
|
|
109
|
-
.muka-chat-
|
|
110
|
-
|
|
96
|
+
.muka-chat-composer__attachments {
|
|
97
|
+
display: flex;
|
|
98
|
+
gap: var(--spacing-3);
|
|
99
|
+
overflow-x: auto;
|
|
100
|
+
scroll-behavior: smooth;
|
|
101
|
+
scrollbar-width: none;
|
|
111
102
|
}
|
|
112
103
|
|
|
113
|
-
.muka-chat-
|
|
114
|
-
|
|
115
|
-
color: var(--color-text-subtle-default);
|
|
116
|
-
cursor: not-allowed;
|
|
104
|
+
.muka-chat-composer__attachments::-webkit-scrollbar {
|
|
105
|
+
display: none;
|
|
117
106
|
}
|
|
118
107
|
|
|
119
|
-
.muka-chat-
|
|
120
|
-
|
|
121
|
-
|
|
108
|
+
.muka-chat-composer__overflow {
|
|
109
|
+
position: absolute;
|
|
110
|
+
top: 50%;
|
|
111
|
+
right: var(--spacing-2);
|
|
112
|
+
transform: translateY(-50%);
|
|
122
113
|
}
|
|
@@ -4,27 +4,38 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.ChatComposer = void 0;
|
|
5
5
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
6
|
const react_1 = require("react");
|
|
7
|
+
const Button_1 = require("../Button");
|
|
7
8
|
const Icon_1 = require("../Icon");
|
|
8
9
|
const Spinner_1 = require("../Spinner");
|
|
9
10
|
require("./ChatComposer.css");
|
|
10
11
|
/**
|
|
11
12
|
* ChatComposer — input affordance for chat conversations.
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
14
|
+
* A horizontal row of `[leading button] · [input field] · [trailing button]`.
|
|
15
|
+
* The trailing button toggles between a mic (empty field) and a send button
|
|
16
|
+
* (text entered). Supports a voice-recording layout and a staged-attachments
|
|
17
|
+
* strip. Submits on Enter (Shift+Enter for a newline). Designed to live in a
|
|
18
|
+
* `BottomBar`.
|
|
15
19
|
*/
|
|
16
|
-
exports.ChatComposer = (0, react_1.forwardRef)(({ value, onChange, onSubmit, placeholder = 'Reply...',
|
|
20
|
+
exports.ChatComposer = (0, react_1.forwardRef)(({ value, onChange, onSubmit, placeholder = 'Reply...', onLeadingClick, leadingIcon = 'add', leadingLabel = 'Add attachment', onEmoji, showEmoji = true, emojiLabel = 'Add emoji', onRecordStart, micLabel = 'Record voice message', sendLabel = 'Send message', recording = false, recordingSlot, onRecordPause, onRecordDiscard, pauseLabel = 'Pause recording', discardLabel = 'Discard recording', attachments, attachmentsOverflowLabel = 'Show more attachments', loading = false, disabled = false, maxLines = 10, autoFocus = false, className = '', }, forwardedRef) => {
|
|
17
21
|
const textareaRef = (0, react_1.useRef)(null);
|
|
22
|
+
const attachmentsRef = (0, react_1.useRef)(null);
|
|
18
23
|
(0, react_1.useImperativeHandle)(forwardedRef, () => textareaRef.current);
|
|
24
|
+
// Auto-grow the textarea up to `maxLines`, then scroll.
|
|
19
25
|
(0, react_1.useEffect)(() => {
|
|
20
26
|
const el = textareaRef.current;
|
|
21
27
|
if (!el)
|
|
22
28
|
return;
|
|
23
29
|
el.style.height = 'auto';
|
|
30
|
+
const lineHeight = parseFloat(getComputedStyle(el).lineHeight) || 20;
|
|
31
|
+
const maxHeight = lineHeight * maxLines;
|
|
24
32
|
const next = Math.min(el.scrollHeight, maxHeight);
|
|
25
33
|
el.style.height = `${next}px`;
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
el.style.overflowY = el.scrollHeight > maxHeight ? 'auto' : 'hidden';
|
|
35
|
+
}, [value, maxLines, recording]);
|
|
36
|
+
const canSubmit = recording
|
|
37
|
+
? !disabled && !loading
|
|
38
|
+
: !disabled && !loading && value.trim().length > 0;
|
|
28
39
|
const handleSubmit = () => {
|
|
29
40
|
if (!canSubmit)
|
|
30
41
|
return;
|
|
@@ -36,8 +47,18 @@ exports.ChatComposer = (0, react_1.forwardRef)(({ value, onChange, onSubmit, pla
|
|
|
36
47
|
handleSubmit();
|
|
37
48
|
}
|
|
38
49
|
};
|
|
50
|
+
const scrollAttachments = () => {
|
|
51
|
+
const el = attachmentsRef.current;
|
|
52
|
+
if (!el)
|
|
53
|
+
return;
|
|
54
|
+
el.scrollBy({ left: el.clientWidth * 0.8, behavior: 'smooth' });
|
|
55
|
+
};
|
|
56
|
+
// Trailing button is a mic only when the field is empty, not recording, and
|
|
57
|
+
// a record handler is supplied; otherwise it is the send button.
|
|
58
|
+
const showMic = !recording && onRecordStart && value.trim().length === 0;
|
|
39
59
|
const classes = [
|
|
40
60
|
'muka-chat-composer',
|
|
61
|
+
recording && 'muka-chat-composer--recording',
|
|
41
62
|
disabled && 'muka-chat-composer--disabled',
|
|
42
63
|
className,
|
|
43
64
|
]
|
|
@@ -46,7 +67,9 @@ exports.ChatComposer = (0, react_1.forwardRef)(({ value, onChange, onSubmit, pla
|
|
|
46
67
|
return ((0, jsx_runtime_1.jsxs)("form", { className: classes, onSubmit: (e) => {
|
|
47
68
|
e.preventDefault();
|
|
48
69
|
handleSubmit();
|
|
49
|
-
}, children: [attachments && ((0, jsx_runtime_1.
|
|
70
|
+
}, children: [attachments && ((0, jsx_runtime_1.jsxs)("div", { className: "muka-chat-composer__attachments-strip", children: [(0, jsx_runtime_1.jsx)("div", { className: "muka-chat-composer__attachments", ref: attachmentsRef, children: attachments }), (0, jsx_runtime_1.jsx)(Button_1.Button, { type: "button", className: "muka-chat-composer__overflow", variant: "secondary", size: "sm", iconOnly: true, "aria-label": attachmentsOverflowLabel, onClick: scrollAttachments, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "arrow-right-s", size: "xs" }) })] })), (0, jsx_runtime_1.jsxs)("div", { className: "muka-chat-composer__row", children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { type: "button", variant: "secondary", size: "lg", iconOnly: true, disabled: disabled, "aria-label": recording ? discardLabel : leadingLabel, onClick: recording ? onRecordDiscard : onLeadingClick, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: recording ? 'delete-bin' : leadingIcon, size: "md" }) }), recording ? ((0, jsx_runtime_1.jsx)("div", { className: "muka-chat-composer__recording", children: recordingSlot })) : ((0, jsx_runtime_1.jsxs)("div", { className: "muka-chat-composer__field", children: [(0, jsx_runtime_1.jsx)("textarea", { ref: textareaRef, className: "muka-chat-composer__input", value: value, onChange: (e) => onChange(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled,
|
|
71
|
+
// eslint-disable-next-line jsx-a11y/no-autofocus
|
|
72
|
+
autoFocus: autoFocus, rows: 1, "aria-label": placeholder }), showEmoji && ((0, jsx_runtime_1.jsx)(Button_1.Button, { type: "button", className: "muka-chat-composer__emoji", variant: "ghost", size: "md", iconOnly: true, disabled: disabled, "aria-label": emojiLabel, onClick: onEmoji, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "emotion-happy", size: "sm" }) }))] })), recording && ((0, jsx_runtime_1.jsx)(Button_1.Button, { type: "button", variant: "secondary", size: "lg", iconOnly: true, disabled: disabled, "aria-label": pauseLabel, onClick: onRecordPause, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "pause-circle", size: "md" }) })), showMic ? ((0, jsx_runtime_1.jsx)(Button_1.Button, { type: "button", variant: "secondary", size: "lg", iconOnly: true, disabled: disabled, "aria-label": micLabel, onClick: onRecordStart, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "mic", size: "md" }) })) : ((0, jsx_runtime_1.jsx)(Button_1.Button, { type: "submit", variant: "primary", size: "lg", iconOnly: true, disabled: !canSubmit, "aria-label": sendLabel, children: loading ? ((0, jsx_runtime_1.jsx)(Spinner_1.Spinner, { size: "sm", variant: "inverse" })) : ((0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "send-plane2", size: "md" })) }))] })] }));
|
|
50
73
|
});
|
|
51
74
|
exports.ChatComposer.displayName = 'ChatComposer';
|
|
52
75
|
exports.default = exports.ChatComposer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatComposer.js","sourceRoot":"","sources":["../../../../components/ChatComposer/ChatComposer.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;AAEb,iCAKe;AACf,
|
|
1
|
+
{"version":3,"file":"ChatComposer.js","sourceRoot":"","sources":["../../../../components/ChatComposer/ChatComposer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ChatComposer = void 0;
|
|
6
|
+
exports.default = exports.ChatComposer = void 0;
|
|
4
7
|
var ChatComposer_1 = require("./ChatComposer");
|
|
5
8
|
Object.defineProperty(exports, "ChatComposer", { enumerable: true, get: function () { return ChatComposer_1.ChatComposer; } });
|
|
9
|
+
var ChatComposer_2 = require("./ChatComposer");
|
|
10
|
+
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(ChatComposer_2).default; } });
|
|
6
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../components/ChatComposer/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../components/ChatComposer/index.ts"],"names":[],"mappings":";;;;;;AAAA,+CAAsE;AAA7D,4GAAA,YAAY,OAAA;AACrB,+CAAyC;AAAhC,wHAAA,OAAO,OAAA"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
'use client';
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
3
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
7
|
exports.ProgressAccordeon = void 0;
|
|
5
8
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
9
|
+
const react_1 = __importDefault(require("react"));
|
|
6
10
|
const Button_1 = require("../Button");
|
|
7
11
|
const Icon_1 = require("../Icon");
|
|
8
12
|
const Divider_1 = require("../Divider");
|
|
@@ -64,12 +68,22 @@ const ProgressAccordeon = ({ state, stepNumber, heading, description, children,
|
|
|
64
68
|
// Past steps wrap the (always-mounted) slot in a grid animation container that
|
|
65
69
|
// collapses its height to zero. Marked inert + aria-hidden while collapsed so
|
|
66
70
|
// the still-mounted content is skipped by keyboard focus and assistive tech.
|
|
67
|
-
//
|
|
68
|
-
// `inert` prop
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
// `inert` is set imperatively on the DOM node rather than via a React prop:
|
|
72
|
+
// React 18 drops a boolean `inert` prop, while React 19 warns on the string
|
|
73
|
+
// form — toggling the attribute directly works correctly under both.
|
|
74
|
+
const slotWrapperRef = react_1.default.useRef(null);
|
|
75
|
+
react_1.default.useEffect(() => {
|
|
76
|
+
const node = slotWrapperRef.current;
|
|
77
|
+
if (!node)
|
|
78
|
+
return;
|
|
79
|
+
if (collapsed) {
|
|
80
|
+
node.setAttribute('inert', '');
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
node.removeAttribute('inert');
|
|
84
|
+
}
|
|
85
|
+
}, [collapsed]);
|
|
86
|
+
const pastSlot = hasSlot ? ((0, jsx_runtime_1.jsx)("div", { ref: slotWrapperRef, className: `muka-progress-accordeon__slot-wrapper${collapsed ? ' muka-progress-accordeon__slot-wrapper--collapsed' : ''}`, "aria-hidden": collapsed || undefined, children: (0, jsx_runtime_1.jsx)("div", { className: "muka-progress-accordeon__slot-clip", children: slot }) })) : null;
|
|
73
87
|
return ((0, jsx_runtime_1.jsxs)("div", { className: rootClasses, role: "group", "aria-label": `Step ${stepNumber}: ${heading}`, "aria-current": isCurrent ? 'step' : undefined, children: [isPast ? ((0, jsx_runtime_1.jsxs)("div", { className: "muka-progress-accordeon__body", children: [header, pastSlot] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [header, slot] })), hasActions && ((0, jsx_runtime_1.jsxs)("div", { className: "muka-progress-accordeon__actions", children: [secondaryAction && ((0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "secondary", size: "md", onClick: secondaryAction.onClick, disabled: secondaryAction.disabled, className: "muka-progress-accordeon__action", children: secondaryAction.label })), primaryAction && ((0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "primary", size: "md", onClick: primaryAction.onClick, disabled: primaryAction.disabled, className: "muka-progress-accordeon__action", children: primaryAction.label }))] })), divider && (0, jsx_runtime_1.jsx)(Divider_1.Divider, { className: "muka-progress-accordeon__divider" })] }));
|
|
74
88
|
};
|
|
75
89
|
exports.ProgressAccordeon = ProgressAccordeon;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProgressAccordeon.js","sourceRoot":"","sources":["../../../../components/ProgressAccordeon/ProgressAccordeon.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC
|
|
1
|
+
{"version":3,"file":"ProgressAccordeon.js","sourceRoot":"","sources":["../../../../components/ProgressAccordeon/ProgressAccordeon.tsx"],"names":[],"mappings":"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"}
|
|
@@ -3,15 +3,9 @@
|
|
|
3
3
|
.muka-chat-composer {
|
|
4
4
|
display: flex;
|
|
5
5
|
flex-direction: column;
|
|
6
|
-
gap: var(--spacing-
|
|
6
|
+
gap: var(--spacing-3);
|
|
7
7
|
width: 100%;
|
|
8
8
|
max-width: 768px;
|
|
9
|
-
padding: var(--spacing-3);
|
|
10
|
-
background-color: var(--color-surface-level3);
|
|
11
|
-
border-radius: var(--radius-xl);
|
|
12
|
-
box-shadow:
|
|
13
|
-
0 0 0.5px var(--color-black-alpha-5, rgba(0, 0, 0, 0.09)),
|
|
14
|
-
0 8px 8px var(--color-black-alpha-5, rgba(0, 0, 0, 0.09));
|
|
15
9
|
}
|
|
16
10
|
|
|
17
11
|
.muka-chat-composer--disabled {
|
|
@@ -19,28 +13,33 @@
|
|
|
19
13
|
pointer-events: none;
|
|
20
14
|
}
|
|
21
15
|
|
|
22
|
-
/* ───
|
|
16
|
+
/* ─── Input row ────────────────────────────────────────── */
|
|
23
17
|
|
|
24
|
-
.muka-chat-
|
|
18
|
+
.muka-chat-composer__row {
|
|
25
19
|
display: flex;
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
width: 100%;
|
|
21
|
+
align-items: flex-end;
|
|
22
|
+
gap: var(--spacing-3);
|
|
28
23
|
}
|
|
29
24
|
|
|
30
|
-
/* ───
|
|
25
|
+
/* ─── Text field ───────────────────────────────────────── */
|
|
31
26
|
|
|
32
|
-
.muka-chat-
|
|
27
|
+
.muka-chat-composer__field {
|
|
33
28
|
display: flex;
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
flex: 1 1 auto;
|
|
30
|
+
min-width: 0;
|
|
31
|
+
box-sizing: border-box;
|
|
32
|
+
align-items: center;
|
|
33
|
+
gap: var(--spacing-1);
|
|
34
|
+
min-height: var(--input-field-height-lg, 48px);
|
|
35
|
+
padding: 0 var(--spacing-2);
|
|
36
36
|
border: var(--border-width-regular) solid var(--input-field-color-default-border);
|
|
37
37
|
border-radius: var(--input-field-radius-lg);
|
|
38
38
|
background-color: var(--input-field-color-default-background);
|
|
39
|
-
padding: var(--spacing-2);
|
|
40
39
|
transition: border-color 0.12s ease;
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
.muka-chat-
|
|
42
|
+
.muka-chat-composer__field:focus-within {
|
|
44
43
|
border-color: var(--input-field-color-focus-border, var(--color-action-default));
|
|
45
44
|
}
|
|
46
45
|
|
|
@@ -48,16 +47,17 @@
|
|
|
48
47
|
flex: 1 1 auto;
|
|
49
48
|
min-width: 0;
|
|
50
49
|
width: 100%;
|
|
50
|
+
box-sizing: border-box;
|
|
51
51
|
resize: none;
|
|
52
52
|
border: none;
|
|
53
53
|
background: transparent;
|
|
54
54
|
outline: none;
|
|
55
|
-
padding: var(--spacing-1)
|
|
55
|
+
padding: 0 var(--spacing-1);
|
|
56
56
|
color: var(--color-text-default-default);
|
|
57
|
-
font-family: var(--text-body-
|
|
58
|
-
font-weight: var(--text-body-
|
|
59
|
-
font-size: var(--text-body-
|
|
60
|
-
line-height: var(--text-body-
|
|
57
|
+
font-family: var(--text-body-base-regular-fontFamily);
|
|
58
|
+
font-weight: var(--text-body-base-regular-fontWeight);
|
|
59
|
+
font-size: var(--text-body-base-regular-fontSize);
|
|
60
|
+
line-height: var(--text-body-base-regular-lineHeight);
|
|
61
61
|
appearance: none;
|
|
62
62
|
-webkit-appearance: none;
|
|
63
63
|
}
|
|
@@ -66,57 +66,48 @@
|
|
|
66
66
|
color: var(--color-text-subtle-default);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
/*
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
display: flex;
|
|
73
|
-
align-items: center;
|
|
74
|
-
justify-content: space-between;
|
|
75
|
-
gap: var(--spacing-2);
|
|
69
|
+
/* Keep the in-field emoji button flush to the bottom-right as the field grows */
|
|
70
|
+
.muka-chat-composer__emoji {
|
|
71
|
+
flex-shrink: 0;
|
|
76
72
|
}
|
|
77
73
|
|
|
78
|
-
|
|
79
|
-
display: flex;
|
|
80
|
-
align-items: center;
|
|
81
|
-
gap: var(--spacing-1);
|
|
82
|
-
}
|
|
74
|
+
/* ─── Recording bar ────────────────────────────────────── */
|
|
83
75
|
|
|
84
|
-
.muka-chat-
|
|
76
|
+
.muka-chat-composer__recording {
|
|
85
77
|
display: flex;
|
|
78
|
+
flex: 1 1 auto;
|
|
79
|
+
min-width: 0;
|
|
80
|
+
box-sizing: border-box;
|
|
86
81
|
align-items: center;
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
min-height: var(--input-field-height-lg, 48px);
|
|
83
|
+
padding: var(--card-padding-sm);
|
|
84
|
+
border: var(--border-width-regular) solid var(--card-color-default-border);
|
|
85
|
+
border-radius: var(--radius-lg);
|
|
86
|
+
background-color: var(--card-color-default-background);
|
|
89
87
|
}
|
|
90
88
|
|
|
91
|
-
/* ───
|
|
89
|
+
/* ─── Staged attachments strip ─────────────────────────── */
|
|
92
90
|
|
|
93
|
-
.muka-chat-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
justify-content: center;
|
|
97
|
-
width: var(--size-3xl, 40px);
|
|
98
|
-
height: var(--size-3xl, 40px);
|
|
99
|
-
border: none;
|
|
100
|
-
border-radius: var(--radius-lg);
|
|
101
|
-
background-color: var(--button-color-primary-background-default);
|
|
102
|
-
color: var(--button-color-primary-foreground-default);
|
|
103
|
-
cursor: pointer;
|
|
104
|
-
flex-shrink: 0;
|
|
105
|
-
-webkit-tap-highlight-color: transparent;
|
|
106
|
-
transition: background-color 0.12s ease;
|
|
91
|
+
.muka-chat-composer__attachments-strip {
|
|
92
|
+
position: relative;
|
|
93
|
+
width: 100%;
|
|
107
94
|
}
|
|
108
95
|
|
|
109
|
-
.muka-chat-
|
|
110
|
-
|
|
96
|
+
.muka-chat-composer__attachments {
|
|
97
|
+
display: flex;
|
|
98
|
+
gap: var(--spacing-3);
|
|
99
|
+
overflow-x: auto;
|
|
100
|
+
scroll-behavior: smooth;
|
|
101
|
+
scrollbar-width: none;
|
|
111
102
|
}
|
|
112
103
|
|
|
113
|
-
.muka-chat-
|
|
114
|
-
|
|
115
|
-
color: var(--color-text-subtle-default);
|
|
116
|
-
cursor: not-allowed;
|
|
104
|
+
.muka-chat-composer__attachments::-webkit-scrollbar {
|
|
105
|
+
display: none;
|
|
117
106
|
}
|
|
118
107
|
|
|
119
|
-
.muka-chat-
|
|
120
|
-
|
|
121
|
-
|
|
108
|
+
.muka-chat-composer__overflow {
|
|
109
|
+
position: absolute;
|
|
110
|
+
top: 50%;
|
|
111
|
+
right: var(--spacing-2);
|
|
112
|
+
transform: translateY(-50%);
|
|
122
113
|
}
|
|
@@ -1,27 +1,38 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { forwardRef, useEffect, useImperativeHandle, useRef, } from 'react';
|
|
4
|
+
import { Button } from '../Button';
|
|
4
5
|
import { Icon } from '../Icon';
|
|
5
6
|
import { Spinner } from '../Spinner';
|
|
6
7
|
import './ChatComposer.css';
|
|
7
8
|
/**
|
|
8
9
|
* ChatComposer — input affordance for chat conversations.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
* A horizontal row of `[leading button] · [input field] · [trailing button]`.
|
|
12
|
+
* The trailing button toggles between a mic (empty field) and a send button
|
|
13
|
+
* (text entered). Supports a voice-recording layout and a staged-attachments
|
|
14
|
+
* strip. Submits on Enter (Shift+Enter for a newline). Designed to live in a
|
|
15
|
+
* `BottomBar`.
|
|
12
16
|
*/
|
|
13
|
-
export const ChatComposer = forwardRef(({ value, onChange, onSubmit, placeholder = 'Reply...',
|
|
17
|
+
export const ChatComposer = forwardRef(({ value, onChange, onSubmit, placeholder = 'Reply...', onLeadingClick, leadingIcon = 'add', leadingLabel = 'Add attachment', onEmoji, showEmoji = true, emojiLabel = 'Add emoji', onRecordStart, micLabel = 'Record voice message', sendLabel = 'Send message', recording = false, recordingSlot, onRecordPause, onRecordDiscard, pauseLabel = 'Pause recording', discardLabel = 'Discard recording', attachments, attachmentsOverflowLabel = 'Show more attachments', loading = false, disabled = false, maxLines = 10, autoFocus = false, className = '', }, forwardedRef) => {
|
|
14
18
|
const textareaRef = useRef(null);
|
|
19
|
+
const attachmentsRef = useRef(null);
|
|
15
20
|
useImperativeHandle(forwardedRef, () => textareaRef.current);
|
|
21
|
+
// Auto-grow the textarea up to `maxLines`, then scroll.
|
|
16
22
|
useEffect(() => {
|
|
17
23
|
const el = textareaRef.current;
|
|
18
24
|
if (!el)
|
|
19
25
|
return;
|
|
20
26
|
el.style.height = 'auto';
|
|
27
|
+
const lineHeight = parseFloat(getComputedStyle(el).lineHeight) || 20;
|
|
28
|
+
const maxHeight = lineHeight * maxLines;
|
|
21
29
|
const next = Math.min(el.scrollHeight, maxHeight);
|
|
22
30
|
el.style.height = `${next}px`;
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
el.style.overflowY = el.scrollHeight > maxHeight ? 'auto' : 'hidden';
|
|
32
|
+
}, [value, maxLines, recording]);
|
|
33
|
+
const canSubmit = recording
|
|
34
|
+
? !disabled && !loading
|
|
35
|
+
: !disabled && !loading && value.trim().length > 0;
|
|
25
36
|
const handleSubmit = () => {
|
|
26
37
|
if (!canSubmit)
|
|
27
38
|
return;
|
|
@@ -33,8 +44,18 @@ export const ChatComposer = forwardRef(({ value, onChange, onSubmit, placeholder
|
|
|
33
44
|
handleSubmit();
|
|
34
45
|
}
|
|
35
46
|
};
|
|
47
|
+
const scrollAttachments = () => {
|
|
48
|
+
const el = attachmentsRef.current;
|
|
49
|
+
if (!el)
|
|
50
|
+
return;
|
|
51
|
+
el.scrollBy({ left: el.clientWidth * 0.8, behavior: 'smooth' });
|
|
52
|
+
};
|
|
53
|
+
// Trailing button is a mic only when the field is empty, not recording, and
|
|
54
|
+
// a record handler is supplied; otherwise it is the send button.
|
|
55
|
+
const showMic = !recording && onRecordStart && value.trim().length === 0;
|
|
36
56
|
const classes = [
|
|
37
57
|
'muka-chat-composer',
|
|
58
|
+
recording && 'muka-chat-composer--recording',
|
|
38
59
|
disabled && 'muka-chat-composer--disabled',
|
|
39
60
|
className,
|
|
40
61
|
]
|
|
@@ -43,7 +64,9 @@ export const ChatComposer = forwardRef(({ value, onChange, onSubmit, placeholder
|
|
|
43
64
|
return (_jsxs("form", { className: classes, onSubmit: (e) => {
|
|
44
65
|
e.preventDefault();
|
|
45
66
|
handleSubmit();
|
|
46
|
-
}, children: [attachments && (
|
|
67
|
+
}, children: [attachments && (_jsxs("div", { className: "muka-chat-composer__attachments-strip", children: [_jsx("div", { className: "muka-chat-composer__attachments", ref: attachmentsRef, children: attachments }), _jsx(Button, { type: "button", className: "muka-chat-composer__overflow", variant: "secondary", size: "sm", iconOnly: true, "aria-label": attachmentsOverflowLabel, onClick: scrollAttachments, children: _jsx(Icon, { name: "arrow-right-s", size: "xs" }) })] })), _jsxs("div", { className: "muka-chat-composer__row", children: [_jsx(Button, { type: "button", variant: "secondary", size: "lg", iconOnly: true, disabled: disabled, "aria-label": recording ? discardLabel : leadingLabel, onClick: recording ? onRecordDiscard : onLeadingClick, children: _jsx(Icon, { name: recording ? 'delete-bin' : leadingIcon, size: "md" }) }), recording ? (_jsx("div", { className: "muka-chat-composer__recording", children: recordingSlot })) : (_jsxs("div", { className: "muka-chat-composer__field", children: [_jsx("textarea", { ref: textareaRef, className: "muka-chat-composer__input", value: value, onChange: (e) => onChange(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled,
|
|
68
|
+
// eslint-disable-next-line jsx-a11y/no-autofocus
|
|
69
|
+
autoFocus: autoFocus, rows: 1, "aria-label": placeholder }), showEmoji && (_jsx(Button, { type: "button", className: "muka-chat-composer__emoji", variant: "ghost", size: "md", iconOnly: true, disabled: disabled, "aria-label": emojiLabel, onClick: onEmoji, children: _jsx(Icon, { name: "emotion-happy", size: "sm" }) }))] })), recording && (_jsx(Button, { type: "button", variant: "secondary", size: "lg", iconOnly: true, disabled: disabled, "aria-label": pauseLabel, onClick: onRecordPause, children: _jsx(Icon, { name: "pause-circle", size: "md" }) })), showMic ? (_jsx(Button, { type: "button", variant: "secondary", size: "lg", iconOnly: true, disabled: disabled, "aria-label": micLabel, onClick: onRecordStart, children: _jsx(Icon, { name: "mic", size: "md" }) })) : (_jsx(Button, { type: "submit", variant: "primary", size: "lg", iconOnly: true, disabled: !canSubmit, "aria-label": sendLabel, children: loading ? (_jsx(Spinner, { size: "sm", variant: "inverse" })) : (_jsx(Icon, { name: "send-plane2", size: "md" })) }))] })] }));
|
|
47
70
|
});
|
|
48
71
|
ChatComposer.displayName = 'ChatComposer';
|
|
49
72
|
export default ChatComposer;
|