fix(mail-list): truncate long subjects so they don't overlap the timestamp

In the single-line (focused) message-list layout, the subject span used
`shrink-0`, which prevented `truncate` from engaging: a long subject sized to
its full content width and overflowed the bounded subject/preview group,
rendering on top of the timestamp on the right.

Let the subject shrink and truncate (`shrink-0` -> `min-w-0`), and give the
inline preview a high shrink factor (`shrink-[9999]`) so it collapses first —
the subject stays fully visible while there's room and only truncates with an
ellipsis once the preview is gone, never colliding with the time.

Applied to both email-list-item and thread-list-item (single-email and
thread-aggregate rows).
This commit is contained in:
Shuki Vaknin
2026-06-24 16:33:43 +02:00
committed by Linus Rath
parent 079ec57204
commit 5f713a033b
2 changed files with 6 additions and 6 deletions
+2 -2
View File
@@ -195,13 +195,13 @@ export function EmailListItem({ email, selected, onClick, onDoubleClick, onConte
</span> </span>
<div className="flex min-w-0 flex-1 items-center gap-2 text-sm"> <div className="flex min-w-0 flex-1 items-center gap-2 text-sm">
<span className={cn( <span className={cn(
'shrink-0 truncate', 'min-w-0 truncate',
isUnread ? 'font-semibold text-foreground' : 'text-foreground/90' isUnread ? 'font-semibold text-foreground' : 'text-foreground/90'
)}> )}>
{email.subject || t('no_subject')} {email.subject || t('no_subject')}
</span> </span>
{inlinePreview && ( {inlinePreview && (
<span className="min-w-0 truncate text-muted-foreground">{inlinePreview}</span> <span className="min-w-0 shrink-[9999] truncate text-muted-foreground">{inlinePreview}</span>
)} )}
</div> </div>
</div> </div>
+4 -4
View File
@@ -245,13 +245,13 @@ const SingleEmailItem = React.forwardRef<HTMLDivElement, SingleEmailItemProps>(
</span> </span>
<div className="flex min-w-0 flex-1 items-center gap-2 text-sm"> <div className="flex min-w-0 flex-1 items-center gap-2 text-sm">
<span className={cn( <span className={cn(
'shrink-0 truncate', 'min-w-0 truncate',
isUnread ? 'font-semibold text-foreground' : 'text-foreground/90' isUnread ? 'font-semibold text-foreground' : 'text-foreground/90'
)}> )}>
{email.subject || '(no subject)'} {email.subject || '(no subject)'}
</span> </span>
{inlinePreview && ( {inlinePreview && (
<span className="min-w-0 truncate text-muted-foreground">{inlinePreview}</span> <span className="min-w-0 shrink-[9999] truncate text-muted-foreground">{inlinePreview}</span>
)} )}
</div> </div>
</div> </div>
@@ -691,13 +691,13 @@ export const ThreadListItem = React.forwardRef<HTMLDivElement, ThreadListItemPro
</span> </span>
<div className="flex min-w-0 flex-1 items-center gap-2 text-sm"> <div className="flex min-w-0 flex-1 items-center gap-2 text-sm">
<span className={cn( <span className={cn(
'shrink-0 truncate', 'min-w-0 truncate',
hasUnread ? 'font-semibold text-foreground' : 'text-foreground/90' hasUnread ? 'font-semibold text-foreground' : 'text-foreground/90'
)}> )}>
{latestEmail.subject || '(no subject)'} {latestEmail.subject || '(no subject)'}
</span> </span>
{inlinePreview && ( {inlinePreview && (
<span className="min-w-0 truncate text-muted-foreground">{inlinePreview}</span> <span className="min-w-0 shrink-[9999] truncate text-muted-foreground">{inlinePreview}</span>
)} )}
</div> </div>
</div> </div>