mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
2 rows on mobile
This commit is contained in:
@@ -144,16 +144,11 @@ export default function ChatPanel({
|
||||
}
|
||||
|
||||
const listClass = fillHeight ? 'flex-1 min-h-0 overflow-y-auto' : 'h-48 overflow-y-auto';
|
||||
const isStackedNickname = nicknameLayout === 'stacked';
|
||||
// The composer stays as one horizontal row because this panel is used as a
|
||||
// dense control strip. The chat input is the only control that should absorb
|
||||
// tight-space pressure, so it gets no minimum width while the surrounding
|
||||
// controls stay compact and predictable.
|
||||
const composerClass = 'flex min-w-0 items-stretch gap-0.5 overflow-hidden';
|
||||
// The nickname editor is deliberately narrow in compact chat bars. Users can
|
||||
// still type longer names, but the field no longer reserves enough width to
|
||||
// crowd out the always-visible TTS controls.
|
||||
const nicknameClass = isStackedNickname ? 'w-[5rem] sm:w-[7rem] shrink-0' : 'w-[5rem] sm:w-[7rem] shrink-0';
|
||||
// The composer class owns the responsive row behavior in CSS. A container
|
||||
// query is used instead of JavaScript so the layout responds to the actual
|
||||
// panel width, which matters because this component appears in sidebars and
|
||||
// mobile layouts that do not map cleanly to viewport breakpoints.
|
||||
const composerClass = 'chat-composer';
|
||||
// Native selects include generous built-in padding and try to preserve the
|
||||
// width of their longest option. Removing horizontal padding and forcing
|
||||
// min-w-0 lets the row stay intact while keeping labels readable.
|
||||
@@ -179,11 +174,11 @@ export default function ChatPanel({
|
||||
</div>
|
||||
{!hideInput && (
|
||||
<form className={composerClass} onSubmit={handleSend}>
|
||||
<div className={nicknameClass}>
|
||||
<div className="chat-composer-nickname">
|
||||
<NicknameForm compact />
|
||||
</div>
|
||||
<input
|
||||
className="field-input min-w-0 flex-[1_1_0%]"
|
||||
className="field-input chat-composer-input"
|
||||
value={draft}
|
||||
onChange={(e) => {
|
||||
const next = e.target.value;
|
||||
@@ -209,8 +204,15 @@ export default function ChatPanel({
|
||||
placeholder={canChat ? 'Type a message…' : hideSpectatorNotice ? '' : 'Spectators cannot chat'}
|
||||
disabled={!canChat}
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!canChat || sending}
|
||||
className="button-dark chat-composer-send disabled:opacity-50"
|
||||
>
|
||||
{sending ? '...' : 'Send'}
|
||||
</button>
|
||||
{ttsSupported && (
|
||||
<div className="flex min-w-0 shrink items-center gap-0.5 overflow-hidden">
|
||||
<div className="chat-composer-tts">
|
||||
<label className="flex shrink-0 items-center gap-0.5 whitespace-nowrap text-xs text-slate-300">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -311,13 +313,6 @@ export default function ChatPanel({
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!canChat || sending}
|
||||
className="button-dark h-full shrink-0 self-stretch disabled:opacity-50"
|
||||
>
|
||||
{sending ? '...' : 'Send'}
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
</CardFrame>
|
||||
|
||||
@@ -112,6 +112,80 @@ body {
|
||||
@apply px-0.5 py-0.5 text-sm font-medium text-white transition-colors bg-rose-600 hover:bg-rose-500 rounded-md;
|
||||
}
|
||||
|
||||
.chat-composer {
|
||||
/* The chat bar lives in several panel widths, so container queries are more
|
||||
accurate than viewport media queries. The default narrow layout preserves
|
||||
a usable chat row first, then moves all TTS controls to a second row. */
|
||||
container-type: inline-size;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
gap: 0.125rem;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chat-composer-nickname {
|
||||
/* Keep nickname deliberately compact so the message input and Send button
|
||||
remain usable on mobile while still allowing longer typed nicknames. */
|
||||
flex: 0 0 5rem;
|
||||
min-width: 0;
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.chat-composer-input {
|
||||
/* This input is the pressure valve for the first row. It can shrink to the
|
||||
remaining space, but the TTS controls no longer steal that row on mobile. */
|
||||
flex: 1 1 0%;
|
||||
min-width: 0;
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.chat-composer-send {
|
||||
/* Send must stay with the message input in the narrow two-row layout. */
|
||||
flex: 0 0 auto;
|
||||
align-self: stretch;
|
||||
order: 3;
|
||||
}
|
||||
|
||||
.chat-composer-tts {
|
||||
/* The full-width basis is what creates the second row when the composer is
|
||||
narrow; the controls themselves still remain one compact TTS strip. */
|
||||
display: flex;
|
||||
flex: 1 1 100%;
|
||||
align-items: center;
|
||||
gap: 0.125rem;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
order: 4;
|
||||
}
|
||||
|
||||
@container (min-width: 44rem) {
|
||||
.chat-composer {
|
||||
/* Once there is enough room for a meaningful message field, all controls
|
||||
return to the single-row desktop layout. */
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.chat-composer-nickname {
|
||||
flex-basis: 7rem;
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.chat-composer-input {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.chat-composer-tts {
|
||||
flex: 0 1 auto;
|
||||
order: 3;
|
||||
}
|
||||
|
||||
.chat-composer-send {
|
||||
order: 4;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
|
||||
Reference in New Issue
Block a user