@tldraw/editor 3.16.0-canary.bcde131f3274 → 3.16.0-canary.bf7be9dad88b

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.
Files changed (134) hide show
  1. package/dist-cjs/index.d.ts +83 -104
  2. package/dist-cjs/index.js +6 -6
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/TldrawEditor.js +2 -6
  5. package/dist-cjs/lib/TldrawEditor.js.map +2 -2
  6. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +11 -1
  7. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  8. package/dist-cjs/lib/editor/Editor.js +23 -113
  9. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  10. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +4 -0
  11. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +2 -2
  12. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +4 -2
  13. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +2 -2
  14. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +10 -0
  15. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  16. package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
  17. package/dist-cjs/lib/hooks/useCanvasEvents.js +15 -12
  18. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  19. package/dist-cjs/lib/hooks/useDocumentEvents.js +5 -5
  20. package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
  21. package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js +1 -2
  22. package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js.map +2 -2
  23. package/dist-cjs/lib/hooks/useGestureEvents.js +1 -1
  24. package/dist-cjs/lib/hooks/useGestureEvents.js.map +2 -2
  25. package/dist-cjs/lib/hooks/useHandleEvents.js +3 -3
  26. package/dist-cjs/lib/hooks/useHandleEvents.js.map +2 -2
  27. package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js +4 -1
  28. package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js.map +2 -2
  29. package/dist-cjs/lib/hooks/useSelectionEvents.js +4 -4
  30. package/dist-cjs/lib/hooks/useSelectionEvents.js.map +2 -2
  31. package/dist-cjs/lib/license/LicenseManager.js +143 -53
  32. package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
  33. package/dist-cjs/lib/license/LicenseProvider.js +39 -1
  34. package/dist-cjs/lib/license/LicenseProvider.js.map +2 -2
  35. package/dist-cjs/lib/license/Watermark.js +143 -75
  36. package/dist-cjs/lib/license/Watermark.js.map +3 -3
  37. package/dist-cjs/lib/license/useLicenseManagerState.js.map +2 -2
  38. package/dist-cjs/lib/primitives/Vec.js +0 -4
  39. package/dist-cjs/lib/primitives/Vec.js.map +2 -2
  40. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +50 -20
  41. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
  42. package/dist-cjs/lib/primitives/geometry/Group2d.js +8 -1
  43. package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
  44. package/dist-cjs/lib/utils/dom.js +12 -1
  45. package/dist-cjs/lib/utils/dom.js.map +2 -2
  46. package/dist-cjs/lib/utils/getPointerInfo.js +2 -2
  47. package/dist-cjs/lib/utils/getPointerInfo.js.map +2 -2
  48. package/dist-cjs/lib/utils/reparenting.js +2 -35
  49. package/dist-cjs/lib/utils/reparenting.js.map +3 -3
  50. package/dist-cjs/version.js +3 -3
  51. package/dist-cjs/version.js.map +1 -1
  52. package/dist-esm/index.d.mts +83 -104
  53. package/dist-esm/index.mjs +9 -7
  54. package/dist-esm/index.mjs.map +2 -2
  55. package/dist-esm/lib/TldrawEditor.mjs +3 -7
  56. package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
  57. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +12 -2
  58. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  59. package/dist-esm/lib/editor/Editor.mjs +23 -113
  60. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  61. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +4 -0
  62. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +2 -2
  63. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +4 -2
  64. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +2 -2
  65. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +10 -0
  66. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  67. package/dist-esm/lib/hooks/useCanvasEvents.mjs +17 -13
  68. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  69. package/dist-esm/lib/hooks/useDocumentEvents.mjs +11 -6
  70. package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
  71. package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs +2 -3
  72. package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs.map +2 -2
  73. package/dist-esm/lib/hooks/useGestureEvents.mjs +2 -2
  74. package/dist-esm/lib/hooks/useGestureEvents.mjs.map +2 -2
  75. package/dist-esm/lib/hooks/useHandleEvents.mjs +9 -4
  76. package/dist-esm/lib/hooks/useHandleEvents.mjs.map +2 -2
  77. package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs +4 -1
  78. package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs.map +2 -2
  79. package/dist-esm/lib/hooks/useSelectionEvents.mjs +6 -5
  80. package/dist-esm/lib/hooks/useSelectionEvents.mjs.map +2 -2
  81. package/dist-esm/lib/license/LicenseManager.mjs +144 -54
  82. package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
  83. package/dist-esm/lib/license/LicenseProvider.mjs +39 -2
  84. package/dist-esm/lib/license/LicenseProvider.mjs.map +2 -2
  85. package/dist-esm/lib/license/Watermark.mjs +144 -76
  86. package/dist-esm/lib/license/Watermark.mjs.map +3 -3
  87. package/dist-esm/lib/license/useLicenseManagerState.mjs.map +2 -2
  88. package/dist-esm/lib/primitives/Vec.mjs +0 -4
  89. package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
  90. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +53 -21
  91. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  92. package/dist-esm/lib/primitives/geometry/Group2d.mjs +8 -1
  93. package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
  94. package/dist-esm/lib/utils/dom.mjs +12 -1
  95. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  96. package/dist-esm/lib/utils/getPointerInfo.mjs +2 -2
  97. package/dist-esm/lib/utils/getPointerInfo.mjs.map +2 -2
  98. package/dist-esm/lib/utils/reparenting.mjs +3 -40
  99. package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
  100. package/dist-esm/version.mjs +3 -3
  101. package/dist-esm/version.mjs.map +1 -1
  102. package/editor.css +8 -3
  103. package/package.json +7 -7
  104. package/src/index.ts +4 -9
  105. package/src/lib/TldrawEditor.tsx +3 -15
  106. package/src/lib/components/default-components/DefaultCanvas.tsx +8 -2
  107. package/src/lib/editor/Editor.test.ts +90 -0
  108. package/src/lib/editor/Editor.ts +36 -150
  109. package/src/lib/editor/derivations/notVisibleShapes.ts +6 -0
  110. package/src/lib/editor/managers/FocusManager/FocusManager.ts +6 -2
  111. package/src/lib/editor/shapes/ShapeUtil.ts +32 -0
  112. package/src/lib/editor/types/misc-types.ts +0 -6
  113. package/src/lib/hooks/useCanvasEvents.ts +17 -11
  114. package/src/lib/hooks/useDocumentEvents.ts +11 -6
  115. package/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts +2 -2
  116. package/src/lib/hooks/useGestureEvents.ts +2 -2
  117. package/src/lib/hooks/useHandleEvents.ts +9 -4
  118. package/src/lib/hooks/usePassThroughMouseOverEvents.ts +4 -1
  119. package/src/lib/hooks/useSelectionEvents.ts +6 -5
  120. package/src/lib/license/LicenseManager.test.ts +721 -382
  121. package/src/lib/license/LicenseManager.ts +204 -58
  122. package/src/lib/license/LicenseProvider.tsx +74 -2
  123. package/src/lib/license/Watermark.tsx +151 -77
  124. package/src/lib/license/useLicenseManagerState.ts +2 -2
  125. package/src/lib/primitives/Vec.ts +0 -5
  126. package/src/lib/primitives/geometry/Geometry2d.test.ts +420 -0
  127. package/src/lib/primitives/geometry/Geometry2d.ts +78 -21
  128. package/src/lib/primitives/geometry/Group2d.ts +10 -1
  129. package/src/lib/test/InFrontOfTheCanvas.test.tsx +187 -0
  130. package/src/lib/utils/dom.test.ts +94 -0
  131. package/src/lib/utils/dom.ts +38 -1
  132. package/src/lib/utils/getPointerInfo.ts +2 -1
  133. package/src/lib/utils/reparenting.ts +3 -69
  134. package/src/version.ts +3 -3
@@ -3,7 +3,7 @@ import { memo, useRef } from 'react'
3
3
  import { useCanvasEvents } from '../hooks/useCanvasEvents'
4
4
  import { useEditor } from '../hooks/useEditor'
5
5
  import { usePassThroughWheelEvents } from '../hooks/usePassThroughWheelEvents'
6
- import { preventDefault, stopEventPropagation } from '../utils/dom'
6
+ import { markEventAsHandled, preventDefault } from '../utils/dom'
7
7
  import { runtime } from '../utils/runtime'
8
8
  import { watermarkDesktopSvg, watermarkMobileSvg } from '../watermarks'
9
9
  import { LicenseManager } from './LicenseManager'
@@ -28,12 +28,62 @@ export const Watermark = memo(function Watermark() {
28
28
  return (
29
29
  <>
30
30
  <LicenseStyles />
31
- <WatermarkInner src={isMobile ? WATERMARK_MOBILE_LOCAL_SRC : WATERMARK_DESKTOP_LOCAL_SRC} />
31
+ <WatermarkInner
32
+ src={isMobile ? WATERMARK_MOBILE_LOCAL_SRC : WATERMARK_DESKTOP_LOCAL_SRC}
33
+ isUnlicensed={licenseManagerState === 'unlicensed'}
34
+ />
32
35
  </>
33
36
  )
34
37
  })
35
38
 
36
- const WatermarkInner = memo(function WatermarkInner({ src }: { src: string }) {
39
+ const UnlicensedWatermark = memo(function UnlicensedWatermark({
40
+ isDebugMode,
41
+ isMobile,
42
+ }: {
43
+ isDebugMode: boolean
44
+ isMobile: boolean
45
+ }) {
46
+ const events = useCanvasEvents()
47
+ const ref = useRef<HTMLDivElement>(null)
48
+ usePassThroughWheelEvents(ref)
49
+
50
+ const url =
51
+ 'https://tldraw.dev/pricing?utm_source=dotcom&utm_medium=organic&utm_campaign=watermark'
52
+
53
+ return (
54
+ <div
55
+ ref={ref}
56
+ className={LicenseManager.className}
57
+ data-debug={isDebugMode}
58
+ data-mobile={isMobile}
59
+ data-unlicensed={true}
60
+ data-testid="tl-watermark-unlicensed"
61
+ draggable={false}
62
+ {...events}
63
+ >
64
+ <button
65
+ draggable={false}
66
+ role="button"
67
+ onPointerDown={(e) => {
68
+ markEventAsHandled(e)
69
+ preventDefault(e)
70
+ }}
71
+ title="The tldraw SDK requires a license key to work in production. You can get a free 100-day trial license at tldraw.dev/pricing."
72
+ onClick={() => runtime.openWindow(url, '_blank')}
73
+ >
74
+ Get a license for production
75
+ </button>
76
+ </div>
77
+ )
78
+ })
79
+
80
+ const WatermarkInner = memo(function WatermarkInner({
81
+ src,
82
+ isUnlicensed,
83
+ }: {
84
+ src: string
85
+ isUnlicensed: boolean
86
+ }) {
37
87
  const editor = useEditor()
38
88
  const isDebugMode = useValue('debug mode', () => editor.getInstanceState().isDebugMode, [editor])
39
89
  const isMobile = useValue('is mobile', () => editor.getViewportScreenBounds().width < 700, [
@@ -47,12 +97,17 @@ const WatermarkInner = memo(function WatermarkInner({ src }: { src: string }) {
47
97
  const maskCss = `url('${src}') center 100% / 100% no-repeat`
48
98
  const url = 'https://tldraw.dev/?utm_source=dotcom&utm_medium=organic&utm_campaign=watermark'
49
99
 
100
+ if (isUnlicensed) {
101
+ return <UnlicensedWatermark isDebugMode={isDebugMode} isMobile={isMobile} />
102
+ }
103
+
50
104
  return (
51
105
  <div
52
106
  ref={ref}
53
107
  className={LicenseManager.className}
54
108
  data-debug={isDebugMode}
55
109
  data-mobile={isMobile}
110
+ data-testid="tl-watermark-licensed"
56
111
  draggable={false}
57
112
  {...events}
58
113
  >
@@ -60,10 +115,10 @@ const WatermarkInner = memo(function WatermarkInner({ src }: { src: string }) {
60
115
  draggable={false}
61
116
  role="button"
62
117
  onPointerDown={(e) => {
63
- stopEventPropagation(e)
118
+ markEventAsHandled(e)
64
119
  preventDefault(e)
65
120
  }}
66
- title="made with tldraw"
121
+ title="Build infinite canvas applications with the tldraw SDK. Learn more at https://tldraw.dev."
67
122
  onClick={() => runtime.openWindow(url, '_blank')}
68
123
  style={{ mask: maskCss, WebkitMask: maskCss }}
69
124
  />
@@ -75,7 +130,8 @@ const LicenseStyles = memo(function LicenseStyles() {
75
130
  const editor = useEditor()
76
131
  const className = LicenseManager.className
77
132
 
78
- const CSS = `/* ------------------- SEE LICENSE -------------------
133
+ const CSS = `
134
+ /* ------------------- SEE LICENSE -------------------
79
135
  The tldraw watermark is part of tldraw's license. It is shown for unlicensed
80
136
  or "licensed-with-watermark" users. By using this library, you agree to
81
137
  preserve the watermark's behavior, keeping it visible, unobscured, and
@@ -84,87 +140,105 @@ available to user-interaction.
84
140
  To remove the watermark, please purchase a license at tldraw.dev.
85
141
  */
86
142
 
87
- .${className} {
88
- position: absolute;
89
- bottom: var(--tl-space-2);
90
- right: var(--tl-space-2);
91
- width: 96px;
92
- height: 32px;
93
- display: flex;
94
- align-items: center;
95
- justify-content: center;
96
- z-index: var(--tl-layer-watermark) !important;
97
- background-color: color-mix(in srgb, var(--tl-color-background) 62%, transparent);
98
- opacity: 1;
99
- border-radius: 5px;
100
- pointer-events: all;
101
- padding: 2px;
102
- box-sizing: content-box;
143
+ .${className} {
144
+ position: absolute;
145
+ bottom: max(var(--tl-space-2), env(safe-area-inset-bottom));
146
+ right: max(var(--tl-space-2), env(safe-area-inset-right));
147
+ width: 96px;
148
+ height: 32px;
149
+ display: flex;
150
+ align-items: center;
151
+ justify-content: center;
152
+ z-index: var(--tl-layer-watermark) !important;
153
+ background-color: color-mix(in srgb, var(--tl-color-background) 62%, transparent);
154
+ opacity: 1;
155
+ border-radius: 5px;
156
+ pointer-events: all;
157
+ padding: 2px;
158
+ box-sizing: content-box;
159
+ }
160
+
161
+ .${className} > button {
162
+ position: absolute;
163
+ width: 96px;
164
+ height: 32px;
165
+ pointer-events: all;
166
+ cursor: inherit;
167
+ color: var(--tl-color-text);
168
+ opacity: .38;
169
+ border: 0;
170
+ padding: 0;
171
+ background-color: currentColor;
172
+ }
173
+
174
+ .${className}[data-debug='true'] {
175
+ bottom: max(46px, env(safe-area-inset-bottom));
176
+ }
177
+
178
+ .${className}[data-mobile='true'] {
179
+ border-radius: 4px 0px 0px 4px;
180
+ right: max(-2px, calc(env(safe-area-inset-right) - 2px));
181
+ width: 8px;
182
+ height: 48px;
183
+ }
184
+
185
+ .${className}[data-mobile='true'] > button {
186
+ width: 8px;
187
+ height: 32px;
188
+ }
189
+
190
+ .${className}[data-unlicensed='true'] > button {
191
+ font-size: 100px;
192
+ position: absolute;
193
+ pointer-events: all;
194
+ cursor: pointer;
195
+ color: var(--tl-color-text);
196
+ opacity: 0.8;
197
+ border: 0;
198
+ padding: 0;
199
+ background-color: transparent;
200
+ font-size: 11px;
201
+ font-weight: 600;
202
+ text-align: center;
203
+ }
204
+
205
+ .${className}[data-mobile='true'][data-unlicensed='true'] > button {
206
+ display: none;
207
+ }
208
+
209
+ @media (hover: hover) {
210
+ .${className}[data-licensed='false'] > button {
211
+ pointer-events: none;
103
212
  }
104
213
 
105
- .${className} > button {
106
- position: absolute;
107
- width: 96px;
108
- height: 32px;
109
- pointer-events: all;
110
- cursor: inherit;
111
- color: var(--tl-color-text);
112
- opacity: .38;
113
- border: 0;
114
- padding: 0;
115
- background-color: currentColor;
214
+ .${className}[data-licensed='false']:hover {
215
+ background-color: var(--tl-color-background);
216
+ transition: background-color 0.2s ease-in-out;
217
+ transition-delay: 0.32s;
116
218
  }
117
219
 
118
- .${className}[data-debug='true'] {
119
- bottom: 46px;
220
+ .${className}[data-licensed='false']:hover > button {
221
+ animation: ${className}_delayed_link 0.2s forwards ease-in-out;
222
+ animation-delay: 0.32s;
120
223
  }
121
224
 
122
- .${className}[data-mobile='true'] {
123
- border-radius: 4px 0px 0px 4px;
124
- right: -2px;
125
- width: 8px;
126
- height: 48px;
225
+ .${className}[data-licensed='false'] > button:focus-visible {
226
+ opacity: 1;
127
227
  }
228
+ }
128
229
 
129
- .${className}[data-mobile='true'] > button {
130
- width: 8px;
131
- height: 32px;
230
+ @keyframes ${className}_delayed_link {
231
+ 0% {
232
+ cursor: inherit;
233
+ opacity: .38;
234
+ pointer-events: none;
132
235
  }
133
-
134
- @media (hover: hover) {
135
- .${className} > button {
136
- pointer-events: none;
137
- }
138
-
139
- .${className}:hover {
140
- background-color: var(--tl-color-background);
141
- transition: background-color 0.2s ease-in-out;
142
- transition-delay: 0.32s;
143
- }
144
-
145
- .${className}:hover > button {
146
- animation: ${className}_delayed_link 0.2s forwards ease-in-out;
147
- animation-delay: 0.32s;
148
- }
149
-
150
- .${className} > button:focus-visible {
151
- opacity: 1;
152
- }
236
+ 100% {
237
+ cursor: pointer;
238
+ opacity: 1;
239
+ pointer-events: all;
153
240
  }
154
-
155
-
156
- @keyframes ${className}_delayed_link {
157
- 0% {
158
- cursor: inherit;
159
- opacity: .38;
160
- pointer-events: none;
161
- }
162
- 100% {
163
- cursor: pointer;
164
- opacity: 1;
165
- pointer-events: all;
166
- }
167
- }`
241
+ }`
168
242
 
169
243
  return <style nonce={editor.options.nonce}>{CSS}</style>
170
244
  })
@@ -1,7 +1,7 @@
1
1
  import { useValue } from '@tldraw/state-react'
2
- import { LicenseManager } from './LicenseManager'
2
+ import { LicenseManager, LicenseState } from './LicenseManager'
3
3
 
4
4
  /** @internal */
5
- export function useLicenseManagerState(licenseManager: LicenseManager) {
5
+ export function useLicenseManagerState(licenseManager: LicenseManager): LicenseState {
6
6
  return useValue('watermarkState', () => licenseManager.state.get(), [licenseManager])
7
7
  }
@@ -240,11 +240,6 @@ export class Vec {
240
240
  return Vec.EqualsXY(this, x, y)
241
241
  }
242
242
 
243
- /** @deprecated use `uni` instead */
244
- norm() {
245
- return this.uni()
246
- }
247
-
248
243
  toFixed() {
249
244
  this.x = toFixed(this.x)
250
245
  this.y = toFixed(this.y)