tldraw 4.1.0-canary.4095f8cc2614 → 4.1.0-canary.5b2a01989756
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/defaultExternalContentHandlers.js +1 -1
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/curved-arrow.js +8 -2
- package/dist-cjs/lib/shapes/arrow/curved-arrow.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/straight-arrow.js +4 -1
- 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/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/defaultExternalContentHandlers.mjs +1 -1
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/curved-arrow.mjs +8 -2
- package/dist-esm/lib/shapes/arrow/curved-arrow.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/straight-arrow.mjs +4 -1
- 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/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/package.json +3 -3
- package/src/lib/defaultExternalContentHandlers.ts +1 -1
- package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +211 -1
- package/src/lib/shapes/arrow/curved-arrow.ts +8 -2
- package/src/lib/shapes/arrow/straight-arrow.ts +5 -1
- package/src/lib/shapes/shared/RichTextLabel.tsx +1 -1
- 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 } from './shared'
|
|
4
|
+
import { createOrUpdateArrowBinding, getArrowBindings, getArrowInfo } from './shared'
|
|
5
5
|
|
|
6
6
|
let editor: TestEditor
|
|
7
7
|
|
|
@@ -620,3 +620,213 @@ 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,7 +154,10 @@ export function getCurvedArrowInfo(
|
|
|
154
154
|
}
|
|
155
155
|
if (!point) {
|
|
156
156
|
if (isClosed) {
|
|
157
|
-
const nearestPoint = startShapeInfo.geometry.nearestPoint(startInStartShapeLocalSpace
|
|
157
|
+
const nearestPoint = startShapeInfo.geometry.nearestPoint(startInStartShapeLocalSpace, {
|
|
158
|
+
includeInternal: false,
|
|
159
|
+
includeLabels: false,
|
|
160
|
+
})
|
|
158
161
|
if (Vec.DistMin(nearestPoint, startInStartShapeLocalSpace, 1)) {
|
|
159
162
|
point = nearestPoint
|
|
160
163
|
}
|
|
@@ -233,7 +236,10 @@ export function getCurvedArrowInfo(
|
|
|
233
236
|
}
|
|
234
237
|
if (!point) {
|
|
235
238
|
if (isClosed) {
|
|
236
|
-
const nearestPoint = endShapeInfo.geometry.nearestPoint(endInEndShapeLocalSpace
|
|
239
|
+
const nearestPoint = endShapeInfo.geometry.nearestPoint(endInEndShapeLocalSpace, {
|
|
240
|
+
includeInternal: false,
|
|
241
|
+
includeLabels: false,
|
|
242
|
+
})
|
|
237
243
|
if (Vec.DistMin(nearestPoint, endInEndShapeLocalSpace, 1)) {
|
|
238
244
|
point = nearestPoint
|
|
239
245
|
}
|
|
@@ -248,7 +248,11 @@ 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
|
|
251
|
+
targetInt = targetShapeInfo.geometry.nearestPoint(targetTo, {
|
|
252
|
+
includeLabels: false,
|
|
253
|
+
includeInternal: false,
|
|
254
|
+
})
|
|
255
|
+
|
|
252
256
|
if (!Vec.DistMin(targetInt, targetTo, 1)) {
|
|
253
257
|
return
|
|
254
258
|
}
|
|
@@ -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') return
|
|
112
|
+
if (e.name !== 'pointer_up' || !link) return
|
|
113
113
|
|
|
114
114
|
if (!isDragging.current) {
|
|
115
115
|
window.open(link, '_blank', 'noopener, noreferrer')
|
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.5b2a01989756'
|
|
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-26T15:44:39.359Z',
|
|
8
|
+
patch: '2025-09-26T15:44:39.359Z',
|
|
9
9
|
}
|