Skip to content

Commit 05236db

Browse files
authored
fix(MessageComposer): make textarea full-width in custom composer layouts (#3241)
### 🎯 Goal The message composer `<textarea>` does not fill its container when the SDK is integrated into a custom composer layout — it collapses to ~160px — even though it stretches correctly in our own example apps. Root cause: the rules that give the composer textarea its width live only inside the `.str-chat__message-composer-controls` wrapper, scoped as: ```scss .str-chat .str-chat__message-composer-controls .str-chat__textarea textarea { width: 100%; } ``` `.str-chat__textarea` and its `<textarea>` are rendered by `TextareaComposer`, but a custom composer that renders `<TextareaComposer>` without the default `MessageComposerUI` never produces the `.str-chat__message-composer-controls` wrapper. So the selector never matches, no `width` is applied, and the bare `<textarea>` falls back to its intrinsic `cols=20` width (~160px). Our example apps use the default `MessageComposerUI`, so the wrapper is present and the bug is invisible there. This is a recurring integration pain point, hence fixing it in the SDK rather than asking each integrator to re-add the width rule. ### 🛠 Implementation details Lifted the `.str-chat__textarea` block out of the `.str-chat__message-composer-controls` wrapper in `MessageComposer.scss` so it is scoped to the `TextareaComposer`'s own elements (`.str-chat .str-chat__textarea` / `.str-chat .str-chat__textarea textarea`) instead of the composer-controls layout wrapper. Why this is safe: - `.str-chat__textarea` and its `<textarea>` are rendered **only** by `TextareaComposer`, and no other rule targets `.str-chat__textarea`, so lowering selector specificity from `(0,3,1)` to `(0,2,1)` conflicts with nothing. - `flex: 1` on the wrapper is ignored when its parent isn't a flex container (custom composers) and continues to work in the default composer where the parent is `display: flex`. - The default `MessageComposerUI` already had all of these declarations applied, so its rendering is unchanged. Net effect: any composer that renders `<TextareaComposer>` now gets a full-width textarea, with or without the default `MessageComposerUI`. ### 🎨 UI Changes Verified live in a custom (Slack-style) composer that renders `<TextareaComposer>` without `MessageComposerUI`: - **Before:** composer `<textarea>` computed width = **160px** (intrinsic `cols=20` fallback). - **After:** composer `<textarea>` computed width = **1059px** — fills the composer container; the placeholder spans the full width. No visual change in the default composer (`MessageComposerUI`), which already carried these styles. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved message composer layout consistency by ensuring the text area consistently fills available space across different composer configurations. * Preserved the existing text area look and behavior, including typography, sizing, scrollbar handling, and focus-visible styling. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 3bb8a2f commit 05236db

1 file changed

Lines changed: 35 additions & 21 deletions

File tree

src/components/MessageComposer/styling/MessageComposer.scss

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -191,27 +191,6 @@
191191
ease-out;
192192
}
193193

194-
.str-chat__textarea {
195-
flex: 1;
196-
min-width: 0;
197-
position: relative;
198-
display: flex;
199-
align-items: center;
200-
width: 100%;
201-
202-
textarea {
203-
background: transparent;
204-
color: var(--str-chat__input-text-default);
205-
font: var(--str-chat__font-body-default);
206-
resize: none;
207-
border: none;
208-
box-shadow: none;
209-
outline: none;
210-
width: 100%;
211-
scrollbar-width: none;
212-
}
213-
}
214-
215194
.str-chat__emoji-picker-button {
216195
display: flex;
217196
cursor: pointer;
@@ -265,6 +244,41 @@
265244
}
266245
}
267246

247+
// Scoped to the TextareaComposer's own elements (not the composer-controls
248+
// wrapper) so the textarea fills its container in any composer layout — e.g.
249+
// a custom composer that renders <TextareaComposer> without the default
250+
// MessageComposerUI. Without this the bare <textarea> falls back to its
251+
// intrinsic `cols` width (~160px).
252+
.str-chat__textarea {
253+
flex: 1;
254+
min-width: 0;
255+
position: relative;
256+
display: flex;
257+
align-items: center;
258+
width: 100%;
259+
260+
textarea {
261+
background: transparent;
262+
color: var(--str-chat__input-text-default);
263+
font: var(--str-chat__font-body-default);
264+
resize: none;
265+
border: none;
266+
box-shadow: none;
267+
outline: none;
268+
width: 100%;
269+
scrollbar-width: none;
270+
271+
// The composer intentionally has no focus ring on the textarea itself.
272+
// Re-assert the reset on :focus-visible so it keeps outranking the global
273+
// `.str-chat *:not(:disabled):focus-visible` outline (base.scss, (0,3,0))
274+
// now that this rule is scoped one level shallower (was (0,3,1) under
275+
// .str-chat__message-composer-controls, now (0,2,1)).
276+
&:focus-visible {
277+
outline: none;
278+
}
279+
}
280+
}
281+
268282
.str-chat__message-composer--command-active
269283
.str-chat__message-composer__additional-actions {
270284
max-width: 0;

0 commit comments

Comments
 (0)