Next release
This release adds a center operation to Editor.alignShapes, a tleditors registry of mounted editors, iterateGraphemes to @tldraw/utils, and two new reactive methods on AtomMap. It also deprecates useViewportHeight, speeds up the signals and store layers, and fixes a batch of crashes and interaction bugs across dialogs, sync reconnection, undo, the frame loop, and keyboard shortcut tooltips.
API changes
-
🔜
useViewportHeight()is deprecated. Readwindow.visualViewportdirectly instead. The hook returns only the visible viewport's bottom edge, and keeping a panel clear of the software keyboard generally needs the whole visible rectangle. (#9826) -
Add
'center'as anEditor.alignShapesoperation. It applies the existing'center-horizontal'and'center-vertical'operations together, so shapes center on both axes in one command. (#9074) -
Add
tleditors, a reactive global registry of currently mounted editors. Use it to reach live editors from outside the React tree, for example from sidebar chrome or a keyboard shortcut handler. (#9904)import { tleditors, useValue } from 'tldraw' const mounted = useValue('mounted editors', () => tleditors.getMounted(), []) -
Add
getOrInsert(key, defaultValue)andgetOrInsertComputed(key, callback)toAtomMap, matching theMapmethods added in newer JavaScript runtimes. Both are reactive, and the callback only runs when the key is absent. (#9752) -
Add
isPage(record)to@tldraw/tlschema, a type guard that narrows an unknown record toTLPage, matching the guards already exported for the other record types. (#9774) -
Add
iterateGraphemes(str)to@tldraw/utils. It iterates a string's grapheme clusters, usingIntl.Segmenterwhen it's available and falling back to code-point iteration when it isn't. (#9896) -
EmojiPickerProps.onSelectnow receives the originating event as an optional second argument. Custom reaction palettes can forward it to opt into shift multi-select. (#9999)
Improvements
- Shift-click an emoji in a comment's reaction palette to add several reactions without the palette closing. A plain click still applies the reaction and closes the palette. (#9999)
- Reduce per-pointer-event allocations in
Group2dandEditorhit-testing. (#8600) - Speed up signal reads in
@tldraw/state. Capturing a parent used to scan the capturing signal's parent set twice, once to check for the parent and again to add it. (#9690) - Reduce the work and allocations in
@tldraw/storehistory bookkeeping, so squashing record diffs and filtering query history no longer build intermediate copies on every tick. (#9689, #9869)
Bug fixes
- Fix the editor failing to load on older browsers that lack
Intl.Segmenter, such as Firefox before 125. (#9896) - Fix the frame loop stopping permanently when a
tickorframelistener threw, which silently disabled camera animations, edge scrolling, and other frame-driven behavior for the rest of the session. (#9946) - Fix a crash when computing a frame's geometry if its heading text couldn't be measured yet. (#9496)
- Fix undo after a cut also reverting the change made before it. (#9920)
- Fix small, slowly drawn loops sometimes failing to close, because dense input sampling made the stroke measure shorter than it was. (#9930)
- Fix modifier keys (Shift, Alt, Ctrl, Cmd) briefly being treated as held at the start of a new click or drag right after being released, which could momentarily affect snapping and other modifier-dependent behavior. (#9523)
- Fix Flatten to image producing different groupings depending on selection order, and not merging clusters that were only connected through a bridging shape. (#8661)
- Fix pasted links showing a broken preview image when the linked page has no Open Graph image. (#9909)
- Fix video shapes showing a floating spinner with no bounding box while their asset uploads or loads. They now show the same loading plate as image shapes. (#9994)
- Fix closing a stacked dialog by touch also closing the dialog beneath it. (#10002)
- Fix wheel event normalization passing through non-finite delta values. (#9586)
- Fix license validation treating native apps served from Tauri's origins,
tauri://localhostandhttp://tauri.localhost, as development environments. A Tauri app is now a production deployment, so it needs a license whose hosts match its origin. (#10060) - Fix the counterclockwise rotation tooltip not showing its comma key. (#9772)
- Fix the spacing around the cursor chat item in the context menu. (#9921)
- Fix the people menu's collaborator rows not lining up with your own row above them: the follow icon sat too close to the right edge, and collaborator names sat slightly left of your own. (#9900)
- Fix the comment thread popover briefly rendering with a doubled shadow the first time a thread is opened. (#9886)
- Fix background tabs repeatedly dropping and re-establishing their sync connection when the browser throttles timers. (#9964)