diff --git a/apps/docs/content/releases/next.mdx b/apps/docs/content/releases/next.mdx index c7cf4f2f1335..5a7fed2b5a40 100644 --- a/apps/docs/content/releases/next.mdx +++ b/apps/docs/content/releases/next.mdx @@ -273,6 +273,8 @@ New helpers `getOwnerDocument()` and `getOwnerWindow()` are exported from `@tldr - Optimize geometry hot paths for hit testing: reduce allocations and function call overhead in `Vec`, `Edge2d`, `Circle2d`, `Arc2d`, `Polyline2d`, and intersection routines. Circle hit testing is up to 19x faster, polyline nearest-point is 6.8x faster. ([#8210](https://github.com/tldraw/tldraw/pull/8210)) - Exports now automatically trim to visual content bounds, capturing overflow like thick strokes and arrowheads without extra whitespace. ([#8202](https://github.com/tldraw/tldraw/pull/8202)) - Improve resize performance for multiple geo shapes with text labels by batching DOM measurements into a single pass per frame. ([#7949](https://github.com/tldraw/tldraw/pull/7949)) +- Allow Cmd+click / Ctrl+click on style panel items to apply style changes only to selected shapes without updating defaults for future shapes. ([#8452](https://github.com/tldraw/tldraw/pull/8452)) +- Hide selection overlay when nudging shapes with arrow keys. ([#8447](https://github.com/tldraw/tldraw/pull/8447)) - Replace `@use-gesture/react` dependency with custom gesture handling, reducing bundle size and eliminating a stale dependency. ([#8392](https://github.com/tldraw/tldraw/pull/8392)) - Tighten iframe referrer policy for embeds to send only the origin instead of the full URL to third-party embed providers. ([#8412](https://github.com/tldraw/tldraw/pull/8412)) - Move the debug mode toggle into the preferences submenu. ([#8259](https://github.com/tldraw/tldraw/pull/8259)) @@ -294,3 +296,9 @@ New helpers `getOwnerDocument()` and `getOwnerWindow()` are exported from `@tldr - Fix right-clicking inside a multi-selection over a filled background shape changing the selection. ([#8434](https://github.com/tldraw/tldraw/pull/8434)) - Fix memory leak where the Editor was retained after unmount via a shared throttled `updateHoveredShapeId` closure. ([#8439](https://github.com/tldraw/tldraw/pull/8439)) - Fix pattern fill not scaling correctly with dynamic size mode. ([#8441](https://github.com/tldraw/tldraw/pull/8441)) +- Fix arrow labels rendered at incorrect size when editing at high zoom in dynamic size mode. ([#8451](https://github.com/tldraw/tldraw/pull/8451)) +- Fix shadow artifact and oversized caret on notes and geo shapes at high zoom in dynamic size mode. ([#8378](https://github.com/tldraw/tldraw/pull/8378)) +- Fix crash from duplicate fractional index keys in `kickoutOccludedShapes` during multiplayer sync. ([#8448](https://github.com/tldraw/tldraw/pull/8448)) +- Fix NaN propagation from zero-length labeled arrows causing all shapes to disappear. ([#8329](https://github.com/tldraw/tldraw/pull/8329)) +- Fix crash when isolating curved arrows with degenerate geometry. ([#8176](https://github.com/tldraw/tldraw/pull/8176)) +- Fix camera state stuck at 'moving' on dispose, blocking shape interactions on the next editor instance. ([#8396](https://github.com/tldraw/tldraw/pull/8396)) diff --git a/apps/docs/content/sdk-features/locked-shapes.mdx b/apps/docs/content/sdk-features/locked-shapes.mdx index c81392904746..eaa728ce703c 100644 --- a/apps/docs/content/sdk-features/locked-shapes.mdx +++ b/apps/docs/content/sdk-features/locked-shapes.mdx @@ -115,4 +115,4 @@ When this returns `true`, double-clicking the locked shape enters edit mode, let ## Locking in the UI -In the default tldraw UI, users can lock shapes through the context menu or the keyboard shortcut (`Shift+L`). Locked shapes display a lock indicator when hovered, and the context menu shows an unlock option. +In the default tldraw UI, users can lock shapes through the context menu or the keyboard shortcut (`Shift+L`). Users can right-click on a locked shape to access the context menu, which shows an unlock option. diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-decision-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-decision-light-1-chromium-linux.png index 23a60c13ac1a..ebd10aabdb90 100644 Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-decision-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-decision-light-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-class-defs-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-class-defs-light-1-chromium-linux.png index 4e3f169ac366..63882a73ab98 100644 Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-class-defs-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-class-defs-light-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-custom-edge-styles-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-custom-edge-styles-light-1-chromium-linux.png index b1dd0cc6e66d..d7e4a98f414b 100644 Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-custom-edge-styles-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-custom-edge-styles-light-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-subgraphs-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-subgraphs-light-1-chromium-linux.png index 424949d2eb98..47db950ed359 100644 Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-subgraphs-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-subgraphs-light-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-basics-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-basics-light-1-chromium-linux.png index a12e1f992667..2901f5984696 100644 Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-basics-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-basics-light-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-alt-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-alt-light-1-chromium-linux.png index 208a6b3e1d62..834c2f403f80 100644 Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-alt-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-alt-light-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-parallel-lanes-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-parallel-lanes-light-1-chromium-linux.png index bf1ad9ef4a99..5f0d17a25902 100644 Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-parallel-lanes-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-parallel-lanes-light-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-basic-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-basic-light-1-chromium-linux.png index 8c431c8a8528..7a1cf8c941a6 100644 Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-basic-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-basic-light-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-fork-join-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-fork-join-light-1-chromium-linux.png index eb02bf1f9de7..44369c501694 100644 Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-fork-join-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-fork-join-light-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-nested-state-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-nested-state-light-1-chromium-linux.png index 0059bd5f9345..8b91999b210f 100644 Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-nested-state-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-nested-state-light-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-Mobile-Chrome-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-Mobile-Chrome-linux.png index 34164d9a56b4..075ad5fbc006 100644 Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-Mobile-Chrome-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-Mobile-Chrome-linux.png differ diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-chromium-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-chromium-linux.png index 34164d9a56b4..075ad5fbc006 100644 Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-chromium-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-Mobile-Chrome-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-Mobile-Chrome-linux.png index 4ded440b4a35..f673d0fafe2a 100644 Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-Mobile-Chrome-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-Mobile-Chrome-linux.png differ diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-chromium-linux.png index 4ded440b4a35..f673d0fafe2a 100644 Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-Mobile-Chrome-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-Mobile-Chrome-linux.png index b4a59e9ebcef..02c2b8f55b84 100644 Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-Mobile-Chrome-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-Mobile-Chrome-linux.png differ diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-chromium-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-chromium-linux.png index 78a063bc8038..9d973b41730d 100644 Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-chromium-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-chromium-linux.png differ diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-Mobile-Chrome-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-Mobile-Chrome-linux.png index 0c9bf4a0176a..11df23bf4e0c 100644 Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-Mobile-Chrome-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-Mobile-Chrome-linux.png differ diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-chromium-linux.png index ef8af95fc494..619dafacc9b2 100644 Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-chromium-linux.png differ diff --git a/packages/tldraw/src/lib/shapes/shared/PathBuilder.test.tsx b/packages/tldraw/src/lib/shapes/shared/PathBuilder.test.tsx index a6b7d2a9eb5a..40389b469159 100644 --- a/packages/tldraw/src/lib/shapes/shared/PathBuilder.test.tsx +++ b/packages/tldraw/src/lib/shapes/shared/PathBuilder.test.tsx @@ -105,11 +105,11 @@ describe('PathBuilder', () => { .toSvg({ strokeWidth: 10, style: 'draw', randomSeed: '123' }) expect(path).toMatchInlineSnapshot(` - - `) + + `) const closed = new PathBuilder() .moveTo(0, 0) .lineTo(100, 100) @@ -119,11 +119,11 @@ describe('PathBuilder', () => { .toSvg({ strokeWidth: 10, style: 'draw', randomSeed: '123' }) expect(closed).toMatchInlineSnapshot(` - - `) + + `) }) }) diff --git a/packages/tldraw/src/lib/shapes/shared/PathBuilder.tsx b/packages/tldraw/src/lib/shapes/shared/PathBuilder.tsx index 9141049d42d3..3623edc36b05 100644 --- a/packages/tldraw/src/lib/shapes/shared/PathBuilder.tsx +++ b/packages/tldraw/src/lib/shapes/shared/PathBuilder.tsx @@ -811,9 +811,14 @@ export class PathBuilder { tangentToNext, tangentToPrev, } of drawCommands) { - const offset = command.isClose - ? lastMoveToOffset - : { x: random() * offsetAmount, y: random() * offsetAmount } + let offset: VecLike + if (command.isClose) { + offset = lastMoveToOffset + } else { + const direction = new Vec(random(), random()).uni() + const magnitude = Math.sqrt(Math.abs(random())) * offsetAmount + offset = Vec.Mul(direction, magnitude) + } if (command.type === 'move') { lastMoveToOffset = offset