fix(stream-bubble): shrink bubble to text width and equalise bubble-to-bubble gap at ~14px regardless of same-sender grouping
This commit is contained in:
parent
67ee378b39
commit
53acca3755
3 changed files with 30 additions and 14 deletions
|
|
@ -6,8 +6,11 @@ import { useStreamLayoutDebug } from './streamDebug';
|
||||||
import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
|
import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
|
||||||
import { Time } from '../Time';
|
import { Time } from '../Time';
|
||||||
|
|
||||||
// Stream rows use a fixed `S400` gap so the rail-bridge offsets in
|
// Day-divider rows fall back to this `S400` MessageBase spacing variant
|
||||||
// layout.css.ts (StreamRailBridgeY = S400) match the gap between rows.
|
// (see RoomTimeline.renderDayDivider). Message rows force collapse=true
|
||||||
|
// in Message.tsx so their marginTop drops to 0 — the rail-bridge offsets
|
||||||
|
// still resolve against `StreamRailBridgeY = S400` and the small overlap
|
||||||
|
// over the tighter gap stays hidden by the dot halo.
|
||||||
export const STREAM_MESSAGE_SPACING = '400' as const;
|
export const STREAM_MESSAGE_SPACING = '400' as const;
|
||||||
|
|
||||||
// Sample timestamp used by the day-divider's invisible track-1 placeholder.
|
// Sample timestamp used by the day-divider's invisible track-1 placeholder.
|
||||||
|
|
@ -159,10 +162,7 @@ export const StreamLayout = as<'div', StreamLayoutProps>(
|
||||||
)}
|
)}
|
||||||
ref={railRef}
|
ref={railRef}
|
||||||
/>
|
/>
|
||||||
<span
|
<span className={classNames(css.StreamDotHalo, css.StreamHeaderDotHalo)} ref={dotRef}>
|
||||||
className={classNames(css.StreamDotHalo, css.StreamHeaderDotHalo)}
|
|
||||||
ref={dotRef}
|
|
||||||
>
|
|
||||||
<span
|
<span
|
||||||
className={css.StreamDotFill}
|
className={css.StreamDotFill}
|
||||||
style={{ backgroundColor: dotColor, opacity: dotOpacity }}
|
style={{ backgroundColor: dotColor, opacity: dotOpacity }}
|
||||||
|
|
|
||||||
|
|
@ -209,8 +209,13 @@ export const StreamRoot = recipe({
|
||||||
columnGap: StreamRowGapVar,
|
columnGap: StreamRowGapVar,
|
||||||
paddingLeft: StreamRowPadVar,
|
paddingLeft: StreamRowPadVar,
|
||||||
alignItems: 'flex-start',
|
alignItems: 'flex-start',
|
||||||
paddingTop: config.space.S100,
|
// Vertical padding tuned to ~3px (down from S100/4px) so the
|
||||||
paddingBottom: config.space.S100,
|
// bubble-to-bubble gap reads tighter. Per-row contribution to the
|
||||||
|
// gap drops from 8px to 7px on each side — combined with
|
||||||
|
// MessageBase's S100 top/bot the total bubble↔bubble gap is
|
||||||
|
// 4 + 3 + 0 (collapsed marginTop) + 3 + 4 = 14px ≈ S400/1.14.
|
||||||
|
paddingTop: toRem(3),
|
||||||
|
paddingBottom: toRem(3),
|
||||||
paddingRight: config.space.S400,
|
paddingRight: config.space.S400,
|
||||||
},
|
},
|
||||||
variants: {
|
variants: {
|
||||||
|
|
@ -435,13 +440,16 @@ export const StreamBubble = recipe({
|
||||||
borderRadius: `${toRem(4)} ${toRem(16)} ${toRem(16)} ${toRem(16)}`,
|
borderRadius: `${toRem(4)} ${toRem(16)} ${toRem(16)} ${toRem(16)}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Mobile fills the message column (block 100%); desktop fits content
|
// Both breakpoints fit content (inline-block + fit-content + max-width
|
||||||
// (inline-block fit-content). Branched via useScreenSizeContext, not
|
// 100% of the message column). Per user feedback бабл должен быть «по
|
||||||
// CSS media queries — see docs/plans/dm_1x1_redesign.md §5.5.
|
// размеру текстового сообщения», not stretched to the column's right
|
||||||
|
// edge on mobile. Padding still tightens on mobile (S300 vs 15px) to
|
||||||
|
// keep the bubble visually compact on narrow viewports.
|
||||||
compact: {
|
compact: {
|
||||||
true: {
|
true: {
|
||||||
display: 'block',
|
display: 'inline-block',
|
||||||
width: '100%',
|
width: 'fit-content',
|
||||||
|
maxWidth: '100%',
|
||||||
paddingLeft: config.space.S300,
|
paddingLeft: config.space.S300,
|
||||||
paddingRight: config.space.S300,
|
paddingRight: config.space.S300,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -896,7 +896,15 @@ export const Message = as<'div', MessageProps>(
|
||||||
className={classNames(css.MessageBase, className)}
|
className={classNames(css.MessageBase, className)}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
space={layout === 'channel' ? CHANNEL_MESSAGE_SPACING : STREAM_MESSAGE_SPACING}
|
space={layout === 'channel' ? CHANNEL_MESSAGE_SPACING : STREAM_MESSAGE_SPACING}
|
||||||
collapse={collapse}
|
// Stream rows always render with collapsed marginTop (=0) so the
|
||||||
|
// bubble-to-bubble gap is uniform regardless of same-sender grouping.
|
||||||
|
// Total gap = 4×S100 (StreamRoot + MessageBase vertical padding on
|
||||||
|
// both sides) = 16px. The rail-bridge in layout.css.ts is still S400
|
||||||
|
// each side — it overshoots slightly across the smaller gap, but the
|
||||||
|
// overlap lands inside DotColumn behind the dot halo and stays
|
||||||
|
// invisible. `collapse` still drives avatar/header visibility inside
|
||||||
|
// ChannelLayout — channel mode keeps the original behaviour.
|
||||||
|
collapse={layout === 'channel' ? collapse : true}
|
||||||
highlight={highlight}
|
highlight={highlight}
|
||||||
selected={!!menuAnchor || !!emojiBoardAnchor}
|
selected={!!menuAnchor || !!emojiBoardAnchor}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue