@tldraw/editor 3.16.0-canary.2b37b2b68fe4 → 3.16.0-canary.36b89de88b02
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/components/default-components/DefaultErrorFallback.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
- package/dist-cjs/lib/config/TLUserPreferences.js +1 -1
- package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +1 -1
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +2 -0
- package/dist-cjs/lib/hooks/useCanvasEvents.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/components/default-components/DefaultErrorFallback.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
- package/dist-esm/lib/config/TLUserPreferences.mjs +1 -1
- package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +1 -1
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +2 -0
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +14 -37
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +1 -1
- package/src/lib/config/TLUserPreferences.ts +1 -1
- package/src/lib/editor/Editor.test.ts +12 -11
- package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +15 -14
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +16 -15
- package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +49 -48
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +24 -23
- package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +7 -6
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +12 -11
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +57 -50
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +51 -26
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +14 -13
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +21 -26
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +1 -1
- package/src/lib/hooks/useCanvasEvents.ts +3 -0
- package/src/lib/license/LicenseManager.test.ts +3 -1
- package/src/lib/license/Watermark.test.tsx +2 -1
- package/src/lib/utils/sync/LocalIndexedDb.test.ts +2 -1
- package/src/lib/utils/sync/TLLocalSyncClient.test.ts +15 -15
- package/src/version.ts +3 -3
package/dist-cjs/index.js
CHANGED
|
@@ -86,7 +86,7 @@ const DefaultErrorFallback = ({ error, editor }) => {
|
|
|
86
86
|
setIsDarkMode(null);
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
|
-
if (typeof window !== "undefined" &&
|
|
89
|
+
if (typeof window !== "undefined" && window.matchMedia) {
|
|
90
90
|
setIsDarkMode(window.matchMedia("(prefers-color-scheme: dark)").matches);
|
|
91
91
|
}
|
|
92
92
|
}, [isDarkModeFromApp]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/components/default-components/DefaultErrorFallback.tsx"],
|
|
4
|
-
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { noop } from '@tldraw/utils'\nimport classNames from 'classnames'\nimport { ComponentType, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { Editor } from '../../editor/Editor'\nimport { EditorProvider } from '../../hooks/useEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\nimport { hardResetEditor } from '../../utils/hardResetEditor'\nimport { refreshPage } from '../../utils/refreshPage'\nimport { ErrorBoundary } from '../ErrorBoundary'\n\nconst BASE_ERROR_URL = 'https://github.com/tldraw/tldraw/issues/new'\n\n/** @public */\nexport type TLErrorFallbackComponent = ComponentType<{ error: unknown; editor?: Editor }>\n\n/** @public @react */\nexport const DefaultErrorFallback: TLErrorFallbackComponent = ({ error, editor }) => {\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst [shouldShowError, setShouldShowError] = useState(process.env.NODE_ENV === 'development')\n\tconst [didCopy, setDidCopy] = useState(false)\n\tconst [shouldShowResetConfirmation, setShouldShowResetConfirmation] = useState(false)\n\n\tlet Canvas: React.ComponentType | null = null\n\ttry {\n\t\tconst components = useEditorComponents()\n\t\tCanvas = components.Canvas ?? null\n\t} catch {\n\t\t// allow this to fail silently\n\t}\n\n\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\tconst errorStack = error instanceof Error ? error.stack : null\n\n\tconst isDarkModeFromApp = useValue(\n\t\t'isDarkMode',\n\t\t() => {\n\t\t\ttry {\n\t\t\t\tif (editor) {\n\t\t\t\t\treturn editor.user.getIsDarkMode()\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// we're in a funky error state so this might not work for spooky\n\t\t\t\t// reasons. if not, we'll have another attempt later:\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\t\t[editor]\n\t)\n\tconst [isDarkMode, setIsDarkMode] = useState<null | boolean>(null)\n\tuseLayoutEffect(() => {\n\t\t// if we found a theme class from the app, we can just use that\n\t\tif (isDarkModeFromApp !== null) {\n\t\t\tsetIsDarkMode(isDarkModeFromApp)\n\t\t}\n\n\t\t// do any of our parents have a theme class? if yes then we can just\n\t\t// rely on that and don't need to set our own class\n\t\tlet parent = containerRef.current?.parentElement\n\t\tlet foundParentThemeClass = false\n\t\twhile (parent) {\n\t\t\tif (\n\t\t\t\tparent.classList.contains('tl-theme__dark') ||\n\t\t\t\tparent.classList.contains('tl-theme__light')\n\t\t\t) {\n\t\t\t\tfoundParentThemeClass = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tparent = parent.parentElement\n\t\t}\n\t\tif (foundParentThemeClass) {\n\t\t\tsetIsDarkMode(null)\n\t\t\treturn\n\t\t}\n\n\t\t// if we can't find a theme class from the app or from a parent, we have\n\t\t// to fall back on using a media query:\n\t\tif (typeof window !== 'undefined' &&
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuIG;AAvIH,yBAAyB;AACzB,mBAAqB;AACrB,wBAAuB;AACvB,mBAA4E;AAE5E,uBAA+B;AAC/B,iCAAoC;AACpC,6BAAgC;AAChC,yBAA4B;AAC5B,2BAA8B;AAE9B,MAAM,iBAAiB;AAMhB,MAAM,uBAAiD,CAAC,EAAE,OAAO,OAAO,MAAM;AACpF,QAAM,mBAAe,qBAAuB,IAAI;AAChD,QAAM,CAAC,iBAAiB,kBAAkB,QAAI,uBAAS,QAAQ,IAAI,aAAa,aAAa;AAC7F,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAC5C,QAAM,CAAC,6BAA6B,8BAA8B,QAAI,uBAAS,KAAK;AAEpF,MAAI,SAAqC;AACzC,MAAI;AACH,UAAM,iBAAa,gDAAoB;AACvC,aAAS,WAAW,UAAU;AAAA,EAC/B,QAAQ;AAAA,EAER;AAEA,QAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,QAAM,aAAa,iBAAiB,QAAQ,MAAM,QAAQ;AAE1D,QAAM,wBAAoB;AAAA,IACzB;AAAA,IACA,MAAM;AACL,UAAI;AACH,YAAI,QAAQ;AACX,iBAAO,OAAO,KAAK,cAAc;AAAA,QAClC;AAAA,MACD,QAAQ;AAAA,MAGR;AACA,aAAO;AAAA,IACR;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AACA,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAyB,IAAI;AACjE,oCAAgB,MAAM;AAErB,QAAI,sBAAsB,MAAM;AAC/B,oBAAc,iBAAiB;AAAA,IAChC;AAIA,QAAI,SAAS,aAAa,SAAS;AACnC,QAAI,wBAAwB;AAC5B,WAAO,QAAQ;AACd,UACC,OAAO,UAAU,SAAS,gBAAgB,KAC1C,OAAO,UAAU,SAAS,iBAAiB,GAC1C;AACD,gCAAwB;AACxB;AAAA,MACD;AACA,eAAS,OAAO;AAAA,IACjB;AACA,QAAI,uBAAuB;AAC1B,oBAAc,IAAI;AAClB;AAAA,IACD;AAIA,QAAI,OAAO,WAAW,eAAe,
|
|
4
|
+
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { noop } from '@tldraw/utils'\nimport classNames from 'classnames'\nimport { ComponentType, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { Editor } from '../../editor/Editor'\nimport { EditorProvider } from '../../hooks/useEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\nimport { hardResetEditor } from '../../utils/hardResetEditor'\nimport { refreshPage } from '../../utils/refreshPage'\nimport { ErrorBoundary } from '../ErrorBoundary'\n\nconst BASE_ERROR_URL = 'https://github.com/tldraw/tldraw/issues/new'\n\n/** @public */\nexport type TLErrorFallbackComponent = ComponentType<{ error: unknown; editor?: Editor }>\n\n/** @public @react */\nexport const DefaultErrorFallback: TLErrorFallbackComponent = ({ error, editor }) => {\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst [shouldShowError, setShouldShowError] = useState(process.env.NODE_ENV === 'development')\n\tconst [didCopy, setDidCopy] = useState(false)\n\tconst [shouldShowResetConfirmation, setShouldShowResetConfirmation] = useState(false)\n\n\tlet Canvas: React.ComponentType | null = null\n\ttry {\n\t\tconst components = useEditorComponents()\n\t\tCanvas = components.Canvas ?? null\n\t} catch {\n\t\t// allow this to fail silently\n\t}\n\n\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\tconst errorStack = error instanceof Error ? error.stack : null\n\n\tconst isDarkModeFromApp = useValue(\n\t\t'isDarkMode',\n\t\t() => {\n\t\t\ttry {\n\t\t\t\tif (editor) {\n\t\t\t\t\treturn editor.user.getIsDarkMode()\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// we're in a funky error state so this might not work for spooky\n\t\t\t\t// reasons. if not, we'll have another attempt later:\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\t\t[editor]\n\t)\n\tconst [isDarkMode, setIsDarkMode] = useState<null | boolean>(null)\n\tuseLayoutEffect(() => {\n\t\t// if we found a theme class from the app, we can just use that\n\t\tif (isDarkModeFromApp !== null) {\n\t\t\tsetIsDarkMode(isDarkModeFromApp)\n\t\t}\n\n\t\t// do any of our parents have a theme class? if yes then we can just\n\t\t// rely on that and don't need to set our own class\n\t\tlet parent = containerRef.current?.parentElement\n\t\tlet foundParentThemeClass = false\n\t\twhile (parent) {\n\t\t\tif (\n\t\t\t\tparent.classList.contains('tl-theme__dark') ||\n\t\t\t\tparent.classList.contains('tl-theme__light')\n\t\t\t) {\n\t\t\t\tfoundParentThemeClass = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tparent = parent.parentElement\n\t\t}\n\t\tif (foundParentThemeClass) {\n\t\t\tsetIsDarkMode(null)\n\t\t\treturn\n\t\t}\n\n\t\t// if we can't find a theme class from the app or from a parent, we have\n\t\t// to fall back on using a media query:\n\t\tif (typeof window !== 'undefined' && window.matchMedia) {\n\t\t\tsetIsDarkMode(window.matchMedia('(prefers-color-scheme: dark)').matches)\n\t\t}\n\t}, [isDarkModeFromApp])\n\n\tuseEffect(() => {\n\t\tif (didCopy) {\n\t\t\tconst timeout = editor?.timers.setTimeout(() => {\n\t\t\t\tsetDidCopy(false)\n\t\t\t}, 2000)\n\t\t\treturn () => clearTimeout(timeout)\n\t\t}\n\t}, [didCopy, editor])\n\n\tconst copyError = () => {\n\t\tconst textarea = document.createElement('textarea')\n\t\ttextarea.value = errorStack ?? errorMessage\n\t\tdocument.body.appendChild(textarea)\n\t\ttextarea.select()\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\tdocument.execCommand('copy')\n\t\ttextarea.remove()\n\t\tsetDidCopy(true)\n\t}\n\n\tconst refresh = () => {\n\t\trefreshPage()\n\t}\n\n\tconst resetLocalState = async () => {\n\t\thardResetEditor()\n\t}\n\n\tconst url = new URL(BASE_ERROR_URL)\n\turl.searchParams.set('title', errorMessage)\n\turl.searchParams.set('labels', `bug`)\n\turl.searchParams.set(\n\t\t'body',\n\t\t`Hey, I ran into an error while using tldraw:\n\n\\`\\`\\`js\n${errorStack ?? errorMessage}\n\\`\\`\\`\n\nMy browser: ${navigator.userAgent}`\n\t)\n\n\treturn (\n\t\t<div\n\t\t\tref={containerRef}\n\t\t\tclassName={classNames(\n\t\t\t\t'tl-container tl-error-boundary',\n\t\t\t\t// error-boundary is sometimes used outside of the theme\n\t\t\t\t// container, so we need to provide it with a theme for our\n\t\t\t\t// styles to work correctly\n\t\t\t\tisDarkMode === null ? '' : isDarkMode ? 'tl-theme__dark' : 'tl-theme__light'\n\t\t\t)}\n\t\t>\n\t\t\t<div className=\"tl-error-boundary__overlay\" />\n\t\t\t{editor && (\n\t\t\t\t// opportunistically attempt to render the canvas to reassure\n\t\t\t\t// the user that their document is still there. there's a good\n\t\t\t\t// chance this won't work (ie the error that we're currently\n\t\t\t\t// notifying the user about originates in the canvas) so it's\n\t\t\t\t// not a big deal if it doesn't work - in that case we just have\n\t\t\t\t// a plain grey background.\n\t\t\t\t<ErrorBoundary onError={noop} fallback={() => null}>\n\t\t\t\t\t<EditorProvider editor={editor}>\n\t\t\t\t\t\t<div className=\"tl-overlay tl-error-boundary__canvas\">{Canvas ? <Canvas /> : null}</div>\n\t\t\t\t\t</EditorProvider>\n\t\t\t\t</ErrorBoundary>\n\t\t\t)}\n\t\t\t<div\n\t\t\t\tclassName={classNames('tl-modal', 'tl-error-boundary__content', {\n\t\t\t\t\t'tl-error-boundary__content__expanded': shouldShowError && !shouldShowResetConfirmation,\n\t\t\t\t})}\n\t\t\t>\n\t\t\t\t{shouldShowResetConfirmation ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<h2>Are you sure?</h2>\n\t\t\t\t\t\t<p>Resetting your data will delete your drawing and cannot be undone.</p>\n\t\t\t\t\t\t<div className=\"tl-error-boundary__content__actions\">\n\t\t\t\t\t\t\t<button className=\"tlui-button\" onClick={() => setShouldShowResetConfirmation(false)}>\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button className=\"tlui-button tl-error-boundary__reset\" onClick={resetLocalState}>\n\t\t\t\t\t\t\t\tReset data\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<h2>Something went wrong</h2>\n\t\t\t\t\t\t<p>Please refresh your browser.</p>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\tIf the issue continues after refreshing, you may need to reset the tldraw data stored\n\t\t\t\t\t\t\ton your device.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t<strong>Note:</strong> Resetting will erase your current project and any unsaved work.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t{process.env.NODE_ENV !== 'production' && (\n\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\tIf you're developing with the SDK and need help, join us on{' '}\n\t\t\t\t\t\t\t\t<a href=\"https://discord.tldraw.com/?utm_source=sdk&utm_medium=organic&utm_campaign=error-screen\">\n\t\t\t\t\t\t\t\t\tDiscord\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t.\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{shouldShowError && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\tMessage:\n\t\t\t\t\t\t\t\t<h4>\n\t\t\t\t\t\t\t\t\t<code>{errorMessage}</code>\n\t\t\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t\t\tStack trace:\n\t\t\t\t\t\t\t\t<div className=\"tl-error-boundary__content__error\">\n\t\t\t\t\t\t\t\t\t<pre>\n\t\t\t\t\t\t\t\t\t\t<code>{errorStack ?? errorMessage}</code>\n\t\t\t\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t\t\t\t<button className=\"tlui-button\" onClick={copyError}>\n\t\t\t\t\t\t\t\t\t\t{didCopy ? 'Copied!' : 'Copy'}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<div className=\"tl-error-boundary__content__actions\">\n\t\t\t\t\t\t\t<button className=\"tlui-button\" onClick={() => setShouldShowError(!shouldShowError)}>\n\t\t\t\t\t\t\t\t{shouldShowError ? 'Hide details' : 'Show details'}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<div className=\"tl-error-boundary__content__actions__group\">\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-button tl-error-boundary__reset\"\n\t\t\t\t\t\t\t\t\tonClick={() => setShouldShowResetConfirmation(true)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tReset data\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button className=\"tlui-button tl-error-boundary__refresh\" onClick={refresh}>\n\t\t\t\t\t\t\t\t\tRefresh Page\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["classNames"]
|
|
7
7
|
}
|
|
@@ -116,7 +116,7 @@ function getRandomColor() {
|
|
|
116
116
|
return USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)];
|
|
117
117
|
}
|
|
118
118
|
function userPrefersReducedMotion() {
|
|
119
|
-
if (typeof window !== "undefined" &&
|
|
119
|
+
if (typeof window !== "undefined" && window.matchMedia) {
|
|
120
120
|
return window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches ?? false;
|
|
121
121
|
}
|
|
122
122
|
return false;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/config/TLUserPreferences.ts"],
|
|
4
|
-
"sourcesContent": ["import { atom } from '@tldraw/state'\nimport { getDefaultTranslationLocale } from '@tldraw/tlschema'\nimport { getFromLocalStorage, setInLocalStorage, structuredClone, uniqueId } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\n\nconst USER_DATA_KEY = 'TLDRAW_USER_DATA_v3'\n\n/**\n * A user of tldraw\n *\n * @public\n */\nexport interface TLUserPreferences {\n\tid: string\n\tname?: string | null\n\tcolor?: string | null\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale?: string | null\n\tanimationSpeed?: number | null\n\tareKeyboardShortcutsEnabled?: boolean | null\n\tedgeScrollSpeed?: number | null\n\tcolorScheme?: 'light' | 'dark' | 'system'\n\tisSnapMode?: boolean | null\n\tisWrapMode?: boolean | null\n\tisDynamicSizeMode?: boolean | null\n\tisPasteAtCursorMode?: boolean | null\n\tshowUiLabels?: boolean | null\n}\n\ninterface UserDataSnapshot {\n\tversion: number\n\tuser: TLUserPreferences\n}\n\ninterface UserChangeBroadcastMessage {\n\ttype: typeof broadcastEventKey\n\torigin: string\n\tdata: UserDataSnapshot\n}\n\n/** @public */\nexport const userTypeValidator: T.Validator<TLUserPreferences> = T.object<TLUserPreferences>({\n\tid: T.string,\n\tname: T.string.nullable().optional(),\n\tcolor: T.string.nullable().optional(),\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale: T.string.nullable().optional(),\n\tanimationSpeed: T.number.nullable().optional(),\n\tareKeyboardShortcutsEnabled: T.boolean.nullable().optional(),\n\tedgeScrollSpeed: T.number.nullable().optional(),\n\tcolorScheme: T.literalEnum('light', 'dark', 'system').optional(),\n\tisSnapMode: T.boolean.nullable().optional(),\n\tisWrapMode: T.boolean.nullable().optional(),\n\tisDynamicSizeMode: T.boolean.nullable().optional(),\n\tisPasteAtCursorMode: T.boolean.nullable().optional(),\n\tshowUiLabels: T.boolean.nullable().optional(),\n})\n\nconst Versions = {\n\tAddAnimationSpeed: 1,\n\tAddIsSnapMode: 2,\n\tMakeFieldsNullable: 3,\n\tAddEdgeScrollSpeed: 4,\n\tAddExcalidrawSelectMode: 5,\n\tAddDynamicSizeMode: 6,\n\tAllowSystemColorScheme: 7,\n\tAddPasteAtCursor: 8,\n\tAddKeyboardShortcuts: 9,\n\tAddShowUiLabels: 10,\n} as const\n\nconst CURRENT_VERSION = Math.max(...Object.values(Versions))\n\nfunction migrateSnapshot(data: { version: number; user: any }) {\n\tif (data.version < Versions.AddAnimationSpeed) {\n\t\tdata.user.animationSpeed = 1\n\t}\n\tif (data.version < Versions.AddIsSnapMode) {\n\t\tdata.user.isSnapMode = false\n\t}\n\tif (data.version < Versions.MakeFieldsNullable) {\n\t\t// noop\n\t}\n\tif (data.version < Versions.AddEdgeScrollSpeed) {\n\t\tdata.user.edgeScrollSpeed = 1\n\t}\n\tif (data.version < Versions.AddExcalidrawSelectMode) {\n\t\tdata.user.isWrapMode = false\n\t}\n\tif (data.version < Versions.AllowSystemColorScheme) {\n\t\tif (data.user.isDarkMode === true) {\n\t\t\tdata.user.colorScheme = 'dark'\n\t\t} else if (data.user.isDarkMode === false) {\n\t\t\tdata.user.colorScheme = 'light'\n\t\t}\n\t\tdelete data.user.isDarkMode\n\t}\n\n\tif (data.version < Versions.AddDynamicSizeMode) {\n\t\tdata.user.isDynamicSizeMode = false\n\t}\n\tif (data.version < Versions.AddPasteAtCursor) {\n\t\tdata.user.isPasteAtCursorMode = false\n\t}\n\tif (data.version < Versions.AddKeyboardShortcuts) {\n\t\tdata.user.areKeyboardShortcutsEnabled = true\n\t}\n\tif (data.version < Versions.AddShowUiLabels) {\n\t\tdata.user.showUiLabels = false\n\t}\n\n\t// finally\n\tdata.version = CURRENT_VERSION\n}\n\n/** @internal */\nexport const USER_COLORS = [\n\t'#FF802B',\n\t'#EC5E41',\n\t'#F2555A',\n\t'#F04F88',\n\t'#E34BA9',\n\t'#BD54C6',\n\t'#9D5BD2',\n\t'#7B66DC',\n\t'#02B1CC',\n\t'#11B3A3',\n\t'#39B178',\n\t'#55B467',\n] as const\n\nfunction getRandomColor() {\n\treturn USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)]\n}\n\n/** @internal */\nexport function userPrefersReducedMotion() {\n\tif (typeof window !== 'undefined' &&
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { atom } from '@tldraw/state'\nimport { getDefaultTranslationLocale } from '@tldraw/tlschema'\nimport { getFromLocalStorage, setInLocalStorage, structuredClone, uniqueId } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\n\nconst USER_DATA_KEY = 'TLDRAW_USER_DATA_v3'\n\n/**\n * A user of tldraw\n *\n * @public\n */\nexport interface TLUserPreferences {\n\tid: string\n\tname?: string | null\n\tcolor?: string | null\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale?: string | null\n\tanimationSpeed?: number | null\n\tareKeyboardShortcutsEnabled?: boolean | null\n\tedgeScrollSpeed?: number | null\n\tcolorScheme?: 'light' | 'dark' | 'system'\n\tisSnapMode?: boolean | null\n\tisWrapMode?: boolean | null\n\tisDynamicSizeMode?: boolean | null\n\tisPasteAtCursorMode?: boolean | null\n\tshowUiLabels?: boolean | null\n}\n\ninterface UserDataSnapshot {\n\tversion: number\n\tuser: TLUserPreferences\n}\n\ninterface UserChangeBroadcastMessage {\n\ttype: typeof broadcastEventKey\n\torigin: string\n\tdata: UserDataSnapshot\n}\n\n/** @public */\nexport const userTypeValidator: T.Validator<TLUserPreferences> = T.object<TLUserPreferences>({\n\tid: T.string,\n\tname: T.string.nullable().optional(),\n\tcolor: T.string.nullable().optional(),\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale: T.string.nullable().optional(),\n\tanimationSpeed: T.number.nullable().optional(),\n\tareKeyboardShortcutsEnabled: T.boolean.nullable().optional(),\n\tedgeScrollSpeed: T.number.nullable().optional(),\n\tcolorScheme: T.literalEnum('light', 'dark', 'system').optional(),\n\tisSnapMode: T.boolean.nullable().optional(),\n\tisWrapMode: T.boolean.nullable().optional(),\n\tisDynamicSizeMode: T.boolean.nullable().optional(),\n\tisPasteAtCursorMode: T.boolean.nullable().optional(),\n\tshowUiLabels: T.boolean.nullable().optional(),\n})\n\nconst Versions = {\n\tAddAnimationSpeed: 1,\n\tAddIsSnapMode: 2,\n\tMakeFieldsNullable: 3,\n\tAddEdgeScrollSpeed: 4,\n\tAddExcalidrawSelectMode: 5,\n\tAddDynamicSizeMode: 6,\n\tAllowSystemColorScheme: 7,\n\tAddPasteAtCursor: 8,\n\tAddKeyboardShortcuts: 9,\n\tAddShowUiLabels: 10,\n} as const\n\nconst CURRENT_VERSION = Math.max(...Object.values(Versions))\n\nfunction migrateSnapshot(data: { version: number; user: any }) {\n\tif (data.version < Versions.AddAnimationSpeed) {\n\t\tdata.user.animationSpeed = 1\n\t}\n\tif (data.version < Versions.AddIsSnapMode) {\n\t\tdata.user.isSnapMode = false\n\t}\n\tif (data.version < Versions.MakeFieldsNullable) {\n\t\t// noop\n\t}\n\tif (data.version < Versions.AddEdgeScrollSpeed) {\n\t\tdata.user.edgeScrollSpeed = 1\n\t}\n\tif (data.version < Versions.AddExcalidrawSelectMode) {\n\t\tdata.user.isWrapMode = false\n\t}\n\tif (data.version < Versions.AllowSystemColorScheme) {\n\t\tif (data.user.isDarkMode === true) {\n\t\t\tdata.user.colorScheme = 'dark'\n\t\t} else if (data.user.isDarkMode === false) {\n\t\t\tdata.user.colorScheme = 'light'\n\t\t}\n\t\tdelete data.user.isDarkMode\n\t}\n\n\tif (data.version < Versions.AddDynamicSizeMode) {\n\t\tdata.user.isDynamicSizeMode = false\n\t}\n\tif (data.version < Versions.AddPasteAtCursor) {\n\t\tdata.user.isPasteAtCursorMode = false\n\t}\n\tif (data.version < Versions.AddKeyboardShortcuts) {\n\t\tdata.user.areKeyboardShortcutsEnabled = true\n\t}\n\tif (data.version < Versions.AddShowUiLabels) {\n\t\tdata.user.showUiLabels = false\n\t}\n\n\t// finally\n\tdata.version = CURRENT_VERSION\n}\n\n/** @internal */\nexport const USER_COLORS = [\n\t'#FF802B',\n\t'#EC5E41',\n\t'#F2555A',\n\t'#F04F88',\n\t'#E34BA9',\n\t'#BD54C6',\n\t'#9D5BD2',\n\t'#7B66DC',\n\t'#02B1CC',\n\t'#11B3A3',\n\t'#39B178',\n\t'#55B467',\n] as const\n\nfunction getRandomColor() {\n\treturn USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)]\n}\n\n/** @internal */\nexport function userPrefersReducedMotion() {\n\tif (typeof window !== 'undefined' && window.matchMedia) {\n\t\treturn window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches ?? false\n\t}\n\n\treturn false\n}\n\n/** @public */\nexport const defaultUserPreferences = Object.freeze({\n\tname: '',\n\tlocale: getDefaultTranslationLocale(),\n\tcolor: getRandomColor(),\n\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tedgeScrollSpeed: 1,\n\tanimationSpeed: userPrefersReducedMotion() ? 0 : 1,\n\tareKeyboardShortcutsEnabled: true,\n\tisSnapMode: false,\n\tisWrapMode: false,\n\tisDynamicSizeMode: false,\n\tisPasteAtCursorMode: false,\n\tshowUiLabels: false,\n\tcolorScheme: 'light',\n}) satisfies Readonly<Omit<TLUserPreferences, 'id'>>\n\n/** @public */\nexport function getFreshUserPreferences(): TLUserPreferences {\n\treturn {\n\t\tid: uniqueId(),\n\t\tcolor: getRandomColor(),\n\t}\n}\n\nfunction migrateUserPreferences(userData: unknown): TLUserPreferences {\n\tif (userData === null || typeof userData !== 'object') {\n\t\treturn getFreshUserPreferences()\n\t}\n\n\tif (!('version' in userData) || !('user' in userData) || typeof userData.version !== 'number') {\n\t\treturn getFreshUserPreferences()\n\t}\n\n\tconst snapshot = structuredClone(userData) as any\n\n\tmigrateSnapshot(snapshot)\n\n\ttry {\n\t\treturn userTypeValidator.validate(snapshot.user)\n\t} catch {\n\t\treturn getFreshUserPreferences()\n\t}\n}\n\nfunction loadUserPreferences(): TLUserPreferences {\n\tconst userData = (JSON.parse(getFromLocalStorage(USER_DATA_KEY) || 'null') ??\n\t\tnull) as null | UserDataSnapshot\n\n\treturn migrateUserPreferences(userData)\n}\n\nconst globalUserPreferences = atom<TLUserPreferences | null>('globalUserData', null)\n\nfunction storeUserPreferences() {\n\tsetInLocalStorage(\n\t\tUSER_DATA_KEY,\n\t\tJSON.stringify({\n\t\t\tversion: CURRENT_VERSION,\n\t\t\tuser: globalUserPreferences.get(),\n\t\t})\n\t)\n}\n\n/** @public */\nexport function setUserPreferences(user: TLUserPreferences) {\n\tuserTypeValidator.validate(user)\n\tglobalUserPreferences.set(user)\n\tstoreUserPreferences()\n\tbroadcastUserPreferencesChange()\n}\n\nconst isTest = typeof process !== 'undefined' && process.env.NODE_ENV === 'test'\n\nconst channel =\n\ttypeof BroadcastChannel !== 'undefined' && !isTest\n\t\t? new BroadcastChannel('tldraw-user-sync')\n\t\t: null\n\nchannel?.addEventListener('message', (e) => {\n\tconst data = e.data as undefined | UserChangeBroadcastMessage\n\tif (data?.type === broadcastEventKey && data?.origin !== getBroadcastOrigin()) {\n\t\tglobalUserPreferences.set(migrateUserPreferences(data.data))\n\t}\n})\n\nlet _broadcastOrigin = null as null | string\nfunction getBroadcastOrigin() {\n\tif (_broadcastOrigin === null) {\n\t\t_broadcastOrigin = uniqueId()\n\t}\n\treturn _broadcastOrigin\n}\nconst broadcastEventKey = 'tldraw-user-preferences-change' as const\n\nfunction broadcastUserPreferencesChange() {\n\tchannel?.postMessage({\n\t\ttype: broadcastEventKey,\n\t\torigin: getBroadcastOrigin(),\n\t\tdata: {\n\t\t\tuser: getUserPreferences(),\n\t\t\tversion: CURRENT_VERSION,\n\t\t},\n\t} satisfies UserChangeBroadcastMessage)\n}\n\n/** @public */\nexport function getUserPreferences(): TLUserPreferences {\n\tlet prefs = globalUserPreferences.get()\n\tif (!prefs) {\n\t\tprefs = loadUserPreferences()\n\t\tsetUserPreferences(prefs)\n\t}\n\treturn prefs\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -78,7 +78,7 @@ class UserPreferencesManager {
|
|
|
78
78
|
__runInitializers(_init, 5, this);
|
|
79
79
|
__publicField(this, "systemColorScheme", (0, import_state.atom)("systemColorScheme", "light"));
|
|
80
80
|
__publicField(this, "disposables", /* @__PURE__ */ new Set());
|
|
81
|
-
if (typeof window === "undefined" || !
|
|
81
|
+
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
82
82
|
const darkModeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
83
83
|
if (darkModeMediaQuery?.matches) {
|
|
84
84
|
this.systemColorScheme.set("dark");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts"],
|
|
4
|
-
"sourcesContent": ["import { atom, computed } from '@tldraw/state'\nimport { TLUserPreferences, defaultUserPreferences } from '../../../config/TLUserPreferences'\nimport { TLUser } from '../../../config/createTLUser'\n\n/** @public */\nexport class UserPreferencesManager {\n\tsystemColorScheme = atom<'dark' | 'light'>('systemColorScheme', 'light')\n\tdisposables = new Set<() => void>()\n\tdispose() {\n\t\tthis.disposables.forEach((d) => d())\n\t}\n\tconstructor(\n\t\tprivate readonly user: TLUser,\n\t\tprivate readonly inferDarkMode: boolean\n\t) {\n\t\tif (typeof window === 'undefined' || !
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+B;AAC/B,+BAA0D;AAD1D;AAsCC,2BAAC,wBAiBD,sBAAC,wBAgBD,2BAAC,wBAID,0BAAC,wBAID,uCAAC,wBAOD,cAAC,wBAID,gBAAC,wBAID,kBAAC,wBAID,iBAAC,wBAID,sBAAC,wBAID,sBAAC,wBAID,+BAAC,wBAMD,+BAAC,wBAOD,wBAAC;AAtHK,MAAM,uBAAuB;AAAA,EAMnC,YACkB,MACA,eAChB;AAFgB;AACA;AARZ;AACN,iDAAoB,mBAAuB,qBAAqB,OAAO;AACvE,uCAAc,oBAAI,IAAgB;AAQjC,QAAI,OAAO,WAAW,eAAe,
|
|
4
|
+
"sourcesContent": ["import { atom, computed } from '@tldraw/state'\nimport { TLUserPreferences, defaultUserPreferences } from '../../../config/TLUserPreferences'\nimport { TLUser } from '../../../config/createTLUser'\n\n/** @public */\nexport class UserPreferencesManager {\n\tsystemColorScheme = atom<'dark' | 'light'>('systemColorScheme', 'light')\n\tdisposables = new Set<() => void>()\n\tdispose() {\n\t\tthis.disposables.forEach((d) => d())\n\t}\n\tconstructor(\n\t\tprivate readonly user: TLUser,\n\t\tprivate readonly inferDarkMode: boolean\n\t) {\n\t\tif (typeof window === 'undefined' || !window.matchMedia) return\n\n\t\tconst darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n\t\tif (darkModeMediaQuery?.matches) {\n\t\t\tthis.systemColorScheme.set('dark')\n\t\t}\n\t\tconst handleChange = (e: MediaQueryListEvent) => {\n\t\t\tif (e.matches) {\n\t\t\t\tthis.systemColorScheme.set('dark')\n\t\t\t} else {\n\t\t\t\tthis.systemColorScheme.set('light')\n\t\t\t}\n\t\t}\n\t\tdarkModeMediaQuery?.addEventListener('change', handleChange)\n\t\tthis.disposables.add(() => darkModeMediaQuery?.removeEventListener('change', handleChange))\n\t}\n\n\tupdateUserPreferences(userPreferences: Partial<TLUserPreferences>) {\n\t\tthis.user.setUserPreferences({\n\t\t\t...this.user.userPreferences.get(),\n\t\t\t...userPreferences,\n\t\t})\n\t}\n\t@computed getUserPreferences() {\n\t\treturn {\n\t\t\tid: this.getId(),\n\t\t\tname: this.getName(),\n\t\t\tlocale: this.getLocale(),\n\t\t\tcolor: this.getColor(),\n\t\t\tanimationSpeed: this.getAnimationSpeed(),\n\t\t\tareKeyboardShortcutsEnabled: this.getAreKeyboardShortcutsEnabled(),\n\t\t\tisSnapMode: this.getIsSnapMode(),\n\t\t\tcolorScheme: this.user.userPreferences.get().colorScheme,\n\t\t\tisDarkMode: this.getIsDarkMode(),\n\t\t\tisWrapMode: this.getIsWrapMode(),\n\t\t\tisDynamicResizeMode: this.getIsDynamicResizeMode(),\n\t\t\tshowUiLabels: this.getShowUiLabels(),\n\t\t}\n\t}\n\n\t@computed getIsDarkMode() {\n\t\tswitch (this.user.userPreferences.get().colorScheme) {\n\t\t\tcase 'dark':\n\t\t\t\treturn true\n\t\t\tcase 'light':\n\t\t\t\treturn false\n\t\t\tcase 'system':\n\t\t\t\treturn this.systemColorScheme.get() === 'dark'\n\t\t\tdefault:\n\t\t\t\treturn this.inferDarkMode ? this.systemColorScheme.get() === 'dark' : false\n\t\t}\n\t}\n\n\t/**\n\t * The speed at which the user can scroll by dragging toward the edge of the screen.\n\t */\n\t@computed getEdgeScrollSpeed() {\n\t\treturn this.user.userPreferences.get().edgeScrollSpeed ?? defaultUserPreferences.edgeScrollSpeed\n\t}\n\n\t@computed getAnimationSpeed() {\n\t\treturn this.user.userPreferences.get().animationSpeed ?? defaultUserPreferences.animationSpeed\n\t}\n\n\t@computed getAreKeyboardShortcutsEnabled() {\n\t\treturn (\n\t\t\tthis.user.userPreferences.get().areKeyboardShortcutsEnabled ??\n\t\t\tdefaultUserPreferences.areKeyboardShortcutsEnabled\n\t\t)\n\t}\n\n\t@computed getId() {\n\t\treturn this.user.userPreferences.get().id\n\t}\n\n\t@computed getName() {\n\t\treturn this.user.userPreferences.get().name?.trim() ?? defaultUserPreferences.name\n\t}\n\n\t@computed getLocale() {\n\t\treturn this.user.userPreferences.get().locale ?? defaultUserPreferences.locale\n\t}\n\n\t@computed getColor() {\n\t\treturn this.user.userPreferences.get().color ?? defaultUserPreferences.color\n\t}\n\n\t@computed getIsSnapMode() {\n\t\treturn this.user.userPreferences.get().isSnapMode ?? defaultUserPreferences.isSnapMode\n\t}\n\n\t@computed getIsWrapMode() {\n\t\treturn this.user.userPreferences.get().isWrapMode ?? defaultUserPreferences.isWrapMode\n\t}\n\n\t@computed getIsDynamicResizeMode() {\n\t\treturn (\n\t\t\tthis.user.userPreferences.get().isDynamicSizeMode ?? defaultUserPreferences.isDynamicSizeMode\n\t\t)\n\t}\n\n\t@computed getIsPasteAtCursorMode() {\n\t\treturn (\n\t\t\tthis.user.userPreferences.get().isPasteAtCursorMode ??\n\t\t\tdefaultUserPreferences.isPasteAtCursorMode\n\t\t)\n\t}\n\n\t@computed getShowUiLabels() {\n\t\treturn this.user.userPreferences.get().showUiLabels ?? defaultUserPreferences.showUiLabels\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -137,6 +137,8 @@ function useCanvasEvents() {
|
|
|
137
137
|
(0, import_react.useEffect)(() => {
|
|
138
138
|
let lastX, lastY;
|
|
139
139
|
function onPointerMove(e) {
|
|
140
|
+
if (e.isKilled) return;
|
|
141
|
+
e.isKilled = true;
|
|
140
142
|
if (e.clientX === lastX && e.clientY === lastY) return;
|
|
141
143
|
lastX = e.clientX;
|
|
142
144
|
lastY = e.clientY;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/hooks/useCanvasEvents.ts"],
|
|
4
|
-
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport React, { useEffect, useMemo } from 'react'\nimport { RIGHT_MOUSE_BUTTON } from '../constants'\nimport {\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tstopEventPropagation,\n} from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\nimport { useEditor } from './useEditor'\n\nexport function useCanvasEvents() {\n\tconst editor = useEditor()\n\tconst currentTool = useValue('current tool', () => editor.getCurrentTool(), [editor])\n\n\tconst events = useMemo(\n\t\tfunction canvasEvents() {\n\t\t\tfunction onPointerDown(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\n\t\t\t\tif (e.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'right_click',\n\t\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 5) return\n\n\t\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerUp(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\n\t\t\t\treleasePointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerEnter(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })\n\t\t\t}\n\n\t\t\tfunction onPointerLeave(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })\n\t\t\t}\n\n\t\t\tfunction onTouchStart(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tfunction onTouchEnd(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\t// check that e.target is an HTMLElement\n\t\t\t\tif (!(e.target instanceof HTMLElement)) return\n\n\t\t\t\tif (\n\t\t\t\t\te.target.tagName !== 'A' &&\n\t\t\t\t\te.target.tagName !== 'TEXTAREA' &&\n\t\t\t\t\t!e.target.isContentEditable &&\n\t\t\t\t\t// When in EditingShape state, we are actually clicking on a 'DIV'\n\t\t\t\t\t// not A/TEXTAREA/contenteditable element yet. So, to preserve cursor position\n\t\t\t\t\t// for edit mode on mobile we need to not preventDefault.\n\t\t\t\t\t// TODO: Find out if we still need this preventDefault in general though.\n\t\t\t\t\t!(editor.getEditingShape() && e.target.className.includes('tl-text-content'))\n\t\t\t\t) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onDragOver(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tasync function onDrop(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t\tstopEventPropagation(e)\n\n\t\t\t\tif (e.dataTransfer?.files?.length) {\n\t\t\t\t\tconst files = Array.from(e.dataTransfer.files)\n\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'files',\n\t\t\t\t\t\tfiles,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst url = e.dataTransfer.getData('url')\n\t\t\t\tif (url) {\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'url',\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onClick(e: React.MouseEvent) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonPointerDown,\n\t\t\t\tonPointerUp,\n\t\t\t\tonPointerEnter,\n\t\t\t\tonPointerLeave,\n\t\t\t\tonDragOver,\n\t\t\t\tonDrop,\n\t\t\t\tonTouchStart,\n\t\t\t\tonTouchEnd,\n\t\t\t\tonClick,\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\t// onPointerMove is special: where we're only interested in the other events when they're\n\t// happening _on_ the canvas (as opposed to outside of it, or on UI floating over it), we want\n\t// the pointer position to be up to date regardless of whether it's over the tldraw canvas or\n\t// not. So instead of returning a listener to be attached to the canvas, we directly attach a\n\t// listener to the whole document instead.\n\tuseEffect(() => {\n\t\tlet lastX: number, lastY: number\n\n\t\tfunction onPointerMove(e: PointerEvent) {\n\t\t\tif (e.clientX === lastX && e.clientY === lastY) return\n\t\t\tlastX = e.clientX\n\t\t\tlastY = e.clientY\n\n\t\t\t// For tools that benefit from a higher fidelity of events,\n\t\t\t// we dispatch the coalesced events.\n\t\t\t// N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.\n\t\t\tconst events =\n\t\t\t\tcurrentTool.useCoalescedEvents && e.getCoalescedEvents ? e.getCoalescedEvents() : [e]\n\t\t\tfor (const singleEvent of events) {\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t...getPointerInfo(singleEvent),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tdocument.body.addEventListener('pointermove', onPointerMove)\n\t\treturn () => {\n\t\t\tdocument.body.removeEventListener('pointermove', onPointerMove)\n\t\t}\n\t}, [editor, currentTool])\n\n\treturn events\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport React, { useEffect, useMemo } from 'react'\nimport { RIGHT_MOUSE_BUTTON } from '../constants'\nimport {\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tstopEventPropagation,\n} from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\nimport { useEditor } from './useEditor'\n\nexport function useCanvasEvents() {\n\tconst editor = useEditor()\n\tconst currentTool = useValue('current tool', () => editor.getCurrentTool(), [editor])\n\n\tconst events = useMemo(\n\t\tfunction canvasEvents() {\n\t\t\tfunction onPointerDown(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\n\t\t\t\tif (e.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'right_click',\n\t\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 5) return\n\n\t\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerUp(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\n\t\t\t\treleasePointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerEnter(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })\n\t\t\t}\n\n\t\t\tfunction onPointerLeave(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })\n\t\t\t}\n\n\t\t\tfunction onTouchStart(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tfunction onTouchEnd(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\t// check that e.target is an HTMLElement\n\t\t\t\tif (!(e.target instanceof HTMLElement)) return\n\n\t\t\t\tif (\n\t\t\t\t\te.target.tagName !== 'A' &&\n\t\t\t\t\te.target.tagName !== 'TEXTAREA' &&\n\t\t\t\t\t!e.target.isContentEditable &&\n\t\t\t\t\t// When in EditingShape state, we are actually clicking on a 'DIV'\n\t\t\t\t\t// not A/TEXTAREA/contenteditable element yet. So, to preserve cursor position\n\t\t\t\t\t// for edit mode on mobile we need to not preventDefault.\n\t\t\t\t\t// TODO: Find out if we still need this preventDefault in general though.\n\t\t\t\t\t!(editor.getEditingShape() && e.target.className.includes('tl-text-content'))\n\t\t\t\t) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onDragOver(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tasync function onDrop(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t\tstopEventPropagation(e)\n\n\t\t\t\tif (e.dataTransfer?.files?.length) {\n\t\t\t\t\tconst files = Array.from(e.dataTransfer.files)\n\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'files',\n\t\t\t\t\t\tfiles,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst url = e.dataTransfer.getData('url')\n\t\t\t\tif (url) {\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'url',\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onClick(e: React.MouseEvent) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonPointerDown,\n\t\t\t\tonPointerUp,\n\t\t\t\tonPointerEnter,\n\t\t\t\tonPointerLeave,\n\t\t\t\tonDragOver,\n\t\t\t\tonDrop,\n\t\t\t\tonTouchStart,\n\t\t\t\tonTouchEnd,\n\t\t\t\tonClick,\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\t// onPointerMove is special: where we're only interested in the other events when they're\n\t// happening _on_ the canvas (as opposed to outside of it, or on UI floating over it), we want\n\t// the pointer position to be up to date regardless of whether it's over the tldraw canvas or\n\t// not. So instead of returning a listener to be attached to the canvas, we directly attach a\n\t// listener to the whole document instead.\n\tuseEffect(() => {\n\t\tlet lastX: number, lastY: number\n\n\t\tfunction onPointerMove(e: PointerEvent) {\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tif (e.clientX === lastX && e.clientY === lastY) return\n\t\t\tlastX = e.clientX\n\t\t\tlastY = e.clientY\n\n\t\t\t// For tools that benefit from a higher fidelity of events,\n\t\t\t// we dispatch the coalesced events.\n\t\t\t// N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.\n\t\t\tconst events =\n\t\t\t\tcurrentTool.useCoalescedEvents && e.getCoalescedEvents ? e.getCoalescedEvents() : [e]\n\t\t\tfor (const singleEvent of events) {\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t...getPointerInfo(singleEvent),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tdocument.body.addEventListener('pointermove', onPointerMove)\n\t\treturn () => {\n\t\t\tdocument.body.removeEventListener('pointermove', onPointerMove)\n\t\t}\n\t}, [editor, currentTool])\n\n\treturn events\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["events"]
|
|
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.36b89de88b02";
|
|
26
26
|
const publishDates = {
|
|
27
27
|
major: "2024-09-13T14:36:29.063Z",
|
|
28
|
-
minor: "2025-08-
|
|
29
|
-
patch: "2025-08-
|
|
28
|
+
minor: "2025-08-19T10:38:37.569Z",
|
|
29
|
+
patch: "2025-08-19T10:38:37.569Z"
|
|
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.36b89de88b02'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-08-19T10:38:37.569Z',\n\tpatch: '2025-08-19T10:38:37.569Z',\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
|
@@ -53,7 +53,7 @@ const DefaultErrorFallback = ({ error, editor }) => {
|
|
|
53
53
|
setIsDarkMode(null);
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
|
-
if (typeof window !== "undefined" &&
|
|
56
|
+
if (typeof window !== "undefined" && window.matchMedia) {
|
|
57
57
|
setIsDarkMode(window.matchMedia("(prefers-color-scheme: dark)").matches);
|
|
58
58
|
}
|
|
59
59
|
}, [isDarkModeFromApp]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/components/default-components/DefaultErrorFallback.tsx"],
|
|
4
|
-
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { noop } from '@tldraw/utils'\nimport classNames from 'classnames'\nimport { ComponentType, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { Editor } from '../../editor/Editor'\nimport { EditorProvider } from '../../hooks/useEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\nimport { hardResetEditor } from '../../utils/hardResetEditor'\nimport { refreshPage } from '../../utils/refreshPage'\nimport { ErrorBoundary } from '../ErrorBoundary'\n\nconst BASE_ERROR_URL = 'https://github.com/tldraw/tldraw/issues/new'\n\n/** @public */\nexport type TLErrorFallbackComponent = ComponentType<{ error: unknown; editor?: Editor }>\n\n/** @public @react */\nexport const DefaultErrorFallback: TLErrorFallbackComponent = ({ error, editor }) => {\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst [shouldShowError, setShouldShowError] = useState(process.env.NODE_ENV === 'development')\n\tconst [didCopy, setDidCopy] = useState(false)\n\tconst [shouldShowResetConfirmation, setShouldShowResetConfirmation] = useState(false)\n\n\tlet Canvas: React.ComponentType | null = null\n\ttry {\n\t\tconst components = useEditorComponents()\n\t\tCanvas = components.Canvas ?? null\n\t} catch {\n\t\t// allow this to fail silently\n\t}\n\n\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\tconst errorStack = error instanceof Error ? error.stack : null\n\n\tconst isDarkModeFromApp = useValue(\n\t\t'isDarkMode',\n\t\t() => {\n\t\t\ttry {\n\t\t\t\tif (editor) {\n\t\t\t\t\treturn editor.user.getIsDarkMode()\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// we're in a funky error state so this might not work for spooky\n\t\t\t\t// reasons. if not, we'll have another attempt later:\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\t\t[editor]\n\t)\n\tconst [isDarkMode, setIsDarkMode] = useState<null | boolean>(null)\n\tuseLayoutEffect(() => {\n\t\t// if we found a theme class from the app, we can just use that\n\t\tif (isDarkModeFromApp !== null) {\n\t\t\tsetIsDarkMode(isDarkModeFromApp)\n\t\t}\n\n\t\t// do any of our parents have a theme class? if yes then we can just\n\t\t// rely on that and don't need to set our own class\n\t\tlet parent = containerRef.current?.parentElement\n\t\tlet foundParentThemeClass = false\n\t\twhile (parent) {\n\t\t\tif (\n\t\t\t\tparent.classList.contains('tl-theme__dark') ||\n\t\t\t\tparent.classList.contains('tl-theme__light')\n\t\t\t) {\n\t\t\t\tfoundParentThemeClass = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tparent = parent.parentElement\n\t\t}\n\t\tif (foundParentThemeClass) {\n\t\t\tsetIsDarkMode(null)\n\t\t\treturn\n\t\t}\n\n\t\t// if we can't find a theme class from the app or from a parent, we have\n\t\t// to fall back on using a media query:\n\t\tif (typeof window !== 'undefined' &&
|
|
5
|
-
"mappings": "AAuIG,SAoBE,UApBF,KAuBG,YAvBH;AAvIH,SAAS,gBAAgB;AACzB,SAAS,YAAY;AACrB,OAAO,gBAAgB;AACvB,SAAwB,WAAW,iBAAiB,QAAQ,gBAAgB;AAE5E,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAE9B,MAAM,iBAAiB;AAMhB,MAAM,uBAAiD,CAAC,EAAE,OAAO,OAAO,MAAM;AACpF,QAAM,eAAe,OAAuB,IAAI;AAChD,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAS,QAAQ,IAAI,aAAa,aAAa;AAC7F,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,6BAA6B,8BAA8B,IAAI,SAAS,KAAK;AAEpF,MAAI,SAAqC;AACzC,MAAI;AACH,UAAM,aAAa,oBAAoB;AACvC,aAAS,WAAW,UAAU;AAAA,EAC/B,QAAQ;AAAA,EAER;AAEA,QAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,QAAM,aAAa,iBAAiB,QAAQ,MAAM,QAAQ;AAE1D,QAAM,oBAAoB;AAAA,IACzB;AAAA,IACA,MAAM;AACL,UAAI;AACH,YAAI,QAAQ;AACX,iBAAO,OAAO,KAAK,cAAc;AAAA,QAClC;AAAA,MACD,QAAQ;AAAA,MAGR;AACA,aAAO;AAAA,IACR;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AACA,QAAM,CAAC,YAAY,aAAa,IAAI,SAAyB,IAAI;AACjE,kBAAgB,MAAM;AAErB,QAAI,sBAAsB,MAAM;AAC/B,oBAAc,iBAAiB;AAAA,IAChC;AAIA,QAAI,SAAS,aAAa,SAAS;AACnC,QAAI,wBAAwB;AAC5B,WAAO,QAAQ;AACd,UACC,OAAO,UAAU,SAAS,gBAAgB,KAC1C,OAAO,UAAU,SAAS,iBAAiB,GAC1C;AACD,gCAAwB;AACxB;AAAA,MACD;AACA,eAAS,OAAO;AAAA,IACjB;AACA,QAAI,uBAAuB;AAC1B,oBAAc,IAAI;AAClB;AAAA,IACD;AAIA,QAAI,OAAO,WAAW,eAAe,
|
|
4
|
+
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { noop } from '@tldraw/utils'\nimport classNames from 'classnames'\nimport { ComponentType, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { Editor } from '../../editor/Editor'\nimport { EditorProvider } from '../../hooks/useEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\nimport { hardResetEditor } from '../../utils/hardResetEditor'\nimport { refreshPage } from '../../utils/refreshPage'\nimport { ErrorBoundary } from '../ErrorBoundary'\n\nconst BASE_ERROR_URL = 'https://github.com/tldraw/tldraw/issues/new'\n\n/** @public */\nexport type TLErrorFallbackComponent = ComponentType<{ error: unknown; editor?: Editor }>\n\n/** @public @react */\nexport const DefaultErrorFallback: TLErrorFallbackComponent = ({ error, editor }) => {\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst [shouldShowError, setShouldShowError] = useState(process.env.NODE_ENV === 'development')\n\tconst [didCopy, setDidCopy] = useState(false)\n\tconst [shouldShowResetConfirmation, setShouldShowResetConfirmation] = useState(false)\n\n\tlet Canvas: React.ComponentType | null = null\n\ttry {\n\t\tconst components = useEditorComponents()\n\t\tCanvas = components.Canvas ?? null\n\t} catch {\n\t\t// allow this to fail silently\n\t}\n\n\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\tconst errorStack = error instanceof Error ? error.stack : null\n\n\tconst isDarkModeFromApp = useValue(\n\t\t'isDarkMode',\n\t\t() => {\n\t\t\ttry {\n\t\t\t\tif (editor) {\n\t\t\t\t\treturn editor.user.getIsDarkMode()\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// we're in a funky error state so this might not work for spooky\n\t\t\t\t// reasons. if not, we'll have another attempt later:\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\t\t[editor]\n\t)\n\tconst [isDarkMode, setIsDarkMode] = useState<null | boolean>(null)\n\tuseLayoutEffect(() => {\n\t\t// if we found a theme class from the app, we can just use that\n\t\tif (isDarkModeFromApp !== null) {\n\t\t\tsetIsDarkMode(isDarkModeFromApp)\n\t\t}\n\n\t\t// do any of our parents have a theme class? if yes then we can just\n\t\t// rely on that and don't need to set our own class\n\t\tlet parent = containerRef.current?.parentElement\n\t\tlet foundParentThemeClass = false\n\t\twhile (parent) {\n\t\t\tif (\n\t\t\t\tparent.classList.contains('tl-theme__dark') ||\n\t\t\t\tparent.classList.contains('tl-theme__light')\n\t\t\t) {\n\t\t\t\tfoundParentThemeClass = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tparent = parent.parentElement\n\t\t}\n\t\tif (foundParentThemeClass) {\n\t\t\tsetIsDarkMode(null)\n\t\t\treturn\n\t\t}\n\n\t\t// if we can't find a theme class from the app or from a parent, we have\n\t\t// to fall back on using a media query:\n\t\tif (typeof window !== 'undefined' && window.matchMedia) {\n\t\t\tsetIsDarkMode(window.matchMedia('(prefers-color-scheme: dark)').matches)\n\t\t}\n\t}, [isDarkModeFromApp])\n\n\tuseEffect(() => {\n\t\tif (didCopy) {\n\t\t\tconst timeout = editor?.timers.setTimeout(() => {\n\t\t\t\tsetDidCopy(false)\n\t\t\t}, 2000)\n\t\t\treturn () => clearTimeout(timeout)\n\t\t}\n\t}, [didCopy, editor])\n\n\tconst copyError = () => {\n\t\tconst textarea = document.createElement('textarea')\n\t\ttextarea.value = errorStack ?? errorMessage\n\t\tdocument.body.appendChild(textarea)\n\t\ttextarea.select()\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\tdocument.execCommand('copy')\n\t\ttextarea.remove()\n\t\tsetDidCopy(true)\n\t}\n\n\tconst refresh = () => {\n\t\trefreshPage()\n\t}\n\n\tconst resetLocalState = async () => {\n\t\thardResetEditor()\n\t}\n\n\tconst url = new URL(BASE_ERROR_URL)\n\turl.searchParams.set('title', errorMessage)\n\turl.searchParams.set('labels', `bug`)\n\turl.searchParams.set(\n\t\t'body',\n\t\t`Hey, I ran into an error while using tldraw:\n\n\\`\\`\\`js\n${errorStack ?? errorMessage}\n\\`\\`\\`\n\nMy browser: ${navigator.userAgent}`\n\t)\n\n\treturn (\n\t\t<div\n\t\t\tref={containerRef}\n\t\t\tclassName={classNames(\n\t\t\t\t'tl-container tl-error-boundary',\n\t\t\t\t// error-boundary is sometimes used outside of the theme\n\t\t\t\t// container, so we need to provide it with a theme for our\n\t\t\t\t// styles to work correctly\n\t\t\t\tisDarkMode === null ? '' : isDarkMode ? 'tl-theme__dark' : 'tl-theme__light'\n\t\t\t)}\n\t\t>\n\t\t\t<div className=\"tl-error-boundary__overlay\" />\n\t\t\t{editor && (\n\t\t\t\t// opportunistically attempt to render the canvas to reassure\n\t\t\t\t// the user that their document is still there. there's a good\n\t\t\t\t// chance this won't work (ie the error that we're currently\n\t\t\t\t// notifying the user about originates in the canvas) so it's\n\t\t\t\t// not a big deal if it doesn't work - in that case we just have\n\t\t\t\t// a plain grey background.\n\t\t\t\t<ErrorBoundary onError={noop} fallback={() => null}>\n\t\t\t\t\t<EditorProvider editor={editor}>\n\t\t\t\t\t\t<div className=\"tl-overlay tl-error-boundary__canvas\">{Canvas ? <Canvas /> : null}</div>\n\t\t\t\t\t</EditorProvider>\n\t\t\t\t</ErrorBoundary>\n\t\t\t)}\n\t\t\t<div\n\t\t\t\tclassName={classNames('tl-modal', 'tl-error-boundary__content', {\n\t\t\t\t\t'tl-error-boundary__content__expanded': shouldShowError && !shouldShowResetConfirmation,\n\t\t\t\t})}\n\t\t\t>\n\t\t\t\t{shouldShowResetConfirmation ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<h2>Are you sure?</h2>\n\t\t\t\t\t\t<p>Resetting your data will delete your drawing and cannot be undone.</p>\n\t\t\t\t\t\t<div className=\"tl-error-boundary__content__actions\">\n\t\t\t\t\t\t\t<button className=\"tlui-button\" onClick={() => setShouldShowResetConfirmation(false)}>\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button className=\"tlui-button tl-error-boundary__reset\" onClick={resetLocalState}>\n\t\t\t\t\t\t\t\tReset data\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<h2>Something went wrong</h2>\n\t\t\t\t\t\t<p>Please refresh your browser.</p>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\tIf the issue continues after refreshing, you may need to reset the tldraw data stored\n\t\t\t\t\t\t\ton your device.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t<strong>Note:</strong> Resetting will erase your current project and any unsaved work.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t{process.env.NODE_ENV !== 'production' && (\n\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\tIf you're developing with the SDK and need help, join us on{' '}\n\t\t\t\t\t\t\t\t<a href=\"https://discord.tldraw.com/?utm_source=sdk&utm_medium=organic&utm_campaign=error-screen\">\n\t\t\t\t\t\t\t\t\tDiscord\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t.\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{shouldShowError && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\tMessage:\n\t\t\t\t\t\t\t\t<h4>\n\t\t\t\t\t\t\t\t\t<code>{errorMessage}</code>\n\t\t\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t\t\tStack trace:\n\t\t\t\t\t\t\t\t<div className=\"tl-error-boundary__content__error\">\n\t\t\t\t\t\t\t\t\t<pre>\n\t\t\t\t\t\t\t\t\t\t<code>{errorStack ?? errorMessage}</code>\n\t\t\t\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t\t\t\t<button className=\"tlui-button\" onClick={copyError}>\n\t\t\t\t\t\t\t\t\t\t{didCopy ? 'Copied!' : 'Copy'}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<div className=\"tl-error-boundary__content__actions\">\n\t\t\t\t\t\t\t<button className=\"tlui-button\" onClick={() => setShouldShowError(!shouldShowError)}>\n\t\t\t\t\t\t\t\t{shouldShowError ? 'Hide details' : 'Show details'}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<div className=\"tl-error-boundary__content__actions__group\">\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-button tl-error-boundary__reset\"\n\t\t\t\t\t\t\t\t\tonClick={() => setShouldShowResetConfirmation(true)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tReset data\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button className=\"tlui-button tl-error-boundary__refresh\" onClick={refresh}>\n\t\t\t\t\t\t\t\t\tRefresh Page\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -87,7 +87,7 @@ function getRandomColor() {
|
|
|
87
87
|
return USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)];
|
|
88
88
|
}
|
|
89
89
|
function userPrefersReducedMotion() {
|
|
90
|
-
if (typeof window !== "undefined" &&
|
|
90
|
+
if (typeof window !== "undefined" && window.matchMedia) {
|
|
91
91
|
return window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches ?? false;
|
|
92
92
|
}
|
|
93
93
|
return false;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/config/TLUserPreferences.ts"],
|
|
4
|
-
"sourcesContent": ["import { atom } from '@tldraw/state'\nimport { getDefaultTranslationLocale } from '@tldraw/tlschema'\nimport { getFromLocalStorage, setInLocalStorage, structuredClone, uniqueId } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\n\nconst USER_DATA_KEY = 'TLDRAW_USER_DATA_v3'\n\n/**\n * A user of tldraw\n *\n * @public\n */\nexport interface TLUserPreferences {\n\tid: string\n\tname?: string | null\n\tcolor?: string | null\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale?: string | null\n\tanimationSpeed?: number | null\n\tareKeyboardShortcutsEnabled?: boolean | null\n\tedgeScrollSpeed?: number | null\n\tcolorScheme?: 'light' | 'dark' | 'system'\n\tisSnapMode?: boolean | null\n\tisWrapMode?: boolean | null\n\tisDynamicSizeMode?: boolean | null\n\tisPasteAtCursorMode?: boolean | null\n\tshowUiLabels?: boolean | null\n}\n\ninterface UserDataSnapshot {\n\tversion: number\n\tuser: TLUserPreferences\n}\n\ninterface UserChangeBroadcastMessage {\n\ttype: typeof broadcastEventKey\n\torigin: string\n\tdata: UserDataSnapshot\n}\n\n/** @public */\nexport const userTypeValidator: T.Validator<TLUserPreferences> = T.object<TLUserPreferences>({\n\tid: T.string,\n\tname: T.string.nullable().optional(),\n\tcolor: T.string.nullable().optional(),\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale: T.string.nullable().optional(),\n\tanimationSpeed: T.number.nullable().optional(),\n\tareKeyboardShortcutsEnabled: T.boolean.nullable().optional(),\n\tedgeScrollSpeed: T.number.nullable().optional(),\n\tcolorScheme: T.literalEnum('light', 'dark', 'system').optional(),\n\tisSnapMode: T.boolean.nullable().optional(),\n\tisWrapMode: T.boolean.nullable().optional(),\n\tisDynamicSizeMode: T.boolean.nullable().optional(),\n\tisPasteAtCursorMode: T.boolean.nullable().optional(),\n\tshowUiLabels: T.boolean.nullable().optional(),\n})\n\nconst Versions = {\n\tAddAnimationSpeed: 1,\n\tAddIsSnapMode: 2,\n\tMakeFieldsNullable: 3,\n\tAddEdgeScrollSpeed: 4,\n\tAddExcalidrawSelectMode: 5,\n\tAddDynamicSizeMode: 6,\n\tAllowSystemColorScheme: 7,\n\tAddPasteAtCursor: 8,\n\tAddKeyboardShortcuts: 9,\n\tAddShowUiLabels: 10,\n} as const\n\nconst CURRENT_VERSION = Math.max(...Object.values(Versions))\n\nfunction migrateSnapshot(data: { version: number; user: any }) {\n\tif (data.version < Versions.AddAnimationSpeed) {\n\t\tdata.user.animationSpeed = 1\n\t}\n\tif (data.version < Versions.AddIsSnapMode) {\n\t\tdata.user.isSnapMode = false\n\t}\n\tif (data.version < Versions.MakeFieldsNullable) {\n\t\t// noop\n\t}\n\tif (data.version < Versions.AddEdgeScrollSpeed) {\n\t\tdata.user.edgeScrollSpeed = 1\n\t}\n\tif (data.version < Versions.AddExcalidrawSelectMode) {\n\t\tdata.user.isWrapMode = false\n\t}\n\tif (data.version < Versions.AllowSystemColorScheme) {\n\t\tif (data.user.isDarkMode === true) {\n\t\t\tdata.user.colorScheme = 'dark'\n\t\t} else if (data.user.isDarkMode === false) {\n\t\t\tdata.user.colorScheme = 'light'\n\t\t}\n\t\tdelete data.user.isDarkMode\n\t}\n\n\tif (data.version < Versions.AddDynamicSizeMode) {\n\t\tdata.user.isDynamicSizeMode = false\n\t}\n\tif (data.version < Versions.AddPasteAtCursor) {\n\t\tdata.user.isPasteAtCursorMode = false\n\t}\n\tif (data.version < Versions.AddKeyboardShortcuts) {\n\t\tdata.user.areKeyboardShortcutsEnabled = true\n\t}\n\tif (data.version < Versions.AddShowUiLabels) {\n\t\tdata.user.showUiLabels = false\n\t}\n\n\t// finally\n\tdata.version = CURRENT_VERSION\n}\n\n/** @internal */\nexport const USER_COLORS = [\n\t'#FF802B',\n\t'#EC5E41',\n\t'#F2555A',\n\t'#F04F88',\n\t'#E34BA9',\n\t'#BD54C6',\n\t'#9D5BD2',\n\t'#7B66DC',\n\t'#02B1CC',\n\t'#11B3A3',\n\t'#39B178',\n\t'#55B467',\n] as const\n\nfunction getRandomColor() {\n\treturn USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)]\n}\n\n/** @internal */\nexport function userPrefersReducedMotion() {\n\tif (typeof window !== 'undefined' &&
|
|
5
|
-
"mappings": "AAAA,SAAS,YAAY;AACrB,SAAS,mCAAmC;AAC5C,SAAS,qBAAqB,mBAAmB,iBAAiB,gBAAgB;AAClF,SAAS,SAAS;AAElB,MAAM,gBAAgB;AAoCf,MAAM,oBAAoD,EAAE,OAA0B;AAAA,EAC5F,IAAI,EAAE;AAAA,EACN,MAAM,EAAE,OAAO,SAAS,EAAE,SAAS;AAAA,EACnC,OAAO,EAAE,OAAO,SAAS,EAAE,SAAS;AAAA;AAAA,EAEpC,QAAQ,EAAE,OAAO,SAAS,EAAE,SAAS;AAAA,EACrC,gBAAgB,EAAE,OAAO,SAAS,EAAE,SAAS;AAAA,EAC7C,6BAA6B,EAAE,QAAQ,SAAS,EAAE,SAAS;AAAA,EAC3D,iBAAiB,EAAE,OAAO,SAAS,EAAE,SAAS;AAAA,EAC9C,aAAa,EAAE,YAAY,SAAS,QAAQ,QAAQ,EAAE,SAAS;AAAA,EAC/D,YAAY,EAAE,QAAQ,SAAS,EAAE,SAAS;AAAA,EAC1C,YAAY,EAAE,QAAQ,SAAS,EAAE,SAAS;AAAA,EAC1C,mBAAmB,EAAE,QAAQ,SAAS,EAAE,SAAS;AAAA,EACjD,qBAAqB,EAAE,QAAQ,SAAS,EAAE,SAAS;AAAA,EACnD,cAAc,EAAE,QAAQ,SAAS,EAAE,SAAS;AAC7C,CAAC;AAED,MAAM,WAAW;AAAA,EAChB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,iBAAiB;AAClB;AAEA,MAAM,kBAAkB,KAAK,IAAI,GAAG,OAAO,OAAO,QAAQ,CAAC;AAE3D,SAAS,gBAAgB,MAAsC;AAC9D,MAAI,KAAK,UAAU,SAAS,mBAAmB;AAC9C,SAAK,KAAK,iBAAiB;AAAA,EAC5B;AACA,MAAI,KAAK,UAAU,SAAS,eAAe;AAC1C,SAAK,KAAK,aAAa;AAAA,EACxB;AACA,MAAI,KAAK,UAAU,SAAS,oBAAoB;AAAA,EAEhD;AACA,MAAI,KAAK,UAAU,SAAS,oBAAoB;AAC/C,SAAK,KAAK,kBAAkB;AAAA,EAC7B;AACA,MAAI,KAAK,UAAU,SAAS,yBAAyB;AACpD,SAAK,KAAK,aAAa;AAAA,EACxB;AACA,MAAI,KAAK,UAAU,SAAS,wBAAwB;AACnD,QAAI,KAAK,KAAK,eAAe,MAAM;AAClC,WAAK,KAAK,cAAc;AAAA,IACzB,WAAW,KAAK,KAAK,eAAe,OAAO;AAC1C,WAAK,KAAK,cAAc;AAAA,IACzB;AACA,WAAO,KAAK,KAAK;AAAA,EAClB;AAEA,MAAI,KAAK,UAAU,SAAS,oBAAoB;AAC/C,SAAK,KAAK,oBAAoB;AAAA,EAC/B;AACA,MAAI,KAAK,UAAU,SAAS,kBAAkB;AAC7C,SAAK,KAAK,sBAAsB;AAAA,EACjC;AACA,MAAI,KAAK,UAAU,SAAS,sBAAsB;AACjD,SAAK,KAAK,8BAA8B;AAAA,EACzC;AACA,MAAI,KAAK,UAAU,SAAS,iBAAiB;AAC5C,SAAK,KAAK,eAAe;AAAA,EAC1B;AAGA,OAAK,UAAU;AAChB;AAGO,MAAM,cAAc;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAEA,SAAS,iBAAiB;AACzB,SAAO,YAAY,KAAK,MAAM,KAAK,OAAO,IAAI,YAAY,MAAM,CAAC;AAClE;AAGO,SAAS,2BAA2B;AAC1C,MAAI,OAAO,WAAW,eAAe,
|
|
4
|
+
"sourcesContent": ["import { atom } from '@tldraw/state'\nimport { getDefaultTranslationLocale } from '@tldraw/tlschema'\nimport { getFromLocalStorage, setInLocalStorage, structuredClone, uniqueId } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\n\nconst USER_DATA_KEY = 'TLDRAW_USER_DATA_v3'\n\n/**\n * A user of tldraw\n *\n * @public\n */\nexport interface TLUserPreferences {\n\tid: string\n\tname?: string | null\n\tcolor?: string | null\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale?: string | null\n\tanimationSpeed?: number | null\n\tareKeyboardShortcutsEnabled?: boolean | null\n\tedgeScrollSpeed?: number | null\n\tcolorScheme?: 'light' | 'dark' | 'system'\n\tisSnapMode?: boolean | null\n\tisWrapMode?: boolean | null\n\tisDynamicSizeMode?: boolean | null\n\tisPasteAtCursorMode?: boolean | null\n\tshowUiLabels?: boolean | null\n}\n\ninterface UserDataSnapshot {\n\tversion: number\n\tuser: TLUserPreferences\n}\n\ninterface UserChangeBroadcastMessage {\n\ttype: typeof broadcastEventKey\n\torigin: string\n\tdata: UserDataSnapshot\n}\n\n/** @public */\nexport const userTypeValidator: T.Validator<TLUserPreferences> = T.object<TLUserPreferences>({\n\tid: T.string,\n\tname: T.string.nullable().optional(),\n\tcolor: T.string.nullable().optional(),\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale: T.string.nullable().optional(),\n\tanimationSpeed: T.number.nullable().optional(),\n\tareKeyboardShortcutsEnabled: T.boolean.nullable().optional(),\n\tedgeScrollSpeed: T.number.nullable().optional(),\n\tcolorScheme: T.literalEnum('light', 'dark', 'system').optional(),\n\tisSnapMode: T.boolean.nullable().optional(),\n\tisWrapMode: T.boolean.nullable().optional(),\n\tisDynamicSizeMode: T.boolean.nullable().optional(),\n\tisPasteAtCursorMode: T.boolean.nullable().optional(),\n\tshowUiLabels: T.boolean.nullable().optional(),\n})\n\nconst Versions = {\n\tAddAnimationSpeed: 1,\n\tAddIsSnapMode: 2,\n\tMakeFieldsNullable: 3,\n\tAddEdgeScrollSpeed: 4,\n\tAddExcalidrawSelectMode: 5,\n\tAddDynamicSizeMode: 6,\n\tAllowSystemColorScheme: 7,\n\tAddPasteAtCursor: 8,\n\tAddKeyboardShortcuts: 9,\n\tAddShowUiLabels: 10,\n} as const\n\nconst CURRENT_VERSION = Math.max(...Object.values(Versions))\n\nfunction migrateSnapshot(data: { version: number; user: any }) {\n\tif (data.version < Versions.AddAnimationSpeed) {\n\t\tdata.user.animationSpeed = 1\n\t}\n\tif (data.version < Versions.AddIsSnapMode) {\n\t\tdata.user.isSnapMode = false\n\t}\n\tif (data.version < Versions.MakeFieldsNullable) {\n\t\t// noop\n\t}\n\tif (data.version < Versions.AddEdgeScrollSpeed) {\n\t\tdata.user.edgeScrollSpeed = 1\n\t}\n\tif (data.version < Versions.AddExcalidrawSelectMode) {\n\t\tdata.user.isWrapMode = false\n\t}\n\tif (data.version < Versions.AllowSystemColorScheme) {\n\t\tif (data.user.isDarkMode === true) {\n\t\t\tdata.user.colorScheme = 'dark'\n\t\t} else if (data.user.isDarkMode === false) {\n\t\t\tdata.user.colorScheme = 'light'\n\t\t}\n\t\tdelete data.user.isDarkMode\n\t}\n\n\tif (data.version < Versions.AddDynamicSizeMode) {\n\t\tdata.user.isDynamicSizeMode = false\n\t}\n\tif (data.version < Versions.AddPasteAtCursor) {\n\t\tdata.user.isPasteAtCursorMode = false\n\t}\n\tif (data.version < Versions.AddKeyboardShortcuts) {\n\t\tdata.user.areKeyboardShortcutsEnabled = true\n\t}\n\tif (data.version < Versions.AddShowUiLabels) {\n\t\tdata.user.showUiLabels = false\n\t}\n\n\t// finally\n\tdata.version = CURRENT_VERSION\n}\n\n/** @internal */\nexport const USER_COLORS = [\n\t'#FF802B',\n\t'#EC5E41',\n\t'#F2555A',\n\t'#F04F88',\n\t'#E34BA9',\n\t'#BD54C6',\n\t'#9D5BD2',\n\t'#7B66DC',\n\t'#02B1CC',\n\t'#11B3A3',\n\t'#39B178',\n\t'#55B467',\n] as const\n\nfunction getRandomColor() {\n\treturn USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)]\n}\n\n/** @internal */\nexport function userPrefersReducedMotion() {\n\tif (typeof window !== 'undefined' && window.matchMedia) {\n\t\treturn window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches ?? false\n\t}\n\n\treturn false\n}\n\n/** @public */\nexport const defaultUserPreferences = Object.freeze({\n\tname: '',\n\tlocale: getDefaultTranslationLocale(),\n\tcolor: getRandomColor(),\n\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tedgeScrollSpeed: 1,\n\tanimationSpeed: userPrefersReducedMotion() ? 0 : 1,\n\tareKeyboardShortcutsEnabled: true,\n\tisSnapMode: false,\n\tisWrapMode: false,\n\tisDynamicSizeMode: false,\n\tisPasteAtCursorMode: false,\n\tshowUiLabels: false,\n\tcolorScheme: 'light',\n}) satisfies Readonly<Omit<TLUserPreferences, 'id'>>\n\n/** @public */\nexport function getFreshUserPreferences(): TLUserPreferences {\n\treturn {\n\t\tid: uniqueId(),\n\t\tcolor: getRandomColor(),\n\t}\n}\n\nfunction migrateUserPreferences(userData: unknown): TLUserPreferences {\n\tif (userData === null || typeof userData !== 'object') {\n\t\treturn getFreshUserPreferences()\n\t}\n\n\tif (!('version' in userData) || !('user' in userData) || typeof userData.version !== 'number') {\n\t\treturn getFreshUserPreferences()\n\t}\n\n\tconst snapshot = structuredClone(userData) as any\n\n\tmigrateSnapshot(snapshot)\n\n\ttry {\n\t\treturn userTypeValidator.validate(snapshot.user)\n\t} catch {\n\t\treturn getFreshUserPreferences()\n\t}\n}\n\nfunction loadUserPreferences(): TLUserPreferences {\n\tconst userData = (JSON.parse(getFromLocalStorage(USER_DATA_KEY) || 'null') ??\n\t\tnull) as null | UserDataSnapshot\n\n\treturn migrateUserPreferences(userData)\n}\n\nconst globalUserPreferences = atom<TLUserPreferences | null>('globalUserData', null)\n\nfunction storeUserPreferences() {\n\tsetInLocalStorage(\n\t\tUSER_DATA_KEY,\n\t\tJSON.stringify({\n\t\t\tversion: CURRENT_VERSION,\n\t\t\tuser: globalUserPreferences.get(),\n\t\t})\n\t)\n}\n\n/** @public */\nexport function setUserPreferences(user: TLUserPreferences) {\n\tuserTypeValidator.validate(user)\n\tglobalUserPreferences.set(user)\n\tstoreUserPreferences()\n\tbroadcastUserPreferencesChange()\n}\n\nconst isTest = typeof process !== 'undefined' && process.env.NODE_ENV === 'test'\n\nconst channel =\n\ttypeof BroadcastChannel !== 'undefined' && !isTest\n\t\t? new BroadcastChannel('tldraw-user-sync')\n\t\t: null\n\nchannel?.addEventListener('message', (e) => {\n\tconst data = e.data as undefined | UserChangeBroadcastMessage\n\tif (data?.type === broadcastEventKey && data?.origin !== getBroadcastOrigin()) {\n\t\tglobalUserPreferences.set(migrateUserPreferences(data.data))\n\t}\n})\n\nlet _broadcastOrigin = null as null | string\nfunction getBroadcastOrigin() {\n\tif (_broadcastOrigin === null) {\n\t\t_broadcastOrigin = uniqueId()\n\t}\n\treturn _broadcastOrigin\n}\nconst broadcastEventKey = 'tldraw-user-preferences-change' as const\n\nfunction broadcastUserPreferencesChange() {\n\tchannel?.postMessage({\n\t\ttype: broadcastEventKey,\n\t\torigin: getBroadcastOrigin(),\n\t\tdata: {\n\t\t\tuser: getUserPreferences(),\n\t\t\tversion: CURRENT_VERSION,\n\t\t},\n\t} satisfies UserChangeBroadcastMessage)\n}\n\n/** @public */\nexport function getUserPreferences(): TLUserPreferences {\n\tlet prefs = globalUserPreferences.get()\n\tif (!prefs) {\n\t\tprefs = loadUserPreferences()\n\t\tsetUserPreferences(prefs)\n\t}\n\treturn prefs\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -57,7 +57,7 @@ class UserPreferencesManager {
|
|
|
57
57
|
__runInitializers(_init, 5, this);
|
|
58
58
|
__publicField(this, "systemColorScheme", atom("systemColorScheme", "light"));
|
|
59
59
|
__publicField(this, "disposables", /* @__PURE__ */ new Set());
|
|
60
|
-
if (typeof window === "undefined" || !
|
|
60
|
+
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
61
61
|
const darkModeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
62
62
|
if (darkModeMediaQuery?.matches) {
|
|
63
63
|
this.systemColorScheme.set("dark");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts"],
|
|
4
|
-
"sourcesContent": ["import { atom, computed } from '@tldraw/state'\nimport { TLUserPreferences, defaultUserPreferences } from '../../../config/TLUserPreferences'\nimport { TLUser } from '../../../config/createTLUser'\n\n/** @public */\nexport class UserPreferencesManager {\n\tsystemColorScheme = atom<'dark' | 'light'>('systemColorScheme', 'light')\n\tdisposables = new Set<() => void>()\n\tdispose() {\n\t\tthis.disposables.forEach((d) => d())\n\t}\n\tconstructor(\n\t\tprivate readonly user: TLUser,\n\t\tprivate readonly inferDarkMode: boolean\n\t) {\n\t\tif (typeof window === 'undefined' || !
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,SAAS,MAAM,gBAAgB;AAC/B,SAA4B,8BAA8B;AAqCzD,2BAAC,WAiBD,sBAAC,WAgBD,2BAAC,WAID,0BAAC,WAID,uCAAC,WAOD,cAAC,WAID,gBAAC,WAID,kBAAC,WAID,iBAAC,WAID,sBAAC,WAID,sBAAC,WAID,+BAAC,WAMD,+BAAC,WAOD,wBAAC;AAtHK,MAAM,uBAAuB;AAAA,EAMnC,YACkB,MACA,eAChB;AAFgB;AACA;AARZ;AACN,6CAAoB,KAAuB,qBAAqB,OAAO;AACvE,uCAAc,oBAAI,IAAgB;AAQjC,QAAI,OAAO,WAAW,eAAe,
|
|
4
|
+
"sourcesContent": ["import { atom, computed } from '@tldraw/state'\nimport { TLUserPreferences, defaultUserPreferences } from '../../../config/TLUserPreferences'\nimport { TLUser } from '../../../config/createTLUser'\n\n/** @public */\nexport class UserPreferencesManager {\n\tsystemColorScheme = atom<'dark' | 'light'>('systemColorScheme', 'light')\n\tdisposables = new Set<() => void>()\n\tdispose() {\n\t\tthis.disposables.forEach((d) => d())\n\t}\n\tconstructor(\n\t\tprivate readonly user: TLUser,\n\t\tprivate readonly inferDarkMode: boolean\n\t) {\n\t\tif (typeof window === 'undefined' || !window.matchMedia) return\n\n\t\tconst darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n\t\tif (darkModeMediaQuery?.matches) {\n\t\t\tthis.systemColorScheme.set('dark')\n\t\t}\n\t\tconst handleChange = (e: MediaQueryListEvent) => {\n\t\t\tif (e.matches) {\n\t\t\t\tthis.systemColorScheme.set('dark')\n\t\t\t} else {\n\t\t\t\tthis.systemColorScheme.set('light')\n\t\t\t}\n\t\t}\n\t\tdarkModeMediaQuery?.addEventListener('change', handleChange)\n\t\tthis.disposables.add(() => darkModeMediaQuery?.removeEventListener('change', handleChange))\n\t}\n\n\tupdateUserPreferences(userPreferences: Partial<TLUserPreferences>) {\n\t\tthis.user.setUserPreferences({\n\t\t\t...this.user.userPreferences.get(),\n\t\t\t...userPreferences,\n\t\t})\n\t}\n\t@computed getUserPreferences() {\n\t\treturn {\n\t\t\tid: this.getId(),\n\t\t\tname: this.getName(),\n\t\t\tlocale: this.getLocale(),\n\t\t\tcolor: this.getColor(),\n\t\t\tanimationSpeed: this.getAnimationSpeed(),\n\t\t\tareKeyboardShortcutsEnabled: this.getAreKeyboardShortcutsEnabled(),\n\t\t\tisSnapMode: this.getIsSnapMode(),\n\t\t\tcolorScheme: this.user.userPreferences.get().colorScheme,\n\t\t\tisDarkMode: this.getIsDarkMode(),\n\t\t\tisWrapMode: this.getIsWrapMode(),\n\t\t\tisDynamicResizeMode: this.getIsDynamicResizeMode(),\n\t\t\tshowUiLabels: this.getShowUiLabels(),\n\t\t}\n\t}\n\n\t@computed getIsDarkMode() {\n\t\tswitch (this.user.userPreferences.get().colorScheme) {\n\t\t\tcase 'dark':\n\t\t\t\treturn true\n\t\t\tcase 'light':\n\t\t\t\treturn false\n\t\t\tcase 'system':\n\t\t\t\treturn this.systemColorScheme.get() === 'dark'\n\t\t\tdefault:\n\t\t\t\treturn this.inferDarkMode ? this.systemColorScheme.get() === 'dark' : false\n\t\t}\n\t}\n\n\t/**\n\t * The speed at which the user can scroll by dragging toward the edge of the screen.\n\t */\n\t@computed getEdgeScrollSpeed() {\n\t\treturn this.user.userPreferences.get().edgeScrollSpeed ?? defaultUserPreferences.edgeScrollSpeed\n\t}\n\n\t@computed getAnimationSpeed() {\n\t\treturn this.user.userPreferences.get().animationSpeed ?? defaultUserPreferences.animationSpeed\n\t}\n\n\t@computed getAreKeyboardShortcutsEnabled() {\n\t\treturn (\n\t\t\tthis.user.userPreferences.get().areKeyboardShortcutsEnabled ??\n\t\t\tdefaultUserPreferences.areKeyboardShortcutsEnabled\n\t\t)\n\t}\n\n\t@computed getId() {\n\t\treturn this.user.userPreferences.get().id\n\t}\n\n\t@computed getName() {\n\t\treturn this.user.userPreferences.get().name?.trim() ?? defaultUserPreferences.name\n\t}\n\n\t@computed getLocale() {\n\t\treturn this.user.userPreferences.get().locale ?? defaultUserPreferences.locale\n\t}\n\n\t@computed getColor() {\n\t\treturn this.user.userPreferences.get().color ?? defaultUserPreferences.color\n\t}\n\n\t@computed getIsSnapMode() {\n\t\treturn this.user.userPreferences.get().isSnapMode ?? defaultUserPreferences.isSnapMode\n\t}\n\n\t@computed getIsWrapMode() {\n\t\treturn this.user.userPreferences.get().isWrapMode ?? defaultUserPreferences.isWrapMode\n\t}\n\n\t@computed getIsDynamicResizeMode() {\n\t\treturn (\n\t\t\tthis.user.userPreferences.get().isDynamicSizeMode ?? defaultUserPreferences.isDynamicSizeMode\n\t\t)\n\t}\n\n\t@computed getIsPasteAtCursorMode() {\n\t\treturn (\n\t\t\tthis.user.userPreferences.get().isPasteAtCursorMode ??\n\t\t\tdefaultUserPreferences.isPasteAtCursorMode\n\t\t)\n\t}\n\n\t@computed getShowUiLabels() {\n\t\treturn this.user.userPreferences.get().showUiLabels ?? defaultUserPreferences.showUiLabels\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -119,6 +119,8 @@ function useCanvasEvents() {
|
|
|
119
119
|
useEffect(() => {
|
|
120
120
|
let lastX, lastY;
|
|
121
121
|
function onPointerMove(e) {
|
|
122
|
+
if (e.isKilled) return;
|
|
123
|
+
e.isKilled = true;
|
|
122
124
|
if (e.clientX === lastX && e.clientY === lastY) return;
|
|
123
125
|
lastX = e.clientX;
|
|
124
126
|
lastY = e.clientY;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/hooks/useCanvasEvents.ts"],
|
|
4
|
-
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport React, { useEffect, useMemo } from 'react'\nimport { RIGHT_MOUSE_BUTTON } from '../constants'\nimport {\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tstopEventPropagation,\n} from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\nimport { useEditor } from './useEditor'\n\nexport function useCanvasEvents() {\n\tconst editor = useEditor()\n\tconst currentTool = useValue('current tool', () => editor.getCurrentTool(), [editor])\n\n\tconst events = useMemo(\n\t\tfunction canvasEvents() {\n\t\t\tfunction onPointerDown(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\n\t\t\t\tif (e.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'right_click',\n\t\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 5) return\n\n\t\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerUp(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\n\t\t\t\treleasePointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerEnter(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })\n\t\t\t}\n\n\t\t\tfunction onPointerLeave(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })\n\t\t\t}\n\n\t\t\tfunction onTouchStart(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tfunction onTouchEnd(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\t// check that e.target is an HTMLElement\n\t\t\t\tif (!(e.target instanceof HTMLElement)) return\n\n\t\t\t\tif (\n\t\t\t\t\te.target.tagName !== 'A' &&\n\t\t\t\t\te.target.tagName !== 'TEXTAREA' &&\n\t\t\t\t\t!e.target.isContentEditable &&\n\t\t\t\t\t// When in EditingShape state, we are actually clicking on a 'DIV'\n\t\t\t\t\t// not A/TEXTAREA/contenteditable element yet. So, to preserve cursor position\n\t\t\t\t\t// for edit mode on mobile we need to not preventDefault.\n\t\t\t\t\t// TODO: Find out if we still need this preventDefault in general though.\n\t\t\t\t\t!(editor.getEditingShape() && e.target.className.includes('tl-text-content'))\n\t\t\t\t) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onDragOver(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tasync function onDrop(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t\tstopEventPropagation(e)\n\n\t\t\t\tif (e.dataTransfer?.files?.length) {\n\t\t\t\t\tconst files = Array.from(e.dataTransfer.files)\n\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'files',\n\t\t\t\t\t\tfiles,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst url = e.dataTransfer.getData('url')\n\t\t\t\tif (url) {\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'url',\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onClick(e: React.MouseEvent) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonPointerDown,\n\t\t\t\tonPointerUp,\n\t\t\t\tonPointerEnter,\n\t\t\t\tonPointerLeave,\n\t\t\t\tonDragOver,\n\t\t\t\tonDrop,\n\t\t\t\tonTouchStart,\n\t\t\t\tonTouchEnd,\n\t\t\t\tonClick,\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\t// onPointerMove is special: where we're only interested in the other events when they're\n\t// happening _on_ the canvas (as opposed to outside of it, or on UI floating over it), we want\n\t// the pointer position to be up to date regardless of whether it's over the tldraw canvas or\n\t// not. So instead of returning a listener to be attached to the canvas, we directly attach a\n\t// listener to the whole document instead.\n\tuseEffect(() => {\n\t\tlet lastX: number, lastY: number\n\n\t\tfunction onPointerMove(e: PointerEvent) {\n\t\t\tif (e.clientX === lastX && e.clientY === lastY) return\n\t\t\tlastX = e.clientX\n\t\t\tlastY = e.clientY\n\n\t\t\t// For tools that benefit from a higher fidelity of events,\n\t\t\t// we dispatch the coalesced events.\n\t\t\t// N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.\n\t\t\tconst events =\n\t\t\t\tcurrentTool.useCoalescedEvents && e.getCoalescedEvents ? e.getCoalescedEvents() : [e]\n\t\t\tfor (const singleEvent of events) {\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t...getPointerInfo(singleEvent),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tdocument.body.addEventListener('pointermove', onPointerMove)\n\t\treturn () => {\n\t\t\tdocument.body.removeEventListener('pointermove', onPointerMove)\n\t\t}\n\t}, [editor, currentTool])\n\n\treturn events\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport React, { useEffect, useMemo } from 'react'\nimport { RIGHT_MOUSE_BUTTON } from '../constants'\nimport {\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tstopEventPropagation,\n} from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\nimport { useEditor } from './useEditor'\n\nexport function useCanvasEvents() {\n\tconst editor = useEditor()\n\tconst currentTool = useValue('current tool', () => editor.getCurrentTool(), [editor])\n\n\tconst events = useMemo(\n\t\tfunction canvasEvents() {\n\t\t\tfunction onPointerDown(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\n\t\t\t\tif (e.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'right_click',\n\t\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 5) return\n\n\t\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerUp(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\n\t\t\t\treleasePointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerEnter(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })\n\t\t\t}\n\n\t\t\tfunction onPointerLeave(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })\n\t\t\t}\n\n\t\t\tfunction onTouchStart(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tfunction onTouchEnd(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\t// check that e.target is an HTMLElement\n\t\t\t\tif (!(e.target instanceof HTMLElement)) return\n\n\t\t\t\tif (\n\t\t\t\t\te.target.tagName !== 'A' &&\n\t\t\t\t\te.target.tagName !== 'TEXTAREA' &&\n\t\t\t\t\t!e.target.isContentEditable &&\n\t\t\t\t\t// When in EditingShape state, we are actually clicking on a 'DIV'\n\t\t\t\t\t// not A/TEXTAREA/contenteditable element yet. So, to preserve cursor position\n\t\t\t\t\t// for edit mode on mobile we need to not preventDefault.\n\t\t\t\t\t// TODO: Find out if we still need this preventDefault in general though.\n\t\t\t\t\t!(editor.getEditingShape() && e.target.className.includes('tl-text-content'))\n\t\t\t\t) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onDragOver(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tasync function onDrop(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t\tstopEventPropagation(e)\n\n\t\t\t\tif (e.dataTransfer?.files?.length) {\n\t\t\t\t\tconst files = Array.from(e.dataTransfer.files)\n\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'files',\n\t\t\t\t\t\tfiles,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst url = e.dataTransfer.getData('url')\n\t\t\t\tif (url) {\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'url',\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onClick(e: React.MouseEvent) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonPointerDown,\n\t\t\t\tonPointerUp,\n\t\t\t\tonPointerEnter,\n\t\t\t\tonPointerLeave,\n\t\t\t\tonDragOver,\n\t\t\t\tonDrop,\n\t\t\t\tonTouchStart,\n\t\t\t\tonTouchEnd,\n\t\t\t\tonClick,\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\t// onPointerMove is special: where we're only interested in the other events when they're\n\t// happening _on_ the canvas (as opposed to outside of it, or on UI floating over it), we want\n\t// the pointer position to be up to date regardless of whether it's over the tldraw canvas or\n\t// not. So instead of returning a listener to be attached to the canvas, we directly attach a\n\t// listener to the whole document instead.\n\tuseEffect(() => {\n\t\tlet lastX: number, lastY: number\n\n\t\tfunction onPointerMove(e: PointerEvent) {\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tif (e.clientX === lastX && e.clientY === lastY) return\n\t\t\tlastX = e.clientX\n\t\t\tlastY = e.clientY\n\n\t\t\t// For tools that benefit from a higher fidelity of events,\n\t\t\t// we dispatch the coalesced events.\n\t\t\t// N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.\n\t\t\tconst events =\n\t\t\t\tcurrentTool.useCoalescedEvents && e.getCoalescedEvents ? e.getCoalescedEvents() : [e]\n\t\t\tfor (const singleEvent of events) {\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t...getPointerInfo(singleEvent),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tdocument.body.addEventListener('pointermove', onPointerMove)\n\t\treturn () => {\n\t\t\tdocument.body.removeEventListener('pointermove', onPointerMove)\n\t\t}\n\t}, [editor, currentTool])\n\n\treturn events\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAgB,WAAW,eAAe;AAC1C,SAAS,0BAA0B;AACnC;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB;AAEnB,SAAS,kBAAkB;AACjC,QAAM,SAAS,UAAU;AACzB,QAAM,cAAc,SAAS,gBAAgB,MAAM,OAAO,eAAe,GAAG,CAAC,MAAM,CAAC;AAEpF,QAAM,SAAS;AAAA,IACd,SAAS,eAAe;AACvB,eAAS,cAAc,GAAuB;AAC7C,YAAK,EAAU,SAAU;AAEzB,YAAI,EAAE,WAAW,oBAAoB;AACpC,iBAAO,SAAS;AAAA,YACf,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,GAAG,eAAe,CAAC;AAAA,UACpB,CAAC;AACD;AAAA,QACD;AAEA,YAAI,EAAE,WAAW,KAAK,EAAE,WAAW,KAAK,EAAE,WAAW,EAAG;AAExD,0BAAkB,EAAE,eAAe,CAAC;AAEpC,eAAO,SAAS;AAAA,UACf,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,GAAG,eAAe,CAAC;AAAA,QACpB,CAAC;AAAA,MACF;AAEA,eAAS,YAAY,GAAuB;AAC3C,YAAK,EAAU,SAAU;AACzB,YAAI,EAAE,WAAW,KAAK,EAAE,WAAW,KAAK,EAAE,WAAW,KAAK,EAAE,WAAW,EAAG;AAE1E,8BAAsB,EAAE,eAAe,CAAC;AAExC,eAAO,SAAS;AAAA,UACf,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,GAAG,eAAe,CAAC;AAAA,QACpB,CAAC;AAAA,MACF;AAEA,eAAS,eAAe,GAAuB;AAC9C,YAAK,EAAU,SAAU;AACzB,YAAI,OAAO,iBAAiB,EAAE,aAAa,EAAE,gBAAgB,MAAO;AACpE,cAAM,WAAW,EAAE,gBAAgB,WAAW,EAAE,gBAAgB;AAChE,eAAO,oBAAoB,EAAE,kBAAkB,WAAW,OAAO,KAAK,CAAC;AAAA,MACxE;AAEA,eAAS,eAAe,GAAuB;AAC9C,YAAK,EAAU,SAAU;AACzB,YAAI,OAAO,iBAAiB,EAAE,aAAa,EAAE,gBAAgB,MAAO;AACpE,cAAM,WAAW,EAAE,gBAAgB,WAAW,EAAE,gBAAgB;AAChE,eAAO,oBAAoB,EAAE,kBAAkB,WAAW,QAAQ,KAAK,CAAC;AAAA,MACzE;AAEA,eAAS,aAAa,GAAqB;AAC1C;AAAC,QAAC,EAAU,WAAW;AACvB,uBAAe,CAAC;AAAA,MACjB;AAEA,eAAS,WAAW,GAAqB;AACxC;AAAC,QAAC,EAAU,WAAW;AAEvB,YAAI,EAAE,EAAE,kBAAkB,aAAc;AAExC,YACC,EAAE,OAAO,YAAY,OACrB,EAAE,OAAO,YAAY,cACrB,CAAC,EAAE,OAAO;AAAA;AAAA;AAAA;AAAA,QAKV,EAAE,OAAO,gBAAgB,KAAK,EAAE,OAAO,UAAU,SAAS,iBAAiB,IAC1E;AACD,yBAAe,CAAC;AAAA,QACjB;AAAA,MACD;AAEA,eAAS,WAAW,GAA6B;AAChD,uBAAe,CAAC;AAAA,MACjB;AAEA,qBAAe,OAAO,GAA6B;AAClD,uBAAe,CAAC;AAChB,6BAAqB,CAAC;AAEtB,YAAI,EAAE,cAAc,OAAO,QAAQ;AAClC,gBAAM,QAAQ,MAAM,KAAK,EAAE,aAAa,KAAK;AAE7C,gBAAM,OAAO,mBAAmB;AAAA,YAC/B,MAAM;AAAA,YACN;AAAA,YACA,OAAO,OAAO,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,CAAC;AAAA,UAC1D,CAAC;AACD;AAAA,QACD;AAEA,cAAM,MAAM,EAAE,aAAa,QAAQ,KAAK;AACxC,YAAI,KAAK;AACR,gBAAM,OAAO,mBAAmB;AAAA,YAC/B,MAAM;AAAA,YACN;AAAA,YACA,OAAO,OAAO,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,CAAC;AAAA,UAC1D,CAAC;AACD;AAAA,QACD;AAAA,MACD;AAEA,eAAS,QAAQ,GAAqB;AACrC,6BAAqB,CAAC;AAAA,MACvB;AAEA,aAAO;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AAOA,YAAU,MAAM;AACf,QAAI,OAAe;AAEnB,aAAS,cAAc,GAAiB;AACvC,UAAK,EAAU,SAAU;AACxB,MAAC,EAAU,WAAW;AAEvB,UAAI,EAAE,YAAY,SAAS,EAAE,YAAY,MAAO;AAChD,cAAQ,EAAE;AACV,cAAQ,EAAE;AAKV,YAAMA,UACL,YAAY,sBAAsB,EAAE,qBAAqB,EAAE,mBAAmB,IAAI,CAAC,CAAC;AACrF,iBAAW,eAAeA,SAAQ;AACjC,eAAO,SAAS;AAAA,UACf,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,GAAG,eAAe,WAAW;AAAA,QAC9B,CAAC;AAAA,MACF;AAAA,IACD;AAEA,aAAS,KAAK,iBAAiB,eAAe,aAAa;AAC3D,WAAO,MAAM;AACZ,eAAS,KAAK,oBAAoB,eAAe,aAAa;AAAA,IAC/D;AAAA,EACD,GAAG,CAAC,QAAQ,WAAW,CAAC;AAExB,SAAO;AACR;",
|
|
6
6
|
"names": ["events"]
|
|
7
7
|
}
|