diff --git a/apps/docs/content/getting-started/releases.mdx b/apps/docs/content/getting-started/releases.mdx index 3c2e52d8285c..b9202ecf5738 100644 --- a/apps/docs/content/getting-started/releases.mdx +++ b/apps/docs/content/getting-started/releases.mdx @@ -33,6 +33,7 @@ We ship an experimental `tldraw-migrate` agent skill to let an agent help you up ## v5.x +- [v5.1](/releases/v5.1.0) - Page menu redesign, copy-styles shortcut, selectable locked shapes, public translation APIs, and performance improvements - [v5.0](/releases/v5.0.0) - Custom themes, overlays, performance, extensiblity, and attribution ## v4.x diff --git a/apps/docs/content/releases/next.mdx b/apps/docs/content/releases/next.mdx index 644184a25852..5b6277b140bd 100644 --- a/apps/docs/content/releases/next.mdx +++ b/apps/docs/content/releases/next.mdx @@ -2,40 +2,23 @@ title: Next release description: Changes coming in the next release author: tldraw -date: 05/06/2026 +date: 06/03/2026 order: 0 status: published -last_version: v5.0.2 +last_version: v5.1.0 --- -This release redesigns the page menu around inline interaction, adds a keyboard shortcut to copy styles from a hovered shape, and adds a `selectLockedShapes` option for inspecting locked shapes, along with new public translation APIs, canvas performance improvements, and various rendering and UI bug fixes. - -## What's new - -### Page menu redesign ([#8836](https://github.com/tldraw/tldraw/pull/8836)) - -The page menu no longer has an explicit edit mode. Reorder pages by dragging a row directly, rename inline by double-clicking the label or pressing Enter, and drag the new resize handle at the bottom of the popover to adjust the list height — the height is persisted across sessions and a double-click on the handle resets it to the default. The current page is now indicated by a subtle background pill, the row submenu trigger reveals on hover, and the "Create new page" button is pinned to the footer of the popover. +This release simplifies multi-click handling down to a single double-click event — a breaking change for anyone relying on triple- or quadruple-click handlers — and fixes a number of canvas interaction bugs around pinch-zoom selection, pasting mid-gesture, note list editing, and zoom clamping. ## API changes -- Add a `selectLockedShapes` option to `TldrawOptions`. When enabled, locked shapes can be selected by left click or by brush/scribble selection while remaining protected from edits, moves, and deletes. ([#8860](https://github.com/tldraw/tldraw/pull/8860)) -- Export `TldrawUiTranslationProvider`, `AssetUrlsProvider`, and `useAssetUrls` as public API so components like `TldrawSelectionForeground` can be rendered without the full `TldrawUiContextProvider`. ([#8909](https://github.com/tldraw/tldraw/pull/8909)) -- Add `FontManager.dispose()`, `OverlayManager.dispose()`, and `OverlayUtil.dispose()` for cleaning up manager state across editor lifecycles. ([#8896](https://github.com/tldraw/tldraw/pull/8896)) - -## Improvements - -- Add a `q` shortcut that copies the styles of the hovered shape and applies them to the next shape you create. ([#8917](https://github.com/tldraw/tldraw/pull/8917)) (contributed by [@kaneel](https://github.com/kaneel)) -- Improve performance on busy canvases — `getRenderingShapes()` now skips its sort step when only shape props, not the set of shape ids, have changed. ([#8784](https://github.com/tldraw/tldraw/pull/8784)) -- Improve drawing performance on pages with many shapes by skipping spatial index and culling recomputation when only shape props change. ([#8799](https://github.com/tldraw/tldraw/pull/8799), [#8804](https://github.com/tldraw/tldraw/pull/8804)) +- 💥 Simplify multi-click handling to double-click only. `ClickManager` no longer tracks triple or quadruple clicks: the `triple_click` and `quadruple_click` events and the `onTripleClick` / `onQuadrupleClick` handlers have been removed, and `TLClickEventName` is now just `'double_click'`. ([#8897](https://github.com/tldraw/tldraw/pull/8897)) ## Bug fixes -- Fix a misleading "license expired" console warning for perpetual licenses on covered versions. ([#8791](https://github.com/tldraw/tldraw/pull/8791)) -- Fix inconsistent tooltip behavior on the video toolbar by using `TldrawUiToolbarButton` for the replace and download buttons. ([#8794](https://github.com/tldraw/tldraw/pull/8794)) -- Fix the missing open-state hint on the page menu and zoom menu triggers when rendered outside the main toolbar. ([#8813](https://github.com/tldraw/tldraw/pull/8813)) -- Mark the tldraw UI layer with `role="document"` so toolbars, menus, and dialogs stay reachable to mobile screen readers like VoiceOver and TalkBack, which do not announce the outer canvas `role="application"`. ([#8901](https://github.com/tldraw/tldraw/pull/8901)) -- Fix selection edge resize handles overlapping corner handles, which made corners hard to grab on small shapes. ([#8926](https://github.com/tldraw/tldraw/pull/8926)) -- Fix a bug where deleting a shape inside a group could move the group to a different z-index. ([#8925](https://github.com/tldraw/tldraw/pull/8925)) (contributed by [@kaneel](https://github.com/kaneel)) -- Avoid console errors from calling `preventDefault` on non-cancelable events. ([#8910](https://github.com/tldraw/tldraw/pull/8910)) -- Only log the missing-translation warning once per session instead of once per `useTranslation` consumer. ([#8909](https://github.com/tldraw/tldraw/pull/8909)) -- Catch `image.decode()` rejections from the icon preload effect so they no longer surface as uncaught promise errors in the console. ([#8824](https://github.com/tldraw/tldraw/pull/8824)) +- Fix the fill style dropdown trigger showing a misleading tooltip for the currently selected fill. ([#9023](https://github.com/tldraw/tldraw/pull/9023)) +- Fix a two-finger pinch unintentionally changing the selection on touch devices. ([#9006](https://github.com/tldraw/tldraw/pull/9006)) +- Pasting content while dragging, translating, resizing, or rotating no longer steals selection from the shape being manipulated. ([#8976](https://github.com/tldraw/tldraw/pull/8976)) +- Fix a bug where pressing `Tab` while editing a list inside a note shape created a new note instead of indenting the list item. ([#8958](https://github.com/tldraw/tldraw/pull/8958)) +- Fix the viewport shifting slightly when zooming past the minimum or maximum zoom level. ([#8957](https://github.com/tldraw/tldraw/pull/8957)) +- Fix `debounce(...).cancel()` leaving an awaited call hanging forever; it now rejects the pending promise. ([#8683](https://github.com/tldraw/tldraw/pull/8683)) diff --git a/apps/docs/content/releases/v5.1.0.mdx b/apps/docs/content/releases/v5.1.0.mdx new file mode 100644 index 000000000000..eacacd2a753c --- /dev/null +++ b/apps/docs/content/releases/v5.1.0.mdx @@ -0,0 +1,50 @@ +--- +title: v5.1.0 +description: Page menu redesign, a copy-styles shortcut, a selectLockedShapes option, public translation APIs, and more +author: tldraw +date: 06/03/2026 +order: 0 +status: published +keywords: + - changelog + - release + - v5.1 + - v5.1.0 + - page-menu + - copy-styles + - locked-shapes + - translations +--- + +[View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v5.1.0) + +This release redesigns the page menu around inline interaction, adds a keyboard shortcut to copy styles from a hovered shape, and adds a `selectLockedShapes` option for inspecting locked shapes, along with new public translation APIs, canvas performance improvements, and various rendering and UI bug fixes. + +## What's new + +### Page menu redesign ([#8836](https://github.com/tldraw/tldraw/pull/8836)) + +The page menu no longer has an explicit edit mode. Reorder pages by dragging a row directly, rename inline by double-clicking the label or pressing Enter, and drag the new resize handle at the bottom of the popover to adjust the list height — the height is persisted across sessions and a double-click on the handle resets it to the default. The current page is now indicated by a subtle background pill, the row submenu trigger reveals on hover, and the "Create new page" button is pinned to the footer of the popover. + +## API changes + +- Add a `selectLockedShapes` option to `TldrawOptions`. When enabled, locked shapes can be selected by left click or by brush/scribble selection while remaining protected from edits, moves, and deletes. ([#8860](https://github.com/tldraw/tldraw/pull/8860)) +- Export `TldrawUiTranslationProvider`, `AssetUrlsProvider`, and `useAssetUrls` as public API so components like `TldrawSelectionForeground` can be rendered without the full `TldrawUiContextProvider`. ([#8909](https://github.com/tldraw/tldraw/pull/8909)) +- Add `FontManager.dispose()`, `OverlayManager.dispose()`, and `OverlayUtil.dispose()` for cleaning up manager state across editor lifecycles. ([#8896](https://github.com/tldraw/tldraw/pull/8896)) + +## Improvements + +- Improve performance on busy canvases — `getRenderingShapes()` now skips its sort step when only shape props, not the set of shape ids, have changed. ([#8784](https://github.com/tldraw/tldraw/pull/8784)) +- Improve drawing performance on pages with many shapes by skipping spatial index and culling recomputation when only shape props change. ([#8799](https://github.com/tldraw/tldraw/pull/8799), [#8804](https://github.com/tldraw/tldraw/pull/8804)) + +## Bug fixes + +- Fix a misleading "license expired" console warning for perpetual licenses on covered versions. ([#8791](https://github.com/tldraw/tldraw/pull/8791)) +- Fix inconsistent tooltip behavior on the video toolbar by using `TldrawUiToolbarButton` for the replace and download buttons. ([#8794](https://github.com/tldraw/tldraw/pull/8794)) +- Fix the missing open-state hint on the page menu and zoom menu triggers when rendered outside the main toolbar. ([#8813](https://github.com/tldraw/tldraw/pull/8813)) +- Mark the tldraw UI layer with `role="document"` so toolbars, menus, and dialogs stay reachable to mobile screen readers like VoiceOver and TalkBack, which do not announce the outer canvas `role="application"`. ([#8901](https://github.com/tldraw/tldraw/pull/8901)) +- Fix selection edge resize handles overlapping corner handles, which made corners hard to grab on small shapes. ([#8926](https://github.com/tldraw/tldraw/pull/8926)) +- Fix a bug where deleting a shape inside a group could move the group to a different z-index. ([#8925](https://github.com/tldraw/tldraw/pull/8925)) +- Avoid console errors from calling `preventDefault` on non-cancelable events. ([#8910](https://github.com/tldraw/tldraw/pull/8910)) +- Only log the missing-translation warning once per session instead of once per `useTranslation` consumer. ([#8909](https://github.com/tldraw/tldraw/pull/8909)) +- Catch `image.decode()` rejections from the icon preload effect so they no longer surface as uncaught promise errors in the console. ([#8824](https://github.com/tldraw/tldraw/pull/8824)) diff --git a/apps/docs/scripts/lib/generateSection.ts b/apps/docs/scripts/lib/generateSection.ts index 3b64f2356784..bc03734f1d84 100644 --- a/apps/docs/scripts/lib/generateSection.ts +++ b/apps/docs/scripts/lib/generateSection.ts @@ -120,7 +120,12 @@ export function generateSection(section: InputSection, articles: Articles, index ? sectionUncategorizedArticles : sectionCategoryArticles[category.id] - categoryArticles.sort(sortArticles).forEach((article, i) => { + const sortedArticles = + sectionId === 'releases' + ? sortReleaseArticles(categoryArticles) + : categoryArticles.sort(sortArticles) + + sortedArticles.forEach((article, i) => { article.categoryIndex = i article.sectionIndex = articleSectionIndex assignToArticles(getArticleKey(article), article) @@ -150,6 +155,39 @@ const sortArticles = (articleA: Article, articleB: Article) => { : categoryIndexA - categoryIndexB } +// Parse a release title like "v5.1.0" into a [major, minor, patch] tuple, or null +// for non-version pages (the "Next release" and "Migration skill" articles). +function getReleaseVersion(article: Article): [number, number, number] | null { + const match = /^v(\d+)\.(\d+)\.(\d+)$/.exec(article.title.trim()) + if (!match) return null + return [Number(match[1]), Number(match[2]), Number(match[3])] +} + +// The releases section can't rely on the generic title sort: version titles don't +// compare correctly as strings (e.g. "v3.10.0" < "v3.2.0") and the "Next release" +// and "Migration skill" pages need fixed positions. Order it explicitly so the +// sidebar and prev/next nav read: Next release, the latest version, Migration skill, +// then every other version newest-first. +function sortReleaseArticles(articles: Article[]): Article[] { + const next = articles.find((a) => a.path === '/releases/next') + const migration = articles.find((a) => a.path === '/releases/migration-skill') + + const versions = articles + .filter((a) => a !== next && a !== migration) + .sort((a, b) => { + const [majorA, minorA, patchA] = getReleaseVersion(a) ?? [0, 0, 0] + const [majorB, minorB, patchB] = getReleaseVersion(b) ?? [0, 0, 0] + return majorB - majorA || minorB - minorA || patchB - patchA || a.title.localeCompare(b.title) + }) + + const ordered: Article[] = [] + if (next) ordered.push(next) + if (versions.length > 0) ordered.push(versions[0]) + if (migration) ordered.push(migration) + ordered.push(...versions.slice(1)) + return ordered +} + function getArticleData({ articleId, categoryId: categoryIdOverride, diff --git a/apps/docs/utils/ContentDatabase.ts b/apps/docs/utils/ContentDatabase.ts index 565b1ed9c79b..3ed447350fb0 100644 --- a/apps/docs/utils/ContentDatabase.ts +++ b/apps/docs/utils/ContentDatabase.ts @@ -173,6 +173,14 @@ export class ContentDatabase { } } + // The releases section is ordered newest-first (so the latest release and the + // "Next release" page sit at the top of the list), but its prev/next nav should + // still read chronologically: "previous" → the older release, "next" → the newer + // release. Newer releases have a lower sectionIndex, so swap the computed links. + if (article.sectionId === 'releases') { + return { prev: next ?? null, next: prev ?? null } + } + return { prev: prev ?? null, next: next ?? null } } diff --git a/skills/shared/release-notes-guide.md b/skills/shared/release-notes-guide.md index bf07ed68e0c5..c4189953f471 100644 --- a/skills/shared/release-notes-guide.md +++ b/skills/shared/release-notes-guide.md @@ -65,7 +65,7 @@ When a PR is reverted, also remove the original PR's entry from `next.mdx` if it ## Team members (do not credit) -angrycaptain19, AniKrisn, ds300, kostyafarber, max-dra, mimecuvalo, MitjaBezensek, profdl, Siobhantldraw, steveruizok, tldrawdaniel, huppy-bot, github-actions, Somehats, todepond, Taha-Hassan-Git, alex-mckenna-1, max-drake +angrycaptain19, AniKrisn, ds300, kaneel, kostyafarber, max-dra, mimecuvalo, MitjaBezensek, profdl, Siobhantldraw, steveruizok, tldrawdaniel, danieljamesross, jsscclr, frolic, huppy-bot, github-actions, Somehats, todepond, Taha-Hassan-Git, alex-mckenna-1, max-drake Credit community contributors with: diff --git a/skills/update-release-notes/shared/release-notes-guide.md b/skills/update-release-notes/shared/release-notes-guide.md index bf07ed68e0c5..c4189953f471 100644 --- a/skills/update-release-notes/shared/release-notes-guide.md +++ b/skills/update-release-notes/shared/release-notes-guide.md @@ -65,7 +65,7 @@ When a PR is reverted, also remove the original PR's entry from `next.mdx` if it ## Team members (do not credit) -angrycaptain19, AniKrisn, ds300, kostyafarber, max-dra, mimecuvalo, MitjaBezensek, profdl, Siobhantldraw, steveruizok, tldrawdaniel, huppy-bot, github-actions, Somehats, todepond, Taha-Hassan-Git, alex-mckenna-1, max-drake +angrycaptain19, AniKrisn, ds300, kaneel, kostyafarber, max-dra, mimecuvalo, MitjaBezensek, profdl, Siobhantldraw, steveruizok, tldrawdaniel, danieljamesross, jsscclr, frolic, huppy-bot, github-actions, Somehats, todepond, Taha-Hassan-Git, alex-mckenna-1, max-drake Credit community contributors with: