Skip to content

fix(conversations): wrap long lines in the compose ticket editor - #75904

Merged
xljones merged 3 commits into
masterfrom
posthog-code/fix-compose-editor-wrap
Jul 31, 2026
Merged

fix(conversations): wrap long lines in the compose ticket editor#75904
xljones merged 3 commits into
masterfrom
posthog-code/fix-compose-editor-wrap

Conversation

@xljones

@xljones xljones commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Problem

In the "New outbound ticket" compose modal (ComposeTicketModal), typing into the message editor grew the modal wider and wider until it hit its max width, instead of the text wrapping. This happens with ordinary spaced text, not just long unbreakable strings. Reported from a Slack thread.

Two things combined to cause it:

  1. LemonModal is width: fit-content (capped at max-width: 90%), so it sizes to its content.
  2. The compose wrapper used min-w-[500px] — a floor with no ceiling. With no bounded width, the message paragraph laid out at its max-content width (one long line), so the modal ballooned toward 90% of the viewport as you typed.

overflow-wrap alone wouldn't fix this, since spaced text can already break — the paragraph just had unlimited room to grow into.

Changes

  • ComposeTicketModal.tsx — give the content wrapper a definite width, w-[500px] max-w-full, instead of the floor-only min-w-[500px]. Now the modal stays ~500px and text wraps. max-w-full keeps it from overflowing narrow viewports.
  • SupportEditor.scss — add overflow-wrap: anywhere to the editable .SupportEditor__content, so a long unbreakable token (like a URL) also breaks instead of overflowing the now-bounded box. This mirrors the rule already present on the read-only .SupportRichContentPreview.

How did you test this code?

This is a layout/CSS change. I (the PostHog Slack app agent) could not run the full app here, so I did not do manual testing in the live product and added no automated tests.

To validate the fix without the app, I built a standalone HTML reproduction using the real rules from LemonModal.scss and SupportEditor.scss and the exact wrapper classes, and rendered it with headless Chromium. Measured modal widths at a 1280px viewport:

State Modal width
Empty 534px
Long text — before fix 1152px (= 90% cap, ballooned)
Long text — after fix 534px (wraps)

Note

The screenshots below are from that CSS reproduction, not the live app — the width/wrapping behaviour is driven by the production CSS rules, but the theme (input chrome, colours) is approximated. Worth a quick manual confirm in the real modal before merge.

Empty modal

Empty compose modal

Long message — before (modal balloons to the 90% cap)

Before fix — modal expands horizontally

Long message — after (stays ~500px, wraps, long URL breaks)

After fix — modal stays bounded and wraps

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Investigated and fixed by the PostHog Slack app agent from a Slack thread. The reporter noticed the compose modal expanding horizontally as they typed. I first tried overflow-wrap on the editor, but the reporter pointed out spaced text also expands it — which pointed at the real cause: fit-content modal + a floor-only wrapper width. I traced widths through LemonModal.scss, bounded the wrapper, and kept overflow-wrap for unbreakable tokens. I verified both halves with a headless-Chromium reproduction built from the production CSS (numbers and screenshots above). No repo skills were invoked.


Created with PostHog from a Slack thread

The editable SupportEditor content lacked overflow-wrap, so a long unbreakable string (URL/token) in the "New outbound ticket" compose box wouldn't break and grew the editor and its modal wider until hitting the modal max width. The read-only SupportRichContentPreview already handles this with overflow-wrap: anywhere; mirror that rule on the editor content.

Generated-By: PostHog Code
Task-Id: 3495c5cc-3a7c-43be-a332-be5af74b4699
@trunk-io

trunk-io Bot commented Jul 31, 2026

Copy link
Copy Markdown

😎 Merged manually by @xljones - details.

@github-actions

Copy link
Copy Markdown
Contributor

Hey @xljones! 👋

It looks like your git author email on this PR isn't your @posthog.com address (xljones@icloud.com). Since you're on the PostHog team, it's worth pointing your local git author email at your @posthog.com address. Why it matters:

  • Consistent work identity in git history — internal tooling that attributes commits to team members keys off your @posthog.com address.
  • Keeps team contributions easy to tell apart from external community ones when scanning history.

You can fix it for this repo with:

git config user.email "you@posthog.com"

Or set it globally with git config --global user.email "you@posthog.com". No need to redo this PR — just a nudge for next time. 🙂

The compose wrapper used min-w-[500px], a floor with no ceiling. Since LemonModal is width: fit-content (max-width: 90%), the message paragraph laid out at its max-content width and ballooned the modal toward 90% of the viewport as you typed — even with ordinary spaced text, not just unbreakable strings. Give the wrapper a definite width (w-[500px] max-w-full) so it stays bounded and the text wraps.

Generated-By: PostHog Code
Task-Id: 3495c5cc-3a7c-43be-a332-be5af74b4699
xljones added a commit to PostHog/pr-assets that referenced this pull request Jul 31, 2026
xljones added a commit to PostHog/pr-assets that referenced this pull request Jul 31, 2026
xljones added a commit to PostHog/pr-assets that referenced this pull request Jul 31, 2026
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

Bundle size — no change

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 65.43 MiB · no change

No file changed by more than 1000 B.

Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report

Eager graph — within budget

How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.25 MiB · 22 files 🟢 -20 B (-0.0%) ███░░░░░░░ 27.7% of 4.51 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
8.12 MiB · 3,023 files 🔺 +30 B (+0.0%) ████████░░ 83.6% of 9.71 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4.5 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
3.9 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.4 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.3 KiB src/RootErrorBoundary.tsx
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
789 B src/scenes/ChunkLoadErrorBoundary.tsx
762 B src/index.tsx
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
285.3 KiB ../node_modules/.pnpm/posthog-js@1.409.2/node_modules/posthog-js/dist/rrweb.js
267.7 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
235.5 KiB src/taxonomy/core-filter-definitions-by-group.json
231.4 KiB ../node_modules/.pnpm/posthog-js@1.409.2/node_modules/posthog-js/dist/module.js
154.3 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
105.2 KiB src/lib/api.ts
94.7 KiB ../packages/quill/packages/quill/dist/index.js
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js

Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479

Toolbar bundle — eager 2.19 MiB within budget

What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.

Metric Size Δ vs base Budget
Eager (shipped)
entry + static imports
2.19 MiB · 17 files 🟢 -43 B (-0.0%) ████░░░░░░ 38.3% of 5.72 MiB
Deferred (lazy) 2.08 MiB · 33 files no change n/a — loads on demand
Loader dist/toolbar.js 1.1 KiB no change █░░░░░░░░░ 5.8% of 19.5 KiB
Largest eagerly-shipped chunks
Size File
717.7 KiB dist/toolbar/toolbar-app-3ZUOLZ25.css
551.1 KiB dist/toolbar/chunk-chunk-5FDJUV5A.js
484.6 KiB dist/toolbar/chunk-chunk-QCKKTYHY.js
133.6 KiB dist/toolbar/chunk-chunk-UDBJ4EGL.js
131.8 KiB dist/toolbar/chunk-chunk-T5KY5WYR.js
71.0 KiB dist/toolbar/toolbar-app-DBANC7W5.js
69.0 KiB dist/toolbar/chunk-chunk-27JL52RE.js
35.6 KiB dist/toolbar/chunk-chunk-QFZQEUXB.js
20.9 KiB dist/toolbar/chunk-chunk-HWIVFWBZ.js
12.2 KiB dist/toolbar/chunk-chunk-PIK3PADE.js

Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile

Dist folder size — 🔺 +35.1 KiB (+0.0%)

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 1371.05 MiB · 🔺 +35.1 KiB (+0.0%)

Generated-By: PostHog Code
Task-Id: 3495c5cc-3a7c-43be-a332-be5af74b4699
@xljones
xljones marked this pull request as ready for review July 31, 2026 09:57
@xljones xljones added the stamphog Request AI approval (no full review) label Jul 31, 2026
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

🦔 Hogbox preview · ✅ ready

▶ Open the preview

🔑 Login test@posthog.com / 12345678 (demo data)
🧩 Running this PR's backend and frontend, on the PostHog :master base
🔗 Link stable across rebuilds — a re-push swaps the box underneath, the URL stays
🔒 Access tailnet only (PostHog VPN)
🛠️ Admin inspect & debug state in hogland
💤 Idle sleeps after ~30 min idle (snapshot to S3, zero node cost) and wakes on your next visit in ~30s, behind a brief "waking up" screen

commit 3eddcc7 · box box-1b2d28dc4185 · ready in 869s (push → usable) · build log · rebuilds on every push, torn down on close

@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team July 31, 2026 09:58
@greptile-apps

greptile-apps Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "chore(conversations): drop the overflow-..." | Re-trigger Greptile

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trivial CSS/layout width fix outside risky territory; no security, data, or API surface touched, and no concerns raised.

  • 👍 on the PR from greptile-apps[bot], hex-security-app[bot].
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 3L, 2F substantive — within ceiling
tier T1-agent / T1a-trivial (3L, 2F, single-area, fix)
stamphog 2.0.0b4 .stamphog/policy.yml @ 801dfa4 · reviewed head 3eddcc7

@xljones
xljones merged commit e4be231 into master Jul 31, 2026
270 of 314 checks passed
@xljones
xljones deleted the posthog-code/fix-compose-editor-wrap branch July 31, 2026 10:28
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 31, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-31 11:00 UTC Run
prod-us ✅ Deployed 2026-07-31 11:20 UTC Run
prod-eu ✅ Deployed 2026-07-31 11:19 UTC Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stamphog Request AI approval (no full review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant