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) +})