diff --git a/client/src/components/Planner/PlaceInspector.test.tsx b/client/src/components/Planner/PlaceInspector.test.tsx index 1c35fd0b..22e51a0d 100644 --- a/client/src/components/Planner/PlaceInspector.test.tsx +++ b/client/src/components/Planner/PlaceInspector.test.tsx @@ -647,5 +647,43 @@ describe('PlaceInspector', () => { expect(screen.queryByText('Participants')).toBeNull(); }); + // ── Scroll / overflow (issue #1195) ────────────────────────────────────── + + it('FE-PLANNER-INSPECTOR-046: content area is a bounded flex scroll region', () => { + const longText = 'Lorem ipsum dolor sit amet. '.repeat(200); + const p = buildPlace({ id: 200, description: longText, notes: longText } as any); + render(); + const scroll = screen.getByTestId('inspector-scroll') as HTMLElement; + expect(scroll.style.overflowY).toBe('auto'); + expect(scroll.style.minHeight).toBe('0px'); + // flex must allow the region to shrink/grow within the capped card + expect(scroll.style.flex).not.toBe(''); + expect(scroll.style.flex).not.toBe('0 0 auto'); + }); + + it('FE-PLANNER-INSPECTOR-047: long unbroken description wraps instead of clipping horizontally', () => { + const longWord = 'https://example.com/' + 'a'.repeat(300); + const p = buildPlace({ id: 201, description: longWord } as any); + const { container } = render(); + const descDiv = container.querySelector('.collab-note-md') as HTMLElement; + expect(descDiv).toBeTruthy(); + expect(descDiv.style.overflowWrap).toBe('anywhere'); + expect(descDiv.style.wordBreak).toBe('break-word'); + }); + + it('FE-PLANNER-INSPECTOR-048: description/notes do not shrink so the card scrolls instead of clipping', () => { + const longText = 'Lorem ipsum dolor sit amet. '.repeat(200); + const p = buildPlace({ id: 202, description: longText, notes: longText } as any); + const { container } = render(); + const notes = Array.from(container.querySelectorAll('.collab-note-md')) as HTMLElement[]; + // Both description and notes containers must keep their natural height + // (flex-shrink: 0) — otherwise they compress inside the flex column and + // overflow:hidden clips the text with no scroll (issue #1195). + expect(notes.length).toBe(2); + for (const el of notes) { + expect(el.style.flexShrink).toBe('0'); + } + }); + }); diff --git a/client/src/components/Planner/PlaceInspector.tsx b/client/src/components/Planner/PlaceInspector.tsx index ab4f6ddb..30c93fc6 100644 --- a/client/src/components/Planner/PlaceInspector.tsx +++ b/client/src/components/Planner/PlaceInspector.tsx @@ -217,7 +217,7 @@ export default function PlaceInspector({ locale={locale} timeFormat={timeFormat} onClose={onClose} /> {/* Content — scrollable */} -
+
{/* Info-Chips — hidden on mobile, shown on desktop */}
@@ -253,14 +253,14 @@ export default function PlaceInspector({ {/* Description / Summary */} {(place.description || googleDetails?.summary) && ( -
+
{place.description || googleDetails?.summary || ''}
)} {/* Notes */} {place.notes && ( -
+
{place.notes}
)} @@ -279,7 +279,7 @@ export default function PlaceInspector({
{/* Footer actions */} -
+
{selectedDayId && ( assignmentInDay ? ( onRemoveAssignment(selectedDayId, assignmentInDay.id)} variant="ghost" icon={} @@ -497,7 +497,7 @@ function ParticipantsBox({ tripMembers, participantIds, allJoined, onSetParticip function PlaceInspectorHeader({ openNow, place, category, t, editingName, nameInputRef, nameValue, setNameValue, commitNameEdit, handleNameKeyDown, startNameEdit, onUpdatePlace, locale, timeFormat, onClose }: any) { return ( -
+
{/* Avatar with open/closed ring + tag */}