tldraw 4.1.0-canary.9f9255bd7a83 → 4.1.0-canary.bdf9b3703a3d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/shapes/arrow/curved-arrow.js +2 -8
- package/dist-cjs/lib/shapes/arrow/curved-arrow.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/straight-arrow.js +1 -4
- package/dist-cjs/lib/shapes/arrow/straight-arrow.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js +1 -1
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +1 -1
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
- package/dist-cjs/lib/ui/context/actions.js +0 -20
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/shapes/arrow/curved-arrow.mjs +2 -8
- package/dist-esm/lib/shapes/arrow/curved-arrow.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/straight-arrow.mjs +1 -4
- package/dist-esm/lib/shapes/arrow/straight-arrow.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +1 -1
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +1 -1
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
- package/dist-esm/lib/ui/context/actions.mjs +0 -20
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/package.json +3 -3
- package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +1 -211
- package/src/lib/shapes/arrow/curved-arrow.ts +2 -8
- package/src/lib/shapes/arrow/straight-arrow.ts +1 -5
- package/src/lib/shapes/shared/RichTextLabel.tsx +1 -1
- package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +1 -1
- package/src/lib/ui/context/actions.tsx +0 -22
- package/src/lib/ui/version.ts +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { HALF_PI, TLArrowShape, TLShapeId, createShapeId, toRichText } from '@tldraw/editor'
|
|
2
2
|
import { vi } from 'vitest'
|
|
3
3
|
import { TestEditor } from '../../../test/TestEditor'
|
|
4
|
-
import { createOrUpdateArrowBinding, getArrowBindings
|
|
4
|
+
import { createOrUpdateArrowBinding, getArrowBindings } from './shared'
|
|
5
5
|
|
|
6
6
|
let editor: TestEditor
|
|
7
7
|
|
|
@@ -620,213 +620,3 @@ describe('Arrow export bounds', () => {
|
|
|
620
620
|
expect(arrow.props.richText).not.toBeNull()
|
|
621
621
|
})
|
|
622
622
|
})
|
|
623
|
-
|
|
624
|
-
describe('Arrow terminal positioning bug fix', () => {
|
|
625
|
-
const data = {
|
|
626
|
-
document: {
|
|
627
|
-
store: {
|
|
628
|
-
'shape:1Hm61DGAsY0uqEO-kt75l': {
|
|
629
|
-
x: 637.2890625,
|
|
630
|
-
y: 383.9296875,
|
|
631
|
-
rotation: 0,
|
|
632
|
-
isLocked: false,
|
|
633
|
-
opacity: 1,
|
|
634
|
-
meta: {},
|
|
635
|
-
id: 'shape:1Hm61DGAsY0uqEO-kt75l',
|
|
636
|
-
type: 'geo',
|
|
637
|
-
props: {
|
|
638
|
-
w: 230.66796875,
|
|
639
|
-
h: 114.796875,
|
|
640
|
-
geo: 'rectangle',
|
|
641
|
-
dash: 'draw',
|
|
642
|
-
growY: 0,
|
|
643
|
-
url: '',
|
|
644
|
-
scale: 1,
|
|
645
|
-
color: 'black',
|
|
646
|
-
labelColor: 'black',
|
|
647
|
-
fill: 'none',
|
|
648
|
-
size: 'm',
|
|
649
|
-
font: 'draw',
|
|
650
|
-
align: 'middle',
|
|
651
|
-
verticalAlign: 'middle',
|
|
652
|
-
richText: {
|
|
653
|
-
type: 'doc',
|
|
654
|
-
content: [
|
|
655
|
-
{
|
|
656
|
-
type: 'paragraph',
|
|
657
|
-
},
|
|
658
|
-
],
|
|
659
|
-
},
|
|
660
|
-
},
|
|
661
|
-
parentId: 'page:page',
|
|
662
|
-
index: 'a1',
|
|
663
|
-
typeName: 'shape',
|
|
664
|
-
},
|
|
665
|
-
'binding:nekxhMCGaoEJO98DEqWgo': {
|
|
666
|
-
meta: {},
|
|
667
|
-
id: 'binding:nekxhMCGaoEJO98DEqWgo',
|
|
668
|
-
type: 'arrow',
|
|
669
|
-
fromId: 'shape:j0HKQihjBXqMqgVhfRhDS',
|
|
670
|
-
toId: 'shape:1Hm61DGAsY0uqEO-kt75l',
|
|
671
|
-
props: {
|
|
672
|
-
isPrecise: true,
|
|
673
|
-
isExact: false,
|
|
674
|
-
normalizedAnchor: {
|
|
675
|
-
x: 0.13182672605036325,
|
|
676
|
-
y: 0.8036953858717844,
|
|
677
|
-
},
|
|
678
|
-
snap: 'none',
|
|
679
|
-
terminal: 'start',
|
|
680
|
-
},
|
|
681
|
-
typeName: 'binding',
|
|
682
|
-
},
|
|
683
|
-
'binding:kWamalL_QSq_kFPZDgp7Z': {
|
|
684
|
-
meta: {},
|
|
685
|
-
id: 'binding:kWamalL_QSq_kFPZDgp7Z',
|
|
686
|
-
type: 'arrow',
|
|
687
|
-
fromId: 'shape:j0HKQihjBXqMqgVhfRhDS',
|
|
688
|
-
toId: 'shape:1Hm61DGAsY0uqEO-kt75l',
|
|
689
|
-
props: {
|
|
690
|
-
isPrecise: true,
|
|
691
|
-
isExact: false,
|
|
692
|
-
normalizedAnchor: {
|
|
693
|
-
x: 0.7138744475114731,
|
|
694
|
-
y: 0.45797604464407243,
|
|
695
|
-
},
|
|
696
|
-
snap: 'none',
|
|
697
|
-
terminal: 'end',
|
|
698
|
-
},
|
|
699
|
-
typeName: 'binding',
|
|
700
|
-
},
|
|
701
|
-
'shape:j0HKQihjBXqMqgVhfRhDS': {
|
|
702
|
-
x: 665.296875,
|
|
703
|
-
y: 477.59765625,
|
|
704
|
-
rotation: 0,
|
|
705
|
-
isLocked: false,
|
|
706
|
-
opacity: 1,
|
|
707
|
-
meta: {},
|
|
708
|
-
id: 'shape:j0HKQihjBXqMqgVhfRhDS',
|
|
709
|
-
type: 'arrow',
|
|
710
|
-
props: {
|
|
711
|
-
kind: 'arc',
|
|
712
|
-
elbowMidPoint: 0.5,
|
|
713
|
-
dash: 'draw',
|
|
714
|
-
size: 'm',
|
|
715
|
-
fill: 'none',
|
|
716
|
-
color: 'black',
|
|
717
|
-
labelColor: 'black',
|
|
718
|
-
bend: 0,
|
|
719
|
-
start: {
|
|
720
|
-
x: 0,
|
|
721
|
-
y: 0,
|
|
722
|
-
},
|
|
723
|
-
end: {
|
|
724
|
-
x: 2,
|
|
725
|
-
y: 0,
|
|
726
|
-
},
|
|
727
|
-
arrowheadStart: 'none',
|
|
728
|
-
arrowheadEnd: 'arrow',
|
|
729
|
-
richText: {
|
|
730
|
-
type: 'doc',
|
|
731
|
-
content: [
|
|
732
|
-
{
|
|
733
|
-
type: 'paragraph',
|
|
734
|
-
},
|
|
735
|
-
],
|
|
736
|
-
},
|
|
737
|
-
labelPosition: 0.5,
|
|
738
|
-
font: 'draw',
|
|
739
|
-
scale: 1,
|
|
740
|
-
},
|
|
741
|
-
parentId: 'page:page',
|
|
742
|
-
index: 'a2lbpzZG',
|
|
743
|
-
typeName: 'shape',
|
|
744
|
-
},
|
|
745
|
-
'page:page': {
|
|
746
|
-
meta: {},
|
|
747
|
-
id: 'page:page',
|
|
748
|
-
name: 'Page 1',
|
|
749
|
-
index: 'a1',
|
|
750
|
-
typeName: 'page',
|
|
751
|
-
},
|
|
752
|
-
'document:document': {
|
|
753
|
-
gridSize: 10,
|
|
754
|
-
name: '',
|
|
755
|
-
meta: {},
|
|
756
|
-
id: 'document:document',
|
|
757
|
-
typeName: 'document',
|
|
758
|
-
},
|
|
759
|
-
},
|
|
760
|
-
schema: {
|
|
761
|
-
schemaVersion: 2,
|
|
762
|
-
sequences: {
|
|
763
|
-
'com.tldraw.store': 5,
|
|
764
|
-
'com.tldraw.asset': 1,
|
|
765
|
-
'com.tldraw.camera': 1,
|
|
766
|
-
'com.tldraw.document': 2,
|
|
767
|
-
'com.tldraw.instance': 25,
|
|
768
|
-
'com.tldraw.instance_page_state': 5,
|
|
769
|
-
'com.tldraw.page': 1,
|
|
770
|
-
'com.tldraw.instance_presence': 6,
|
|
771
|
-
'com.tldraw.pointer': 1,
|
|
772
|
-
'com.tldraw.shape': 4,
|
|
773
|
-
'com.tldraw.asset.bookmark': 2,
|
|
774
|
-
'com.tldraw.asset.image': 5,
|
|
775
|
-
'com.tldraw.asset.video': 5,
|
|
776
|
-
'com.tldraw.shape.group': 0,
|
|
777
|
-
'com.tldraw.shape.text': 3,
|
|
778
|
-
'com.tldraw.shape.bookmark': 2,
|
|
779
|
-
'com.tldraw.shape.draw': 2,
|
|
780
|
-
'com.tldraw.shape.geo': 10,
|
|
781
|
-
'com.tldraw.shape.note': 9,
|
|
782
|
-
'com.tldraw.shape.line': 5,
|
|
783
|
-
'com.tldraw.shape.frame': 1,
|
|
784
|
-
'com.tldraw.shape.arrow': 7,
|
|
785
|
-
'com.tldraw.shape.highlight': 1,
|
|
786
|
-
'com.tldraw.shape.embed': 4,
|
|
787
|
-
'com.tldraw.shape.image': 5,
|
|
788
|
-
'com.tldraw.shape.video': 4,
|
|
789
|
-
'com.tldraw.binding.arrow': 1,
|
|
790
|
-
},
|
|
791
|
-
},
|
|
792
|
-
},
|
|
793
|
-
session: {
|
|
794
|
-
version: 0,
|
|
795
|
-
currentPageId: 'page:page',
|
|
796
|
-
exportBackground: true,
|
|
797
|
-
isFocusMode: false,
|
|
798
|
-
isDebugMode: false,
|
|
799
|
-
isToolLocked: false,
|
|
800
|
-
isGridMode: false,
|
|
801
|
-
pageStates: [
|
|
802
|
-
{
|
|
803
|
-
pageId: 'page:page',
|
|
804
|
-
camera: {
|
|
805
|
-
x: 0,
|
|
806
|
-
y: 0,
|
|
807
|
-
z: 1,
|
|
808
|
-
},
|
|
809
|
-
selectedShapeIds: ['shape:j0HKQihjBXqMqgVhfRhDS'],
|
|
810
|
-
focusedGroupId: null,
|
|
811
|
-
},
|
|
812
|
-
],
|
|
813
|
-
},
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
it('should position straight arrow terminals on shape boundary, not text label boundary', () => {
|
|
817
|
-
// Create a geo shape with text label
|
|
818
|
-
editor.loadSnapshot(data as any)
|
|
819
|
-
|
|
820
|
-
const arrow = editor.getShape('shape:j0HKQihjBXqMqgVhfRhDS' as TLShapeId) as TLArrowShape
|
|
821
|
-
expect(arrow).toBeDefined()
|
|
822
|
-
|
|
823
|
-
expect(getArrowBindings(editor, arrow)).toMatchObject({
|
|
824
|
-
end: { props: { isPrecise: true } },
|
|
825
|
-
start: { props: { isPrecise: true } },
|
|
826
|
-
})
|
|
827
|
-
|
|
828
|
-
const info = getArrowInfo(editor, arrow)
|
|
829
|
-
expect(info?.start.handle).toEqual(info?.start.point)
|
|
830
|
-
expect(info?.end.handle).toEqual(info?.end.point)
|
|
831
|
-
})
|
|
832
|
-
})
|
|
@@ -154,10 +154,7 @@ export function getCurvedArrowInfo(
|
|
|
154
154
|
}
|
|
155
155
|
if (!point) {
|
|
156
156
|
if (isClosed) {
|
|
157
|
-
const nearestPoint = startShapeInfo.geometry.nearestPoint(startInStartShapeLocalSpace
|
|
158
|
-
includeInternal: false,
|
|
159
|
-
includeLabels: false,
|
|
160
|
-
})
|
|
157
|
+
const nearestPoint = startShapeInfo.geometry.nearestPoint(startInStartShapeLocalSpace)
|
|
161
158
|
if (Vec.DistMin(nearestPoint, startInStartShapeLocalSpace, 1)) {
|
|
162
159
|
point = nearestPoint
|
|
163
160
|
}
|
|
@@ -236,10 +233,7 @@ export function getCurvedArrowInfo(
|
|
|
236
233
|
}
|
|
237
234
|
if (!point) {
|
|
238
235
|
if (isClosed) {
|
|
239
|
-
const nearestPoint = endShapeInfo.geometry.nearestPoint(endInEndShapeLocalSpace
|
|
240
|
-
includeInternal: false,
|
|
241
|
-
includeLabels: false,
|
|
242
|
-
})
|
|
236
|
+
const nearestPoint = endShapeInfo.geometry.nearestPoint(endInEndShapeLocalSpace)
|
|
243
237
|
if (Vec.DistMin(nearestPoint, endInEndShapeLocalSpace, 1)) {
|
|
244
238
|
point = nearestPoint
|
|
245
239
|
}
|
|
@@ -248,11 +248,7 @@ function updateArrowheadPointWithBoundShape(
|
|
|
248
248
|
if (targetInt === undefined) {
|
|
249
249
|
// No intersection? The arrowhead point will be at the arrow terminal.
|
|
250
250
|
// if we _almost_ hit the target, just put the arrowhead at the target.
|
|
251
|
-
targetInt = targetShapeInfo.geometry.nearestPoint(targetTo
|
|
252
|
-
includeLabels: false,
|
|
253
|
-
includeInternal: false,
|
|
254
|
-
})
|
|
255
|
-
|
|
251
|
+
targetInt = targetShapeInfo.geometry.nearestPoint(targetTo)
|
|
256
252
|
if (!Vec.DistMin(targetInt, targetTo, 1)) {
|
|
257
253
|
return
|
|
258
254
|
}
|
|
@@ -109,7 +109,7 @@ export const RichTextLabel = React.memo(function RichTextLabel({
|
|
|
109
109
|
// We don't get the mouseup event later because we preventDefault
|
|
110
110
|
// so we have to do it manually.
|
|
111
111
|
const handlePointerUp = (e: TLEventInfo) => {
|
|
112
|
-
if (e.name !== 'pointer_up'
|
|
112
|
+
if (e.name !== 'pointer_up') return
|
|
113
113
|
|
|
114
114
|
if (!isDragging.current) {
|
|
115
115
|
window.open(link, '_blank', 'noopener, noreferrer')
|
package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx
CHANGED
|
@@ -165,7 +165,7 @@ export function DefaultKeyboardShortcutsDialogContent() {
|
|
|
165
165
|
<TldrawUiMenuItem
|
|
166
166
|
id="a11y-select-next-shape-container"
|
|
167
167
|
label="a11y.enter-leave-container"
|
|
168
|
-
kbd="cmd+shift+[[
|
|
168
|
+
kbd="cmd+shift+[[↑→]]"
|
|
169
169
|
onSelect={() => {
|
|
170
170
|
/* do nothing */
|
|
171
171
|
}}
|
|
@@ -1344,28 +1344,6 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
|
|
|
1344
1344
|
}
|
|
1345
1345
|
},
|
|
1346
1346
|
},
|
|
1347
|
-
{
|
|
1348
|
-
id: 'toggle-focus-mode',
|
|
1349
|
-
label: {
|
|
1350
|
-
default: 'action.toggle-focus-mode',
|
|
1351
|
-
menu: 'action.toggle-focus-mode.menu',
|
|
1352
|
-
},
|
|
1353
|
-
readonlyOk: true,
|
|
1354
|
-
kbd: 'cmd+.,ctrl+.',
|
|
1355
|
-
checkbox: true,
|
|
1356
|
-
onSelect(source) {
|
|
1357
|
-
// this needs to be deferred because it causes the menu
|
|
1358
|
-
// UI to unmount which puts us in a dodgy state
|
|
1359
|
-
editor.timers.requestAnimationFrame(() => {
|
|
1360
|
-
editor.run(() => {
|
|
1361
|
-
trackEvent('toggle-focus-mode', { source })
|
|
1362
|
-
helpers.clearDialogs()
|
|
1363
|
-
helpers.clearToasts()
|
|
1364
|
-
editor.updateInstanceState({ isFocusMode: !editor.getInstanceState().isFocusMode })
|
|
1365
|
-
})
|
|
1366
|
-
})
|
|
1367
|
-
},
|
|
1368
|
-
},
|
|
1369
1347
|
{
|
|
1370
1348
|
id: 'toggle-grid',
|
|
1371
1349
|
label: {
|
package/src/lib/ui/version.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// This file is automatically generated by internal/scripts/refresh-assets.ts.
|
|
2
2
|
// Do not edit manually. Or do, I'm a comment, not a cop.
|
|
3
3
|
|
|
4
|
-
export const version = '4.1.0-canary.
|
|
4
|
+
export const version = '4.1.0-canary.bdf9b3703a3d'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2025-09-18T14:39:22.803Z',
|
|
7
|
-
minor: '2025-09-
|
|
8
|
-
patch: '2025-09-
|
|
7
|
+
minor: '2025-09-18T18:11:43.980Z',
|
|
8
|
+
patch: '2025-09-18T18:11:43.980Z',
|
|
9
9
|
}
|