diff --git a/src/components/LayoutTree.tsx b/src/components/LayoutTree.tsx
index 50fbbad3bf..2004b1dc2d 100644
--- a/src/components/LayoutTree.tsx
+++ b/src/components/LayoutTree.tsx
@@ -6,7 +6,7 @@ import { css, cx } from '../../styled-system/css'
import Index from '../@types/IndexType'
import ThoughtId from '../@types/ThoughtId'
import { isTouch } from '../browser'
-import { LongPressState } from '../constants'
+import { CONTENT_BOX_PADDING_LEFT, LongPressState } from '../constants'
import testFlags from '../e2e/testFlags'
import usePositionedThoughts from '../hooks/usePositionedThoughts'
import useSizeTracking from '../hooks/useSizeTracking'
@@ -143,8 +143,8 @@ const LayoutTree = () => {
: 0,
)
- // Width of thought bullet
- const [bulletWidth, setBulletWidth] = useState(0)
+ // Width of thought bullet, using the default from Bullet.tsx
+ const [bulletWidth, setBulletWidth] = useState(fontSize * 1.25)
// Distance from toolbar to the first visible thought
const [layoutTop, setLayoutTop] = useState(0)
@@ -260,6 +260,9 @@ const LayoutTree = () => {
useLayoutTreeTop(ref, autocrop)
+ // Add a negative marginRight equal to translateX to ensure the thought takes up the full width.
+ const marginRight = `${-indent + (isTouch ? 2 : -1)}em`
+
return (
{
// Use translateX instead of marginLeft to prevent multiline thoughts from continuously recalculating layout as their width changes during the transition.
// Instead of using spaceAbove, we use -min(spaceAbove, c) + c, where c is the number of pixels of hidden thoughts above the cursor before cropping kicks in.
transform: `translateX(${1.5 - indent}em`,
- // Add a negative marginRight equal to translateX to ensure the thought takes up the full width. Not animated for a more stable visual experience.
- marginRight: `${-indent + (isTouch ? 2 : -1)}em`,
+ // Not animated for a more stable visual experience.
+ marginRight,
}}
>
{cursorThoughtPositioned && (
@@ -306,6 +309,12 @@ const LayoutTree = () => {
{treeThoughtsPositioned.map((thought, index) => (
560 ? '90' : '100'}vw - ${CONTENT_BOX_PADDING_LEFT + thought.x}px - ${1.5 - indent}em)`,
+ }}
index={index}
// Pass unique key for the component
key={thought.key}
diff --git a/src/components/ThoughtAnnotationWrapper.tsx b/src/components/ThoughtAnnotationWrapper.tsx
index badeadd8be..70addb269d 100644
--- a/src/components/ThoughtAnnotationWrapper.tsx
+++ b/src/components/ThoughtAnnotationWrapper.tsx
@@ -81,9 +81,10 @@ const ThoughtAnnotationWrapper: FC<
whiteSpace: ellipsizedUrl ? 'nowrap' : undefined,
/*
Since .editable-annotation-text is display: inline the margin only gets applied to its first line, and not later lines.
- To make sure all lines are aligned need to apply the margin here, and remove margin from the .editable-annotation-text
+ To make sure all lines are aligned need to apply the margin here, and remove margin from the .editable-annotation-text.
+ This margin should match the margin set in editableRecipe (#3353).
*/
- margin: '-0.5px 0 0 calc(1em - 18px)',
+ margin: '-0.5px calc(18px - 1em) 0 calc(1em - 18px)',
paddingRight: multiline ? '1em' : '0.333em',
textAlign: isTableCol1 ? 'right' : 'left',
}),
diff --git a/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-13-thoughts-wrapping-at-560-px-1.png b/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-13-thoughts-wrapping-at-560-px-1.png
new file mode 100644
index 0000000000..fe8c2f7a86
Binary files /dev/null and b/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-13-thoughts-wrapping-at-560-px-1.png differ
diff --git a/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-13-thoughts-wrapping-at-575-px-1.png b/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-13-thoughts-wrapping-at-575-px-1.png
new file mode 100644
index 0000000000..6d30dd0ba8
Binary files /dev/null and b/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-13-thoughts-wrapping-at-575-px-1.png differ
diff --git a/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-18-default-thoughts-wrapping-at-560-px-1.png b/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-18-default-thoughts-wrapping-at-560-px-1.png
new file mode 100644
index 0000000000..05ef8efef2
Binary files /dev/null and b/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-18-default-thoughts-wrapping-at-560-px-1.png differ
diff --git a/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-18-default-thoughts-wrapping-at-575-px-1.png b/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-18-default-thoughts-wrapping-at-575-px-1.png
new file mode 100644
index 0000000000..4673f0bfe0
Binary files /dev/null and b/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-18-default-thoughts-wrapping-at-575-px-1.png differ
diff --git a/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-28-thoughts-wrapping-at-560-px-1.png b/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-28-thoughts-wrapping-at-560-px-1.png
new file mode 100644
index 0000000000..def807cc8a
Binary files /dev/null and b/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-28-thoughts-wrapping-at-560-px-1.png differ
diff --git a/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-28-thoughts-wrapping-at-575-px-1.png b/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-28-thoughts-wrapping-at-575-px-1.png
new file mode 100644
index 0000000000..d2195a9261
Binary files /dev/null and b/src/e2e/puppeteer/__tests__/__image_snapshots__/thought-wrap/font-size-28-thoughts-wrapping-at-575-px-1.png differ
diff --git a/src/e2e/puppeteer/__tests__/thought-wrap.ts b/src/e2e/puppeteer/__tests__/thought-wrap.ts
new file mode 100644
index 0000000000..6f36f5901c
--- /dev/null
+++ b/src/e2e/puppeteer/__tests__/thought-wrap.ts
@@ -0,0 +1,85 @@
+import path from 'path'
+import configureSnapshots from '../configureSnapshots'
+import click from '../helpers/click'
+import hide from '../helpers/hide'
+import hideHUD from '../helpers/hideHUD'
+import paste from '../helpers/paste'
+import screenshot from '../helpers/screenshot-with-no-antialiasing'
+import scroll from '../helpers/scroll'
+import { page } from '../setup'
+
+expect.extend({
+ toMatchImageSnapshot: configureSnapshots({ fileName: path.basename(__filename).replace('.ts', '') }),
+})
+
+/** Set up the snapshot tests. These are defined in a function so they can be run at different font sizes (via adjusting the font size in beforeEach). */
+const testSuite = (width: number) => {
+ describe('', () => {
+ beforeEach(hideHUD)
+ beforeEach(async () => {
+ await page.setViewport({
+ width,
+ height: 1400,
+ })
+ })
+
+ it(`thoughts wrapping at ${width}px`, async () => {
+ await paste(`
+ - m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m
+ - m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m
+ - m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m
+ `)
+
+ const image = await screenshot()
+ expect(image).toMatchImageSnapshot()
+ })
+ })
+}
+
+describe('Font Size: 18 (default)', () => {
+ testSuite(560)
+ testSuite(575)
+})
+
+describe('Font Size: 13', () => {
+ beforeEach(async () => {
+ await click('[data-testid=decrease-font]') // 17
+ await click('[data-testid=decrease-font]') // 16
+ await click('[data-testid=decrease-font]') // 15
+ await click('[data-testid=decrease-font]') // 14
+ await click('[data-testid=decrease-font]') // 13
+
+ // close alert
+ await hide('[data-testid=alert]')
+
+ // scroll to top
+ await scroll(0, 0)
+ })
+
+ testSuite(560)
+ testSuite(575)
+})
+
+describe('Font Size: 28', () => {
+ beforeEach(async () => {
+ await click('[data-testid=increase-font]') // 19
+ await click('[data-testid=increase-font]') // 20
+ await click('[data-testid=increase-font]') // 21
+ await click('[data-testid=increase-font]') // 22
+ await click('[data-testid=increase-font]') // 23
+ await click('[data-testid=increase-font]') // 24
+ await click('[data-testid=increase-font]') // 25
+ await click('[data-testid=increase-font]') // 26
+ await click('[data-testid=increase-font]') // 27
+ await click('[data-testid=increase-font]') // 28
+
+ // close alert
+ await hide('[data-testid=alert]')
+
+ // scroll to top
+ await scroll(0, 0)
+ })
+
+ testSuite(560)
+ testSuite(575)
+})