@tldraw/editor 4.6.0-next.20de11b7e238 → 4.6.0-next.241e87d4700a
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 +668 -96
- package/dist-cjs/index.js +16 -3
- package/dist-cjs/index.js.map +3 -3
- package/dist-cjs/lib/TldrawEditor.js +55 -12
- package/dist-cjs/lib/TldrawEditor.js.map +3 -3
- package/dist-cjs/lib/components/MenuClickCapture.js +16 -1
- package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +3 -3
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +2 -2
- package/dist-cjs/lib/config/createTLStore.js +7 -0
- package/dist-cjs/lib/config/createTLStore.js.map +2 -2
- package/dist-cjs/lib/config/defaultAssets.js +36 -0
- package/dist-cjs/lib/config/defaultAssets.js.map +7 -0
- package/dist-cjs/lib/editor/Editor.js +215 -5
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/assets/AssetUtil.js +66 -0
- package/dist-cjs/lib/editor/assets/AssetUtil.js.map +7 -0
- package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.js +80 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.js.map +7 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js +466 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/perf-types.js +17 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/perf-types.js.map +7 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js +106 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js +586 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js.map +7 -0
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +6 -4
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +11 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +1 -1
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js +6 -0
- package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
- package/dist-cjs/lib/editor/tools/StateNode.js +14 -17
- package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
- package/dist-cjs/lib/editor/types/SvgExportContext.js.map +2 -2
- package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js +12 -7
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/globals/environment.js +18 -1
- package/dist-cjs/lib/globals/environment.js.map +2 -2
- package/dist-cjs/lib/hooks/{useIsDarkMode.js → useColorMode.js} +14 -10
- package/dist-cjs/lib/hooks/useColorMode.js.map +7 -0
- package/dist-cjs/lib/hooks/useCursor.js +3 -7
- package/dist-cjs/lib/hooks/useCursor.js.map +2 -2
- package/dist-cjs/lib/hooks/useDarkMode.js +4 -4
- package/dist-cjs/lib/hooks/useDarkMode.js.map +2 -2
- package/dist-cjs/lib/utils/reparenting.js +2 -1
- package/dist-cjs/lib/utils/reparenting.js.map +2 -2
- package/dist-cjs/lib/utils/richText.js.map +2 -2
- package/dist-cjs/lib/utils/runtime.js +2 -1
- package/dist-cjs/lib/utils/runtime.js.map +2 -2
- package/dist-cjs/lib/utils/sync/hardReset.js +0 -8
- package/dist-cjs/lib/utils/sync/hardReset.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +668 -96
- package/dist-esm/index.mjs +17 -6
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +58 -12
- package/dist-esm/lib/TldrawEditor.mjs.map +3 -3
- package/dist-esm/lib/components/MenuClickCapture.mjs +16 -1
- package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +3 -3
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +2 -2
- package/dist-esm/lib/config/createTLStore.mjs +10 -1
- package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
- package/dist-esm/lib/config/defaultAssets.mjs +16 -0
- package/dist-esm/lib/config/defaultAssets.mjs.map +7 -0
- package/dist-esm/lib/editor/Editor.mjs +215 -5
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/assets/AssetUtil.mjs +46 -0
- package/dist-esm/lib/editor/assets/AssetUtil.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.mjs +60 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs +438 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/perf-types.mjs +1 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/perf-types.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs +88 -0
- package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs +568 -0
- package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +6 -4
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +11 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +1 -1
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs +6 -0
- package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/StateNode.mjs +14 -17
- package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
- package/dist-esm/lib/editor/types/SvgExportContext.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +12 -10
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/globals/environment.mjs +18 -1
- package/dist-esm/lib/globals/environment.mjs.map +2 -2
- package/dist-esm/lib/hooks/useColorMode.mjs +19 -0
- package/dist-esm/lib/hooks/useColorMode.mjs.map +7 -0
- package/dist-esm/lib/hooks/useCursor.mjs +3 -7
- package/dist-esm/lib/hooks/useCursor.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDarkMode.mjs +4 -4
- package/dist-esm/lib/hooks/useDarkMode.mjs.map +2 -2
- package/dist-esm/lib/utils/reparenting.mjs +2 -1
- package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
- package/dist-esm/lib/utils/richText.mjs.map +2 -2
- package/dist-esm/lib/utils/runtime.mjs +2 -1
- package/dist-esm/lib/utils/runtime.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/hardReset.mjs +0 -8
- package/dist-esm/lib/utils/sync/hardReset.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +0 -33
- package/package.json +7 -7
- package/src/index.ts +23 -6
- package/src/lib/TldrawEditor.tsx +90 -13
- package/src/lib/components/MenuClickCapture.tsx +20 -0
- package/src/lib/components/default-components/CanvasShapeIndicators.tsx +3 -3
- package/src/lib/config/createTLStore.ts +22 -1
- package/src/lib/config/defaultAssets.ts +19 -0
- package/src/lib/editor/Editor.ts +301 -27
- package/src/lib/editor/assets/AssetUtil.ts +85 -0
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +9 -2
- package/src/lib/editor/managers/FontManager/FontManager.ts +1 -67
- package/src/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.ts +82 -0
- package/src/lib/editor/managers/PerformanceManager/PerformanceManager.test.ts +522 -0
- package/src/lib/editor/managers/PerformanceManager/PerformanceManager.ts +583 -0
- package/src/lib/editor/managers/PerformanceManager/perf-types.ts +196 -0
- package/src/lib/editor/managers/ThemeManager/ThemeManager.ts +116 -0
- package/src/lib/editor/managers/ThemeManager/defaultThemes.ts +605 -0
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +23 -29
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +5 -3
- package/src/lib/editor/shapes/ShapeUtil.ts +28 -3
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -1
- package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +7 -0
- package/src/lib/editor/tools/StateNode.ts +16 -18
- package/src/lib/editor/types/SvgExportContext.tsx +5 -0
- package/src/lib/editor/types/external-content.ts +1 -0
- package/src/lib/exports/getSvgJsx.tsx +21 -15
- package/src/lib/globals/environment.ts +18 -0
- package/src/lib/hooks/{useIsDarkMode.ts → useColorMode.ts} +9 -5
- package/src/lib/hooks/useCursor.ts +3 -7
- package/src/lib/hooks/useDarkMode.ts +4 -4
- package/src/lib/utils/reparenting.ts +6 -2
- package/src/lib/utils/richText.ts +1 -1
- package/src/lib/utils/runtime.ts +3 -1
- package/src/lib/utils/sync/hardReset.ts +0 -8
- package/src/version.ts +3 -3
- package/dist-cjs/lib/hooks/useIsDarkMode.js.map +0 -7
- package/dist-esm/lib/hooks/useIsDarkMode.mjs +0 -15
- package/dist-esm/lib/hooks/useIsDarkMode.mjs.map +0 -7
|
@@ -61,7 +61,7 @@ describe('UserPreferencesManager', () => {
|
|
|
61
61
|
// Test when window.matchMedia is not available
|
|
62
62
|
delete (window as any).matchMedia
|
|
63
63
|
|
|
64
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
64
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
65
65
|
|
|
66
66
|
expect(userPreferencesManager.systemColorScheme.get()).toBe('light')
|
|
67
67
|
|
|
@@ -76,7 +76,7 @@ describe('UserPreferencesManager', () => {
|
|
|
76
76
|
removeEventListener: vi.fn(),
|
|
77
77
|
})
|
|
78
78
|
|
|
79
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
79
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
80
80
|
|
|
81
81
|
expect(userPreferencesManager.systemColorScheme.get()).toBe('light')
|
|
82
82
|
})
|
|
@@ -88,7 +88,7 @@ describe('UserPreferencesManager', () => {
|
|
|
88
88
|
removeEventListener: vi.fn(),
|
|
89
89
|
})
|
|
90
90
|
|
|
91
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
91
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'system')
|
|
92
92
|
|
|
93
93
|
expect(userPreferencesManager.systemColorScheme.get()).toBe('dark')
|
|
94
94
|
})
|
|
@@ -103,7 +103,7 @@ describe('UserPreferencesManager', () => {
|
|
|
103
103
|
removeEventListener: mockRemoveEventListener,
|
|
104
104
|
})
|
|
105
105
|
|
|
106
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
106
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'system')
|
|
107
107
|
|
|
108
108
|
expect(mockAddEventListener).toHaveBeenCalledWith('change', expect.any(Function))
|
|
109
109
|
})
|
|
@@ -123,7 +123,7 @@ describe('UserPreferencesManager', () => {
|
|
|
123
123
|
removeEventListener: vi.fn(),
|
|
124
124
|
})
|
|
125
125
|
|
|
126
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
126
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'system')
|
|
127
127
|
|
|
128
128
|
expect(userPreferencesManager.systemColorScheme.get()).toBe('light')
|
|
129
129
|
|
|
@@ -141,7 +141,7 @@ describe('UserPreferencesManager', () => {
|
|
|
141
141
|
delete (global as any).window
|
|
142
142
|
|
|
143
143
|
expect(() => {
|
|
144
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
144
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
145
145
|
}).not.toThrow()
|
|
146
146
|
|
|
147
147
|
global.window = originalWindow
|
|
@@ -158,14 +158,14 @@ describe('UserPreferencesManager', () => {
|
|
|
158
158
|
removeEventListener: mockRemoveEventListener,
|
|
159
159
|
})
|
|
160
160
|
|
|
161
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
161
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'system')
|
|
162
162
|
userPreferencesManager.dispose()
|
|
163
163
|
|
|
164
164
|
expect(mockRemoveEventListener).toHaveBeenCalledWith('change', expect.any(Function))
|
|
165
165
|
})
|
|
166
166
|
|
|
167
167
|
it('should call all disposables', () => {
|
|
168
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
168
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
169
169
|
|
|
170
170
|
const mockDisposable1 = vi.fn()
|
|
171
171
|
const mockDisposable2 = vi.fn()
|
|
@@ -182,7 +182,7 @@ describe('UserPreferencesManager', () => {
|
|
|
182
182
|
|
|
183
183
|
describe('updateUserPreferences', () => {
|
|
184
184
|
beforeEach(() => {
|
|
185
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
185
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
186
186
|
})
|
|
187
187
|
|
|
188
188
|
it('should update user preferences with partial data', () => {
|
|
@@ -216,7 +216,7 @@ describe('UserPreferencesManager', () => {
|
|
|
216
216
|
|
|
217
217
|
describe('getUserPreferences', () => {
|
|
218
218
|
beforeEach(() => {
|
|
219
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
219
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
220
220
|
})
|
|
221
221
|
|
|
222
222
|
it('should return complete user preferences with computed values', () => {
|
|
@@ -255,7 +255,7 @@ describe('UserPreferencesManager', () => {
|
|
|
255
255
|
|
|
256
256
|
describe('getIsDarkMode', () => {
|
|
257
257
|
beforeEach(() => {
|
|
258
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
258
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
259
259
|
})
|
|
260
260
|
|
|
261
261
|
it('should return true when colorScheme is dark', () => {
|
|
@@ -282,24 +282,18 @@ describe('UserPreferencesManager', () => {
|
|
|
282
282
|
expect(userPreferencesManager.getIsDarkMode()).toBe(true)
|
|
283
283
|
})
|
|
284
284
|
|
|
285
|
-
it('should
|
|
285
|
+
it('should default to light when colorScheme is undefined', () => {
|
|
286
286
|
userPreferencesAtom.set({ ...mockUserPreferences, colorScheme: undefined })
|
|
287
287
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
expect(managerWithInfer.getIsDarkMode()).toBe(true)
|
|
292
|
-
|
|
293
|
-
// With inferDarkMode = false
|
|
294
|
-
const managerWithoutInfer = new UserPreferencesManager(mockUser, false)
|
|
295
|
-
managerWithoutInfer.systemColorScheme.set('dark')
|
|
296
|
-
expect(managerWithoutInfer.getIsDarkMode()).toBe(false)
|
|
288
|
+
const manager = new UserPreferencesManager(mockUser, 'light')
|
|
289
|
+
manager.systemColorScheme.set('dark')
|
|
290
|
+
expect(manager.getIsDarkMode()).toBe(false)
|
|
297
291
|
})
|
|
298
292
|
})
|
|
299
293
|
|
|
300
294
|
describe('individual preference getters', () => {
|
|
301
295
|
beforeEach(() => {
|
|
302
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
296
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
303
297
|
})
|
|
304
298
|
|
|
305
299
|
describe('getId', () => {
|
|
@@ -499,7 +493,7 @@ describe('UserPreferencesManager', () => {
|
|
|
499
493
|
|
|
500
494
|
describe('reactive behavior', () => {
|
|
501
495
|
beforeEach(() => {
|
|
502
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
496
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
503
497
|
})
|
|
504
498
|
|
|
505
499
|
it('should react to user preferences changes', () => {
|
|
@@ -533,7 +527,7 @@ describe('UserPreferencesManager', () => {
|
|
|
533
527
|
|
|
534
528
|
describe('edge cases and error handling', () => {
|
|
535
529
|
beforeEach(() => {
|
|
536
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
530
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
537
531
|
})
|
|
538
532
|
|
|
539
533
|
it('should handle undefined user preferences gracefully', () => {
|
|
@@ -589,14 +583,14 @@ describe('UserPreferencesManager', () => {
|
|
|
589
583
|
mockMatchMedia.mockReturnValue(null)
|
|
590
584
|
|
|
591
585
|
expect(() => {
|
|
592
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
586
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
593
587
|
}).not.toThrow()
|
|
594
588
|
|
|
595
589
|
expect(userPreferencesManager.systemColorScheme.get()).toBe('light')
|
|
596
590
|
})
|
|
597
591
|
|
|
598
592
|
it('should handle dispose gracefully in all cases', () => {
|
|
599
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
593
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
600
594
|
|
|
601
595
|
// Should not throw even if dispose is called multiple times
|
|
602
596
|
expect(() => userPreferencesManager.dispose()).not.toThrow()
|
|
@@ -608,7 +602,7 @@ describe('UserPreferencesManager', () => {
|
|
|
608
602
|
const originalWindow = global.window
|
|
609
603
|
delete (global as any).window
|
|
610
604
|
|
|
611
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
605
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
612
606
|
|
|
613
607
|
expect(() => userPreferencesManager.dispose()).not.toThrow()
|
|
614
608
|
expect(userPreferencesManager.disposables.size).toBe(0)
|
|
@@ -619,7 +613,7 @@ describe('UserPreferencesManager', () => {
|
|
|
619
613
|
|
|
620
614
|
describe('integration scenarios', () => {
|
|
621
615
|
it('should work with real-world preference scenarios', () => {
|
|
622
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
616
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
623
617
|
|
|
624
618
|
// User starts with system preference
|
|
625
619
|
userPreferencesManager.updateUserPreferences({ colorScheme: 'system' })
|
|
@@ -641,7 +635,7 @@ describe('UserPreferencesManager', () => {
|
|
|
641
635
|
})
|
|
642
636
|
|
|
643
637
|
it('should handle preference updates with multiple fields', () => {
|
|
644
|
-
userPreferencesManager = new UserPreferencesManager(mockUser,
|
|
638
|
+
userPreferencesManager = new UserPreferencesManager(mockUser, 'light')
|
|
645
639
|
|
|
646
640
|
const updates = {
|
|
647
641
|
name: 'New User',
|
|
@@ -12,7 +12,7 @@ export class UserPreferencesManager {
|
|
|
12
12
|
}
|
|
13
13
|
constructor(
|
|
14
14
|
private readonly user: TLCurrentUser,
|
|
15
|
-
private readonly
|
|
15
|
+
private readonly colorScheme: 'light' | 'dark' | 'system'
|
|
16
16
|
) {
|
|
17
17
|
if (typeof window === 'undefined' || !getGlobalWindow().matchMedia) return
|
|
18
18
|
|
|
@@ -57,7 +57,9 @@ export class UserPreferencesManager {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
@computed getIsDarkMode() {
|
|
60
|
-
|
|
60
|
+
const userColorScheme = this.user.userPreferences.get().colorScheme
|
|
61
|
+
const scheme = userColorScheme ?? this.colorScheme
|
|
62
|
+
switch (scheme) {
|
|
61
63
|
case 'dark':
|
|
62
64
|
return true
|
|
63
65
|
case 'light':
|
|
@@ -65,7 +67,7 @@ export class UserPreferencesManager {
|
|
|
65
67
|
case 'system':
|
|
66
68
|
return this.systemColorScheme.get() === 'dark'
|
|
67
69
|
default:
|
|
68
|
-
return
|
|
70
|
+
return false
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
73
|
|
|
@@ -3,6 +3,7 @@ import { EMPTY_ARRAY } from '@tldraw/state'
|
|
|
3
3
|
import { LegacyMigrations, MigrationSequence } from '@tldraw/store'
|
|
4
4
|
import {
|
|
5
5
|
RecordProps,
|
|
6
|
+
TLAsset,
|
|
6
7
|
TLHandle,
|
|
7
8
|
TLParentId,
|
|
8
9
|
TLPropsMigrations,
|
|
@@ -11,14 +12,15 @@ import {
|
|
|
11
12
|
TLShapeId,
|
|
12
13
|
TLShapePartial,
|
|
13
14
|
TLUnknownShape,
|
|
15
|
+
VecModel,
|
|
14
16
|
} from '@tldraw/tlschema'
|
|
17
|
+
import { TLFontFace } from '@tldraw/tlschema'
|
|
15
18
|
import { IndexKey } from '@tldraw/utils'
|
|
16
19
|
import { ReactElement } from 'react'
|
|
17
20
|
import { Box, SelectionHandle } from '../../primitives/Box'
|
|
18
21
|
import { Geometry2d } from '../../primitives/geometry/Geometry2d'
|
|
19
22
|
import { Vec } from '../../primitives/Vec'
|
|
20
23
|
import type { Editor } from '../Editor'
|
|
21
|
-
import { TLFontFace } from '../managers/FontManager/FontManager'
|
|
22
24
|
import { BoundsSnapGeometry } from '../managers/SnapManager/BoundsSnaps'
|
|
23
25
|
import { HandleSnapGeometry } from '../managers/SnapManager/HandleSnaps'
|
|
24
26
|
import { TLClickEventInfo } from '../types/event-types'
|
|
@@ -31,6 +33,7 @@ export interface TLShapeUtilConstructor<T extends TLShape, U extends ShapeUtil<T
|
|
|
31
33
|
type: T['type']
|
|
32
34
|
props?: RecordProps<T>
|
|
33
35
|
migrations?: LegacyMigrations | TLPropsMigrations | MigrationSequence
|
|
36
|
+
handledAssetTypes?: readonly string[]
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
/**
|
|
@@ -168,6 +171,16 @@ export abstract class ShapeUtil<Shape extends TLShape = TLShape> {
|
|
|
168
171
|
*/
|
|
169
172
|
static type: string
|
|
170
173
|
|
|
174
|
+
/**
|
|
175
|
+
* The asset types that this shape can be created from.
|
|
176
|
+
* When a file is dropped on the canvas, the editor finds the shape util
|
|
177
|
+
* whose `handledAssetTypes` includes the asset's type and calls
|
|
178
|
+
* {@link ShapeUtil.createShapeForAsset} to produce the shape.
|
|
179
|
+
*
|
|
180
|
+
* @public
|
|
181
|
+
*/
|
|
182
|
+
static handledAssetTypes?: readonly string[]
|
|
183
|
+
|
|
171
184
|
/**
|
|
172
185
|
* Get the default props for a shape.
|
|
173
186
|
*
|
|
@@ -175,6 +188,18 @@ export abstract class ShapeUtil<Shape extends TLShape = TLShape> {
|
|
|
175
188
|
*/
|
|
176
189
|
abstract getDefaultProps(): Shape['props']
|
|
177
190
|
|
|
191
|
+
/**
|
|
192
|
+
* Create a shape partial for placing an asset on the canvas.
|
|
193
|
+
* Only called for shapes whose constructor declares matching
|
|
194
|
+
* {@link ShapeUtil.handledAssetTypes | `handledAssetTypes`}.
|
|
195
|
+
*
|
|
196
|
+
* @param asset - The asset to create a shape for.
|
|
197
|
+
* @param position - Where to place the shape.
|
|
198
|
+
* @returns A shape partial, or null if this shape can't be created for the asset.
|
|
199
|
+
* @public
|
|
200
|
+
*/
|
|
201
|
+
createShapeForAsset?(asset: TLAsset, position: VecModel): TLShapePartial | null
|
|
202
|
+
|
|
178
203
|
/**
|
|
179
204
|
* Get the shape's geometry.
|
|
180
205
|
*
|
|
@@ -276,7 +301,7 @@ export abstract class ShapeUtil<Shape extends TLShape = TLShape> {
|
|
|
276
301
|
*
|
|
277
302
|
* @public
|
|
278
303
|
*/
|
|
279
|
-
canBind(
|
|
304
|
+
canBind(opts: TLShapeUtilCanBindOpts): boolean {
|
|
280
305
|
return true
|
|
281
306
|
}
|
|
282
307
|
|
|
@@ -526,7 +551,7 @@ export abstract class ShapeUtil<Shape extends TLShape = TLShape> {
|
|
|
526
551
|
* @param type - The shape type.
|
|
527
552
|
* @public
|
|
528
553
|
*/
|
|
529
|
-
canReceiveNewChildrenOfType(shape: Shape,
|
|
554
|
+
canReceiveNewChildrenOfType(shape: Shape, type: TLShape['type']) {
|
|
530
555
|
return false
|
|
531
556
|
}
|
|
532
557
|
|
|
@@ -12,7 +12,7 @@ export class GroupShapeUtil extends ShapeUtil<TLGroupShape> {
|
|
|
12
12
|
static override props = groupShapeProps
|
|
13
13
|
static override migrations = groupShapeMigrations
|
|
14
14
|
|
|
15
|
-
override hideSelectionBoundsFg() {
|
|
15
|
+
override hideSelectionBoundsFg(shape: TLGroupShape) {
|
|
16
16
|
return true
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -17,20 +17,6 @@ import {
|
|
|
17
17
|
TLWheelEventInfo,
|
|
18
18
|
} from '../types/event-types'
|
|
19
19
|
|
|
20
|
-
const STATE_NODES_TO_MEASURE = [
|
|
21
|
-
'brushing',
|
|
22
|
-
'cropping',
|
|
23
|
-
'dragging',
|
|
24
|
-
'dragging_handle',
|
|
25
|
-
'drawing',
|
|
26
|
-
'erasing',
|
|
27
|
-
'lasering',
|
|
28
|
-
'resizing',
|
|
29
|
-
'rotating',
|
|
30
|
-
'scribble_brushing',
|
|
31
|
-
'translating',
|
|
32
|
-
]
|
|
33
|
-
|
|
34
20
|
/** @public */
|
|
35
21
|
export interface TLStateNodeConstructor {
|
|
36
22
|
new (editor: Editor, parent?: StateNode): StateNode
|
|
@@ -39,6 +25,7 @@ export interface TLStateNodeConstructor {
|
|
|
39
25
|
children?(): TLStateNodeConstructor[]
|
|
40
26
|
isLockable: boolean
|
|
41
27
|
useCoalescedEvents: boolean
|
|
28
|
+
trackPerformance: boolean
|
|
42
29
|
}
|
|
43
30
|
|
|
44
31
|
/** @public */
|
|
@@ -94,6 +81,8 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
|
|
|
94
81
|
static children?: () => TLStateNodeConstructor[]
|
|
95
82
|
static isLockable = true
|
|
96
83
|
static useCoalescedEvents = false
|
|
84
|
+
/** Set to `true` in subclasses to emit interaction-start/end performance events when this state is entered/exited. */
|
|
85
|
+
static trackPerformance = false
|
|
97
86
|
|
|
98
87
|
id: string
|
|
99
88
|
type: 'branch' | 'leaf' | 'root'
|
|
@@ -191,8 +180,12 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
|
|
|
191
180
|
|
|
192
181
|
// todo: move this logic into transition
|
|
193
182
|
enter(info: any, from: string) {
|
|
194
|
-
|
|
195
|
-
|
|
183
|
+
const track = (this.constructor as TLStateNodeConstructor).trackPerformance
|
|
184
|
+
if (track) {
|
|
185
|
+
if (debugFlags.measurePerformance.get()) {
|
|
186
|
+
this.performanceTracker.start(this.id)
|
|
187
|
+
}
|
|
188
|
+
this.editor.performance._notifyInteractionStart(this.id, this.getPath())
|
|
196
189
|
}
|
|
197
190
|
|
|
198
191
|
this._isActive.set(true)
|
|
@@ -207,9 +200,14 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
|
|
|
207
200
|
|
|
208
201
|
// todo: move this logic into transition
|
|
209
202
|
exit(info: any, to: string) {
|
|
210
|
-
|
|
211
|
-
|
|
203
|
+
const track = (this.constructor as TLStateNodeConstructor).trackPerformance
|
|
204
|
+
if (track) {
|
|
205
|
+
if (debugFlags.measurePerformance.get() && this.performanceTracker.isStarted()) {
|
|
206
|
+
this.performanceTracker.stop()
|
|
207
|
+
}
|
|
208
|
+
this.editor.performance._notifyInteractionEnd()
|
|
212
209
|
}
|
|
210
|
+
|
|
213
211
|
this._isActive.set(false)
|
|
214
212
|
this.onExit?.(info, to)
|
|
215
213
|
|
|
@@ -42,6 +42,11 @@ export interface SvgExportContext {
|
|
|
42
42
|
*/
|
|
43
43
|
readonly isDarkMode: boolean
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* The color mode to use for this export.
|
|
47
|
+
*/
|
|
48
|
+
readonly colorMode: 'light' | 'dark'
|
|
49
|
+
|
|
45
50
|
/**
|
|
46
51
|
* The scale of the export - how much CSS pixels will be scaled up/down by.
|
|
47
52
|
*/
|
|
@@ -60,6 +60,7 @@ export interface TLFileReplaceExternalContent extends TLBaseExternalContent {
|
|
|
60
60
|
type: 'file-replace'
|
|
61
61
|
file: File
|
|
62
62
|
shapeId: TLShapeId
|
|
63
|
+
/** @deprecated This field is no longer used by the default handler. It may be removed in a future version. */
|
|
63
64
|
isImage: boolean
|
|
64
65
|
}
|
|
65
66
|
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { useAtom, useValue } from '@tldraw/state-react'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
TLShape,
|
|
5
|
-
TLShapeId,
|
|
6
|
-
getColorValue,
|
|
7
|
-
getDefaultColorTheme,
|
|
8
|
-
} from '@tldraw/tlschema'
|
|
2
|
+
import { TLFrameShape, TLShape, TLShapeId } from '@tldraw/tlschema'
|
|
3
|
+
import { TLFontFace } from '@tldraw/tlschema'
|
|
9
4
|
import { hasOwnProperty, promiseWithResolve, uniqueId } from '@tldraw/utils'
|
|
10
5
|
import {
|
|
11
6
|
ComponentType,
|
|
@@ -21,7 +16,7 @@ import { flushSync } from 'react-dom'
|
|
|
21
16
|
import { ErrorBoundary } from '../components/ErrorBoundary'
|
|
22
17
|
import { InnerShape, InnerShapeBackground } from '../components/Shape'
|
|
23
18
|
import type { Editor, TLRenderingShape } from '../editor/Editor'
|
|
24
|
-
import {
|
|
19
|
+
import { getColorValue } from '../editor/managers/ThemeManager/defaultThemes'
|
|
25
20
|
import { ShapeUtil } from '../editor/shapes/ShapeUtil'
|
|
26
21
|
import { TLImageExportOptions } from '../editor/types/misc-types'
|
|
27
22
|
import {
|
|
@@ -54,7 +49,9 @@ export function getSvgJsx(editor: Editor, ids: TLShapeId[], opts: TLImageExportO
|
|
|
54
49
|
const renderPadding =
|
|
55
50
|
typeof opts.padding === 'number' ? opts.padding : editor.options.defaultSvgPadding
|
|
56
51
|
|
|
57
|
-
const
|
|
52
|
+
const colorMode: 'light' | 'dark' =
|
|
53
|
+
opts.darkMode !== undefined ? (opts.darkMode ? 'dark' : 'light') : editor.getColorMode()
|
|
54
|
+
const isDarkMode = colorMode === 'dark'
|
|
58
55
|
|
|
59
56
|
// ---Figure out which shapes we need to include
|
|
60
57
|
const shapeIdsToInclude = editor.getShapeAndDescendantIds(ids)
|
|
@@ -116,6 +113,7 @@ export function getSvgJsx(editor: Editor, ids: TLShapeId[], opts: TLImageExportO
|
|
|
116
113
|
background={background}
|
|
117
114
|
singleFrameShapeId={singleFrameShapeId}
|
|
118
115
|
isDarkMode={isDarkMode}
|
|
116
|
+
colorMode={colorMode}
|
|
119
117
|
renderingShapes={renderingShapes}
|
|
120
118
|
onMount={initialEffectPromise.resolve}
|
|
121
119
|
waitUntil={exportDelay.waitUntil}
|
|
@@ -206,6 +204,7 @@ function SvgExport({
|
|
|
206
204
|
background,
|
|
207
205
|
singleFrameShapeId,
|
|
208
206
|
isDarkMode,
|
|
207
|
+
colorMode,
|
|
209
208
|
renderingShapes,
|
|
210
209
|
onMount,
|
|
211
210
|
waitUntil,
|
|
@@ -218,12 +217,13 @@ function SvgExport({
|
|
|
218
217
|
background: boolean
|
|
219
218
|
singleFrameShapeId: TLShapeId | null
|
|
220
219
|
isDarkMode: boolean
|
|
220
|
+
colorMode: 'light' | 'dark'
|
|
221
221
|
renderingShapes: TLRenderingShape[]
|
|
222
222
|
onMount(): void
|
|
223
223
|
waitUntil(promise: Promise<void>): void
|
|
224
224
|
}) {
|
|
225
225
|
const masksId = useUniqueSafeId()
|
|
226
|
-
const theme =
|
|
226
|
+
const theme = editor.getCurrentTheme()
|
|
227
227
|
|
|
228
228
|
const stateAtom = useAtom<{
|
|
229
229
|
defsById: Record<
|
|
@@ -257,6 +257,7 @@ function SvgExport({
|
|
|
257
257
|
const exportContext = useMemo(
|
|
258
258
|
(): SvgExportContext => ({
|
|
259
259
|
isDarkMode,
|
|
260
|
+
colorMode,
|
|
260
261
|
waitUntil,
|
|
261
262
|
addExportDef,
|
|
262
263
|
scale,
|
|
@@ -272,7 +273,7 @@ function SvgExport({
|
|
|
272
273
|
})
|
|
273
274
|
},
|
|
274
275
|
}),
|
|
275
|
-
[isDarkMode, waitUntil, addExportDef, scale, pixelRatio, editor]
|
|
276
|
+
[isDarkMode, colorMode, waitUntil, addExportDef, scale, pixelRatio, editor]
|
|
276
277
|
)
|
|
277
278
|
|
|
278
279
|
const didRenderRef = useRef(false)
|
|
@@ -443,17 +444,22 @@ function SvgExport({
|
|
|
443
444
|
onMount()
|
|
444
445
|
}, [onMount, shapeElements])
|
|
445
446
|
|
|
446
|
-
|
|
447
|
+
const colors = theme.colors[colorMode]
|
|
448
|
+
let backgroundColor = background ? colors.background : 'transparent'
|
|
447
449
|
|
|
448
450
|
if (singleFrameShapeId && background) {
|
|
449
451
|
const frameShapeUtil = editor.getShapeUtil('frame') as any as
|
|
450
452
|
| undefined
|
|
451
|
-
| {
|
|
453
|
+
| {
|
|
454
|
+
options: {
|
|
455
|
+
showColors: boolean
|
|
456
|
+
}
|
|
457
|
+
}
|
|
452
458
|
if (frameShapeUtil?.options.showColors) {
|
|
453
459
|
const shape = editor.getShape(singleFrameShapeId)! as TLFrameShape
|
|
454
|
-
backgroundColor = getColorValue(
|
|
460
|
+
backgroundColor = getColorValue(colors, shape.props.color, 'frameFill')
|
|
455
461
|
} else {
|
|
456
|
-
backgroundColor =
|
|
462
|
+
backgroundColor = colors.solid
|
|
457
463
|
}
|
|
458
464
|
}
|
|
459
465
|
|
|
@@ -46,8 +46,26 @@ const tlenvReactive = atom('tlenvReactive', {
|
|
|
46
46
|
// on touch-screen laptops, which will become "coarse" if the user touches the screen.
|
|
47
47
|
// See https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/pointer#coarse
|
|
48
48
|
isCoarsePointer: false,
|
|
49
|
+
// Whether the user's display supports P3 color space. This is dynamic because a window can
|
|
50
|
+
// move between displays with different color gamut support.
|
|
51
|
+
supportsP3ColorSpace: false,
|
|
49
52
|
})
|
|
50
53
|
|
|
54
|
+
if (typeof window !== 'undefined') {
|
|
55
|
+
const canRenderP3 = typeof CSS !== 'undefined' && CSS.supports('color', 'color(display-p3 1 1 1)')
|
|
56
|
+
if (canRenderP3) {
|
|
57
|
+
const p3mql = window.matchMedia('(color-gamut: p3)')
|
|
58
|
+
const updateSupportsP3 = () => {
|
|
59
|
+
const supportsP3 = p3mql.matches
|
|
60
|
+
if (supportsP3 !== tlenvReactive.__unsafe__getWithoutCapture().supportsP3ColorSpace) {
|
|
61
|
+
tlenvReactive.update((prev) => ({ ...prev, supportsP3ColorSpace: supportsP3 }))
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
updateSupportsP3()
|
|
65
|
+
p3mql.addEventListener('change', updateSupportsP3)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
51
69
|
if (typeof window !== 'undefined' && !isForcedFinePointer) {
|
|
52
70
|
const mql = getGlobalWindow().matchMedia && getGlobalWindow().matchMedia('(any-pointer: coarse)')
|
|
53
71
|
|
|
@@ -3,11 +3,15 @@ import { useSvgExportContext } from '../editor/types/SvgExportContext'
|
|
|
3
3
|
import { useEditor } from './useEditor'
|
|
4
4
|
|
|
5
5
|
/** @public */
|
|
6
|
-
export function
|
|
6
|
+
export function useColorMode(): 'light' | 'dark' {
|
|
7
7
|
const editor = useEditor()
|
|
8
8
|
const exportContext = useSvgExportContext()
|
|
9
|
-
return useValue(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
return useValue(
|
|
10
|
+
'colorMode',
|
|
11
|
+
() => {
|
|
12
|
+
if (exportContext) return exportContext.colorMode
|
|
13
|
+
return editor.getColorMode()
|
|
14
|
+
},
|
|
15
|
+
[exportContext, editor]
|
|
16
|
+
)
|
|
13
17
|
}
|
|
@@ -3,7 +3,6 @@ import { TLCursorType } from '@tldraw/tlschema'
|
|
|
3
3
|
import { PI, radiansToDegrees } from '../primitives/utils'
|
|
4
4
|
import { useContainer } from './useContainer'
|
|
5
5
|
import { useEditor } from './useEditor'
|
|
6
|
-
import { useIsDarkMode } from './useIsDarkMode'
|
|
7
6
|
|
|
8
7
|
const CORNER_SVG = `<path d='m19.7432 17.0869-4.072 4.068 2.829 2.828-8.473-.013-.013-8.47 2.841 2.842 4.075-4.068 1.414-1.415-2.844-2.842h8.486v8.484l-2.83-2.827z' fill='%23fff'/><path d='m18.6826 16.7334-4.427 4.424 1.828 1.828-5.056-.016-.014-5.054 1.842 1.841 4.428-4.422 2.474-2.475-1.844-1.843h5.073v5.071l-1.83-1.828z' fill='%23000'/>`
|
|
9
8
|
const EDGE_SVG = `<path d='m9 17.9907v.005l5.997 5.996.001-3.999h1.999 2.02v4l5.98-6.001-5.98-5.999.001 4.019-2.021.002h-2l.001-4.022zm1.411.003 3.587-3.588-.001 2.587h3.5 2.521v-2.585l3.565 3.586-3.564 3.585-.001-2.585h-2.521l-3.499-.001-.001 2.586z' fill='%23fff'/><path d='m17.4971 18.9932h2.521v2.586l3.565-3.586-3.565-3.585v2.605h-2.521-3.5v-2.607l-3.586 3.587 3.586 3.586v-2.587z' fill='%23000'/>`
|
|
@@ -67,7 +66,6 @@ export function getCursor(cursor: TLCursorType, rotation = 0, color = 'black') {
|
|
|
67
66
|
export function useCursor() {
|
|
68
67
|
const editor = useEditor()
|
|
69
68
|
const container = useContainer()
|
|
70
|
-
const isDarkMode = useIsDarkMode()
|
|
71
69
|
|
|
72
70
|
useQuickReactor(
|
|
73
71
|
'useCursor',
|
|
@@ -79,11 +77,9 @@ export function useCursor() {
|
|
|
79
77
|
return
|
|
80
78
|
}
|
|
81
79
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
getCursor(type, rotation, isDarkMode ? 'white' : 'black')
|
|
85
|
-
)
|
|
80
|
+
const { cursor } = editor.getCurrentTheme().colors[editor.getColorMode()]
|
|
81
|
+
container.style.setProperty('--tl-cursor', getCursor(type, rotation, cursor))
|
|
86
82
|
},
|
|
87
|
-
[editor, container
|
|
83
|
+
[editor, container]
|
|
88
84
|
)
|
|
89
85
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { useValue } from '@tldraw/state-react'
|
|
2
2
|
import React from 'react'
|
|
3
3
|
import { debugFlags } from '../utils/debug-flags'
|
|
4
|
+
import { useColorMode } from './useColorMode'
|
|
4
5
|
import { useContainer } from './useContainer'
|
|
5
6
|
import { useEditor } from './useEditor'
|
|
6
|
-
import { useIsDarkMode } from './useIsDarkMode'
|
|
7
7
|
|
|
8
8
|
export function useDarkMode() {
|
|
9
9
|
const editor = useEditor()
|
|
10
10
|
const container = useContainer()
|
|
11
|
-
const
|
|
11
|
+
const colorMode = useColorMode()
|
|
12
12
|
const forceSrgb = useValue(debugFlags.forceSrgb)
|
|
13
13
|
|
|
14
14
|
React.useEffect(() => {
|
|
15
|
-
if (
|
|
15
|
+
if (colorMode === 'dark') {
|
|
16
16
|
container.setAttribute('data-color-mode', 'dark')
|
|
17
17
|
container.classList.remove('tl-theme__light')
|
|
18
18
|
container.classList.add('tl-theme__dark')
|
|
@@ -26,5 +26,5 @@ export function useDarkMode() {
|
|
|
26
26
|
} else {
|
|
27
27
|
container.classList.remove('tl-theme__force-sRGB')
|
|
28
28
|
}
|
|
29
|
-
}, [editor, container, forceSrgb,
|
|
29
|
+
}, [editor, container, forceSrgb, colorMode])
|
|
30
30
|
}
|
|
@@ -103,9 +103,13 @@ export function kickoutOccludedShapes(
|
|
|
103
103
|
if (oldParentIndex > -1) {
|
|
104
104
|
// If the old parent is a direct child of the new parent, then we'll add them above the old parent but below the next sibling.
|
|
105
105
|
const siblingsIndexAbove = oldParentSiblingIds[oldParentIndex + 1]
|
|
106
|
-
const
|
|
106
|
+
const siblingAboveIndex = siblingsIndexAbove
|
|
107
107
|
? editor.getShape(siblingsIndexAbove)!.index
|
|
108
|
-
:
|
|
108
|
+
: undefined
|
|
109
|
+
const indexKeyAbove =
|
|
110
|
+
siblingAboveIndex && siblingAboveIndex > prevParent.index
|
|
111
|
+
? siblingAboveIndex
|
|
112
|
+
: getIndexAbove(prevParent.index)
|
|
109
113
|
insertIndexKey = getIndexBetween(prevParent.index, indexKeyAbove)
|
|
110
114
|
} else {
|
|
111
115
|
// If the old parent is not a direct child of the new parent, then we'll add them to the "top" of the new parent's children.
|
|
@@ -2,9 +2,9 @@ import { getSchema, JSONContent, Editor as TTEditor } from '@tiptap/core'
|
|
|
2
2
|
import { Node, Schema } from '@tiptap/pm/model'
|
|
3
3
|
import { EditorProviderProps } from '@tiptap/react'
|
|
4
4
|
import { TLRichText } from '@tldraw/tlschema'
|
|
5
|
+
import { TLFontFace } from '@tldraw/tlschema'
|
|
5
6
|
import { assert, WeakCache } from '@tldraw/utils'
|
|
6
7
|
import type { Editor } from '../editor/Editor'
|
|
7
|
-
import { TLFontFace } from '../editor/managers/FontManager/FontManager'
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* This is the TipTap editor! Docs are {@link https://tiptap.dev/docs}.
|