tldraw 4.1.0-canary.bace23a29058 → 4.1.0-canary.c62140a07605
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/canvas/TldrawCropHandles.js +1 -1
- package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
- package/dist-cjs/lib/canvas/TldrawSelectionForeground.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/bookmark/BookmarkShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +1 -1
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -1
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js +2 -2
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/ShapeFill.js +1 -1
- package/dist-cjs/lib/shapes/text/PlainTextArea.js +1 -1
- package/dist-cjs/lib/shapes/text/RichTextArea.js +1 -1
- package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +1 -1
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js +1 -1
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +1 -1
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
- package/dist-cjs/lib/ui/TldrawUi.js +2 -2
- package/dist-cjs/lib/ui/components/DebugMenu/DefaultDebugMenuContent.js +1 -1
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialog.js +1 -1
- 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/components/MainMenu/DefaultMainMenuContent.js +5 -3
- package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +1 -1
- package/dist-cjs/lib/ui/components/OfflineIndicator/OfflineIndicator.js +1 -1
- package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +1 -1
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +1 -1
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +1 -1
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js +1 -1
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js +1 -1
- package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +1 -1
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +1 -1
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButton.js +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiDialog.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/layout.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +1 -1
- package/dist-cjs/lib/ui/context/actions.js +21 -1
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/breakpoints.js +1 -1
- package/dist-cjs/lib/ui/context/events.js +1 -1
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
- package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +1 -1
- package/dist-cjs/lib/ui/hooks/useLocalStorageState.js +1 -1
- package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
- package/dist-cjs/lib/ui/hooks/useTranslation/useTranslation.js +1 -1
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-cjs/lib/utils/text/richText.js +4 -4
- 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/tools/SelectTool/childStates/Crop/children/Idle.mjs +1 -1
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +1 -1
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.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/components/MainMenu/DefaultMainMenuContent.mjs +5 -3
- package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +20 -0
- 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 +11 -11
- 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/shapes/text/TextShapeTool.test.ts +74 -0
- package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +1 -1
- package/src/lib/tools/SelectTool/childStates/Idle.ts +1 -1
- package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +1 -1
- package/src/lib/ui/components/MainMenu/DefaultMainMenuContent.tsx +1 -5
- package/src/lib/ui/context/actions.tsx +22 -0
- 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')
|
|
@@ -86,6 +86,80 @@ describe('When in idle state', () => {
|
|
|
86
86
|
editor.cancel()
|
|
87
87
|
editor.expectToBeIn('select.idle')
|
|
88
88
|
})
|
|
89
|
+
|
|
90
|
+
it('starts editing selected text shape on Enter key', () => {
|
|
91
|
+
// Create a text shape using the same method as other tests
|
|
92
|
+
expect(editor.getCurrentPageShapes().length).toBe(0)
|
|
93
|
+
editor.setCurrentTool('text')
|
|
94
|
+
editor.pointerDown(0, 0)
|
|
95
|
+
editor.pointerUp()
|
|
96
|
+
editor.expectToBeIn('select.editing_shape')
|
|
97
|
+
|
|
98
|
+
// Update the text shape with some content
|
|
99
|
+
editor.updateShapes<TLTextShape>([
|
|
100
|
+
{
|
|
101
|
+
...editor.getCurrentPageShapes()[0]!,
|
|
102
|
+
type: 'text',
|
|
103
|
+
props: { richText: toRichText('Hello') },
|
|
104
|
+
},
|
|
105
|
+
])
|
|
106
|
+
|
|
107
|
+
// Exit editing mode
|
|
108
|
+
editor.cancel()
|
|
109
|
+
editor.expectToBeIn('select.idle')
|
|
110
|
+
|
|
111
|
+
// Verify the text shape exists and is selected
|
|
112
|
+
expect(editor.getCurrentPageShapes().length).toBe(1)
|
|
113
|
+
const textShape = editor.getCurrentPageShapes()[0]
|
|
114
|
+
expect(textShape.type).toBe('text')
|
|
115
|
+
editor.setSelectedShapes([textShape])
|
|
116
|
+
|
|
117
|
+
// Switch to text tool and press Enter
|
|
118
|
+
editor.setCurrentTool('text')
|
|
119
|
+
editor.expectToBeIn('text.idle')
|
|
120
|
+
editor.keyDown('Enter')
|
|
121
|
+
|
|
122
|
+
// Should transition to editing the selected text shape
|
|
123
|
+
editor.expectToBeIn('select.editing_shape')
|
|
124
|
+
expect(editor.getEditingShapeId()).toBe(textShape.id)
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
it('starts editing selected text shape on numpad Enter key', () => {
|
|
128
|
+
// Create a text shape using the same method as other tests
|
|
129
|
+
expect(editor.getCurrentPageShapes().length).toBe(0)
|
|
130
|
+
editor.setCurrentTool('text')
|
|
131
|
+
editor.pointerDown(0, 0)
|
|
132
|
+
editor.pointerUp()
|
|
133
|
+
editor.expectToBeIn('select.editing_shape')
|
|
134
|
+
|
|
135
|
+
// Update the text shape with some content
|
|
136
|
+
editor.updateShapes<TLTextShape>([
|
|
137
|
+
{
|
|
138
|
+
...editor.getCurrentPageShapes()[0]!,
|
|
139
|
+
type: 'text',
|
|
140
|
+
props: { richText: toRichText('Hello') },
|
|
141
|
+
},
|
|
142
|
+
])
|
|
143
|
+
|
|
144
|
+
// Exit editing mode
|
|
145
|
+
editor.cancel()
|
|
146
|
+
editor.expectToBeIn('select.idle')
|
|
147
|
+
|
|
148
|
+
// Verify the text shape exists and is selected
|
|
149
|
+
expect(editor.getCurrentPageShapes().length).toBe(1)
|
|
150
|
+
const textShape = editor.getCurrentPageShapes()[0]
|
|
151
|
+
expect(textShape.type).toBe('text')
|
|
152
|
+
editor.setSelectedShapes([textShape])
|
|
153
|
+
|
|
154
|
+
// Switch to text tool and press numpad Enter
|
|
155
|
+
editor.setCurrentTool('text')
|
|
156
|
+
editor.expectToBeIn('text.idle')
|
|
157
|
+
editor.keyDown('Enter', { code: 'NumpadEnter' })
|
|
158
|
+
|
|
159
|
+
// Should transition to editing the selected text shape
|
|
160
|
+
editor.expectToBeIn('select.editing_shape')
|
|
161
|
+
expect(editor.getEditingShapeId()).toBe(textShape.id)
|
|
162
|
+
})
|
|
89
163
|
})
|
|
90
164
|
|
|
91
165
|
describe('When in the pointing state', () => {
|
|
@@ -143,7 +143,7 @@ export class Idle extends StateNode {
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
override onKeyUp(info: TLKeyboardEventInfo) {
|
|
146
|
-
switch (info.
|
|
146
|
+
switch (info.key) {
|
|
147
147
|
case 'Enter': {
|
|
148
148
|
this.editor.setCroppingShape(null)
|
|
149
149
|
this.editor.setCurrentTool('select.idle', {})
|
|
@@ -516,7 +516,7 @@ export class Idle extends StateNode {
|
|
|
516
516
|
}
|
|
517
517
|
|
|
518
518
|
override onKeyUp(info: TLKeyboardEventInfo) {
|
|
519
|
-
switch (info.
|
|
519
|
+
switch (info.key) {
|
|
520
520
|
case 'Enter': {
|
|
521
521
|
// Because Enter onKeyDown can happen outside the canvas (but then focus the canvas potentially),
|
|
522
522
|
// we need to check if the canvas was initially selecting something before continuing.
|
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
|
}}
|
|
@@ -165,13 +165,9 @@ export function PreferencesGroup() {
|
|
|
165
165
|
<TogglePasteAtCursorItem />
|
|
166
166
|
<ToggleDebugModeItem />
|
|
167
167
|
</TldrawUiMenuGroup>
|
|
168
|
-
<TldrawUiMenuGroup id="
|
|
168
|
+
<TldrawUiMenuGroup id="user-interface-submenus">
|
|
169
169
|
<InputModeMenu />
|
|
170
|
-
</TldrawUiMenuGroup>
|
|
171
|
-
<TldrawUiMenuGroup id="color-scheme">
|
|
172
170
|
<ColorSchemeMenu />
|
|
173
|
-
</TldrawUiMenuGroup>
|
|
174
|
-
<TldrawUiMenuGroup id="accessibility-menu">
|
|
175
171
|
<AccessibilityMenu />
|
|
176
172
|
</TldrawUiMenuGroup>
|
|
177
173
|
</TldrawUiMenuSubmenu>
|
|
@@ -1344,6 +1344,28 @@ 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
|
+
},
|
|
1347
1369
|
{
|
|
1348
1370
|
id: 'toggle-grid',
|
|
1349
1371
|
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.c62140a07605'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2025-09-18T14:39:22.803Z',
|
|
7
|
-
minor: '2025-
|
|
8
|
-
patch: '2025-
|
|
7
|
+
minor: '2025-10-01T10:03:29.121Z',
|
|
8
|
+
patch: '2025-10-01T10:03:29.121Z',
|
|
9
9
|
}
|