tldraw 3.15.0-canary.e3f6387b7e04 → 3.15.0-canary.ef2f8fce47e3
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.d.ts +39 -8
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawImage.js +5 -2
- package/dist-cjs/lib/TldrawImage.js.map +3 -3
- package/dist-cjs/lib/canvas/TldrawCropHandles.js +1 -1
- package/dist-cjs/lib/canvas/TldrawCropHandles.js.map +2 -2
- package/dist-cjs/lib/canvas/TldrawHandles.js +1 -1
- package/dist-cjs/lib/canvas/TldrawHandles.js.map +2 -2
- package/dist-cjs/lib/canvas/TldrawOverlays.js +1 -1
- package/dist-cjs/lib/canvas/TldrawOverlays.js.map +2 -2
- package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +279 -271
- package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +3 -0
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js +15 -1
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -0
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js +1 -0
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
- package/dist-cjs/lib/styles.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +43 -22
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +8 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +8 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +8 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
- package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +3 -4
- package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/Spinner.js +2 -25
- package/dist-cjs/lib/ui/components/Spinner.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButtonIcon.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +35 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/useTools.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-cjs/lib/utils/tldr/buildFromV1Document.js +2 -1
- package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
- package/dist-esm/index.d.mts +39 -8
- package/dist-esm/index.mjs +4 -2
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawImage.mjs +5 -2
- package/dist-esm/lib/TldrawImage.mjs.map +2 -2
- package/dist-esm/lib/canvas/TldrawCropHandles.mjs +1 -1
- package/dist-esm/lib/canvas/TldrawCropHandles.mjs.map +2 -2
- package/dist-esm/lib/canvas/TldrawHandles.mjs +1 -1
- package/dist-esm/lib/canvas/TldrawHandles.mjs.map +2 -2
- package/dist-esm/lib/canvas/TldrawOverlays.mjs +1 -1
- package/dist-esm/lib/canvas/TldrawOverlays.mjs.map +2 -2
- package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs +279 -271
- package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +3 -0
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +15 -1
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -0
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +1 -0
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
- package/dist-esm/lib/styles.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +43 -22
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +8 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +8 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +8 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
- package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs +3 -4
- package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Spinner.mjs +3 -26
- package/dist-esm/lib/ui/components/Spinner.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/Button/TldrawUiButtonIcon.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs +36 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs.map +1 -1
- package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs +2 -1
- package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
- package/package.json +4 -3
- package/src/index.ts +5 -1
- package/src/lib/TldrawImage.tsx +6 -2
- package/src/lib/canvas/TldrawCropHandles.tsx +1 -1
- package/src/lib/canvas/TldrawHandles.tsx +5 -1
- package/src/lib/canvas/TldrawOverlays.tsx +1 -1
- package/src/lib/canvas/TldrawSelectionForeground.tsx +5 -1
- package/src/lib/shapes/arrow/toolStates/Pointing.tsx +3 -0
- package/src/lib/shapes/line/LineShapeUtil.tsx +19 -2
- package/src/lib/shapes/shared/PlainTextLabel.tsx +1 -0
- package/src/lib/shapes/shared/RichTextLabel.tsx +1 -0
- package/src/lib/styles.tsx +3 -1
- package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +54 -30
- package/src/lib/tools/SelectTool/childStates/Resizing.ts +12 -1
- package/src/lib/tools/SelectTool/childStates/Rotating.ts +11 -0
- package/src/lib/tools/SelectTool/childStates/Translating.ts +11 -0
- package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +3 -4
- package/src/lib/ui/components/Spinner.tsx +2 -24
- package/src/lib/ui/components/primitives/Button/TldrawUiButtonIcon.tsx +2 -2
- package/src/lib/ui/components/primitives/TldrawUiIcon.tsx +41 -3
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +2 -2
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +3 -2
- package/src/lib/ui/context/actions.tsx +1 -1
- package/src/lib/ui/hooks/useTools.tsx +2 -1
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +8 -22
- package/src/lib/utils/tldr/buildFromV1Document.ts +1 -0
- package/src/test/commands/deletePage.test.ts +84 -1
- package/src/test/navigation.test.ts +254 -0
- package/src/test/shapeutils.test.ts +394 -45
- package/tldraw.css +25 -26
|
@@ -414,6 +414,260 @@ describe('Shape navigation', () => {
|
|
|
414
414
|
expect(editor.getSelectedShapeIds()).toEqual([])
|
|
415
415
|
})
|
|
416
416
|
|
|
417
|
+
it('respects container boundaries when navigating with left/right', () => {
|
|
418
|
+
// Create a frame with shapes inside and shapes outside
|
|
419
|
+
editor.createShapes([
|
|
420
|
+
{
|
|
421
|
+
id: ids.frame1,
|
|
422
|
+
type: 'frame',
|
|
423
|
+
x: 0,
|
|
424
|
+
y: 0,
|
|
425
|
+
props: {
|
|
426
|
+
w: 200,
|
|
427
|
+
h: 200,
|
|
428
|
+
},
|
|
429
|
+
},
|
|
430
|
+
// Shapes inside frame
|
|
431
|
+
{
|
|
432
|
+
id: ids.box1,
|
|
433
|
+
type: 'geo',
|
|
434
|
+
x: 10,
|
|
435
|
+
y: 100,
|
|
436
|
+
parentId: ids.frame1,
|
|
437
|
+
props: {
|
|
438
|
+
w: 30,
|
|
439
|
+
h: 30,
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
id: ids.box2,
|
|
444
|
+
type: 'geo',
|
|
445
|
+
x: 50,
|
|
446
|
+
y: 100,
|
|
447
|
+
parentId: ids.frame1,
|
|
448
|
+
props: {
|
|
449
|
+
w: 30,
|
|
450
|
+
h: 30,
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
id: ids.box3,
|
|
455
|
+
type: 'geo',
|
|
456
|
+
x: 90,
|
|
457
|
+
y: 100,
|
|
458
|
+
parentId: ids.frame1,
|
|
459
|
+
props: {
|
|
460
|
+
w: 30,
|
|
461
|
+
h: 30,
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
// Shapes outside frame
|
|
465
|
+
{
|
|
466
|
+
id: ids.box4,
|
|
467
|
+
type: 'geo',
|
|
468
|
+
x: 300,
|
|
469
|
+
y: 100,
|
|
470
|
+
props: {
|
|
471
|
+
w: 30,
|
|
472
|
+
h: 30,
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
id: ids.box5,
|
|
477
|
+
type: 'geo',
|
|
478
|
+
x: 350,
|
|
479
|
+
y: 100,
|
|
480
|
+
props: {
|
|
481
|
+
w: 30,
|
|
482
|
+
h: 30,
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
])
|
|
486
|
+
|
|
487
|
+
// Setup shape centers for consistent testing
|
|
488
|
+
jest.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
|
|
489
|
+
const positions = {
|
|
490
|
+
[ids.box1]: { x: 25, y: 115 },
|
|
491
|
+
[ids.box2]: { x: 65, y: 115 },
|
|
492
|
+
[ids.box3]: { x: 105, y: 115 },
|
|
493
|
+
[ids.box4]: { x: 315, y: 115 },
|
|
494
|
+
[ids.box5]: { x: 365, y: 115 },
|
|
495
|
+
}
|
|
496
|
+
const pos = positions[shape?.id as keyof typeof positions]
|
|
497
|
+
return pos ? ({ center: pos } as any) : ({ center: { x: 0, y: 0 } } as any)
|
|
498
|
+
})
|
|
499
|
+
|
|
500
|
+
// Select a shape inside the frame
|
|
501
|
+
editor.select(ids.box1)
|
|
502
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box1])
|
|
503
|
+
|
|
504
|
+
// Navigate right - should stay within the frame
|
|
505
|
+
editor.selectAdjacentShape('right')
|
|
506
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box2])
|
|
507
|
+
|
|
508
|
+
// Continue navigating right - should still stay within the frame
|
|
509
|
+
editor.selectAdjacentShape('right')
|
|
510
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box3])
|
|
511
|
+
|
|
512
|
+
// Navigate right again - should not leave the frame to go to box4
|
|
513
|
+
editor.selectAdjacentShape('right')
|
|
514
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box3]) // Should stay at box3
|
|
515
|
+
|
|
516
|
+
// Now navigate left to test the other direction
|
|
517
|
+
editor.selectAdjacentShape('left')
|
|
518
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box2])
|
|
519
|
+
|
|
520
|
+
editor.selectAdjacentShape('left')
|
|
521
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box1])
|
|
522
|
+
|
|
523
|
+
// Navigate left again - should not leave the frame
|
|
524
|
+
editor.selectAdjacentShape('left')
|
|
525
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box1]) // Should stay at box1
|
|
526
|
+
|
|
527
|
+
// Now test navigation outside the frame
|
|
528
|
+
editor.select(ids.box4)
|
|
529
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box4])
|
|
530
|
+
|
|
531
|
+
// Navigate right - should move to box5
|
|
532
|
+
editor.selectAdjacentShape('right')
|
|
533
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box5])
|
|
534
|
+
|
|
535
|
+
// Navigate left - should move back to box4
|
|
536
|
+
editor.selectAdjacentShape('left')
|
|
537
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box4])
|
|
538
|
+
|
|
539
|
+
// Navigate left again - should select the frame (nearest shape to the left)
|
|
540
|
+
editor.selectAdjacentShape('left')
|
|
541
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.frame1]) // Should select frame1
|
|
542
|
+
})
|
|
543
|
+
|
|
544
|
+
it('respects container boundaries when navigating with up/down', () => {
|
|
545
|
+
// Create a frame with shapes inside and shapes outside
|
|
546
|
+
editor.createShapes([
|
|
547
|
+
{
|
|
548
|
+
id: ids.frame1,
|
|
549
|
+
type: 'frame',
|
|
550
|
+
x: 0,
|
|
551
|
+
y: 0,
|
|
552
|
+
props: {
|
|
553
|
+
w: 200,
|
|
554
|
+
h: 200,
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
// Shapes inside frame - vertically arranged
|
|
558
|
+
{
|
|
559
|
+
id: ids.box1,
|
|
560
|
+
type: 'geo',
|
|
561
|
+
x: 100,
|
|
562
|
+
y: 10,
|
|
563
|
+
parentId: ids.frame1,
|
|
564
|
+
props: {
|
|
565
|
+
w: 30,
|
|
566
|
+
h: 30,
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
id: ids.box2,
|
|
571
|
+
type: 'geo',
|
|
572
|
+
x: 100,
|
|
573
|
+
y: 50,
|
|
574
|
+
parentId: ids.frame1,
|
|
575
|
+
props: {
|
|
576
|
+
w: 30,
|
|
577
|
+
h: 30,
|
|
578
|
+
},
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
id: ids.box3,
|
|
582
|
+
type: 'geo',
|
|
583
|
+
x: 100,
|
|
584
|
+
y: 90,
|
|
585
|
+
parentId: ids.frame1,
|
|
586
|
+
props: {
|
|
587
|
+
w: 30,
|
|
588
|
+
h: 30,
|
|
589
|
+
},
|
|
590
|
+
},
|
|
591
|
+
// Shapes outside frame - vertically arranged
|
|
592
|
+
{
|
|
593
|
+
id: ids.box4,
|
|
594
|
+
type: 'geo',
|
|
595
|
+
x: 300,
|
|
596
|
+
y: 10,
|
|
597
|
+
props: {
|
|
598
|
+
w: 30,
|
|
599
|
+
h: 30,
|
|
600
|
+
},
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
id: ids.box5,
|
|
604
|
+
type: 'geo',
|
|
605
|
+
x: 300,
|
|
606
|
+
y: 50,
|
|
607
|
+
props: {
|
|
608
|
+
w: 30,
|
|
609
|
+
h: 30,
|
|
610
|
+
},
|
|
611
|
+
},
|
|
612
|
+
])
|
|
613
|
+
|
|
614
|
+
// Setup shape centers for consistent testing
|
|
615
|
+
jest.spyOn(editor, 'getShapePageBounds').mockImplementation((shape: any) => {
|
|
616
|
+
const positions = {
|
|
617
|
+
[ids.box1]: { x: 115, y: 25 },
|
|
618
|
+
[ids.box2]: { x: 115, y: 65 },
|
|
619
|
+
[ids.box3]: { x: 115, y: 105 },
|
|
620
|
+
[ids.box4]: { x: 315, y: 25 },
|
|
621
|
+
[ids.box5]: { x: 315, y: 65 },
|
|
622
|
+
}
|
|
623
|
+
const pos = positions[shape?.id as keyof typeof positions]
|
|
624
|
+
return pos ? ({ center: pos } as any) : ({ center: { x: 0, y: 0 } } as any)
|
|
625
|
+
})
|
|
626
|
+
|
|
627
|
+
// Select a shape inside the frame
|
|
628
|
+
editor.select(ids.box1)
|
|
629
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box1])
|
|
630
|
+
|
|
631
|
+
// Navigate down - should stay within the frame
|
|
632
|
+
editor.selectAdjacentShape('down')
|
|
633
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box2])
|
|
634
|
+
|
|
635
|
+
// Continue navigating down - should still stay within the frame
|
|
636
|
+
editor.selectAdjacentShape('down')
|
|
637
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box3])
|
|
638
|
+
|
|
639
|
+
// Navigate down again - should not leave the frame
|
|
640
|
+
editor.selectAdjacentShape('down')
|
|
641
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box3]) // Should stay at box3
|
|
642
|
+
|
|
643
|
+
// Now navigate up to test the other direction
|
|
644
|
+
editor.selectAdjacentShape('up')
|
|
645
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box2])
|
|
646
|
+
|
|
647
|
+
editor.selectAdjacentShape('up')
|
|
648
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box1])
|
|
649
|
+
|
|
650
|
+
// Navigate up again - should not leave the frame
|
|
651
|
+
editor.selectAdjacentShape('up')
|
|
652
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box1]) // Should stay at box1
|
|
653
|
+
|
|
654
|
+
// Now test navigation outside the frame
|
|
655
|
+
editor.select(ids.box4)
|
|
656
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box4])
|
|
657
|
+
|
|
658
|
+
// Navigate down - should move to box5
|
|
659
|
+
editor.selectAdjacentShape('down')
|
|
660
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box5])
|
|
661
|
+
|
|
662
|
+
// Navigate up - should move back to box4
|
|
663
|
+
editor.selectAdjacentShape('up')
|
|
664
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box4])
|
|
665
|
+
|
|
666
|
+
// Navigate up again - should not enter the frame
|
|
667
|
+
editor.selectAdjacentShape('up')
|
|
668
|
+
expect(editor.getSelectedShapeIds()).toEqual([ids.box4]) // Should stay at box4
|
|
669
|
+
})
|
|
670
|
+
|
|
417
671
|
it('respects container boundaries when navigating with Tab', () => {
|
|
418
672
|
// Create a frame with shapes inside and shapes outside
|
|
419
673
|
editor.createShapes([
|