fix(mobile): trim the note wrap classes to one rule and cover the kept line breaks

overflow-wrap:anywhere alone lets a long URL wrap inside a flex row; break-words
is overridden by it and word-break:break-word is deprecated. MarkdownText already
gets the rule from .collab-note-md, so its call sites drop the duplicate.
This commit is contained in:
Maurice
2026-10-04 13:40:49 +02:00
parent a9c78f680e
commit 5bcb377b9c
6 changed files with 21 additions and 10 deletions
@@ -28,7 +28,7 @@ export default function MarkdownText({ children, className = '', clamp = false }
}) {
return (
<div
className={`collab-note-md break-words [overflow-wrap:anywhere] [word-break:break-word] ${clamp ? 'truncate ' : ''}${className}`}
className={`collab-note-md ${clamp ? 'truncate ' : ''}${className}`}
style={clamp ? { maxHeight: '1.2em', lineHeight: 1.2 } : undefined}
>
<Markdown
+1 -1
View File
@@ -1535,7 +1535,7 @@ img[alt="TREK"] {
/* Markdown in Collab Notes */
.collab-note-md strong, .collab-note-md-full strong { font-weight: 700 !important; }
.collab-note-md, .collab-note-md-full { overflow-wrap: anywhere; word-break: break-word; }
.collab-note-md, .collab-note-md-full { overflow-wrap: anywhere; }
.collab-note-md em, .collab-note-md-full em { font-style: italic !important; }
.collab-note-md h1, .collab-note-md h2, .collab-note-md h3 { font-weight: 700 !important; margin: 0; }
.collab-note-md-full h1 { font-size: 1.3em !important; font-weight: 700 !important; margin: 0.8em 0 0.3em; }
@@ -574,15 +574,15 @@ export function NoteRow({ note, chrome, reorder, drag, onEdit }: {
>
<div className="flex min-w-0 items-start gap-1.5">
{time && <span className={TIME_CHIP}>{time}</span>}
<span className="min-w-0 break-words [overflow-wrap:anywhere] [word-break:break-word] text-[0.875rem] font-semibold">{title}</span>
<span className="min-w-0 text-[0.875rem] [overflow-wrap:anywhere] font-semibold">{title}</span>
</div>
{titleExtra && (
<MarkdownText className="mt-px font-geist text-[0.71875rem] leading-[1.4] text-m-muted break-words [overflow-wrap:anywhere] [word-break:break-word]">{titleExtra}</MarkdownText>
<MarkdownText className="mt-px font-geist text-[0.71875rem] leading-[1.4] text-m-muted">{titleExtra}</MarkdownText>
)}
{detail && (
// Rendered, not raw: a note written with the formatting bar would
// otherwise read as `**asterisks**` on the phone.
<MarkdownText className="mt-px font-geist text-[0.71875rem] leading-[1.45] text-m-muted break-words [overflow-wrap:anywhere] [word-break:break-word]">{detail}</MarkdownText>
<MarkdownText className="mt-px font-geist text-[0.71875rem] leading-[1.45] text-m-muted">{detail}</MarkdownText>
)}
</div>
{chrome.editing && <span className="mt-[2px] flex flex-none items-center gap-1.5">{reorder}</span>}
@@ -474,7 +474,7 @@ export default function MPlaceSheet({ planner, shell }: MTripSheetsProps) {
{day.title || t('planner.dayN', { n: (day.day_number ?? planner.days.indexOf(day) + 1) || '?' })}
</div>
)}
<div className="whitespace-pre-wrap break-words [overflow-wrap:anywhere] [word-break:break-word] font-geist text-[0.75rem] leading-[1.5] text-m-muted">{assignment.notes}</div>
<div className="whitespace-pre-wrap [overflow-wrap:anywhere] font-geist text-[0.75rem] leading-[1.5] text-m-muted">{assignment.notes}</div>
</div>
))}
</div>
@@ -360,7 +360,7 @@ function NoteCardRow({ note, color, canEdit, onTap, onTogglePin, onDelete, t }:
<button type="button" onClick={onTap} className="block w-full px-3 pb-3 pt-[9px] text-left">
{note.content && (
<div className="line-clamp-3 break-words [overflow-wrap:anywhere] [word-break:break-word] font-geist text-[0.75rem] leading-[1.5] text-m-muted [&_a]:underline [&_ol]:list-decimal [&_ol]:pl-4 [&_p]:mb-1 [&_strong]:font-bold [&_ul]:list-disc [&_ul]:pl-4">
<div className="line-clamp-3 [overflow-wrap:anywhere] font-geist text-[0.75rem] leading-[1.5] text-m-muted [&_a]:underline [&_ol]:list-decimal [&_ol]:pl-4 [&_p]:mb-1 [&_strong]:font-bold [&_ul]:list-disc [&_ul]:pl-4">
<Markdown remarkPlugins={[remarkGfm, remarkBreaks]} rehypePlugins={sanitizedMarkdownPlugins} components={sanitizedMarkdownComponents}>{note.content}</Markdown>
</div>
)}
@@ -640,7 +640,7 @@ function NoteViewSheet({ open, note, onClose, t }: {
/>
<div className="min-h-0 flex-1 overflow-y-auto px-[18px] pb-4 pt-1">
{snapshot?.content && (
<div className="break-words [overflow-wrap:anywhere] [word-break:break-word] font-geist text-[0.8125rem] leading-[1.6] text-m-ink [&_a]:underline [&_ol]:list-decimal [&_ol]:pl-5 [&_p]:mb-2 [&_strong]:font-bold [&_ul]:list-disc [&_ul]:pl-5">
<div className="font-geist text-[0.8125rem] leading-[1.6] text-m-ink [overflow-wrap:anywhere] [&_a]:underline [&_ol]:list-decimal [&_ol]:pl-5 [&_p]:mb-2 [&_strong]:font-bold [&_ul]:list-disc [&_ul]:pl-5">
<Markdown remarkPlugins={[remarkGfm, remarkBreaks]} rehypePlugins={sanitizedMarkdownPlugins} components={sanitizedMarkdownComponents}>{snapshot.content}</Markdown>
</div>
)}
@@ -481,8 +481,8 @@ describe('NoteRow', () => {
expect(screen.getByText('09:30')).toBeInTheDocument()
expect(screen.getByText('Buy museum tickets')).toBeInTheDocument()
// Two separate blocks since #1629: the extra title lines are plain text, the
// detail is rendered Markdown, so they cannot be joined into one string.
// Two separate blocks since #1629: the extra title lines and the detail are
// each rendered Markdown, so they cannot be joined into one string.
expect(screen.getByText('Cash only')).toBeInTheDocument()
expect(screen.getByText('at the kiosk')).toBeInTheDocument()
})
@@ -532,6 +532,17 @@ describe('NoteRow', () => {
fireEvent.click(screen.getByText('Buy museum tickets'))
expect(onEdit).toHaveBeenCalledTimes(1)
})
it('FE-MOB-PLROW-045: extra title lines keep their line breaks and turn a pasted URL into a link (#2576)', () => {
const url = 'https://www.google.com/maps/place/Museum/@48.1371079,11.5753822,17z/data=!3m1!4b1!4m6!3m5!1s0x0'
const { container } = render(<NoteRow {...base} note={note({ text: `Museum
Open at nine
${url}`, time: null })} />)
expect(screen.getByRole('link', { name: url })).toHaveAttribute('href', url)
// remark-breaks turns the kept newline into a <br>; joined with a space it would not be there.
expect(container.querySelector('.collab-note-md br')).not.toBeNull()
})
})
// ── Blur booking codes on the plan row (#2457) ────────────────────────────────