@tldraw/editor 3.16.0-canary.ba3bc37d4418 → 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.
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +4 -2
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +2 -2
- package/dist-cjs/lib/license/Watermark.js +94 -88
- package/dist-cjs/lib/license/Watermark.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +4 -2
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +2 -2
- package/dist-esm/lib/license/Watermark.mjs +94 -88
- package/dist-esm/lib/license/Watermark.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +7 -7
- package/src/lib/editor/managers/FocusManager/FocusManager.ts +6 -2
- package/src/lib/license/Watermark.tsx +96 -89
- package/src/version.ts +3 -3
package/dist-cjs/index.js
CHANGED
|
@@ -371,7 +371,7 @@ var import_uniq = require("./lib/utils/uniq");
|
|
|
371
371
|
var import_window_open = require("./lib/utils/window-open");
|
|
372
372
|
(0, import_utils.registerTldrawLibraryVersion)(
|
|
373
373
|
"@tldraw/editor",
|
|
374
|
-
"3.16.0-canary.
|
|
374
|
+
"3.16.0-canary.bf7be9dad88b",
|
|
375
375
|
"cjs"
|
|
376
376
|
);
|
|
377
377
|
//# sourceMappingURL=index.js.map
|
|
@@ -62,8 +62,10 @@ class FocusManager {
|
|
|
62
62
|
}
|
|
63
63
|
handleKeyDown(keyEvent) {
|
|
64
64
|
const container = this.editor.getContainer();
|
|
65
|
-
|
|
66
|
-
if (
|
|
65
|
+
const activeEl = document.activeElement;
|
|
66
|
+
if (this.editor.isIn("select.editing_shape") && !activeEl?.closest(".tlui-contextual-toolbar"))
|
|
67
|
+
return;
|
|
68
|
+
if (activeEl === container && this.editor.getSelectedShapeIds().length > 0) return;
|
|
67
69
|
if (["Tab", "ArrowUp", "ArrowDown"].includes(keyEvent.key)) {
|
|
68
70
|
container.classList.remove("tl-container__no-focus-ring");
|
|
69
71
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/editor/managers/FocusManager/FocusManager.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Editor } from '../../Editor'\n\n/**\n * A manager for ensuring correct focus across the editor.\n * It will listen for changes in the instance state to make sure the\n * container is focused when the editor is focused.\n * Also, it will make sure that the focus is on things like text\n * labels when the editor is in editing mode.\n *\n * @internal\n */\nexport class FocusManager {\n\tprivate disposeSideEffectListener?: () => void\n\n\tconstructor(\n\t\tpublic editor: Editor,\n\t\tautoFocus?: boolean\n\t) {\n\t\tthis.disposeSideEffectListener = editor.sideEffects.registerAfterChangeHandler(\n\t\t\t'instance',\n\t\t\t(prev, next) => {\n\t\t\t\tif (prev.isFocused !== next.isFocused) {\n\t\t\t\t\tthis.updateContainerClass()\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\n\t\tconst currentFocusState = editor.getInstanceState().isFocused\n\t\tif (autoFocus !== currentFocusState) {\n\t\t\teditor.updateInstanceState({ isFocused: !!autoFocus })\n\t\t}\n\t\tthis.updateContainerClass()\n\n\t\tdocument.body.addEventListener('keydown', this.handleKeyDown.bind(this))\n\t\tdocument.body.addEventListener('mousedown', this.handleMouseDown.bind(this))\n\t}\n\n\t/**\n\t * The editor's focus state and the container's focus state\n\t * are not necessarily always in sync. For that reason we\n\t * can't rely on the css `:focus` or `:focus-within` selectors to style the\n\t * editor when it is in focus.\n\t *\n\t * For that reason we synchronize the editor's focus state with a\n\t * special class on the container: tl-container__focused\n\t */\n\tprivate updateContainerClass() {\n\t\tconst container = this.editor.getContainer()\n\t\tconst instanceState = this.editor.getInstanceState()\n\n\t\tif (instanceState.isFocused) {\n\t\t\tcontainer.classList.add('tl-container__focused')\n\t\t} else {\n\t\t\tcontainer.classList.remove('tl-container__focused')\n\t\t}\n\t\tcontainer.classList.add('tl-container__no-focus-ring')\n\t}\n\n\tprivate handleKeyDown(keyEvent: KeyboardEvent) {\n\t\tconst container = this.editor.getContainer()\n\t\tif (this.editor.isIn('select.editing_shape'))
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,MAAM,aAAa;AAAA,EAGzB,YACQ,QACP,WACC;AAFM;AAGP,SAAK,4BAA4B,OAAO,YAAY;AAAA,MACnD;AAAA,MACA,CAAC,MAAM,SAAS;AACf,YAAI,KAAK,cAAc,KAAK,WAAW;AACtC,eAAK,qBAAqB;AAAA,QAC3B;AAAA,MACD;AAAA,IACD;AAEA,UAAM,oBAAoB,OAAO,iBAAiB,EAAE;AACpD,QAAI,cAAc,mBAAmB;AACpC,aAAO,oBAAoB,EAAE,WAAW,CAAC,CAAC,UAAU,CAAC;AAAA,IACtD;AACA,SAAK,qBAAqB;AAE1B,aAAS,KAAK,iBAAiB,WAAW,KAAK,cAAc,KAAK,IAAI,CAAC;AACvE,aAAS,KAAK,iBAAiB,aAAa,KAAK,gBAAgB,KAAK,IAAI,CAAC;AAAA,EAC5E;AAAA,EAvBQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkCA,uBAAuB;AAC9B,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,gBAAgB,KAAK,OAAO,iBAAiB;AAEnD,QAAI,cAAc,WAAW;AAC5B,gBAAU,UAAU,IAAI,uBAAuB;AAAA,IAChD,OAAO;AACN,gBAAU,UAAU,OAAO,uBAAuB;AAAA,IACnD;AACA,cAAU,UAAU,IAAI,6BAA6B;AAAA,EACtD;AAAA,EAEQ,cAAc,UAAyB;AAC9C,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,QAAI,KAAK,OAAO,KAAK,sBAAsB,
|
|
4
|
+
"sourcesContent": ["import type { Editor } from '../../Editor'\n\n/**\n * A manager for ensuring correct focus across the editor.\n * It will listen for changes in the instance state to make sure the\n * container is focused when the editor is focused.\n * Also, it will make sure that the focus is on things like text\n * labels when the editor is in editing mode.\n *\n * @internal\n */\nexport class FocusManager {\n\tprivate disposeSideEffectListener?: () => void\n\n\tconstructor(\n\t\tpublic editor: Editor,\n\t\tautoFocus?: boolean\n\t) {\n\t\tthis.disposeSideEffectListener = editor.sideEffects.registerAfterChangeHandler(\n\t\t\t'instance',\n\t\t\t(prev, next) => {\n\t\t\t\tif (prev.isFocused !== next.isFocused) {\n\t\t\t\t\tthis.updateContainerClass()\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\n\t\tconst currentFocusState = editor.getInstanceState().isFocused\n\t\tif (autoFocus !== currentFocusState) {\n\t\t\teditor.updateInstanceState({ isFocused: !!autoFocus })\n\t\t}\n\t\tthis.updateContainerClass()\n\n\t\tdocument.body.addEventListener('keydown', this.handleKeyDown.bind(this))\n\t\tdocument.body.addEventListener('mousedown', this.handleMouseDown.bind(this))\n\t}\n\n\t/**\n\t * The editor's focus state and the container's focus state\n\t * are not necessarily always in sync. For that reason we\n\t * can't rely on the css `:focus` or `:focus-within` selectors to style the\n\t * editor when it is in focus.\n\t *\n\t * For that reason we synchronize the editor's focus state with a\n\t * special class on the container: tl-container__focused\n\t */\n\tprivate updateContainerClass() {\n\t\tconst container = this.editor.getContainer()\n\t\tconst instanceState = this.editor.getInstanceState()\n\n\t\tif (instanceState.isFocused) {\n\t\t\tcontainer.classList.add('tl-container__focused')\n\t\t} else {\n\t\t\tcontainer.classList.remove('tl-container__focused')\n\t\t}\n\t\tcontainer.classList.add('tl-container__no-focus-ring')\n\t}\n\n\tprivate handleKeyDown(keyEvent: KeyboardEvent) {\n\t\tconst container = this.editor.getContainer()\n\t\tconst activeEl = document.activeElement\n\t\t// Edit mode should remove the focus ring, however if the active element's\n\t\t// parent is the contextual toolbar, then allow it.\n\t\tif (this.editor.isIn('select.editing_shape') && !activeEl?.closest('.tlui-contextual-toolbar'))\n\t\t\treturn\n\t\tif (activeEl === container && this.editor.getSelectedShapeIds().length > 0) return\n\t\tif (['Tab', 'ArrowUp', 'ArrowDown'].includes(keyEvent.key)) {\n\t\t\tcontainer.classList.remove('tl-container__no-focus-ring')\n\t\t}\n\t}\n\n\tprivate handleMouseDown() {\n\t\tconst container = this.editor.getContainer()\n\t\tcontainer.classList.add('tl-container__no-focus-ring')\n\t}\n\n\tfocus() {\n\t\tthis.editor.getContainer().focus()\n\t}\n\n\tblur() {\n\t\tthis.editor.complete() // stop any interaction\n\t\tthis.editor.getContainer().blur() // blur the container\n\t}\n\n\tdispose() {\n\t\tdocument.body.removeEventListener('keydown', this.handleKeyDown.bind(this))\n\t\tdocument.body.removeEventListener('mousedown', this.handleMouseDown.bind(this))\n\t\tthis.disposeSideEffectListener?.()\n\t}\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,MAAM,aAAa;AAAA,EAGzB,YACQ,QACP,WACC;AAFM;AAGP,SAAK,4BAA4B,OAAO,YAAY;AAAA,MACnD;AAAA,MACA,CAAC,MAAM,SAAS;AACf,YAAI,KAAK,cAAc,KAAK,WAAW;AACtC,eAAK,qBAAqB;AAAA,QAC3B;AAAA,MACD;AAAA,IACD;AAEA,UAAM,oBAAoB,OAAO,iBAAiB,EAAE;AACpD,QAAI,cAAc,mBAAmB;AACpC,aAAO,oBAAoB,EAAE,WAAW,CAAC,CAAC,UAAU,CAAC;AAAA,IACtD;AACA,SAAK,qBAAqB;AAE1B,aAAS,KAAK,iBAAiB,WAAW,KAAK,cAAc,KAAK,IAAI,CAAC;AACvE,aAAS,KAAK,iBAAiB,aAAa,KAAK,gBAAgB,KAAK,IAAI,CAAC;AAAA,EAC5E;AAAA,EAvBQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkCA,uBAAuB;AAC9B,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,gBAAgB,KAAK,OAAO,iBAAiB;AAEnD,QAAI,cAAc,WAAW;AAC5B,gBAAU,UAAU,IAAI,uBAAuB;AAAA,IAChD,OAAO;AACN,gBAAU,UAAU,OAAO,uBAAuB;AAAA,IACnD;AACA,cAAU,UAAU,IAAI,6BAA6B;AAAA,EACtD;AAAA,EAEQ,cAAc,UAAyB;AAC9C,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,WAAW,SAAS;AAG1B,QAAI,KAAK,OAAO,KAAK,sBAAsB,KAAK,CAAC,UAAU,QAAQ,0BAA0B;AAC5F;AACD,QAAI,aAAa,aAAa,KAAK,OAAO,oBAAoB,EAAE,SAAS,EAAG;AAC5E,QAAI,CAAC,OAAO,WAAW,WAAW,EAAE,SAAS,SAAS,GAAG,GAAG;AAC3D,gBAAU,UAAU,OAAO,6BAA6B;AAAA,IACzD;AAAA,EACD;AAAA,EAEQ,kBAAkB;AACzB,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,cAAU,UAAU,IAAI,6BAA6B;AAAA,EACtD;AAAA,EAEA,QAAQ;AACP,SAAK,OAAO,aAAa,EAAE,MAAM;AAAA,EAClC;AAAA,EAEA,OAAO;AACN,SAAK,OAAO,SAAS;AACrB,SAAK,OAAO,aAAa,EAAE,KAAK;AAAA,EACjC;AAAA,EAEA,UAAU;AACT,aAAS,KAAK,oBAAoB,WAAW,KAAK,cAAc,KAAK,IAAI,CAAC;AAC1E,aAAS,KAAK,oBAAoB,aAAa,KAAK,gBAAgB,KAAK,IAAI,CAAC;AAC9E,SAAK,4BAA4B;AAAA,EAClC;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -61,7 +61,7 @@ const UnlicensedWatermark = (0, import_react.memo)(function UnlicensedWatermark2
|
|
|
61
61
|
const events = (0, import_useCanvasEvents.useCanvasEvents)();
|
|
62
62
|
const ref = (0, import_react.useRef)(null);
|
|
63
63
|
(0, import_usePassThroughWheelEvents.usePassThroughWheelEvents)(ref);
|
|
64
|
-
const url = "https://tldraw.dev
|
|
64
|
+
const url = "https://tldraw.dev/pricing?utm_source=dotcom&utm_medium=organic&utm_campaign=watermark";
|
|
65
65
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
66
66
|
"div",
|
|
67
67
|
{
|
|
@@ -82,22 +82,9 @@ const UnlicensedWatermark = (0, import_react.memo)(function UnlicensedWatermark2
|
|
|
82
82
|
(0, import_dom.markEventAsHandled)(e);
|
|
83
83
|
(0, import_dom.preventDefault)(e);
|
|
84
84
|
},
|
|
85
|
-
title: "
|
|
85
|
+
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.",
|
|
86
86
|
onClick: () => import_runtime.runtime.openWindow(url, "_blank"),
|
|
87
|
-
|
|
88
|
-
position: "absolute",
|
|
89
|
-
pointerEvents: "all",
|
|
90
|
-
cursor: "pointer",
|
|
91
|
-
color: "var(--tl-color-text)",
|
|
92
|
-
opacity: 0.8,
|
|
93
|
-
border: 0,
|
|
94
|
-
padding: 0,
|
|
95
|
-
backgroundColor: "transparent",
|
|
96
|
-
fontSize: "11px",
|
|
97
|
-
fontWeight: "600",
|
|
98
|
-
textAlign: "center"
|
|
99
|
-
},
|
|
100
|
-
children: "Unlicensed"
|
|
87
|
+
children: "Get a license for production"
|
|
101
88
|
}
|
|
102
89
|
)
|
|
103
90
|
}
|
|
@@ -139,7 +126,7 @@ const WatermarkInner = (0, import_react.memo)(function WatermarkInner2({
|
|
|
139
126
|
(0, import_dom.markEventAsHandled)(e);
|
|
140
127
|
(0, import_dom.preventDefault)(e);
|
|
141
128
|
},
|
|
142
|
-
title: "
|
|
129
|
+
title: "Build infinite canvas applications with the tldraw SDK. Learn more at https://tldraw.dev.",
|
|
143
130
|
onClick: () => import_runtime.runtime.openWindow(url, "_blank"),
|
|
144
131
|
style: { mask: maskCss, WebkitMask: maskCss }
|
|
145
132
|
}
|
|
@@ -150,7 +137,8 @@ const WatermarkInner = (0, import_react.memo)(function WatermarkInner2({
|
|
|
150
137
|
const LicenseStyles = (0, import_react.memo)(function LicenseStyles2() {
|
|
151
138
|
const editor = (0, import_useEditor.useEditor)();
|
|
152
139
|
const className = import_LicenseManager.LicenseManager.className;
|
|
153
|
-
const CSS =
|
|
140
|
+
const CSS = `
|
|
141
|
+
/* ------------------- SEE LICENSE -------------------
|
|
154
142
|
The tldraw watermark is part of tldraw's license. It is shown for unlicensed
|
|
155
143
|
or "licensed-with-watermark" users. By using this library, you agree to
|
|
156
144
|
preserve the watermark's behavior, keeping it visible, unobscured, and
|
|
@@ -159,87 +147,105 @@ available to user-interaction.
|
|
|
159
147
|
To remove the watermark, please purchase a license at tldraw.dev.
|
|
160
148
|
*/
|
|
161
149
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
150
|
+
.${className} {
|
|
151
|
+
position: absolute;
|
|
152
|
+
bottom: max(var(--tl-space-2), env(safe-area-inset-bottom));
|
|
153
|
+
right: max(var(--tl-space-2), env(safe-area-inset-right));
|
|
154
|
+
width: 96px;
|
|
155
|
+
height: 32px;
|
|
156
|
+
display: flex;
|
|
157
|
+
align-items: center;
|
|
158
|
+
justify-content: center;
|
|
159
|
+
z-index: var(--tl-layer-watermark) !important;
|
|
160
|
+
background-color: color-mix(in srgb, var(--tl-color-background) 62%, transparent);
|
|
161
|
+
opacity: 1;
|
|
162
|
+
border-radius: 5px;
|
|
163
|
+
pointer-events: all;
|
|
164
|
+
padding: 2px;
|
|
165
|
+
box-sizing: content-box;
|
|
166
|
+
}
|
|
179
167
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
168
|
+
.${className} > button {
|
|
169
|
+
position: absolute;
|
|
170
|
+
width: 96px;
|
|
171
|
+
height: 32px;
|
|
172
|
+
pointer-events: all;
|
|
173
|
+
cursor: inherit;
|
|
174
|
+
color: var(--tl-color-text);
|
|
175
|
+
opacity: .38;
|
|
176
|
+
border: 0;
|
|
177
|
+
padding: 0;
|
|
178
|
+
background-color: currentColor;
|
|
179
|
+
}
|
|
192
180
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
181
|
+
.${className}[data-debug='true'] {
|
|
182
|
+
bottom: max(46px, env(safe-area-inset-bottom));
|
|
183
|
+
}
|
|
196
184
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
185
|
+
.${className}[data-mobile='true'] {
|
|
186
|
+
border-radius: 4px 0px 0px 4px;
|
|
187
|
+
right: max(-2px, calc(env(safe-area-inset-right) - 2px));
|
|
188
|
+
width: 8px;
|
|
189
|
+
height: 48px;
|
|
190
|
+
}
|
|
203
191
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
192
|
+
.${className}[data-mobile='true'] > button {
|
|
193
|
+
width: 8px;
|
|
194
|
+
height: 32px;
|
|
195
|
+
}
|
|
208
196
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
197
|
+
.${className}[data-unlicensed='true'] > button {
|
|
198
|
+
font-size: 100px;
|
|
199
|
+
position: absolute;
|
|
200
|
+
pointer-events: all;
|
|
201
|
+
cursor: pointer;
|
|
202
|
+
color: var(--tl-color-text);
|
|
203
|
+
opacity: 0.8;
|
|
204
|
+
border: 0;
|
|
205
|
+
padding: 0;
|
|
206
|
+
background-color: transparent;
|
|
207
|
+
font-size: 11px;
|
|
208
|
+
font-weight: 600;
|
|
209
|
+
text-align: center;
|
|
210
|
+
}
|
|
213
211
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
transition-delay: 0.32s;
|
|
218
|
-
}
|
|
212
|
+
.${className}[data-mobile='true'][data-unlicensed='true'] > button {
|
|
213
|
+
display: none;
|
|
214
|
+
}
|
|
219
215
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
216
|
+
@media (hover: hover) {
|
|
217
|
+
.${className}[data-licensed='false'] > button {
|
|
218
|
+
pointer-events: none;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.${className}[data-licensed='false']:hover {
|
|
222
|
+
background-color: var(--tl-color-background);
|
|
223
|
+
transition: background-color 0.2s ease-in-out;
|
|
224
|
+
transition-delay: 0.32s;
|
|
225
|
+
}
|
|
224
226
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
227
|
+
.${className}[data-licensed='false']:hover > button {
|
|
228
|
+
animation: ${className}_delayed_link 0.2s forwards ease-in-out;
|
|
229
|
+
animation-delay: 0.32s;
|
|
228
230
|
}
|
|
229
231
|
|
|
232
|
+
.${className}[data-licensed='false'] > button:focus-visible {
|
|
233
|
+
opacity: 1;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
230
236
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
237
|
+
@keyframes ${className}_delayed_link {
|
|
238
|
+
0% {
|
|
239
|
+
cursor: inherit;
|
|
240
|
+
opacity: .38;
|
|
241
|
+
pointer-events: none;
|
|
242
|
+
}
|
|
243
|
+
100% {
|
|
244
|
+
cursor: pointer;
|
|
245
|
+
opacity: 1;
|
|
246
|
+
pointer-events: all;
|
|
247
|
+
}
|
|
248
|
+
}`;
|
|
243
249
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { nonce: editor.options.nonce, children: CSS });
|
|
244
250
|
});
|
|
245
251
|
//# sourceMappingURL=Watermark.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/license/Watermark.tsx"],
|
|
4
|
-
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { memo, useRef } from 'react'\nimport { useCanvasEvents } from '../hooks/useCanvasEvents'\nimport { useEditor } from '../hooks/useEditor'\nimport { usePassThroughWheelEvents } from '../hooks/usePassThroughWheelEvents'\nimport { markEventAsHandled, preventDefault } from '../utils/dom'\nimport { runtime } from '../utils/runtime'\nimport { watermarkDesktopSvg, watermarkMobileSvg } from '../watermarks'\nimport { LicenseManager } from './LicenseManager'\nimport { useLicenseContext } from './LicenseProvider'\nimport { useLicenseManagerState } from './useLicenseManagerState'\n\nconst WATERMARK_DESKTOP_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkDesktopSvg)}`\nconst WATERMARK_MOBILE_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkMobileSvg)}`\n\n/** @internal */\nexport const Watermark = memo(function Watermark() {\n\tconst licenseManager = useLicenseContext()\n\tconst editor = useEditor()\n\tconst isMobile = useValue('is mobile', () => editor.getViewportScreenBounds().width < 700, [\n\t\teditor,\n\t])\n\n\tconst licenseManagerState = useLicenseManagerState(licenseManager)\n\n\tif (!['licensed-with-watermark', 'unlicensed'].includes(licenseManagerState)) return null\n\n\treturn (\n\t\t<>\n\t\t\t<LicenseStyles />\n\t\t\t<WatermarkInner\n\t\t\t\tsrc={isMobile ? WATERMARK_MOBILE_LOCAL_SRC : WATERMARK_DESKTOP_LOCAL_SRC}\n\t\t\t\tisUnlicensed={licenseManagerState === 'unlicensed'}\n\t\t\t/>\n\t\t</>\n\t)\n})\n\nconst UnlicensedWatermark = memo(function UnlicensedWatermark({\n\tisDebugMode,\n\tisMobile,\n}: {\n\tisDebugMode: boolean\n\tisMobile: boolean\n}) {\n\tconst events = useCanvasEvents()\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\tconst url
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BE;AA5BF,yBAAyB;AACzB,mBAA6B;AAC7B,6BAAgC;AAChC,uBAA0B;AAC1B,uCAA0C;AAC1C,iBAAmD;AACnD,qBAAwB;AACxB,wBAAwD;AACxD,4BAA+B;AAC/B,6BAAkC;AAClC,oCAAuC;AAEvC,MAAM,8BAA8B,2BAA2B,mBAAmB,qCAAmB,CAAC;AACtG,MAAM,6BAA6B,2BAA2B,mBAAmB,oCAAkB,CAAC;AAG7F,MAAM,gBAAY,mBAAK,SAASA,aAAY;AAClD,QAAM,qBAAiB,0CAAkB;AACzC,QAAM,aAAS,4BAAU;AACzB,QAAM,eAAW,6BAAS,aAAa,MAAM,OAAO,wBAAwB,EAAE,QAAQ,KAAK;AAAA,IAC1F;AAAA,EACD,CAAC;AAED,QAAM,0BAAsB,sDAAuB,cAAc;AAEjE,MAAI,CAAC,CAAC,2BAA2B,YAAY,EAAE,SAAS,mBAAmB,EAAG,QAAO;AAErF,SACC,4EACC;AAAA,gDAAC,iBAAc;AAAA,IACf;AAAA,MAAC;AAAA;AAAA,QACA,KAAK,WAAW,6BAA6B;AAAA,QAC7C,cAAc,wBAAwB;AAAA;AAAA,IACvC;AAAA,KACD;AAEF,CAAC;AAED,MAAM,0BAAsB,mBAAK,SAASC,qBAAoB;AAAA,EAC7D;AAAA,EACA;AACD,GAGG;AACF,QAAM,aAAS,wCAAgB;AAC/B,QAAM,UAAM,qBAAuB,IAAI;AACvC,kEAA0B,GAAG;AAE7B,QAAM,
|
|
4
|
+
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { memo, useRef } from 'react'\nimport { useCanvasEvents } from '../hooks/useCanvasEvents'\nimport { useEditor } from '../hooks/useEditor'\nimport { usePassThroughWheelEvents } from '../hooks/usePassThroughWheelEvents'\nimport { markEventAsHandled, preventDefault } from '../utils/dom'\nimport { runtime } from '../utils/runtime'\nimport { watermarkDesktopSvg, watermarkMobileSvg } from '../watermarks'\nimport { LicenseManager } from './LicenseManager'\nimport { useLicenseContext } from './LicenseProvider'\nimport { useLicenseManagerState } from './useLicenseManagerState'\n\nconst WATERMARK_DESKTOP_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkDesktopSvg)}`\nconst WATERMARK_MOBILE_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkMobileSvg)}`\n\n/** @internal */\nexport const Watermark = memo(function Watermark() {\n\tconst licenseManager = useLicenseContext()\n\tconst editor = useEditor()\n\tconst isMobile = useValue('is mobile', () => editor.getViewportScreenBounds().width < 700, [\n\t\teditor,\n\t])\n\n\tconst licenseManagerState = useLicenseManagerState(licenseManager)\n\n\tif (!['licensed-with-watermark', 'unlicensed'].includes(licenseManagerState)) return null\n\n\treturn (\n\t\t<>\n\t\t\t<LicenseStyles />\n\t\t\t<WatermarkInner\n\t\t\t\tsrc={isMobile ? WATERMARK_MOBILE_LOCAL_SRC : WATERMARK_DESKTOP_LOCAL_SRC}\n\t\t\t\tisUnlicensed={licenseManagerState === 'unlicensed'}\n\t\t\t/>\n\t\t</>\n\t)\n})\n\nconst UnlicensedWatermark = memo(function UnlicensedWatermark({\n\tisDebugMode,\n\tisMobile,\n}: {\n\tisDebugMode: boolean\n\tisMobile: boolean\n}) {\n\tconst events = useCanvasEvents()\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\tconst url =\n\t\t'https://tldraw.dev/pricing?utm_source=dotcom&utm_medium=organic&utm_campaign=watermark'\n\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\tclassName={LicenseManager.className}\n\t\t\tdata-debug={isDebugMode}\n\t\t\tdata-mobile={isMobile}\n\t\t\tdata-unlicensed={true}\n\t\t\tdata-testid=\"tl-watermark-unlicensed\"\n\t\t\tdraggable={false}\n\t\t\t{...events}\n\t\t>\n\t\t\t<button\n\t\t\t\tdraggable={false}\n\t\t\t\trole=\"button\"\n\t\t\t\tonPointerDown={(e) => {\n\t\t\t\t\tmarkEventAsHandled(e)\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}}\n\t\t\t\ttitle=\"The tldraw SDK requires a license key to work in production. You can get a free 100-day trial license at tldraw.dev/pricing.\"\n\t\t\t\tonClick={() => runtime.openWindow(url, '_blank')}\n\t\t\t>\n\t\t\t\tGet a license for production\n\t\t\t</button>\n\t\t</div>\n\t)\n})\n\nconst WatermarkInner = memo(function WatermarkInner({\n\tsrc,\n\tisUnlicensed,\n}: {\n\tsrc: string\n\tisUnlicensed: boolean\n}) {\n\tconst editor = useEditor()\n\tconst isDebugMode = useValue('debug mode', () => editor.getInstanceState().isDebugMode, [editor])\n\tconst isMobile = useValue('is mobile', () => editor.getViewportScreenBounds().width < 700, [\n\t\teditor,\n\t])\n\tconst events = useCanvasEvents()\n\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\tconst maskCss = `url('${src}') center 100% / 100% no-repeat`\n\tconst url = 'https://tldraw.dev/?utm_source=dotcom&utm_medium=organic&utm_campaign=watermark'\n\n\tif (isUnlicensed) {\n\t\treturn <UnlicensedWatermark isDebugMode={isDebugMode} isMobile={isMobile} />\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\tclassName={LicenseManager.className}\n\t\t\tdata-debug={isDebugMode}\n\t\t\tdata-mobile={isMobile}\n\t\t\tdata-testid=\"tl-watermark-licensed\"\n\t\t\tdraggable={false}\n\t\t\t{...events}\n\t\t>\n\t\t\t<button\n\t\t\t\tdraggable={false}\n\t\t\t\trole=\"button\"\n\t\t\t\tonPointerDown={(e) => {\n\t\t\t\t\tmarkEventAsHandled(e)\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}}\n\t\t\t\ttitle=\"Build infinite canvas applications with the tldraw SDK. Learn more at https://tldraw.dev.\"\n\t\t\t\tonClick={() => runtime.openWindow(url, '_blank')}\n\t\t\t\tstyle={{ mask: maskCss, WebkitMask: maskCss }}\n\t\t\t/>\n\t\t</div>\n\t)\n})\n\nconst LicenseStyles = memo(function LicenseStyles() {\n\tconst editor = useEditor()\n\tconst className = LicenseManager.className\n\n\tconst CSS = `\n/* ------------------- SEE LICENSE -------------------\nThe tldraw watermark is part of tldraw's license. It is shown for unlicensed\nor \"licensed-with-watermark\" users. By using this library, you agree to\npreserve the watermark's behavior, keeping it visible, unobscured, and\navailable to user-interaction.\n\nTo remove the watermark, please purchase a license at tldraw.dev.\n*/\n\n.${className} {\n\tposition: absolute;\n\tbottom: max(var(--tl-space-2), env(safe-area-inset-bottom));\n\tright: max(var(--tl-space-2), env(safe-area-inset-right));\n\twidth: 96px;\n\theight: 32px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tz-index: var(--tl-layer-watermark) !important;\n\tbackground-color: color-mix(in srgb, var(--tl-color-background) 62%, transparent);\n\topacity: 1;\n\tborder-radius: 5px;\n\tpointer-events: all;\n\tpadding: 2px;\n\tbox-sizing: content-box;\n}\n\n.${className} > button {\n\tposition: absolute;\n\twidth: 96px;\n\theight: 32px;\n\tpointer-events: all;\n\tcursor: inherit;\n\tcolor: var(--tl-color-text);\n\topacity: .38;\n\tborder: 0;\n\tpadding: 0;\n\tbackground-color: currentColor;\n}\n\n.${className}[data-debug='true'] {\n\tbottom: max(46px, env(safe-area-inset-bottom));\n}\n\n.${className}[data-mobile='true'] {\n\tborder-radius: 4px 0px 0px 4px;\n\tright: max(-2px, calc(env(safe-area-inset-right) - 2px));\n\twidth: 8px;\n\theight: 48px;\n}\n\n.${className}[data-mobile='true'] > button {\n\twidth: 8px;\n\theight: 32px;\n}\n\n.${className}[data-unlicensed='true'] > button {\n\tfont-size: 100px;\n\tposition: absolute;\n\tpointer-events: all;\n\tcursor: pointer;\n\tcolor: var(--tl-color-text);\n\topacity: 0.8;\n\tborder: 0;\n\tpadding: 0;\n\tbackground-color: transparent;\n\tfont-size: 11px;\n\tfont-weight: 600;\n\ttext-align: center;\n}\n\n.${className}[data-mobile='true'][data-unlicensed='true'] > button {\n\tdisplay: none;\n}\n\n@media (hover: hover) {\n\t.${className}[data-licensed='false'] > button {\n\t\tpointer-events: none;\n\t}\n\n\t.${className}[data-licensed='false']:hover {\n\t\tbackground-color: var(--tl-color-background);\n\t\ttransition: background-color 0.2s ease-in-out;\n\t\ttransition-delay: 0.32s;\n\t}\n\n\t.${className}[data-licensed='false']:hover > button {\n\t\tanimation: ${className}_delayed_link 0.2s forwards ease-in-out;\n\t\tanimation-delay: 0.32s;\n\t}\n\n\t.${className}[data-licensed='false'] > button:focus-visible {\n\t\topacity: 1;\n\t}\n}\n\n@keyframes ${className}_delayed_link {\n\t0% {\n\t\tcursor: inherit;\n\t\topacity: .38;\n\t\tpointer-events: none;\n\t}\n\t100% {\n\t\tcursor: pointer;\n\t\topacity: 1;\n\t\tpointer-events: all;\n\t}\n}`\n\n\treturn <style nonce={editor.options.nonce}>{CSS}</style>\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["Watermark", "UnlicensedWatermark", "WatermarkInner", "LicenseStyles"]
|
|
7
7
|
}
|
package/dist-cjs/version.js
CHANGED
|
@@ -22,10 +22,10 @@ __export(version_exports, {
|
|
|
22
22
|
version: () => version
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(version_exports);
|
|
25
|
-
const version = "3.16.0-canary.
|
|
25
|
+
const version = "3.16.0-canary.bf7be9dad88b";
|
|
26
26
|
const publishDates = {
|
|
27
27
|
major: "2024-09-13T14:36:29.063Z",
|
|
28
|
-
minor: "2025-09-
|
|
29
|
-
patch: "2025-09-
|
|
28
|
+
minor: "2025-09-17T15:01:00.589Z",
|
|
29
|
+
patch: "2025-09-17T15:01:00.589Z"
|
|
30
30
|
};
|
|
31
31
|
//# sourceMappingURL=version.js.map
|
package/dist-cjs/version.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.16.0-canary.
|
|
4
|
+
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.16.0-canary.bf7be9dad88b'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-09-17T15:01:00.589Z',\n\tpatch: '2025-09-17T15:01:00.589Z',\n}\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-esm/index.mjs
CHANGED
|
@@ -303,7 +303,7 @@ import { uniq } from "./lib/utils/uniq.mjs";
|
|
|
303
303
|
import { openWindow } from "./lib/utils/window-open.mjs";
|
|
304
304
|
registerTldrawLibraryVersion(
|
|
305
305
|
"@tldraw/editor",
|
|
306
|
-
"3.16.0-canary.
|
|
306
|
+
"3.16.0-canary.bf7be9dad88b",
|
|
307
307
|
"esm"
|
|
308
308
|
);
|
|
309
309
|
export {
|
|
@@ -39,8 +39,10 @@ class FocusManager {
|
|
|
39
39
|
}
|
|
40
40
|
handleKeyDown(keyEvent) {
|
|
41
41
|
const container = this.editor.getContainer();
|
|
42
|
-
|
|
43
|
-
if (
|
|
42
|
+
const activeEl = document.activeElement;
|
|
43
|
+
if (this.editor.isIn("select.editing_shape") && !activeEl?.closest(".tlui-contextual-toolbar"))
|
|
44
|
+
return;
|
|
45
|
+
if (activeEl === container && this.editor.getSelectedShapeIds().length > 0) return;
|
|
44
46
|
if (["Tab", "ArrowUp", "ArrowDown"].includes(keyEvent.key)) {
|
|
45
47
|
container.classList.remove("tl-container__no-focus-ring");
|
|
46
48
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/editor/managers/FocusManager/FocusManager.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Editor } from '../../Editor'\n\n/**\n * A manager for ensuring correct focus across the editor.\n * It will listen for changes in the instance state to make sure the\n * container is focused when the editor is focused.\n * Also, it will make sure that the focus is on things like text\n * labels when the editor is in editing mode.\n *\n * @internal\n */\nexport class FocusManager {\n\tprivate disposeSideEffectListener?: () => void\n\n\tconstructor(\n\t\tpublic editor: Editor,\n\t\tautoFocus?: boolean\n\t) {\n\t\tthis.disposeSideEffectListener = editor.sideEffects.registerAfterChangeHandler(\n\t\t\t'instance',\n\t\t\t(prev, next) => {\n\t\t\t\tif (prev.isFocused !== next.isFocused) {\n\t\t\t\t\tthis.updateContainerClass()\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\n\t\tconst currentFocusState = editor.getInstanceState().isFocused\n\t\tif (autoFocus !== currentFocusState) {\n\t\t\teditor.updateInstanceState({ isFocused: !!autoFocus })\n\t\t}\n\t\tthis.updateContainerClass()\n\n\t\tdocument.body.addEventListener('keydown', this.handleKeyDown.bind(this))\n\t\tdocument.body.addEventListener('mousedown', this.handleMouseDown.bind(this))\n\t}\n\n\t/**\n\t * The editor's focus state and the container's focus state\n\t * are not necessarily always in sync. For that reason we\n\t * can't rely on the css `:focus` or `:focus-within` selectors to style the\n\t * editor when it is in focus.\n\t *\n\t * For that reason we synchronize the editor's focus state with a\n\t * special class on the container: tl-container__focused\n\t */\n\tprivate updateContainerClass() {\n\t\tconst container = this.editor.getContainer()\n\t\tconst instanceState = this.editor.getInstanceState()\n\n\t\tif (instanceState.isFocused) {\n\t\t\tcontainer.classList.add('tl-container__focused')\n\t\t} else {\n\t\t\tcontainer.classList.remove('tl-container__focused')\n\t\t}\n\t\tcontainer.classList.add('tl-container__no-focus-ring')\n\t}\n\n\tprivate handleKeyDown(keyEvent: KeyboardEvent) {\n\t\tconst container = this.editor.getContainer()\n\t\tif (this.editor.isIn('select.editing_shape'))
|
|
5
|
-
"mappings": "AAWO,MAAM,aAAa;AAAA,EAGzB,YACQ,QACP,WACC;AAFM;AAGP,SAAK,4BAA4B,OAAO,YAAY;AAAA,MACnD;AAAA,MACA,CAAC,MAAM,SAAS;AACf,YAAI,KAAK,cAAc,KAAK,WAAW;AACtC,eAAK,qBAAqB;AAAA,QAC3B;AAAA,MACD;AAAA,IACD;AAEA,UAAM,oBAAoB,OAAO,iBAAiB,EAAE;AACpD,QAAI,cAAc,mBAAmB;AACpC,aAAO,oBAAoB,EAAE,WAAW,CAAC,CAAC,UAAU,CAAC;AAAA,IACtD;AACA,SAAK,qBAAqB;AAE1B,aAAS,KAAK,iBAAiB,WAAW,KAAK,cAAc,KAAK,IAAI,CAAC;AACvE,aAAS,KAAK,iBAAiB,aAAa,KAAK,gBAAgB,KAAK,IAAI,CAAC;AAAA,EAC5E;AAAA,EAvBQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkCA,uBAAuB;AAC9B,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,gBAAgB,KAAK,OAAO,iBAAiB;AAEnD,QAAI,cAAc,WAAW;AAC5B,gBAAU,UAAU,IAAI,uBAAuB;AAAA,IAChD,OAAO;AACN,gBAAU,UAAU,OAAO,uBAAuB;AAAA,IACnD;AACA,cAAU,UAAU,IAAI,6BAA6B;AAAA,EACtD;AAAA,EAEQ,cAAc,UAAyB;AAC9C,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,QAAI,KAAK,OAAO,KAAK,sBAAsB,
|
|
4
|
+
"sourcesContent": ["import type { Editor } from '../../Editor'\n\n/**\n * A manager for ensuring correct focus across the editor.\n * It will listen for changes in the instance state to make sure the\n * container is focused when the editor is focused.\n * Also, it will make sure that the focus is on things like text\n * labels when the editor is in editing mode.\n *\n * @internal\n */\nexport class FocusManager {\n\tprivate disposeSideEffectListener?: () => void\n\n\tconstructor(\n\t\tpublic editor: Editor,\n\t\tautoFocus?: boolean\n\t) {\n\t\tthis.disposeSideEffectListener = editor.sideEffects.registerAfterChangeHandler(\n\t\t\t'instance',\n\t\t\t(prev, next) => {\n\t\t\t\tif (prev.isFocused !== next.isFocused) {\n\t\t\t\t\tthis.updateContainerClass()\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\n\t\tconst currentFocusState = editor.getInstanceState().isFocused\n\t\tif (autoFocus !== currentFocusState) {\n\t\t\teditor.updateInstanceState({ isFocused: !!autoFocus })\n\t\t}\n\t\tthis.updateContainerClass()\n\n\t\tdocument.body.addEventListener('keydown', this.handleKeyDown.bind(this))\n\t\tdocument.body.addEventListener('mousedown', this.handleMouseDown.bind(this))\n\t}\n\n\t/**\n\t * The editor's focus state and the container's focus state\n\t * are not necessarily always in sync. For that reason we\n\t * can't rely on the css `:focus` or `:focus-within` selectors to style the\n\t * editor when it is in focus.\n\t *\n\t * For that reason we synchronize the editor's focus state with a\n\t * special class on the container: tl-container__focused\n\t */\n\tprivate updateContainerClass() {\n\t\tconst container = this.editor.getContainer()\n\t\tconst instanceState = this.editor.getInstanceState()\n\n\t\tif (instanceState.isFocused) {\n\t\t\tcontainer.classList.add('tl-container__focused')\n\t\t} else {\n\t\t\tcontainer.classList.remove('tl-container__focused')\n\t\t}\n\t\tcontainer.classList.add('tl-container__no-focus-ring')\n\t}\n\n\tprivate handleKeyDown(keyEvent: KeyboardEvent) {\n\t\tconst container = this.editor.getContainer()\n\t\tconst activeEl = document.activeElement\n\t\t// Edit mode should remove the focus ring, however if the active element's\n\t\t// parent is the contextual toolbar, then allow it.\n\t\tif (this.editor.isIn('select.editing_shape') && !activeEl?.closest('.tlui-contextual-toolbar'))\n\t\t\treturn\n\t\tif (activeEl === container && this.editor.getSelectedShapeIds().length > 0) return\n\t\tif (['Tab', 'ArrowUp', 'ArrowDown'].includes(keyEvent.key)) {\n\t\t\tcontainer.classList.remove('tl-container__no-focus-ring')\n\t\t}\n\t}\n\n\tprivate handleMouseDown() {\n\t\tconst container = this.editor.getContainer()\n\t\tcontainer.classList.add('tl-container__no-focus-ring')\n\t}\n\n\tfocus() {\n\t\tthis.editor.getContainer().focus()\n\t}\n\n\tblur() {\n\t\tthis.editor.complete() // stop any interaction\n\t\tthis.editor.getContainer().blur() // blur the container\n\t}\n\n\tdispose() {\n\t\tdocument.body.removeEventListener('keydown', this.handleKeyDown.bind(this))\n\t\tdocument.body.removeEventListener('mousedown', this.handleMouseDown.bind(this))\n\t\tthis.disposeSideEffectListener?.()\n\t}\n}\n"],
|
|
5
|
+
"mappings": "AAWO,MAAM,aAAa;AAAA,EAGzB,YACQ,QACP,WACC;AAFM;AAGP,SAAK,4BAA4B,OAAO,YAAY;AAAA,MACnD;AAAA,MACA,CAAC,MAAM,SAAS;AACf,YAAI,KAAK,cAAc,KAAK,WAAW;AACtC,eAAK,qBAAqB;AAAA,QAC3B;AAAA,MACD;AAAA,IACD;AAEA,UAAM,oBAAoB,OAAO,iBAAiB,EAAE;AACpD,QAAI,cAAc,mBAAmB;AACpC,aAAO,oBAAoB,EAAE,WAAW,CAAC,CAAC,UAAU,CAAC;AAAA,IACtD;AACA,SAAK,qBAAqB;AAE1B,aAAS,KAAK,iBAAiB,WAAW,KAAK,cAAc,KAAK,IAAI,CAAC;AACvE,aAAS,KAAK,iBAAiB,aAAa,KAAK,gBAAgB,KAAK,IAAI,CAAC;AAAA,EAC5E;AAAA,EAvBQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkCA,uBAAuB;AAC9B,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,gBAAgB,KAAK,OAAO,iBAAiB;AAEnD,QAAI,cAAc,WAAW;AAC5B,gBAAU,UAAU,IAAI,uBAAuB;AAAA,IAChD,OAAO;AACN,gBAAU,UAAU,OAAO,uBAAuB;AAAA,IACnD;AACA,cAAU,UAAU,IAAI,6BAA6B;AAAA,EACtD;AAAA,EAEQ,cAAc,UAAyB;AAC9C,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,WAAW,SAAS;AAG1B,QAAI,KAAK,OAAO,KAAK,sBAAsB,KAAK,CAAC,UAAU,QAAQ,0BAA0B;AAC5F;AACD,QAAI,aAAa,aAAa,KAAK,OAAO,oBAAoB,EAAE,SAAS,EAAG;AAC5E,QAAI,CAAC,OAAO,WAAW,WAAW,EAAE,SAAS,SAAS,GAAG,GAAG;AAC3D,gBAAU,UAAU,OAAO,6BAA6B;AAAA,IACzD;AAAA,EACD;AAAA,EAEQ,kBAAkB;AACzB,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,cAAU,UAAU,IAAI,6BAA6B;AAAA,EACtD;AAAA,EAEA,QAAQ;AACP,SAAK,OAAO,aAAa,EAAE,MAAM;AAAA,EAClC;AAAA,EAEA,OAAO;AACN,SAAK,OAAO,SAAS;AACrB,SAAK,OAAO,aAAa,EAAE,KAAK;AAAA,EACjC;AAAA,EAEA,UAAU;AACT,aAAS,KAAK,oBAAoB,WAAW,KAAK,cAAc,KAAK,IAAI,CAAC;AAC1E,aAAS,KAAK,oBAAoB,aAAa,KAAK,gBAAgB,KAAK,IAAI,CAAC;AAC9E,SAAK,4BAA4B;AAAA,EAClC;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -38,7 +38,7 @@ const UnlicensedWatermark = memo(function UnlicensedWatermark2({
|
|
|
38
38
|
const events = useCanvasEvents();
|
|
39
39
|
const ref = useRef(null);
|
|
40
40
|
usePassThroughWheelEvents(ref);
|
|
41
|
-
const url = "https://tldraw.dev
|
|
41
|
+
const url = "https://tldraw.dev/pricing?utm_source=dotcom&utm_medium=organic&utm_campaign=watermark";
|
|
42
42
|
return /* @__PURE__ */ jsx(
|
|
43
43
|
"div",
|
|
44
44
|
{
|
|
@@ -59,22 +59,9 @@ const UnlicensedWatermark = memo(function UnlicensedWatermark2({
|
|
|
59
59
|
markEventAsHandled(e);
|
|
60
60
|
preventDefault(e);
|
|
61
61
|
},
|
|
62
|
-
title: "
|
|
62
|
+
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.",
|
|
63
63
|
onClick: () => runtime.openWindow(url, "_blank"),
|
|
64
|
-
|
|
65
|
-
position: "absolute",
|
|
66
|
-
pointerEvents: "all",
|
|
67
|
-
cursor: "pointer",
|
|
68
|
-
color: "var(--tl-color-text)",
|
|
69
|
-
opacity: 0.8,
|
|
70
|
-
border: 0,
|
|
71
|
-
padding: 0,
|
|
72
|
-
backgroundColor: "transparent",
|
|
73
|
-
fontSize: "11px",
|
|
74
|
-
fontWeight: "600",
|
|
75
|
-
textAlign: "center"
|
|
76
|
-
},
|
|
77
|
-
children: "Unlicensed"
|
|
64
|
+
children: "Get a license for production"
|
|
78
65
|
}
|
|
79
66
|
)
|
|
80
67
|
}
|
|
@@ -116,7 +103,7 @@ const WatermarkInner = memo(function WatermarkInner2({
|
|
|
116
103
|
markEventAsHandled(e);
|
|
117
104
|
preventDefault(e);
|
|
118
105
|
},
|
|
119
|
-
title: "
|
|
106
|
+
title: "Build infinite canvas applications with the tldraw SDK. Learn more at https://tldraw.dev.",
|
|
120
107
|
onClick: () => runtime.openWindow(url, "_blank"),
|
|
121
108
|
style: { mask: maskCss, WebkitMask: maskCss }
|
|
122
109
|
}
|
|
@@ -127,7 +114,8 @@ const WatermarkInner = memo(function WatermarkInner2({
|
|
|
127
114
|
const LicenseStyles = memo(function LicenseStyles2() {
|
|
128
115
|
const editor = useEditor();
|
|
129
116
|
const className = LicenseManager.className;
|
|
130
|
-
const CSS =
|
|
117
|
+
const CSS = `
|
|
118
|
+
/* ------------------- SEE LICENSE -------------------
|
|
131
119
|
The tldraw watermark is part of tldraw's license. It is shown for unlicensed
|
|
132
120
|
or "licensed-with-watermark" users. By using this library, you agree to
|
|
133
121
|
preserve the watermark's behavior, keeping it visible, unobscured, and
|
|
@@ -136,87 +124,105 @@ available to user-interaction.
|
|
|
136
124
|
To remove the watermark, please purchase a license at tldraw.dev.
|
|
137
125
|
*/
|
|
138
126
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
127
|
+
.${className} {
|
|
128
|
+
position: absolute;
|
|
129
|
+
bottom: max(var(--tl-space-2), env(safe-area-inset-bottom));
|
|
130
|
+
right: max(var(--tl-space-2), env(safe-area-inset-right));
|
|
131
|
+
width: 96px;
|
|
132
|
+
height: 32px;
|
|
133
|
+
display: flex;
|
|
134
|
+
align-items: center;
|
|
135
|
+
justify-content: center;
|
|
136
|
+
z-index: var(--tl-layer-watermark) !important;
|
|
137
|
+
background-color: color-mix(in srgb, var(--tl-color-background) 62%, transparent);
|
|
138
|
+
opacity: 1;
|
|
139
|
+
border-radius: 5px;
|
|
140
|
+
pointer-events: all;
|
|
141
|
+
padding: 2px;
|
|
142
|
+
box-sizing: content-box;
|
|
143
|
+
}
|
|
156
144
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
145
|
+
.${className} > button {
|
|
146
|
+
position: absolute;
|
|
147
|
+
width: 96px;
|
|
148
|
+
height: 32px;
|
|
149
|
+
pointer-events: all;
|
|
150
|
+
cursor: inherit;
|
|
151
|
+
color: var(--tl-color-text);
|
|
152
|
+
opacity: .38;
|
|
153
|
+
border: 0;
|
|
154
|
+
padding: 0;
|
|
155
|
+
background-color: currentColor;
|
|
156
|
+
}
|
|
169
157
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
158
|
+
.${className}[data-debug='true'] {
|
|
159
|
+
bottom: max(46px, env(safe-area-inset-bottom));
|
|
160
|
+
}
|
|
173
161
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
162
|
+
.${className}[data-mobile='true'] {
|
|
163
|
+
border-radius: 4px 0px 0px 4px;
|
|
164
|
+
right: max(-2px, calc(env(safe-area-inset-right) - 2px));
|
|
165
|
+
width: 8px;
|
|
166
|
+
height: 48px;
|
|
167
|
+
}
|
|
180
168
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
169
|
+
.${className}[data-mobile='true'] > button {
|
|
170
|
+
width: 8px;
|
|
171
|
+
height: 32px;
|
|
172
|
+
}
|
|
185
173
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
174
|
+
.${className}[data-unlicensed='true'] > button {
|
|
175
|
+
font-size: 100px;
|
|
176
|
+
position: absolute;
|
|
177
|
+
pointer-events: all;
|
|
178
|
+
cursor: pointer;
|
|
179
|
+
color: var(--tl-color-text);
|
|
180
|
+
opacity: 0.8;
|
|
181
|
+
border: 0;
|
|
182
|
+
padding: 0;
|
|
183
|
+
background-color: transparent;
|
|
184
|
+
font-size: 11px;
|
|
185
|
+
font-weight: 600;
|
|
186
|
+
text-align: center;
|
|
187
|
+
}
|
|
190
188
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
transition-delay: 0.32s;
|
|
195
|
-
}
|
|
189
|
+
.${className}[data-mobile='true'][data-unlicensed='true'] > button {
|
|
190
|
+
display: none;
|
|
191
|
+
}
|
|
196
192
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
193
|
+
@media (hover: hover) {
|
|
194
|
+
.${className}[data-licensed='false'] > button {
|
|
195
|
+
pointer-events: none;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.${className}[data-licensed='false']:hover {
|
|
199
|
+
background-color: var(--tl-color-background);
|
|
200
|
+
transition: background-color 0.2s ease-in-out;
|
|
201
|
+
transition-delay: 0.32s;
|
|
202
|
+
}
|
|
201
203
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
204
|
+
.${className}[data-licensed='false']:hover > button {
|
|
205
|
+
animation: ${className}_delayed_link 0.2s forwards ease-in-out;
|
|
206
|
+
animation-delay: 0.32s;
|
|
205
207
|
}
|
|
206
208
|
|
|
209
|
+
.${className}[data-licensed='false'] > button:focus-visible {
|
|
210
|
+
opacity: 1;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
207
213
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
214
|
+
@keyframes ${className}_delayed_link {
|
|
215
|
+
0% {
|
|
216
|
+
cursor: inherit;
|
|
217
|
+
opacity: .38;
|
|
218
|
+
pointer-events: none;
|
|
219
|
+
}
|
|
220
|
+
100% {
|
|
221
|
+
cursor: pointer;
|
|
222
|
+
opacity: 1;
|
|
223
|
+
pointer-events: all;
|
|
224
|
+
}
|
|
225
|
+
}`;
|
|
220
226
|
return /* @__PURE__ */ jsx("style", { nonce: editor.options.nonce, children: CSS });
|
|
221
227
|
});
|
|
222
228
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/license/Watermark.tsx"],
|
|
4
|
-
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { memo, useRef } from 'react'\nimport { useCanvasEvents } from '../hooks/useCanvasEvents'\nimport { useEditor } from '../hooks/useEditor'\nimport { usePassThroughWheelEvents } from '../hooks/usePassThroughWheelEvents'\nimport { markEventAsHandled, preventDefault } from '../utils/dom'\nimport { runtime } from '../utils/runtime'\nimport { watermarkDesktopSvg, watermarkMobileSvg } from '../watermarks'\nimport { LicenseManager } from './LicenseManager'\nimport { useLicenseContext } from './LicenseProvider'\nimport { useLicenseManagerState } from './useLicenseManagerState'\n\nconst WATERMARK_DESKTOP_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkDesktopSvg)}`\nconst WATERMARK_MOBILE_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkMobileSvg)}`\n\n/** @internal */\nexport const Watermark = memo(function Watermark() {\n\tconst licenseManager = useLicenseContext()\n\tconst editor = useEditor()\n\tconst isMobile = useValue('is mobile', () => editor.getViewportScreenBounds().width < 700, [\n\t\teditor,\n\t])\n\n\tconst licenseManagerState = useLicenseManagerState(licenseManager)\n\n\tif (!['licensed-with-watermark', 'unlicensed'].includes(licenseManagerState)) return null\n\n\treturn (\n\t\t<>\n\t\t\t<LicenseStyles />\n\t\t\t<WatermarkInner\n\t\t\t\tsrc={isMobile ? WATERMARK_MOBILE_LOCAL_SRC : WATERMARK_DESKTOP_LOCAL_SRC}\n\t\t\t\tisUnlicensed={licenseManagerState === 'unlicensed'}\n\t\t\t/>\n\t\t</>\n\t)\n})\n\nconst UnlicensedWatermark = memo(function UnlicensedWatermark({\n\tisDebugMode,\n\tisMobile,\n}: {\n\tisDebugMode: boolean\n\tisMobile: boolean\n}) {\n\tconst events = useCanvasEvents()\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\tconst url
|
|
5
|
-
"mappings": "AA4BE,mBACC,KADD;AA5BF,SAAS,gBAAgB;AACzB,SAAS,MAAM,cAAc;AAC7B,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AAC1B,SAAS,iCAAiC;AAC1C,SAAS,oBAAoB,sBAAsB;AACnD,SAAS,eAAe;AACxB,SAAS,qBAAqB,0BAA0B;AACxD,SAAS,sBAAsB;AAC/B,SAAS,yBAAyB;AAClC,SAAS,8BAA8B;AAEvC,MAAM,8BAA8B,2BAA2B,mBAAmB,mBAAmB,CAAC;AACtG,MAAM,6BAA6B,2BAA2B,mBAAmB,kBAAkB,CAAC;AAG7F,MAAM,YAAY,KAAK,SAASA,aAAY;AAClD,QAAM,iBAAiB,kBAAkB;AACzC,QAAM,SAAS,UAAU;AACzB,QAAM,WAAW,SAAS,aAAa,MAAM,OAAO,wBAAwB,EAAE,QAAQ,KAAK;AAAA,IAC1F;AAAA,EACD,CAAC;AAED,QAAM,sBAAsB,uBAAuB,cAAc;AAEjE,MAAI,CAAC,CAAC,2BAA2B,YAAY,EAAE,SAAS,mBAAmB,EAAG,QAAO;AAErF,SACC,iCACC;AAAA,wBAAC,iBAAc;AAAA,IACf;AAAA,MAAC;AAAA;AAAA,QACA,KAAK,WAAW,6BAA6B;AAAA,QAC7C,cAAc,wBAAwB;AAAA;AAAA,IACvC;AAAA,KACD;AAEF,CAAC;AAED,MAAM,sBAAsB,KAAK,SAASC,qBAAoB;AAAA,EAC7D;AAAA,EACA;AACD,GAGG;AACF,QAAM,SAAS,gBAAgB;AAC/B,QAAM,MAAM,OAAuB,IAAI;AACvC,4BAA0B,GAAG;AAE7B,QAAM,
|
|
4
|
+
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { memo, useRef } from 'react'\nimport { useCanvasEvents } from '../hooks/useCanvasEvents'\nimport { useEditor } from '../hooks/useEditor'\nimport { usePassThroughWheelEvents } from '../hooks/usePassThroughWheelEvents'\nimport { markEventAsHandled, preventDefault } from '../utils/dom'\nimport { runtime } from '../utils/runtime'\nimport { watermarkDesktopSvg, watermarkMobileSvg } from '../watermarks'\nimport { LicenseManager } from './LicenseManager'\nimport { useLicenseContext } from './LicenseProvider'\nimport { useLicenseManagerState } from './useLicenseManagerState'\n\nconst WATERMARK_DESKTOP_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkDesktopSvg)}`\nconst WATERMARK_MOBILE_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkMobileSvg)}`\n\n/** @internal */\nexport const Watermark = memo(function Watermark() {\n\tconst licenseManager = useLicenseContext()\n\tconst editor = useEditor()\n\tconst isMobile = useValue('is mobile', () => editor.getViewportScreenBounds().width < 700, [\n\t\teditor,\n\t])\n\n\tconst licenseManagerState = useLicenseManagerState(licenseManager)\n\n\tif (!['licensed-with-watermark', 'unlicensed'].includes(licenseManagerState)) return null\n\n\treturn (\n\t\t<>\n\t\t\t<LicenseStyles />\n\t\t\t<WatermarkInner\n\t\t\t\tsrc={isMobile ? WATERMARK_MOBILE_LOCAL_SRC : WATERMARK_DESKTOP_LOCAL_SRC}\n\t\t\t\tisUnlicensed={licenseManagerState === 'unlicensed'}\n\t\t\t/>\n\t\t</>\n\t)\n})\n\nconst UnlicensedWatermark = memo(function UnlicensedWatermark({\n\tisDebugMode,\n\tisMobile,\n}: {\n\tisDebugMode: boolean\n\tisMobile: boolean\n}) {\n\tconst events = useCanvasEvents()\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\tconst url =\n\t\t'https://tldraw.dev/pricing?utm_source=dotcom&utm_medium=organic&utm_campaign=watermark'\n\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\tclassName={LicenseManager.className}\n\t\t\tdata-debug={isDebugMode}\n\t\t\tdata-mobile={isMobile}\n\t\t\tdata-unlicensed={true}\n\t\t\tdata-testid=\"tl-watermark-unlicensed\"\n\t\t\tdraggable={false}\n\t\t\t{...events}\n\t\t>\n\t\t\t<button\n\t\t\t\tdraggable={false}\n\t\t\t\trole=\"button\"\n\t\t\t\tonPointerDown={(e) => {\n\t\t\t\t\tmarkEventAsHandled(e)\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}}\n\t\t\t\ttitle=\"The tldraw SDK requires a license key to work in production. You can get a free 100-day trial license at tldraw.dev/pricing.\"\n\t\t\t\tonClick={() => runtime.openWindow(url, '_blank')}\n\t\t\t>\n\t\t\t\tGet a license for production\n\t\t\t</button>\n\t\t</div>\n\t)\n})\n\nconst WatermarkInner = memo(function WatermarkInner({\n\tsrc,\n\tisUnlicensed,\n}: {\n\tsrc: string\n\tisUnlicensed: boolean\n}) {\n\tconst editor = useEditor()\n\tconst isDebugMode = useValue('debug mode', () => editor.getInstanceState().isDebugMode, [editor])\n\tconst isMobile = useValue('is mobile', () => editor.getViewportScreenBounds().width < 700, [\n\t\teditor,\n\t])\n\tconst events = useCanvasEvents()\n\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\tconst maskCss = `url('${src}') center 100% / 100% no-repeat`\n\tconst url = 'https://tldraw.dev/?utm_source=dotcom&utm_medium=organic&utm_campaign=watermark'\n\n\tif (isUnlicensed) {\n\t\treturn <UnlicensedWatermark isDebugMode={isDebugMode} isMobile={isMobile} />\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\tclassName={LicenseManager.className}\n\t\t\tdata-debug={isDebugMode}\n\t\t\tdata-mobile={isMobile}\n\t\t\tdata-testid=\"tl-watermark-licensed\"\n\t\t\tdraggable={false}\n\t\t\t{...events}\n\t\t>\n\t\t\t<button\n\t\t\t\tdraggable={false}\n\t\t\t\trole=\"button\"\n\t\t\t\tonPointerDown={(e) => {\n\t\t\t\t\tmarkEventAsHandled(e)\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}}\n\t\t\t\ttitle=\"Build infinite canvas applications with the tldraw SDK. Learn more at https://tldraw.dev.\"\n\t\t\t\tonClick={() => runtime.openWindow(url, '_blank')}\n\t\t\t\tstyle={{ mask: maskCss, WebkitMask: maskCss }}\n\t\t\t/>\n\t\t</div>\n\t)\n})\n\nconst LicenseStyles = memo(function LicenseStyles() {\n\tconst editor = useEditor()\n\tconst className = LicenseManager.className\n\n\tconst CSS = `\n/* ------------------- SEE LICENSE -------------------\nThe tldraw watermark is part of tldraw's license. It is shown for unlicensed\nor \"licensed-with-watermark\" users. By using this library, you agree to\npreserve the watermark's behavior, keeping it visible, unobscured, and\navailable to user-interaction.\n\nTo remove the watermark, please purchase a license at tldraw.dev.\n*/\n\n.${className} {\n\tposition: absolute;\n\tbottom: max(var(--tl-space-2), env(safe-area-inset-bottom));\n\tright: max(var(--tl-space-2), env(safe-area-inset-right));\n\twidth: 96px;\n\theight: 32px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tz-index: var(--tl-layer-watermark) !important;\n\tbackground-color: color-mix(in srgb, var(--tl-color-background) 62%, transparent);\n\topacity: 1;\n\tborder-radius: 5px;\n\tpointer-events: all;\n\tpadding: 2px;\n\tbox-sizing: content-box;\n}\n\n.${className} > button {\n\tposition: absolute;\n\twidth: 96px;\n\theight: 32px;\n\tpointer-events: all;\n\tcursor: inherit;\n\tcolor: var(--tl-color-text);\n\topacity: .38;\n\tborder: 0;\n\tpadding: 0;\n\tbackground-color: currentColor;\n}\n\n.${className}[data-debug='true'] {\n\tbottom: max(46px, env(safe-area-inset-bottom));\n}\n\n.${className}[data-mobile='true'] {\n\tborder-radius: 4px 0px 0px 4px;\n\tright: max(-2px, calc(env(safe-area-inset-right) - 2px));\n\twidth: 8px;\n\theight: 48px;\n}\n\n.${className}[data-mobile='true'] > button {\n\twidth: 8px;\n\theight: 32px;\n}\n\n.${className}[data-unlicensed='true'] > button {\n\tfont-size: 100px;\n\tposition: absolute;\n\tpointer-events: all;\n\tcursor: pointer;\n\tcolor: var(--tl-color-text);\n\topacity: 0.8;\n\tborder: 0;\n\tpadding: 0;\n\tbackground-color: transparent;\n\tfont-size: 11px;\n\tfont-weight: 600;\n\ttext-align: center;\n}\n\n.${className}[data-mobile='true'][data-unlicensed='true'] > button {\n\tdisplay: none;\n}\n\n@media (hover: hover) {\n\t.${className}[data-licensed='false'] > button {\n\t\tpointer-events: none;\n\t}\n\n\t.${className}[data-licensed='false']:hover {\n\t\tbackground-color: var(--tl-color-background);\n\t\ttransition: background-color 0.2s ease-in-out;\n\t\ttransition-delay: 0.32s;\n\t}\n\n\t.${className}[data-licensed='false']:hover > button {\n\t\tanimation: ${className}_delayed_link 0.2s forwards ease-in-out;\n\t\tanimation-delay: 0.32s;\n\t}\n\n\t.${className}[data-licensed='false'] > button:focus-visible {\n\t\topacity: 1;\n\t}\n}\n\n@keyframes ${className}_delayed_link {\n\t0% {\n\t\tcursor: inherit;\n\t\topacity: .38;\n\t\tpointer-events: none;\n\t}\n\t100% {\n\t\tcursor: pointer;\n\t\topacity: 1;\n\t\tpointer-events: all;\n\t}\n}`\n\n\treturn <style nonce={editor.options.nonce}>{CSS}</style>\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["Watermark", "UnlicensedWatermark", "WatermarkInner", "LicenseStyles"]
|
|
7
7
|
}
|
package/dist-esm/version.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const version = "3.16.0-canary.
|
|
1
|
+
const version = "3.16.0-canary.bf7be9dad88b";
|
|
2
2
|
const publishDates = {
|
|
3
3
|
major: "2024-09-13T14:36:29.063Z",
|
|
4
|
-
minor: "2025-09-
|
|
5
|
-
patch: "2025-09-
|
|
4
|
+
minor: "2025-09-17T15:01:00.589Z",
|
|
5
|
+
patch: "2025-09-17T15:01:00.589Z"
|
|
6
6
|
};
|
|
7
7
|
export {
|
|
8
8
|
publishDates,
|
package/dist-esm/version.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.16.0-canary.
|
|
4
|
+
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.16.0-canary.bf7be9dad88b'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-09-17T15:01:00.589Z',\n\tpatch: '2025-09-17T15:01:00.589Z',\n}\n"],
|
|
5
5
|
"mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/editor",
|
|
3
3
|
"description": "tldraw infinite canvas SDK (editor).",
|
|
4
|
-
"version": "3.16.0-canary.
|
|
4
|
+
"version": "3.16.0-canary.bf7be9dad88b",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"@tiptap/core": "^2.9.1",
|
|
51
51
|
"@tiptap/pm": "^2.9.1",
|
|
52
52
|
"@tiptap/react": "^2.9.1",
|
|
53
|
-
"@tldraw/state": "3.16.0-canary.
|
|
54
|
-
"@tldraw/state-react": "3.16.0-canary.
|
|
55
|
-
"@tldraw/store": "3.16.0-canary.
|
|
56
|
-
"@tldraw/tlschema": "3.16.0-canary.
|
|
57
|
-
"@tldraw/utils": "3.16.0-canary.
|
|
58
|
-
"@tldraw/validate": "3.16.0-canary.
|
|
53
|
+
"@tldraw/state": "3.16.0-canary.bf7be9dad88b",
|
|
54
|
+
"@tldraw/state-react": "3.16.0-canary.bf7be9dad88b",
|
|
55
|
+
"@tldraw/store": "3.16.0-canary.bf7be9dad88b",
|
|
56
|
+
"@tldraw/tlschema": "3.16.0-canary.bf7be9dad88b",
|
|
57
|
+
"@tldraw/utils": "3.16.0-canary.bf7be9dad88b",
|
|
58
|
+
"@tldraw/validate": "3.16.0-canary.bf7be9dad88b",
|
|
59
59
|
"@types/core-js": "^2.5.8",
|
|
60
60
|
"@use-gesture/react": "^10.3.1",
|
|
61
61
|
"classnames": "^2.5.1",
|
|
@@ -58,8 +58,12 @@ export class FocusManager {
|
|
|
58
58
|
|
|
59
59
|
private handleKeyDown(keyEvent: KeyboardEvent) {
|
|
60
60
|
const container = this.editor.getContainer()
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
const activeEl = document.activeElement
|
|
62
|
+
// Edit mode should remove the focus ring, however if the active element's
|
|
63
|
+
// parent is the contextual toolbar, then allow it.
|
|
64
|
+
if (this.editor.isIn('select.editing_shape') && !activeEl?.closest('.tlui-contextual-toolbar'))
|
|
65
|
+
return
|
|
66
|
+
if (activeEl === container && this.editor.getSelectedShapeIds().length > 0) return
|
|
63
67
|
if (['Tab', 'ArrowUp', 'ArrowDown'].includes(keyEvent.key)) {
|
|
64
68
|
container.classList.remove('tl-container__no-focus-ring')
|
|
65
69
|
}
|
|
@@ -47,7 +47,8 @@ const UnlicensedWatermark = memo(function UnlicensedWatermark({
|
|
|
47
47
|
const ref = useRef<HTMLDivElement>(null)
|
|
48
48
|
usePassThroughWheelEvents(ref)
|
|
49
49
|
|
|
50
|
-
const url =
|
|
50
|
+
const url =
|
|
51
|
+
'https://tldraw.dev/pricing?utm_source=dotcom&utm_medium=organic&utm_campaign=watermark'
|
|
51
52
|
|
|
52
53
|
return (
|
|
53
54
|
<div
|
|
@@ -67,23 +68,10 @@ const UnlicensedWatermark = memo(function UnlicensedWatermark({
|
|
|
67
68
|
markEventAsHandled(e)
|
|
68
69
|
preventDefault(e)
|
|
69
70
|
}}
|
|
70
|
-
title="
|
|
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."
|
|
71
72
|
onClick={() => runtime.openWindow(url, '_blank')}
|
|
72
|
-
style={{
|
|
73
|
-
position: 'absolute',
|
|
74
|
-
pointerEvents: 'all',
|
|
75
|
-
cursor: 'pointer',
|
|
76
|
-
color: 'var(--tl-color-text)',
|
|
77
|
-
opacity: 0.8,
|
|
78
|
-
border: 0,
|
|
79
|
-
padding: 0,
|
|
80
|
-
backgroundColor: 'transparent',
|
|
81
|
-
fontSize: '11px',
|
|
82
|
-
fontWeight: '600',
|
|
83
|
-
textAlign: 'center',
|
|
84
|
-
}}
|
|
85
73
|
>
|
|
86
|
-
|
|
74
|
+
Get a license for production
|
|
87
75
|
</button>
|
|
88
76
|
</div>
|
|
89
77
|
)
|
|
@@ -130,7 +118,7 @@ const WatermarkInner = memo(function WatermarkInner({
|
|
|
130
118
|
markEventAsHandled(e)
|
|
131
119
|
preventDefault(e)
|
|
132
120
|
}}
|
|
133
|
-
title="
|
|
121
|
+
title="Build infinite canvas applications with the tldraw SDK. Learn more at https://tldraw.dev."
|
|
134
122
|
onClick={() => runtime.openWindow(url, '_blank')}
|
|
135
123
|
style={{ mask: maskCss, WebkitMask: maskCss }}
|
|
136
124
|
/>
|
|
@@ -142,7 +130,8 @@ const LicenseStyles = memo(function LicenseStyles() {
|
|
|
142
130
|
const editor = useEditor()
|
|
143
131
|
const className = LicenseManager.className
|
|
144
132
|
|
|
145
|
-
const CSS =
|
|
133
|
+
const CSS = `
|
|
134
|
+
/* ------------------- SEE LICENSE -------------------
|
|
146
135
|
The tldraw watermark is part of tldraw's license. It is shown for unlicensed
|
|
147
136
|
or "licensed-with-watermark" users. By using this library, you agree to
|
|
148
137
|
preserve the watermark's behavior, keeping it visible, unobscured, and
|
|
@@ -151,87 +140,105 @@ available to user-interaction.
|
|
|
151
140
|
To remove the watermark, please purchase a license at tldraw.dev.
|
|
152
141
|
*/
|
|
153
142
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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;
|
|
170
212
|
}
|
|
171
213
|
|
|
172
|
-
.${className}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
pointer-events: all;
|
|
177
|
-
cursor: inherit;
|
|
178
|
-
color: var(--tl-color-text);
|
|
179
|
-
opacity: .38;
|
|
180
|
-
border: 0;
|
|
181
|
-
padding: 0;
|
|
182
|
-
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;
|
|
183
218
|
}
|
|
184
219
|
|
|
185
|
-
.${className}[data-
|
|
186
|
-
|
|
220
|
+
.${className}[data-licensed='false']:hover > button {
|
|
221
|
+
animation: ${className}_delayed_link 0.2s forwards ease-in-out;
|
|
222
|
+
animation-delay: 0.32s;
|
|
187
223
|
}
|
|
188
224
|
|
|
189
|
-
.${className}[data-
|
|
190
|
-
|
|
191
|
-
right: max(-2px, calc(env(safe-area-inset-right) - 2px));
|
|
192
|
-
width: 8px;
|
|
193
|
-
height: 48px;
|
|
225
|
+
.${className}[data-licensed='false'] > button:focus-visible {
|
|
226
|
+
opacity: 1;
|
|
194
227
|
}
|
|
228
|
+
}
|
|
195
229
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
230
|
+
@keyframes ${className}_delayed_link {
|
|
231
|
+
0% {
|
|
232
|
+
cursor: inherit;
|
|
233
|
+
opacity: .38;
|
|
234
|
+
pointer-events: none;
|
|
199
235
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
.${className}:hover {
|
|
207
|
-
background-color: var(--tl-color-background);
|
|
208
|
-
transition: background-color 0.2s ease-in-out;
|
|
209
|
-
transition-delay: 0.32s;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
.${className}:hover > button {
|
|
213
|
-
animation: ${className}_delayed_link 0.2s forwards ease-in-out;
|
|
214
|
-
animation-delay: 0.32s;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
.${className} > button:focus-visible {
|
|
218
|
-
opacity: 1;
|
|
219
|
-
}
|
|
236
|
+
100% {
|
|
237
|
+
cursor: pointer;
|
|
238
|
+
opacity: 1;
|
|
239
|
+
pointer-events: all;
|
|
220
240
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
@keyframes ${className}_delayed_link {
|
|
224
|
-
0% {
|
|
225
|
-
cursor: inherit;
|
|
226
|
-
opacity: .38;
|
|
227
|
-
pointer-events: none;
|
|
228
|
-
}
|
|
229
|
-
100% {
|
|
230
|
-
cursor: pointer;
|
|
231
|
-
opacity: 1;
|
|
232
|
-
pointer-events: all;
|
|
233
|
-
}
|
|
234
|
-
}`
|
|
241
|
+
}`
|
|
235
242
|
|
|
236
243
|
return <style nonce={editor.options.nonce}>{CSS}</style>
|
|
237
244
|
})
|
package/src/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 = '3.16.0-canary.
|
|
4
|
+
export const version = '3.16.0-canary.bf7be9dad88b'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2024-09-13T14:36:29.063Z',
|
|
7
|
-
minor: '2025-09-
|
|
8
|
-
patch: '2025-09-
|
|
7
|
+
minor: '2025-09-17T15:01:00.589Z',
|
|
8
|
+
patch: '2025-09-17T15:01:00.589Z',
|
|
9
9
|
}
|