v5.6.0

View on GitHub

This release introduces ICU MessageFormat and react-intl for translations, action-driven menu gating, and a ThrottledFunction type in @tldraw/utils. It also improves commenting, canvas navigation, and the select tool, and includes a broad set of bug fixes across selection, undo/redo, local persistence, sync, and the store.

What's new

ICU MessageFormat and react-intl for translations (#8036)

The SDK's UI strings now use ICU MessageFormat, allowing messages to support pluralization, selections, and values interpolation cleanly across languages. We've also added react-intl authoring on top: defineMessages and <F> declare and render messages with their default English next to the code that uses them.

Existing translations overridden by ID through overrides.translations continue to work unchanged.

API changes

  • Add ICU MessageFormat translation support with defineMessages, <F>, and useTldrawI18n. useTranslation's msg now supports interpolating values through an optional second argument and accepts declared message descriptors. (#8036)
  • Add isAvailable(editor), isEnabled(editor) and isChecked(editor) to actions. Menu items built with TldrawUiMenuActionItem and TldrawUiMenuActionCheckboxItem read them: an unavailable action is hidden, a disabled one is greyed out or hidden depending on whenDisabled: 'hide' | 'disable'. useSomeActionsEnabled returns whether any of the given actions is available and enabled, so a submenu can hide when none of its items can run. If you replace a built-in action with a new object instead of spreading it, it loses its gating, and a toggle's checkbox always shows as unchecked. (#11038)
  • TldrawUiMenuActionItem now disables itself when its action's isEnabled returns false, so custom menus that render built-in actions grey them out when they can't run. The public menu item wrappers, such as GroupMenuItem, FrameSelectionMenuItem and ArrangeMenuSubmenu, now also hide outside the select tool, where their actions do nothing. (#11038)
  • Add a ThrottledFunction<T> type to @tldraw/utils for annotating the result of throttle. throttle now returns this type, with the same runtime behavior. (#10927)
  • Add startCommentAt(editor, point) to @tldraw/commenting for starting a comment thread at a specific canvas location from outside the comment tool. (#10970)
  • TLSocketRoom.handleSocketMessage(sessionId, message, socket?), handleSocketClose(sessionId, socket?), and handleSocketError(sessionId, socket?) now accept an optional originating socket parameter so messages and events from superseded connections are ignored. (#11067)
  • Add LaserTool.startScribble() which adds a laser scribble to the current session, starting a fresh session if none is active. (#10781)

Improvements

  • Menus no longer offer actions that would do nothing: grouping locked shapes, flipping a locked shape, unlocking when nothing is locked, exporting all shapes on an empty page, moving to a new page at the page limit, and grouping an arrow away from a shape it's bound to. The main menu hides Paste, instead of disabling it, in browsers that can't read the clipboard. (#11038)
  • Allow keyboard navigation (Tab, Ctrl/Cmd+arrow, and the "Move focus to canvas" button) to reach locked shapes again, so keyboard users can select and unlock them. (#11134)
  • Add a Comment item to the default canvas context menu when commenting is configured. It opens the comment composer where you right-clicked. (#11095)
  • Move the comments filter menu to the right of the hide comments toggle in the comments panel header. (#11135)
  • Cancel comment draft placement and return to the select tool when clicking the canvas, instead of moving the draft comment. (#10969)
  • Draw the hinted outline around shapes, such as a frame you're dragging a shape into, at 2px instead of 2.5px. (#10952)
  • Speed up store.query.index() and store.query.ids() updates by no longer allocating for each change. (#10228)

Bug fixes

  • Fix the edge scrolling preference showing as off when edge scrolling is on at a speed other than 1, such as 0.5 or 2. (#11038)
  • Fix edge scrolling jumping to partial speed after its start delay. (#11126)
  • Fix three resize issues: flipping a rotated selection gave its children the wrong rotation, shapes not aligned with the selection received onResizeStart and onResizeEnd more than once, and resizeBox slid the fixed edge when a shape hit its maxWidth or maxHeight. (#10351)
  • Fix duplicating a page moving its shapes when they were off screen, and starting the new page with the current page's camera instead of the duplicated page's. (#10465)
  • Fix the page menu closing and getting stuck mid-drag when Escape is pressed while reordering pages. (#11115)
  • Fix an empty line under a heading in a text shape that could not be deleted. (#11114)
  • Fix the "rhombus-2" (rhombus left) geo tool showing a raw translation key as its label. (#11062)
  • Fix the keyboard shortcuts dialog opening via keyboard shortcut when KeyboardShortcutsDialog is overridden with null. (#11019)
  • Fix the rich text toolbar reporting the wrong operation in onUiEvent for italic, code, and highlight. (#11018)
  • Fix undo after double-clicking a frame's corner or edge to fit it to content creating an inconsistent history step. (#11075)
  • Fix undo reverting an earlier edit after brushing to select, right-clicking an empty canvas to deselect, pressing Enter on a group, or navigating the selection with the keyboard. (#10476)
  • Fix clicking a child of a locked group selecting the locked group. (#10180)
  • Fix bookmarks, notes, and other non-resizing shapes being mispositioned when their containing group is resized or flipped. (#10619)
  • Fix bounds snapping not engaging while resizing or cropping shapes inside slightly rotated frames or groups. (#10181)
  • Fix the arrow tool's precise mode carrying over when you move to a different target shape. (#10244)
  • Fix holding Cmd/Ctrl+Shift+Arrow switching from selecting a parent or child to selecting the adjacent shape once the key starts repeating. (#10184)
  • Fix arrow-key nudging moving diagonally after using a Cmd+Arrow shortcut on macOS. (#10892)
  • Fix the eraser sometimes dropping a highlighted shape when dragging near a group. (#10182)
  • Fix editor.setCursor throwing for the rotate and resize cursor types, and hex cursor colors breaking SVG cursors. (#10350)
  • Fix editor.animateShapes throwing a TypeError when interpolating draw or highlight shapes to or from empty segments. (#10771)
  • Fix the laser tool crashing when its scribble session times out mid-stroke. (#10781)
  • Fix scribbles added without points disappearing after one idle frame before points could be added on pointer move. (#10336)
  • Fix hit testing and viewport culling using stale bounds when text fonts finish loading after measurement, and fix container descendants retaining stale current-page membership when reparented to another page. (#10341)
  • Fix edits being lost when an editor remounts with the same persistenceKey while the previous one is still saving. (#10752)
  • Fix the comment composer requiring a second tap before focusing and raising the software keyboard on iOS. (#9957)
  • Fix store changes made in the last frame before a listener is removed never reaching that listener. (#10802)
  • Fix a reaction that writes to the store re-running on every unrelated store change. (#10236)
  • Fix undo restoring an in-between state after a single put updated the same record twice. (#10203)
  • Fix store listeners and extractingChanges receiving changes from transactions that rolled back. (#10205)
  • Fix computed caches in store.query not re-running their derive functions when a previously removed record is recreated with the same ID. (#10225)
  • Fix migrateStoreSnapshot throwing on a malformed persisted schema instead of returning a migration error. (#10220)
  • Fix migrations rerunning on records when a persisted schema's sequence version isn't a number. (#10917)
  • Fix a record deleted while offline occasionally reappearing after reconnecting. (#10997)
  • Fix large chunked sync messages being dropped and active sessions being cancelled by a previous socket's late close or error when reconnecting with the same session ID. (#11067)
  • Fix a resumed sync session on a hibernating host skipping the version checks made on first connect, so after a server redeploy a client could be sent changes its schema couldn't handle. It's now rejected with SERVER_TOO_OLD or CLIENT_TOO_OLD, as on connect. (#10122)
  • Fix a record field set to undefined getting the sync session kicked with INVALID_RECORD, and ignore __proto__ keys in incoming changes. (#10118)
  • Fix older sync clients (protocol version 7) silently falling out of sync when the server sent them text-append changes they don't support. (#10095)
Prev
Next release
Next
Migration skill