tldraw 3.16.0-canary.f293c3bb58f5 → 3.16.0-canary.f55016ece635

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist-cjs/index.d.ts +17 -0
  2. package/dist-cjs/index.js +5 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/Tldraw.js +12 -2
  5. package/dist-cjs/lib/Tldraw.js.map +2 -2
  6. package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -4
  7. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  8. package/dist-cjs/lib/ui/TldrawUi.js +13 -12
  9. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  10. package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
  11. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
  12. package/dist-cjs/lib/ui/context/components.js +2 -0
  13. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  14. package/dist-cjs/lib/ui/version.js +3 -3
  15. package/dist-cjs/lib/ui/version.js.map +1 -1
  16. package/dist-esm/index.d.mts +17 -0
  17. package/dist-esm/index.mjs +7 -2
  18. package/dist-esm/index.mjs.map +2 -2
  19. package/dist-esm/lib/Tldraw.mjs +14 -4
  20. package/dist-esm/lib/Tldraw.mjs.map +2 -2
  21. package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -4
  22. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  23. package/dist-esm/lib/ui/TldrawUi.mjs +13 -12
  24. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  25. package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
  26. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
  27. package/dist-esm/lib/ui/context/components.mjs +2 -0
  28. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  29. package/dist-esm/lib/ui/version.mjs +3 -3
  30. package/dist-esm/lib/ui/version.mjs.map +1 -1
  31. package/package.json +3 -3
  32. package/src/index.ts +3 -1
  33. package/src/lib/Tldraw.tsx +15 -2
  34. package/src/lib/defaultExternalContentHandlers.ts +12 -4
  35. package/src/lib/ui/TldrawUi.tsx +16 -10
  36. package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
  37. package/src/lib/ui/context/components.tsx +3 -0
  38. package/src/lib/ui/version.ts +3 -3
  39. package/tldraw.css +8 -0
  40. package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
  41. package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/Tldraw.tsx"],
4
- "sourcesContent": ["import {\n\tDEFAULT_SUPPORTED_IMAGE_TYPES,\n\tDEFAULT_SUPPORT_VIDEO_TYPES,\n\tTLEditorComponents,\n\tTLOnMountHandler,\n\tTLTextOptions,\n\tTldrawEditor,\n\tTldrawEditorBaseProps,\n\tTldrawEditorStoreProps,\n\tdefaultUserPreferences,\n\tmergeArraysAndReplaceDefaults,\n\tuseEditor,\n\tuseEditorComponents,\n\tuseOnMount,\n\tuseShallowArrayIdentity,\n\tuseShallowObjectIdentity,\n} from '@tldraw/editor'\nimport { useMemo } from 'react'\nimport { TldrawHandles } from './canvas/TldrawHandles'\nimport { TldrawOverlays } from './canvas/TldrawOverlays'\nimport { TldrawScribble } from './canvas/TldrawScribble'\nimport { TldrawSelectionForeground } from './canvas/TldrawSelectionForeground'\nimport { TldrawShapeIndicators } from './canvas/TldrawShapeIndicators'\nimport { defaultBindingUtils } from './defaultBindingUtils'\nimport { TLEmbedDefinition } from './defaultEmbedDefinitions'\nimport {\n\tTLExternalContentProps,\n\tregisterDefaultExternalContentHandlers,\n} from './defaultExternalContentHandlers'\nimport { defaultShapeTools } from './defaultShapeTools'\nimport { defaultShapeUtils } from './defaultShapeUtils'\nimport { registerDefaultSideEffects } from './defaultSideEffects'\nimport { defaultTools } from './defaultTools'\nimport { EmbedShapeUtil } from './shapes/embed/EmbedShapeUtil'\nimport { allDefaultFontFaces } from './shapes/shared/defaultFonts'\nimport { TldrawUi, TldrawUiProps } from './ui/TldrawUi'\nimport { TLUiAssetUrlOverrides, useDefaultUiAssetUrlsWithOverrides } from './ui/assetUrls'\nimport { LoadingScreen } from './ui/components/LoadingScreen'\nimport { Spinner } from './ui/components/Spinner'\nimport { AssetUrlsProvider } from './ui/context/asset-urls'\nimport { TLUiComponents, useTldrawUiComponents } from './ui/context/components'\nimport { useUiEvents } from './ui/context/events'\nimport { useToasts } from './ui/context/toasts'\nimport {\n\tTldrawUiTranslationProvider,\n\tuseTranslation,\n} from './ui/hooks/useTranslation/useTranslation'\nimport { useMergedTranslationOverrides } from './ui/overrides'\nimport { useDefaultEditorAssetsWithOverrides } from './utils/static-assets/assetUrls'\nimport { defaultAddFontsFromNode, tipTapDefaultExtensions } from './utils/text/richText'\n\n/**\n * Override the default react components used by the editor and UI. Set components to null to\n * disable them entirely.\n *\n * @example\n * ```tsx\n * import {Tldraw, TLComponents} from 'tldraw'\n *\n * const components: TLComponents = {\n * Scribble: MyCustomScribble,\n * }\n *\n * export function MyApp() {\n * return <Tldraw components={components} />\n * }\n * ```\n *\n *\n * @public\n */\nexport interface TLComponents extends TLEditorComponents, TLUiComponents {}\n\n/** @public */\nexport interface TldrawBaseProps\n\textends TldrawUiProps,\n\t\tTldrawEditorBaseProps,\n\t\tTLExternalContentProps {\n\t/** Urls for custom assets.\n\t *\n\t * \u26A0\uFE0E Important! This must be memoized (with useMemo) or defined outside of any React component.\n\t */\n\tassetUrls?: TLUiAssetUrlOverrides\n\t/** Overrides for tldraw's components.\n\t *\n\t * \u26A0\uFE0E Important! This must be memoized (with useMemo) or defined outside of any React component.\n\t */\n\tcomponents?: TLComponents\n\t/** Custom definitions for tldraw's embeds.\n\t *\n\t * \u26A0\uFE0E Important! This must be memoized (with useMemo) or defined outside of any React component.\n\t */\n\tembeds?: TLEmbedDefinition[]\n}\n\n/** @public */\nexport type TldrawProps = TldrawBaseProps & TldrawEditorStoreProps\n\nconst allDefaultTools = [...defaultTools, ...defaultShapeTools]\n\n/** @public @react */\nexport function Tldraw(props: TldrawProps) {\n\tconst {\n\t\tchildren,\n\t\tmaxImageDimension,\n\t\tmaxAssetSize,\n\t\tacceptedImageMimeTypes,\n\t\tacceptedVideoMimeTypes,\n\t\tonMount,\n\t\tcomponents = {},\n\t\tshapeUtils = [],\n\t\tbindingUtils = [],\n\t\ttools = [],\n\t\tembeds,\n\t\ttextOptions,\n\t\t...rest\n\t} = props\n\n\tconst _components = useShallowObjectIdentity(components)\n\n\tconst componentsWithDefault = useMemo(\n\t\t() => ({\n\t\t\tScribble: TldrawScribble,\n\t\t\tShapeIndicators: TldrawShapeIndicators,\n\t\t\tCollaboratorScribble: TldrawScribble,\n\t\t\tSelectionForeground: TldrawSelectionForeground,\n\t\t\tHandles: TldrawHandles,\n\t\t\tOverlays: TldrawOverlays,\n\t\t\tSpinner,\n\t\t\tLoadingScreen,\n\t\t\t..._components,\n\t\t}),\n\t\t[_components]\n\t)\n\n\tconst _shapeUtils = useShallowArrayIdentity(shapeUtils)\n\tconst shapeUtilsWithDefaults = useMemo(\n\t\t() => mergeArraysAndReplaceDefaults('type', _shapeUtils, defaultShapeUtils),\n\t\t[_shapeUtils]\n\t)\n\n\tconst _bindingUtils = useShallowArrayIdentity(bindingUtils)\n\tconst bindingUtilsWithDefaults = useMemo(\n\t\t() => mergeArraysAndReplaceDefaults('type', _bindingUtils, defaultBindingUtils),\n\t\t[_bindingUtils]\n\t)\n\n\tconst _tools = useShallowArrayIdentity(tools)\n\tconst toolsWithDefaults = useMemo(\n\t\t() => mergeArraysAndReplaceDefaults('id', _tools, allDefaultTools),\n\t\t[_tools]\n\t)\n\n\tconst _imageMimeTypes = useShallowArrayIdentity(\n\t\tacceptedImageMimeTypes ?? DEFAULT_SUPPORTED_IMAGE_TYPES\n\t)\n\tconst _videoMimeTypes = useShallowArrayIdentity(\n\t\tacceptedVideoMimeTypes ?? DEFAULT_SUPPORT_VIDEO_TYPES\n\t)\n\n\tconst textOptionsWithDefaults = useMemo((): TLTextOptions => {\n\t\treturn {\n\t\t\taddFontsFromNode: defaultAddFontsFromNode,\n\t\t\t...textOptions,\n\t\t\ttipTapConfig: {\n\t\t\t\textensions: tipTapDefaultExtensions,\n\t\t\t\t...textOptions?.tipTapConfig,\n\t\t\t},\n\t\t}\n\t}, [textOptions])\n\n\tconst mediaMimeTypes = useMemo(\n\t\t() => [..._imageMimeTypes, ..._videoMimeTypes],\n\t\t[_imageMimeTypes, _videoMimeTypes]\n\t)\n\n\tconst assets = useDefaultEditorAssetsWithOverrides(rest.assetUrls)\n\n\tconst embedShapeUtil = shapeUtilsWithDefaults.find((util) => util.type === 'embed')\n\tif (embedShapeUtil && embeds) {\n\t\tEmbedShapeUtil.setEmbedDefinitions(embeds)\n\t}\n\n\treturn (\n\t\t// We provide an extra higher layer of asset+translations providers here so that\n\t\t// loading UI (which is rendered outside of TldrawUi) may be translated.\n\t\t// Ideally we would refactor to hoist all the UI context providers we can up here. Maybe later.\n\t\t<AssetUrlsProvider assetUrls={useDefaultUiAssetUrlsWithOverrides(rest.assetUrls)}>\n\t\t\t<TldrawUiTranslationProvider\n\t\t\t\toverrides={useMergedTranslationOverrides(rest.overrides)}\n\t\t\t\tlocale={rest.user?.userPreferences.get().locale ?? defaultUserPreferences.locale}\n\t\t\t>\n\t\t\t\t<TldrawEditor\n\t\t\t\t\tinitialState=\"select\"\n\t\t\t\t\t{...rest}\n\t\t\t\t\tcomponents={componentsWithDefault}\n\t\t\t\t\tshapeUtils={shapeUtilsWithDefaults}\n\t\t\t\t\tbindingUtils={bindingUtilsWithDefaults}\n\t\t\t\t\ttools={toolsWithDefaults}\n\t\t\t\t\ttextOptions={textOptionsWithDefaults}\n\t\t\t\t\tassetUrls={assets}\n\t\t\t\t>\n\t\t\t\t\t<TldrawUi {...rest} components={componentsWithDefault} mediaMimeTypes={mediaMimeTypes}>\n\t\t\t\t\t\t<InsideOfEditorAndUiContext\n\t\t\t\t\t\t\tmaxImageDimension={maxImageDimension}\n\t\t\t\t\t\t\tmaxAssetSize={maxAssetSize}\n\t\t\t\t\t\t\tacceptedImageMimeTypes={_imageMimeTypes}\n\t\t\t\t\t\t\tacceptedVideoMimeTypes={_videoMimeTypes}\n\t\t\t\t\t\t\tonMount={onMount}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</TldrawUi>\n\t\t\t\t</TldrawEditor>\n\t\t\t</TldrawUiTranslationProvider>\n\t\t</AssetUrlsProvider>\n\t)\n}\n\n// We put these hooks into a component here so that they can run inside of the context provided by TldrawEditor and TldrawUi.\nfunction InsideOfEditorAndUiContext({\n\tmaxImageDimension,\n\tmaxAssetSize,\n\tacceptedImageMimeTypes,\n\tacceptedVideoMimeTypes,\n\tonMount,\n}: TLExternalContentProps & {\n\tonMount?: TLOnMountHandler\n}) {\n\tconst editor = useEditor()\n\tconst toasts = useToasts()\n\tconst msg = useTranslation()\n\tconst trackEvent = useUiEvents()\n\n\tuseOnMount(() => {\n\t\tconst unsubs: (void | (() => void) | undefined)[] = []\n\n\t\tunsubs.push(registerDefaultSideEffects(editor))\n\n\t\t// now that the editor has mounted (and presumably pre-loaded the fonts actually in use in\n\t\t// the document), we want to preload the other default font faces in the background. These\n\t\t// won't be directly used, but mean that when adding text the user can switch between fonts\n\t\t// quickly, without having to wait for them to load in.\n\t\teditor.fonts.requestFonts(allDefaultFontFaces)\n\n\t\teditor.once('edit', () => trackEvent('edit', { source: 'unknown' }))\n\n\t\t// for content handling, first we register the default handlers...\n\t\tregisterDefaultExternalContentHandlers(editor, {\n\t\t\tmaxImageDimension,\n\t\t\tmaxAssetSize,\n\t\t\tacceptedImageMimeTypes,\n\t\t\tacceptedVideoMimeTypes,\n\t\t\ttoasts,\n\t\t\tmsg,\n\t\t})\n\n\t\t// ...then we call the store's on mount which may override them...\n\t\tunsubs.push(editor.store.props.onMount(editor))\n\n\t\t// ...then we run the user's onMount prop, which may override things again.\n\t\tunsubs.push(onMount?.(editor))\n\n\t\treturn () => {\n\t\t\tunsubs.forEach((fn) => fn?.())\n\t\t}\n\t})\n\n\tconst { Canvas } = useEditorComponents()\n\tconst { ContextMenu } = useTldrawUiComponents()\n\n\tif (ContextMenu) {\n\t\t// should wrap canvas\n\t\treturn <ContextMenu />\n\t}\n\n\tif (Canvas) {\n\t\treturn <Canvas />\n\t}\n\n\treturn null\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tDEFAULT_SUPPORTED_IMAGE_TYPES,\n\tDEFAULT_SUPPORT_VIDEO_TYPES,\n\tTLEditorComponents,\n\tTLOnMountHandler,\n\tTLTextOptions,\n\tTldrawEditor,\n\tTldrawEditorBaseProps,\n\tTldrawEditorStoreProps,\n\tdefaultUserPreferences,\n\tmergeArraysAndReplaceDefaults,\n\tuseEditor,\n\tuseEditorComponents,\n\tuseOnMount,\n\tuseShallowArrayIdentity,\n\tuseShallowObjectIdentity,\n} from '@tldraw/editor'\nimport { useMemo } from 'react'\nimport { TldrawHandles } from './canvas/TldrawHandles'\nimport { TldrawOverlays } from './canvas/TldrawOverlays'\nimport { TldrawScribble } from './canvas/TldrawScribble'\nimport { TldrawSelectionForeground } from './canvas/TldrawSelectionForeground'\nimport { TldrawShapeIndicators } from './canvas/TldrawShapeIndicators'\nimport { defaultBindingUtils } from './defaultBindingUtils'\nimport { TLEmbedDefinition } from './defaultEmbedDefinitions'\nimport {\n\tTLExternalContentProps,\n\tregisterDefaultExternalContentHandlers,\n} from './defaultExternalContentHandlers'\nimport { defaultShapeTools } from './defaultShapeTools'\nimport { defaultShapeUtils } from './defaultShapeUtils'\nimport { registerDefaultSideEffects } from './defaultSideEffects'\nimport { defaultTools } from './defaultTools'\nimport { EmbedShapeUtil } from './shapes/embed/EmbedShapeUtil'\nimport { allDefaultFontFaces } from './shapes/shared/defaultFonts'\nimport { TldrawUi, TldrawUiInFrontOfTheCanvas, TldrawUiProps } from './ui/TldrawUi'\nimport { TLUiAssetUrlOverrides, useDefaultUiAssetUrlsWithOverrides } from './ui/assetUrls'\nimport { LoadingScreen } from './ui/components/LoadingScreen'\nimport { Spinner } from './ui/components/Spinner'\nimport { AssetUrlsProvider } from './ui/context/asset-urls'\nimport { TLUiComponents, useTldrawUiComponents } from './ui/context/components'\nimport { useUiEvents } from './ui/context/events'\nimport { useToasts } from './ui/context/toasts'\nimport {\n\tTldrawUiTranslationProvider,\n\tuseTranslation,\n} from './ui/hooks/useTranslation/useTranslation'\nimport { useMergedTranslationOverrides } from './ui/overrides'\nimport { useDefaultEditorAssetsWithOverrides } from './utils/static-assets/assetUrls'\nimport { defaultAddFontsFromNode, tipTapDefaultExtensions } from './utils/text/richText'\n\n/**\n * Override the default react components used by the editor and UI. Set components to null to\n * disable them entirely.\n *\n * @example\n * ```tsx\n * import {Tldraw, TLComponents} from 'tldraw'\n *\n * const components: TLComponents = {\n * Scribble: MyCustomScribble,\n * }\n *\n * export function MyApp() {\n * return <Tldraw components={components} />\n * }\n * ```\n *\n *\n * @public\n */\nexport interface TLComponents extends TLEditorComponents, TLUiComponents {}\n\n/** @public */\nexport interface TldrawBaseProps\n\textends TldrawUiProps,\n\t\tTldrawEditorBaseProps,\n\t\tTLExternalContentProps {\n\t/** Urls for custom assets.\n\t *\n\t * \u26A0\uFE0E Important! This must be memoized (with useMemo) or defined outside of any React component.\n\t */\n\tassetUrls?: TLUiAssetUrlOverrides\n\t/** Overrides for tldraw's components.\n\t *\n\t * \u26A0\uFE0E Important! This must be memoized (with useMemo) or defined outside of any React component.\n\t */\n\tcomponents?: TLComponents\n\t/** Custom definitions for tldraw's embeds.\n\t *\n\t * \u26A0\uFE0E Important! This must be memoized (with useMemo) or defined outside of any React component.\n\t */\n\tembeds?: TLEmbedDefinition[]\n}\n\n/** @public */\nexport type TldrawProps = TldrawBaseProps & TldrawEditorStoreProps\n\nconst allDefaultTools = [...defaultTools, ...defaultShapeTools]\n\n/** @public @react */\nexport function Tldraw(props: TldrawProps) {\n\tconst {\n\t\tchildren,\n\t\tmaxImageDimension,\n\t\tmaxAssetSize,\n\t\tacceptedImageMimeTypes,\n\t\tacceptedVideoMimeTypes,\n\t\tonMount,\n\t\tcomponents = {},\n\t\tshapeUtils = [],\n\t\tbindingUtils = [],\n\t\ttools = [],\n\t\tembeds,\n\t\ttextOptions,\n\t\t...rest\n\t} = props\n\n\tconst _components = useShallowObjectIdentity(components)\n\n\tconst CustomInFrontOfTheCanvas = components?.InFrontOfTheCanvas\n\tconst InFrontOfTheCanvas = useMemo(() => {\n\t\tif (rest.hideUi) return CustomInFrontOfTheCanvas ?? null\n\t\tif (!CustomInFrontOfTheCanvas) return TldrawUiInFrontOfTheCanvas\n\n\t\treturn () => (\n\t\t\t<>\n\t\t\t\t<TldrawUiInFrontOfTheCanvas />\n\t\t\t\t<CustomInFrontOfTheCanvas />\n\t\t\t</>\n\t\t)\n\t}, [rest.hideUi, CustomInFrontOfTheCanvas])\n\tconst componentsWithDefault = useMemo(\n\t\t() => ({\n\t\t\tScribble: TldrawScribble,\n\t\t\tShapeIndicators: TldrawShapeIndicators,\n\t\t\tCollaboratorScribble: TldrawScribble,\n\t\t\tSelectionForeground: TldrawSelectionForeground,\n\t\t\tHandles: TldrawHandles,\n\t\t\tOverlays: TldrawOverlays,\n\t\t\tSpinner,\n\t\t\tLoadingScreen,\n\t\t\t..._components,\n\t\t\tInFrontOfTheCanvas,\n\t\t}),\n\t\t[_components, InFrontOfTheCanvas]\n\t)\n\n\tconst _shapeUtils = useShallowArrayIdentity(shapeUtils)\n\tconst shapeUtilsWithDefaults = useMemo(\n\t\t() => mergeArraysAndReplaceDefaults('type', _shapeUtils, defaultShapeUtils),\n\t\t[_shapeUtils]\n\t)\n\n\tconst _bindingUtils = useShallowArrayIdentity(bindingUtils)\n\tconst bindingUtilsWithDefaults = useMemo(\n\t\t() => mergeArraysAndReplaceDefaults('type', _bindingUtils, defaultBindingUtils),\n\t\t[_bindingUtils]\n\t)\n\n\tconst _tools = useShallowArrayIdentity(tools)\n\tconst toolsWithDefaults = useMemo(\n\t\t() => mergeArraysAndReplaceDefaults('id', _tools, allDefaultTools),\n\t\t[_tools]\n\t)\n\n\tconst _imageMimeTypes = useShallowArrayIdentity(\n\t\tacceptedImageMimeTypes ?? DEFAULT_SUPPORTED_IMAGE_TYPES\n\t)\n\tconst _videoMimeTypes = useShallowArrayIdentity(\n\t\tacceptedVideoMimeTypes ?? DEFAULT_SUPPORT_VIDEO_TYPES\n\t)\n\n\tconst textOptionsWithDefaults = useMemo((): TLTextOptions => {\n\t\treturn {\n\t\t\taddFontsFromNode: defaultAddFontsFromNode,\n\t\t\t...textOptions,\n\t\t\ttipTapConfig: {\n\t\t\t\textensions: tipTapDefaultExtensions,\n\t\t\t\t...textOptions?.tipTapConfig,\n\t\t\t},\n\t\t}\n\t}, [textOptions])\n\n\tconst mediaMimeTypes = useMemo(\n\t\t() => [..._imageMimeTypes, ..._videoMimeTypes],\n\t\t[_imageMimeTypes, _videoMimeTypes]\n\t)\n\n\tconst assets = useDefaultEditorAssetsWithOverrides(rest.assetUrls)\n\n\tconst embedShapeUtil = shapeUtilsWithDefaults.find((util) => util.type === 'embed')\n\tif (embedShapeUtil && embeds) {\n\t\tEmbedShapeUtil.setEmbedDefinitions(embeds)\n\t}\n\n\treturn (\n\t\t// We provide an extra higher layer of asset+translations providers here so that\n\t\t// loading UI (which is rendered outside of TldrawUi) may be translated.\n\t\t// Ideally we would refactor to hoist all the UI context providers we can up here. Maybe later.\n\t\t<AssetUrlsProvider assetUrls={useDefaultUiAssetUrlsWithOverrides(rest.assetUrls)}>\n\t\t\t<TldrawUiTranslationProvider\n\t\t\t\toverrides={useMergedTranslationOverrides(rest.overrides)}\n\t\t\t\tlocale={rest.user?.userPreferences.get().locale ?? defaultUserPreferences.locale}\n\t\t\t>\n\t\t\t\t<TldrawEditor\n\t\t\t\t\tinitialState=\"select\"\n\t\t\t\t\t{...rest}\n\t\t\t\t\tcomponents={componentsWithDefault}\n\t\t\t\t\tshapeUtils={shapeUtilsWithDefaults}\n\t\t\t\t\tbindingUtils={bindingUtilsWithDefaults}\n\t\t\t\t\ttools={toolsWithDefaults}\n\t\t\t\t\ttextOptions={textOptionsWithDefaults}\n\t\t\t\t\tassetUrls={assets}\n\t\t\t\t>\n\t\t\t\t\t<TldrawUi {...rest} components={componentsWithDefault} mediaMimeTypes={mediaMimeTypes}>\n\t\t\t\t\t\t<InsideOfEditorAndUiContext\n\t\t\t\t\t\t\tmaxImageDimension={maxImageDimension}\n\t\t\t\t\t\t\tmaxAssetSize={maxAssetSize}\n\t\t\t\t\t\t\tacceptedImageMimeTypes={_imageMimeTypes}\n\t\t\t\t\t\t\tacceptedVideoMimeTypes={_videoMimeTypes}\n\t\t\t\t\t\t\tonMount={onMount}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</TldrawUi>\n\t\t\t\t</TldrawEditor>\n\t\t\t</TldrawUiTranslationProvider>\n\t\t</AssetUrlsProvider>\n\t)\n}\n\n// We put these hooks into a component here so that they can run inside of the context provided by TldrawEditor and TldrawUi.\nfunction InsideOfEditorAndUiContext({\n\tmaxImageDimension,\n\tmaxAssetSize,\n\tacceptedImageMimeTypes,\n\tacceptedVideoMimeTypes,\n\tonMount,\n}: TLExternalContentProps & {\n\tonMount?: TLOnMountHandler\n}) {\n\tconst editor = useEditor()\n\tconst toasts = useToasts()\n\tconst msg = useTranslation()\n\tconst trackEvent = useUiEvents()\n\n\tuseOnMount(() => {\n\t\tconst unsubs: (void | (() => void) | undefined)[] = []\n\n\t\tunsubs.push(registerDefaultSideEffects(editor))\n\n\t\t// now that the editor has mounted (and presumably pre-loaded the fonts actually in use in\n\t\t// the document), we want to preload the other default font faces in the background. These\n\t\t// won't be directly used, but mean that when adding text the user can switch between fonts\n\t\t// quickly, without having to wait for them to load in.\n\t\teditor.fonts.requestFonts(allDefaultFontFaces)\n\n\t\teditor.once('edit', () => trackEvent('edit', { source: 'unknown' }))\n\n\t\t// for content handling, first we register the default handlers...\n\t\tregisterDefaultExternalContentHandlers(editor, {\n\t\t\tmaxImageDimension,\n\t\t\tmaxAssetSize,\n\t\t\tacceptedImageMimeTypes,\n\t\t\tacceptedVideoMimeTypes,\n\t\t\ttoasts,\n\t\t\tmsg,\n\t\t})\n\n\t\t// ...then we call the store's on mount which may override them...\n\t\tunsubs.push(editor.store.props.onMount(editor))\n\n\t\t// ...then we run the user's onMount prop, which may override things again.\n\t\tunsubs.push(onMount?.(editor))\n\n\t\treturn () => {\n\t\t\tunsubs.forEach((fn) => fn?.())\n\t\t}\n\t})\n\n\tconst { Canvas } = useEditorComponents()\n\tconst { ContextMenu } = useTldrawUiComponents()\n\n\tif (ContextMenu) {\n\t\t// should wrap canvas\n\t\treturn <ContextMenu />\n\t}\n\n\tif (Canvas) {\n\t\treturn <Canvas />\n\t}\n\n\treturn null\n}\n"],
5
+ "mappings": "AA8HG,mBACC,KADD;AA9HH;AAAA,EACC;AAAA,EACA;AAAA,EAIA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,iCAAiC;AAC1C,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AAEpC;AAAA,EAEC;AAAA,OACM;AACP,SAAS,yBAAyB;AAClC,SAAS,yBAAyB;AAClC,SAAS,kCAAkC;AAC3C,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,UAAU,kCAAiD;AACpE,SAAgC,0CAA0C;AAC1E,SAAS,qBAAqB;AAC9B,SAAS,eAAe;AACxB,SAAS,yBAAyB;AAClC,SAAyB,6BAA6B;AACtD,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B;AAAA,EACC;AAAA,EACA;AAAA,OACM;AACP,SAAS,qCAAqC;AAC9C,SAAS,2CAA2C;AACpD,SAAS,yBAAyB,+BAA+B;AAiDjE,MAAM,kBAAkB,CAAC,GAAG,cAAc,GAAG,iBAAiB;AAGvD,SAAS,OAAO,OAAoB;AAC1C,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,CAAC;AAAA,IACd,aAAa,CAAC;AAAA,IACd,eAAe,CAAC;AAAA,IAChB,QAAQ,CAAC;AAAA,IACT;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACJ,IAAI;AAEJ,QAAM,cAAc,yBAAyB,UAAU;AAEvD,QAAM,2BAA2B,YAAY;AAC7C,QAAM,qBAAqB,QAAQ,MAAM;AACxC,QAAI,KAAK,OAAQ,QAAO,4BAA4B;AACpD,QAAI,CAAC,yBAA0B,QAAO;AAEtC,WAAO,MACN,iCACC;AAAA,0BAAC,8BAA2B;AAAA,MAC5B,oBAAC,4BAAyB;AAAA,OAC3B;AAAA,EAEF,GAAG,CAAC,KAAK,QAAQ,wBAAwB,CAAC;AAC1C,QAAM,wBAAwB;AAAA,IAC7B,OAAO;AAAA,MACN,UAAU;AAAA,MACV,iBAAiB;AAAA,MACjB,sBAAsB;AAAA,MACtB,qBAAqB;AAAA,MACrB,SAAS;AAAA,MACT,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,GAAG;AAAA,MACH;AAAA,IACD;AAAA,IACA,CAAC,aAAa,kBAAkB;AAAA,EACjC;AAEA,QAAM,cAAc,wBAAwB,UAAU;AACtD,QAAM,yBAAyB;AAAA,IAC9B,MAAM,8BAA8B,QAAQ,aAAa,iBAAiB;AAAA,IAC1E,CAAC,WAAW;AAAA,EACb;AAEA,QAAM,gBAAgB,wBAAwB,YAAY;AAC1D,QAAM,2BAA2B;AAAA,IAChC,MAAM,8BAA8B,QAAQ,eAAe,mBAAmB;AAAA,IAC9E,CAAC,aAAa;AAAA,EACf;AAEA,QAAM,SAAS,wBAAwB,KAAK;AAC5C,QAAM,oBAAoB;AAAA,IACzB,MAAM,8BAA8B,MAAM,QAAQ,eAAe;AAAA,IACjE,CAAC,MAAM;AAAA,EACR;AAEA,QAAM,kBAAkB;AAAA,IACvB,0BAA0B;AAAA,EAC3B;AACA,QAAM,kBAAkB;AAAA,IACvB,0BAA0B;AAAA,EAC3B;AAEA,QAAM,0BAA0B,QAAQ,MAAqB;AAC5D,WAAO;AAAA,MACN,kBAAkB;AAAA,MAClB,GAAG;AAAA,MACH,cAAc;AAAA,QACb,YAAY;AAAA,QACZ,GAAG,aAAa;AAAA,MACjB;AAAA,IACD;AAAA,EACD,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,iBAAiB;AAAA,IACtB,MAAM,CAAC,GAAG,iBAAiB,GAAG,eAAe;AAAA,IAC7C,CAAC,iBAAiB,eAAe;AAAA,EAClC;AAEA,QAAM,SAAS,oCAAoC,KAAK,SAAS;AAEjE,QAAM,iBAAiB,uBAAuB,KAAK,CAAC,SAAS,KAAK,SAAS,OAAO;AAClF,MAAI,kBAAkB,QAAQ;AAC7B,mBAAe,oBAAoB,MAAM;AAAA,EAC1C;AAEA;AAAA;AAAA;AAAA;AAAA,IAIC,oBAAC,qBAAkB,WAAW,mCAAmC,KAAK,SAAS,GAC9E;AAAA,MAAC;AAAA;AAAA,QACA,WAAW,8BAA8B,KAAK,SAAS;AAAA,QACvD,QAAQ,KAAK,MAAM,gBAAgB,IAAI,EAAE,UAAU,uBAAuB;AAAA,QAE1E;AAAA,UAAC;AAAA;AAAA,YACA,cAAa;AAAA,YACZ,GAAG;AAAA,YACJ,YAAY;AAAA,YACZ,YAAY;AAAA,YACZ,cAAc;AAAA,YACd,OAAO;AAAA,YACP,aAAa;AAAA,YACb,WAAW;AAAA,YAEX,+BAAC,YAAU,GAAG,MAAM,YAAY,uBAAuB,gBACtD;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,wBAAwB;AAAA,kBACxB,wBAAwB;AAAA,kBACxB;AAAA;AAAA,cACD;AAAA,cACC;AAAA,eACF;AAAA;AAAA,QACD;AAAA;AAAA,IACD,GACD;AAAA;AAEF;AAGA,SAAS,2BAA2B;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAEG;AACF,QAAM,SAAS,UAAU;AACzB,QAAM,SAAS,UAAU;AACzB,QAAM,MAAM,eAAe;AAC3B,QAAM,aAAa,YAAY;AAE/B,aAAW,MAAM;AAChB,UAAM,SAA8C,CAAC;AAErD,WAAO,KAAK,2BAA2B,MAAM,CAAC;AAM9C,WAAO,MAAM,aAAa,mBAAmB;AAE7C,WAAO,KAAK,QAAQ,MAAM,WAAW,QAAQ,EAAE,QAAQ,UAAU,CAAC,CAAC;AAGnE,2CAAuC,QAAQ;AAAA,MAC9C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC;AAGD,WAAO,KAAK,OAAO,MAAM,MAAM,QAAQ,MAAM,CAAC;AAG9C,WAAO,KAAK,UAAU,MAAM,CAAC;AAE7B,WAAO,MAAM;AACZ,aAAO,QAAQ,CAAC,OAAO,KAAK,CAAC;AAAA,IAC9B;AAAA,EACD,CAAC;AAED,QAAM,EAAE,OAAO,IAAI,oBAAoB;AACvC,QAAM,EAAE,YAAY,IAAI,sBAAsB;AAE9C,MAAI,aAAa;AAEhB,WAAO,oBAAC,eAAY;AAAA,EACrB;AAEA,MAAI,QAAQ;AACX,WAAO,oBAAC,UAAO;AAAA,EAChB;AAEA,SAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -53,7 +53,7 @@ function registerDefaultExternalContentHandlers(editor, options) {
53
53
  });
54
54
  }
55
55
  async function defaultHandleExternalFileAsset(editor, { file, assetId }, options) {
56
- const isSuccess = runFileChecks(file, options);
56
+ const isSuccess = notifyIfFileNotAllowed(file, options);
57
57
  if (!isSuccess) assert(false, "File checks failed");
58
58
  const assetInfo = await getAssetInfo(file, options, assetId);
59
59
  const result = await editor.uploadAsset(assetInfo, file);
@@ -62,7 +62,7 @@ async function defaultHandleExternalFileAsset(editor, { file, assetId }, options
62
62
  return AssetRecordType.create(assetInfo);
63
63
  }
64
64
  async function defaultHandleExternalFileReplaceContent(editor, { file, shapeId, isImage }, options) {
65
- const isSuccess = runFileChecks(file, options);
65
+ const isSuccess = notifyIfFileNotAllowed(file, options);
66
66
  if (!isSuccess) assert(false, "File checks failed");
67
67
  const shape = editor.getShape(shapeId);
68
68
  if (!shape) assert(false, "Shape not found");
@@ -231,7 +231,7 @@ async function defaultHandleExternalFileContent(editor, { point, files }, option
231
231
  const assetPartials = [];
232
232
  const assetsToUpdate = [];
233
233
  for (const file of files) {
234
- const isSuccess = runFileChecks(file, options);
234
+ const isSuccess = notifyIfFileNotAllowed(file, options);
235
235
  if (!isSuccess) continue;
236
236
  const assetInfo = await getAssetInfo(file, options);
237
237
  if (acceptedImageMimeTypes.includes(file.type)) {
@@ -545,7 +545,7 @@ function createEmptyBookmarkShape(editor, url, position) {
545
545
  });
546
546
  return editor.getShape(partial.id);
547
547
  }
548
- function runFileChecks(file, options) {
548
+ function notifyIfFileNotAllowed(file, options) {
549
549
  const {
550
550
  acceptedImageMimeTypes = DEFAULT_SUPPORTED_IMAGE_TYPES,
551
551
  acceptedVideoMimeTypes = DEFAULT_SUPPORT_VIDEO_TYPES,
@@ -616,6 +616,7 @@ export {
616
616
  defaultHandleExternalUrlContent,
617
617
  getAssetInfo,
618
618
  getMediaAssetInfoPartial,
619
+ notifyIfFileNotAllowed,
619
620
  registerDefaultExternalContentHandlers
620
621
  };
621
622
  //# sourceMappingURL=defaultExternalContentHandlers.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/defaultExternalContentHandlers.ts"],
4
- "sourcesContent": ["import {\n\tAssetRecordType,\n\tDEFAULT_SUPPORTED_IMAGE_TYPES,\n\tDEFAULT_SUPPORT_VIDEO_TYPES,\n\tEditor,\n\tMediaHelpers,\n\tTLAsset,\n\tTLAssetId,\n\tTLBookmarkAsset,\n\tTLBookmarkShape,\n\tTLContent,\n\tTLFileExternalAsset,\n\tTLFileReplaceExternalContent,\n\tTLImageAsset,\n\tTLImageShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLTextShape,\n\tTLTextShapeProps,\n\tTLUrlExternalAsset,\n\tTLVideoAsset,\n\tTLVideoShape,\n\tVec,\n\tVecLike,\n\tassert,\n\tcreateShapeId,\n\tfetch,\n\tgetHashForBuffer,\n\tgetHashForString,\n\tmaybeSnapToGrid,\n\ttoRichText,\n} from '@tldraw/editor'\nimport { EmbedDefinition } from './defaultEmbedDefinitions'\nimport { EmbedShapeUtil } from './shapes/embed/EmbedShapeUtil'\nimport { getCroppedImageDataForReplacedImage } from './shapes/shared/crop'\nimport { FONT_FAMILIES, FONT_SIZES, TEXT_PROPS } from './shapes/shared/default-shape-constants'\nimport { TLUiToastsContextType } from './ui/context/toasts'\nimport { useTranslation } from './ui/hooks/useTranslation/useTranslation'\nimport { containBoxSize } from './utils/assets/assets'\nimport { putExcalidrawContent } from './utils/excalidraw/putExcalidrawContent'\nimport { renderRichTextFromHTML } from './utils/text/richText'\nimport { cleanupText, isRightToLeftLanguage } from './utils/text/text'\n\n/**\n * 5000px\n * @public\n */\nexport const DEFAULT_MAX_IMAGE_DIMENSION = 5000\n/**\n * 10mb\n * @public\n */\nexport const DEFAULT_MAX_ASSET_SIZE = 10 * 1024 * 1024\n\n/** @public */\nexport interface TLExternalContentProps {\n\t/**\n\t * The maximum dimension (width or height) of an image. Images larger than this will be rescaled\n\t * to fit. Defaults to infinity.\n\t */\n\tmaxImageDimension?: number\n\t/**\n\t * The maximum size (in bytes) of an asset. Assets larger than this will be rejected. Defaults\n\t * to 10mb (10 * 1024 * 1024).\n\t */\n\tmaxAssetSize?: number\n\t/**\n\t * The mime types of images that are allowed to be handled. Defaults to\n\t * DEFAULT_SUPPORTED_IMAGE_TYPES.\n\t */\n\tacceptedImageMimeTypes?: readonly string[]\n\t/**\n\t * The mime types of videos that are allowed to be handled. Defaults to\n\t * DEFAULT_SUPPORT_VIDEO_TYPES.\n\t */\n\tacceptedVideoMimeTypes?: readonly string[]\n}\n\n/** @public */\nexport interface TLDefaultExternalContentHandlerOpts extends TLExternalContentProps {\n\ttoasts: TLUiToastsContextType\n\tmsg: ReturnType<typeof useTranslation>\n}\n\n/** @public */\nexport function registerDefaultExternalContentHandlers(\n\teditor: Editor,\n\toptions: TLDefaultExternalContentHandlerOpts\n) {\n\t// files -> asset\n\teditor.registerExternalAssetHandler('file', async (externalAsset) => {\n\t\treturn defaultHandleExternalFileAsset(editor, externalAsset, options)\n\t})\n\n\t// urls -> bookmark asset\n\teditor.registerExternalAssetHandler('url', async (externalAsset) => {\n\t\treturn defaultHandleExternalUrlAsset(editor, externalAsset, options)\n\t})\n\n\t// svg text\n\teditor.registerExternalContentHandler('svg-text', async (externalContent) => {\n\t\treturn defaultHandleExternalSvgTextContent(editor, externalContent)\n\t})\n\n\t// embeds\n\teditor.registerExternalContentHandler<'embed', EmbedDefinition>('embed', (externalContent) => {\n\t\treturn defaultHandleExternalEmbedContent(editor, externalContent)\n\t})\n\n\t// files\n\teditor.registerExternalContentHandler('files', async (externalContent) => {\n\t\treturn defaultHandleExternalFileContent(editor, externalContent, options)\n\t})\n\n\t// file-replace -> asset\n\teditor.registerExternalContentHandler('file-replace', async (externalContent) => {\n\t\treturn defaultHandleExternalFileReplaceContent(editor, externalContent, options)\n\t})\n\n\t// text\n\teditor.registerExternalContentHandler('text', async (externalContent) => {\n\t\treturn defaultHandleExternalTextContent(editor, externalContent)\n\t})\n\n\t// url\n\teditor.registerExternalContentHandler('url', async (externalContent) => {\n\t\treturn defaultHandleExternalUrlContent(editor, externalContent, options)\n\t})\n\n\t// tldraw\n\teditor.registerExternalContentHandler('tldraw', async (externalContent) => {\n\t\treturn defaultHandleExternalTldrawContent(editor, externalContent)\n\t})\n\n\t// excalidraw\n\teditor.registerExternalContentHandler('excalidraw', async (externalContent) => {\n\t\treturn defaultHandleExternalExcalidrawContent(editor, externalContent)\n\t})\n}\n\n/** @public */\nexport async function defaultHandleExternalFileAsset(\n\teditor: Editor,\n\t{ file, assetId }: TLFileExternalAsset,\n\toptions: TLDefaultExternalContentHandlerOpts\n) {\n\tconst isSuccess = runFileChecks(file, options)\n\tif (!isSuccess) assert(false, 'File checks failed')\n\n\tconst assetInfo = await getAssetInfo(file, options, assetId)\n\tconst result = await editor.uploadAsset(assetInfo, file)\n\tassetInfo.props.src = result.src\n\tif (result.meta) assetInfo.meta = { ...assetInfo.meta, ...result.meta }\n\n\treturn AssetRecordType.create(assetInfo)\n}\n\n/** @public */\nexport async function defaultHandleExternalFileReplaceContent(\n\teditor: Editor,\n\t{ file, shapeId, isImage }: TLFileReplaceExternalContent,\n\toptions: TLDefaultExternalContentHandlerOpts\n) {\n\tconst isSuccess = runFileChecks(file, options)\n\tif (!isSuccess) assert(false, 'File checks failed')\n\n\tconst shape = editor.getShape(shapeId)\n\tif (!shape) assert(false, 'Shape not found')\n\n\tconst hash = getHashForBuffer(await file.arrayBuffer())\n\tconst assetId = AssetRecordType.createId(hash)\n\teditor.createTemporaryAssetPreview(assetId, file)\n\tconst assetInfoPartial = await getMediaAssetInfoPartial(\n\t\tfile,\n\t\tassetId,\n\t\tisImage /* isImage */,\n\t\t!isImage /* isVideo */\n\t)\n\teditor.createAssets([assetInfoPartial])\n\n\t// And update the shape\n\tif (shape.type === 'image') {\n\t\tconst imageShape = shape as TLImageShape\n\t\tconst currentCrop = imageShape.props.crop\n\n\t\t// Calculate new dimensions that preserve the current visual size of the cropped area\n\t\tlet newWidth = assetInfoPartial.props.w\n\t\tlet newHeight = assetInfoPartial.props.h\n\t\tlet newX = imageShape.x\n\t\tlet newY = imageShape.y\n\t\tlet finalCrop = currentCrop\n\n\t\tif (currentCrop) {\n\t\t\t// Use the dedicated function to calculate the new crop and dimensions\n\t\t\tconst result = getCroppedImageDataForReplacedImage(\n\t\t\t\timageShape,\n\t\t\t\tassetInfoPartial.props.w,\n\t\t\t\tassetInfoPartial.props.h\n\t\t\t)\n\n\t\t\tfinalCrop = result.crop\n\t\t\tnewWidth = result.w\n\t\t\tnewHeight = result.h\n\t\t\tnewX = result.x\n\t\t\tnewY = result.y\n\t\t}\n\n\t\teditor.updateShapes<TLImageShape>([\n\t\t\t{\n\t\t\t\tid: imageShape.id,\n\t\t\t\ttype: imageShape.type,\n\t\t\t\tprops: {\n\t\t\t\t\tassetId: assetId,\n\t\t\t\t\tcrop: finalCrop,\n\t\t\t\t\tw: newWidth,\n\t\t\t\t\th: newHeight,\n\t\t\t\t},\n\t\t\t\tx: newX,\n\t\t\t\ty: newY,\n\t\t\t},\n\t\t])\n\t} else if (shape.type === 'video') {\n\t\teditor.updateShapes<TLVideoShape>([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: {\n\t\t\t\t\tassetId: assetId,\n\t\t\t\t\tw: assetInfoPartial.props.w,\n\t\t\t\t\th: assetInfoPartial.props.h,\n\t\t\t\t},\n\t\t\t},\n\t\t])\n\t}\n\n\tconst asset = (await editor.getAssetForExternalContent({\n\t\ttype: 'file',\n\t\tfile,\n\t\tassetId,\n\t})) as TLAsset\n\n\teditor.updateAssets([{ ...asset, id: assetId }])\n\n\treturn asset\n}\n\n/** @public */\nexport async function defaultHandleExternalUrlAsset(\n\teditor: Editor,\n\t{ url }: TLUrlExternalAsset,\n\t{ toasts, msg }: TLDefaultExternalContentHandlerOpts\n): Promise<TLBookmarkAsset> {\n\tlet meta: { image: string; favicon: string; title: string; description: string }\n\n\ttry {\n\t\tconst resp = await fetch(url, {\n\t\t\tmethod: 'GET',\n\t\t\tmode: 'no-cors',\n\t\t})\n\t\tconst html = await resp.text()\n\t\tconst doc = new DOMParser().parseFromString(html, 'text/html')\n\t\tmeta = {\n\t\t\timage: doc.head.querySelector('meta[property=\"og:image\"]')?.getAttribute('content') ?? '',\n\t\t\tfavicon:\n\t\t\t\tdoc.head.querySelector('link[rel=\"apple-touch-icon\"]')?.getAttribute('href') ??\n\t\t\t\tdoc.head.querySelector('link[rel=\"icon\"]')?.getAttribute('href') ??\n\t\t\t\t'',\n\t\t\ttitle: doc.head.querySelector('meta[property=\"og:title\"]')?.getAttribute('content') ?? url,\n\t\t\tdescription:\n\t\t\t\tdoc.head.querySelector('meta[property=\"og:description\"]')?.getAttribute('content') ?? '',\n\t\t}\n\t\tif (!meta.image.startsWith('http')) {\n\t\t\tmeta.image = new URL(meta.image, url).href\n\t\t}\n\t\tif (!meta.favicon.startsWith('http')) {\n\t\t\tmeta.favicon = new URL(meta.favicon, url).href\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(error)\n\t\ttoasts.addToast({\n\t\t\ttitle: msg('assets.url.failed'),\n\t\t\tseverity: 'error',\n\t\t})\n\t\tmeta = { image: '', favicon: '', title: '', description: '' }\n\t}\n\n\t// Create the bookmark asset from the meta\n\treturn {\n\t\tid: AssetRecordType.createId(getHashForString(url)),\n\t\ttypeName: 'asset',\n\t\ttype: 'bookmark',\n\t\tprops: {\n\t\t\tsrc: url,\n\t\t\tdescription: meta.description,\n\t\t\timage: meta.image,\n\t\t\tfavicon: meta.favicon,\n\t\t\ttitle: meta.title,\n\t\t},\n\t\tmeta: {},\n\t} as TLBookmarkAsset\n}\n\n/** @public */\nexport async function defaultHandleExternalSvgTextContent(\n\teditor: Editor,\n\t{ point, text }: { point?: VecLike; text: string }\n) {\n\tconst position =\n\t\tpoint ??\n\t\t(editor.inputs.shiftKey\n\t\t\t? editor.inputs.currentPagePoint\n\t\t\t: editor.getViewportPageBounds().center)\n\n\tconst svg = new DOMParser().parseFromString(text, 'image/svg+xml').querySelector('svg')\n\tif (!svg) {\n\t\tthrow new Error('No <svg/> element present')\n\t}\n\n\tlet width = parseFloat(svg.getAttribute('width') || '0')\n\tlet height = parseFloat(svg.getAttribute('height') || '0')\n\n\tif (!(width && height)) {\n\t\tdocument.body.appendChild(svg)\n\t\tconst box = svg.getBoundingClientRect()\n\t\tdocument.body.removeChild(svg)\n\n\t\twidth = box.width\n\t\theight = box.height\n\t}\n\n\tconst asset = await editor.getAssetForExternalContent({\n\t\ttype: 'file',\n\t\tfile: new File([text], 'asset.svg', { type: 'image/svg+xml' }),\n\t})\n\n\tif (!asset) throw Error('Could not create an asset')\n\n\tcreateShapesForAssets(editor, [asset], position)\n}\n\n/** @public */\nexport function defaultHandleExternalEmbedContent<T>(\n\teditor: Editor,\n\t{ point, url, embed }: { point?: VecLike; url: string; embed: T }\n) {\n\tconst position =\n\t\tpoint ??\n\t\t(editor.inputs.shiftKey\n\t\t\t? editor.inputs.currentPagePoint\n\t\t\t: editor.getViewportPageBounds().center)\n\n\tconst { width, height } = embed as { width: number; height: number }\n\n\tconst id = createShapeId()\n\n\tconst newPoint = maybeSnapToGrid(\n\t\tnew Vec(position.x - (width || 450) / 2, position.y - (height || 450) / 2),\n\t\teditor\n\t)\n\tconst shapePartial: TLShapePartial = {\n\t\tid,\n\t\ttype: 'embed',\n\t\tx: newPoint.x,\n\t\ty: newPoint.y,\n\t\tprops: {\n\t\t\tw: width,\n\t\t\th: height,\n\t\t\turl,\n\t\t},\n\t}\n\n\tif (editor.canCreateShape(shapePartial)) {\n\t\teditor.createShape(shapePartial).select(id)\n\t}\n}\n\n/** @public */\nexport async function defaultHandleExternalFileContent(\n\teditor: Editor,\n\t{ point, files }: { point?: VecLike; files: File[] },\n\toptions: TLDefaultExternalContentHandlerOpts\n) {\n\tconst { acceptedImageMimeTypes = DEFAULT_SUPPORTED_IMAGE_TYPES, toasts, msg } = options\n\tif (files.length > editor.options.maxFilesAtOnce) {\n\t\ttoasts.addToast({ title: msg('assets.files.amount-too-big'), severity: 'error' })\n\t\treturn\n\t}\n\n\tconst position =\n\t\tpoint ??\n\t\t(editor.inputs.shiftKey\n\t\t\t? editor.inputs.currentPagePoint\n\t\t\t: editor.getViewportPageBounds().center)\n\n\tconst pagePoint = new Vec(position.x, position.y)\n\tconst assetPartials: TLAsset[] = []\n\tconst assetsToUpdate: {\n\t\tasset: TLAsset\n\t\tfile: File\n\t}[] = []\n\tfor (const file of files) {\n\t\tconst isSuccess = runFileChecks(file, options)\n\t\tif (!isSuccess) continue\n\n\t\tconst assetInfo = await getAssetInfo(file, options)\n\t\tif (acceptedImageMimeTypes.includes(file.type)) {\n\t\t\teditor.createTemporaryAssetPreview(assetInfo.id, file)\n\t\t}\n\t\tassetPartials.push(assetInfo)\n\t\tassetsToUpdate.push({ asset: assetInfo, file })\n\t}\n\n\tPromise.allSettled(\n\t\tassetsToUpdate.map(async (assetAndFile) => {\n\t\t\ttry {\n\t\t\t\tconst newAsset = await editor.getAssetForExternalContent({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tfile: assetAndFile.file,\n\t\t\t\t})\n\n\t\t\t\tif (!newAsset) {\n\t\t\t\t\tthrow Error('Could not create an asset')\n\t\t\t\t}\n\n\t\t\t\t// Save the new asset under the old asset's id\n\t\t\t\teditor.updateAssets([{ ...newAsset, id: assetAndFile.asset.id }])\n\t\t\t} catch (error) {\n\t\t\t\ttoasts.addToast({\n\t\t\t\t\ttitle: msg('assets.files.upload-failed'),\n\t\t\t\t\tseverity: 'error',\n\t\t\t\t})\n\t\t\t\tconsole.error(error)\n\t\t\t\teditor.deleteAssets([assetAndFile.asset.id])\n\t\t\t\treturn\n\t\t\t}\n\t\t})\n\t)\n\n\tcreateShapesForAssets(editor, assetPartials, pagePoint)\n}\n\n/** @public */\nexport async function defaultHandleExternalTextContent(\n\teditor: Editor,\n\t{ point, text, html }: { point?: VecLike; text: string; html?: string }\n) {\n\tconst p =\n\t\tpoint ??\n\t\t(editor.inputs.shiftKey\n\t\t\t? editor.inputs.currentPagePoint\n\t\t\t: editor.getViewportPageBounds().center)\n\n\tconst defaultProps = editor.getShapeUtil<TLTextShape>('text').getDefaultProps()\n\n\tconst cleanedUpPlaintext = cleanupText(text)\n\tconst richTextToPaste = html\n\t\t? renderRichTextFromHTML(editor, html)\n\t\t: toRichText(cleanedUpPlaintext)\n\n\t// todo: discuss\n\t// If we have one shape with rich text selected, update the shape's text.\n\t// const onlySelectedShape = editor.getOnlySelectedShape()\n\t// if (onlySelectedShape && 'richText' in onlySelectedShape.props) {\n\t// \teditor.updateShapes([\n\t// \t\t{\n\t// \t\t\tid: onlySelectedShape.id,\n\t// \t\t\ttype: onlySelectedShape.type,\n\t// \t\t\tprops: {\n\t// \t\t\t\trichText: richTextToPaste,\n\t// \t\t\t},\n\t// \t\t},\n\t// \t])\n\n\t// \treturn\n\t// }\n\n\t// Measure the text with default values\n\tlet w: number\n\tlet h: number\n\tlet autoSize: boolean\n\tlet align = 'middle' as TLTextShapeProps['textAlign']\n\n\tconst htmlToMeasure = html ?? cleanedUpPlaintext.replace(/\\n/g, '<br>')\n\tconst isMultiLine = html\n\t\t? richTextToPaste.content.length > 1\n\t\t: cleanedUpPlaintext.split('\\n').length > 1\n\n\t// check whether the text contains the most common characters in RTL languages\n\tconst isRtl = isRightToLeftLanguage(cleanedUpPlaintext)\n\n\tif (isMultiLine) {\n\t\talign = isMultiLine ? (isRtl ? 'end' : 'start') : 'middle'\n\t}\n\n\tconst rawSize = editor.textMeasure.measureHtml(htmlToMeasure, {\n\t\t...TEXT_PROPS,\n\t\tfontFamily: FONT_FAMILIES[defaultProps.font],\n\t\tfontSize: FONT_SIZES[defaultProps.size],\n\t\tmaxWidth: null,\n\t})\n\n\tconst minWidth = Math.min(\n\t\tisMultiLine ? editor.getViewportPageBounds().width * 0.9 : 920,\n\t\tMath.max(200, editor.getViewportPageBounds().width * 0.9)\n\t)\n\n\tif (rawSize.w > minWidth) {\n\t\tconst shrunkSize = editor.textMeasure.measureHtml(htmlToMeasure, {\n\t\t\t...TEXT_PROPS,\n\t\t\tfontFamily: FONT_FAMILIES[defaultProps.font],\n\t\t\tfontSize: FONT_SIZES[defaultProps.size],\n\t\t\tmaxWidth: minWidth,\n\t\t})\n\t\tw = shrunkSize.w\n\t\th = shrunkSize.h\n\t\tautoSize = false\n\t\talign = isRtl ? 'end' : 'start'\n\t} else {\n\t\t// autosize is fine\n\t\tw = Math.max(rawSize.w, 10)\n\t\th = Math.max(rawSize.h, 10)\n\t\tautoSize = true\n\t}\n\n\tif (p.y - h / 2 < editor.getViewportPageBounds().minY + 40) {\n\t\tp.y = editor.getViewportPageBounds().minY + 40 + h / 2\n\t}\n\n\tconst newPoint = maybeSnapToGrid(new Vec(p.x - w / 2, p.y - h / 2), editor)\n\tconst shapeId = createShapeId()\n\n\t// Allow this to trigger the max shapes reached alert\n\teditor.createShapes<TLTextShape>([\n\t\t{\n\t\t\tid: shapeId,\n\t\t\ttype: 'text',\n\t\t\tx: newPoint.x,\n\t\t\ty: newPoint.y,\n\t\t\tprops: {\n\t\t\t\trichText: richTextToPaste,\n\t\t\t\t// if the text has more than one line, align it to the left\n\t\t\t\ttextAlign: align,\n\t\t\t\tautoSize,\n\t\t\t\tw,\n\t\t\t},\n\t\t},\n\t])\n}\n\n/** @public */\nexport async function defaultHandleExternalUrlContent(\n\teditor: Editor,\n\t{ point, url }: { point?: VecLike; url: string },\n\t{ toasts, msg }: TLDefaultExternalContentHandlerOpts\n) {\n\t// try to paste as an embed first\n\tconst embedUtil = editor.getShapeUtil('embed') as EmbedShapeUtil | undefined\n\tconst embedInfo = embedUtil?.getEmbedDefinition(url)\n\n\tif (embedInfo) {\n\t\treturn editor.putExternalContent({\n\t\t\ttype: 'embed',\n\t\t\turl: embedInfo.url,\n\t\t\tpoint,\n\t\t\tembed: embedInfo.definition,\n\t\t})\n\t}\n\n\tconst position =\n\t\tpoint ??\n\t\t(editor.inputs.shiftKey\n\t\t\t? editor.inputs.currentPagePoint\n\t\t\t: editor.getViewportPageBounds().center)\n\n\tconst assetId: TLAssetId = AssetRecordType.createId(getHashForString(url))\n\tconst shape = createEmptyBookmarkShape(editor, url, position)\n\n\t// Use an existing asset if we have one, or else else create a new one\n\tlet asset = editor.getAsset(assetId) as TLAsset\n\tlet shouldAlsoCreateAsset = false\n\tif (!asset) {\n\t\tshouldAlsoCreateAsset = true\n\t\ttry {\n\t\t\tconst bookmarkAsset = await editor.getAssetForExternalContent({ type: 'url', url })\n\t\t\tif (!bookmarkAsset) throw Error('Could not create an asset')\n\t\t\tasset = bookmarkAsset\n\t\t} catch {\n\t\t\ttoasts.addToast({\n\t\t\t\ttitle: msg('assets.url.failed'),\n\t\t\t\tseverity: 'error',\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t}\n\n\teditor.run(() => {\n\t\tif (shouldAlsoCreateAsset) {\n\t\t\teditor.createAssets([asset])\n\t\t}\n\n\t\teditor.updateShapes([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: {\n\t\t\t\t\tassetId: asset.id,\n\t\t\t\t},\n\t\t\t},\n\t\t])\n\t})\n}\n\n/** @public */\nexport async function defaultHandleExternalTldrawContent(\n\teditor: Editor,\n\t{ point, content }: { point?: VecLike; content: TLContent }\n) {\n\teditor.run(() => {\n\t\tconst selectionBoundsBefore = editor.getSelectionPageBounds()\n\t\teditor.markHistoryStoppingPoint('paste')\n\n\t\t// Unlock any locked root shapes on paste\n\t\tfor (const shape of content.shapes) {\n\t\t\tif (content.rootShapeIds.includes(shape.id)) {\n\t\t\t\tshape.isLocked = false\n\t\t\t}\n\t\t}\n\n\t\teditor.putContentOntoCurrentPage(content, {\n\t\t\tpoint: point,\n\t\t\tselect: true,\n\t\t})\n\t\tconst selectedBoundsAfter = editor.getSelectionPageBounds()\n\t\tif (\n\t\t\tselectionBoundsBefore &&\n\t\t\tselectedBoundsAfter &&\n\t\t\tselectionBoundsBefore?.collides(selectedBoundsAfter)\n\t\t) {\n\t\t\t// Creates a 'puff' to show content has been pasted\n\t\t\teditor.updateInstanceState({ isChangingStyle: true })\n\t\t\teditor.timers.setTimeout(() => {\n\t\t\t\teditor.updateInstanceState({ isChangingStyle: false })\n\t\t\t}, 150)\n\t\t}\n\t})\n}\n\n/** @public */\nexport async function defaultHandleExternalExcalidrawContent(\n\teditor: Editor,\n\t{ point, content }: { point?: VecLike; content: any }\n) {\n\teditor.run(() => {\n\t\tputExcalidrawContent(editor, content, point)\n\t})\n}\n\n/** @public */\nexport async function getMediaAssetInfoPartial(\n\tfile: File,\n\tassetId: TLAssetId,\n\tisImageType: boolean,\n\tisVideoType: boolean,\n\tmaxImageDimension?: number\n) {\n\tlet fileType = file.type\n\n\tif (file.type === 'video/quicktime') {\n\t\t// hack to make .mov videos work\n\t\tfileType = 'video/mp4'\n\t}\n\n\tconst size = isImageType\n\t\t? await MediaHelpers.getImageSize(file)\n\t\t: await MediaHelpers.getVideoSize(file)\n\n\tconst isAnimated = (await MediaHelpers.isAnimated(file)) || isVideoType\n\n\tconst assetInfo = {\n\t\tid: assetId,\n\t\ttype: isImageType ? 'image' : 'video',\n\t\ttypeName: 'asset',\n\t\tprops: {\n\t\t\tname: file.name,\n\t\t\tsrc: '',\n\t\t\tw: size.w,\n\t\t\th: size.h,\n\t\t\tfileSize: file.size,\n\t\t\tmimeType: fileType,\n\t\t\tisAnimated,\n\t\t},\n\t\tmeta: {},\n\t} as TLImageAsset | TLVideoAsset\n\n\tif (maxImageDimension && isFinite(maxImageDimension)) {\n\t\tconst size = { w: assetInfo.props.w, h: assetInfo.props.h }\n\t\tconst resizedSize = containBoxSize(size, { w: maxImageDimension, h: maxImageDimension })\n\t\tif (size !== resizedSize && MediaHelpers.isStaticImageType(file.type)) {\n\t\t\tassetInfo.props.w = resizedSize.w\n\t\t\tassetInfo.props.h = resizedSize.h\n\t\t}\n\t}\n\n\treturn assetInfo\n}\n\n/**\n * A helper function for an external content handler. It creates bookmarks,\n * images or video shapes corresponding to the type of assets provided.\n *\n * @param editor - The editor instance\n *\n * @param assets - An array of asset Ids\n *\n * @param position - the position at which to create the shapes\n *\n * @public\n */\nexport async function createShapesForAssets(\n\teditor: Editor,\n\tassets: TLAsset[],\n\tposition: VecLike\n): Promise<TLShapeId[]> {\n\tif (!assets.length) return []\n\n\tconst currentPoint = Vec.From(position)\n\tconst partials: TLShapePartial[] = []\n\n\tfor (let i = 0; i < assets.length; i++) {\n\t\tconst asset = assets[i]\n\t\tswitch (asset.type) {\n\t\t\tcase 'image': {\n\t\t\t\tpartials.push({\n\t\t\t\t\tid: createShapeId(),\n\t\t\t\t\ttype: 'image',\n\t\t\t\t\tx: currentPoint.x,\n\t\t\t\t\ty: currentPoint.y,\n\t\t\t\t\topacity: 1,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tassetId: asset.id,\n\t\t\t\t\t\tw: asset.props.w,\n\t\t\t\t\t\th: asset.props.h,\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\tcurrentPoint.x += asset.props.w\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'video': {\n\t\t\t\tpartials.push({\n\t\t\t\t\tid: createShapeId(),\n\t\t\t\t\ttype: 'video',\n\t\t\t\t\tx: currentPoint.x,\n\t\t\t\t\ty: currentPoint.y,\n\t\t\t\t\topacity: 1,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tassetId: asset.id,\n\t\t\t\t\t\tw: asset.props.w,\n\t\t\t\t\t\th: asset.props.h,\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\tcurrentPoint.x += asset.props.w\n\t\t\t}\n\t\t}\n\t}\n\n\teditor.run(() => {\n\t\t// Create any assets\n\t\tconst assetsToCreate = assets.filter((asset) => !editor.getAsset(asset.id))\n\n\t\teditor.store.atomic(() => {\n\t\t\tif (editor.canCreateShapes(partials)) {\n\t\t\t\tif (assetsToCreate.length) {\n\t\t\t\t\teditor.createAssets(assetsToCreate)\n\t\t\t\t}\n\n\t\t\t\t// Create the shapes\n\t\t\t\teditor.createShapes(partials).select(...partials.map((p) => p.id))\n\n\t\t\t\t// Re-position shapes so that the center of the group is at the provided point\n\t\t\t\tcenterSelectionAroundPoint(editor, position)\n\t\t\t}\n\t\t})\n\t})\n\n\treturn partials.map((p) => p.id)\n}\n\n/**\n * Repositions selected shapes do that the center of the group is\n * at the provided position\n *\n * @param editor - The editor instance\n *\n * @param position - the point to center the shapes around\n *\n * @public\n */\nexport function centerSelectionAroundPoint(editor: Editor, position: VecLike) {\n\t// Re-position shapes so that the center of the group is at the provided point\n\tconst viewportPageBounds = editor.getViewportPageBounds()\n\tlet selectionPageBounds = editor.getSelectionPageBounds()\n\n\tif (selectionPageBounds) {\n\t\tconst offset = selectionPageBounds!.center.sub(position)\n\n\t\teditor.updateShapes(\n\t\t\teditor.getSelectedShapes().map((shape) => {\n\t\t\t\tconst localRotation = editor.getShapeParentTransform(shape).decompose().rotation\n\t\t\t\tconst localDelta = Vec.Rot(offset, -localRotation)\n\t\t\t\treturn {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tx: shape.x! - localDelta.x,\n\t\t\t\t\ty: shape.y! - localDelta.y,\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t}\n\tselectionPageBounds = editor.getSelectionPageBounds()\n\t// align selection with the grid if necessary\n\tif (selectionPageBounds && editor.getInstanceState().isGridMode) {\n\t\tconst gridSize = editor.getDocumentSettings().gridSize\n\t\tconst topLeft = new Vec(selectionPageBounds.minX, selectionPageBounds.minY)\n\t\tconst gridSnappedPoint = topLeft.clone().snapToGrid(gridSize)\n\t\tconst delta = Vec.Sub(topLeft, gridSnappedPoint)\n\t\teditor.updateShapes(\n\t\t\teditor.getSelectedShapes().map((shape) => {\n\t\t\t\tconst newPoint = { x: shape.x! - delta.x, y: shape.y! - delta.y }\n\t\t\t\treturn {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\ty: newPoint.y,\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t}\n\t// Zoom out to fit the shapes, if necessary\n\tselectionPageBounds = editor.getSelectionPageBounds()\n\tif (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {\n\t\teditor.zoomToSelection({ animation: { duration: editor.options.animationMediumMs } })\n\t}\n}\n\n/** @public */\nexport function createEmptyBookmarkShape(\n\teditor: Editor,\n\turl: string,\n\tposition: VecLike\n): TLBookmarkShape {\n\tconst partial: TLShapePartial = {\n\t\tid: createShapeId(),\n\t\ttype: 'bookmark',\n\t\tx: position.x - 150,\n\t\ty: position.y - 160,\n\t\topacity: 1,\n\t\tprops: {\n\t\t\tassetId: null,\n\t\t\turl,\n\t\t},\n\t}\n\n\teditor.run(() => {\n\t\t// Allow this to trigger the max shapes reached alert\n\t\teditor.createShape(partial)\n\t\tif (!editor.getShape(partial.id)) return\n\t\teditor.select(partial.id)\n\t\tcenterSelectionAroundPoint(editor, position)\n\t})\n\n\treturn editor.getShape(partial.id) as TLBookmarkShape\n}\n\nfunction runFileChecks(file: File, options: TLDefaultExternalContentHandlerOpts) {\n\tconst {\n\t\tacceptedImageMimeTypes = DEFAULT_SUPPORTED_IMAGE_TYPES,\n\t\tacceptedVideoMimeTypes = DEFAULT_SUPPORT_VIDEO_TYPES,\n\t\tmaxAssetSize = DEFAULT_MAX_ASSET_SIZE,\n\t\ttoasts,\n\t\tmsg,\n\t} = options\n\tconst isImageType = acceptedImageMimeTypes.includes(file.type)\n\tconst isVideoType = acceptedVideoMimeTypes.includes(file.type)\n\n\tif (!isImageType && !isVideoType) {\n\t\ttoasts.addToast({\n\t\t\ttitle: msg('assets.files.type-not-allowed'),\n\t\t\tseverity: 'error',\n\t\t})\n\t\treturn false\n\t}\n\n\tif (file.size > maxAssetSize) {\n\t\ttoasts.addToast({\n\t\t\ttitle: msg('assets.files.size-too-big'),\n\t\t\tseverity: 'error',\n\t\t})\n\t\treturn false\n\t}\n\n\t// Use mime type instead of file ext, this is because\n\t// window.navigator.clipboard does not preserve file names\n\t// of copied files.\n\tif (!file.type) {\n\t\ttoasts.addToast({\n\t\t\ttitle: msg('assets.files.upload-failed'),\n\t\t\tseverity: 'error',\n\t\t})\n\t\tconsole.error('No mime type')\n\t\treturn false\n\t}\n\n\treturn true\n}\n\n/** @public */\nexport async function getAssetInfo(\n\tfile: File,\n\toptions: TLDefaultExternalContentHandlerOpts,\n\tassetId?: TLAssetId\n) {\n\tconst {\n\t\tacceptedImageMimeTypes = DEFAULT_SUPPORTED_IMAGE_TYPES,\n\t\tacceptedVideoMimeTypes = DEFAULT_SUPPORT_VIDEO_TYPES,\n\t\tmaxImageDimension = DEFAULT_MAX_IMAGE_DIMENSION,\n\t} = options\n\n\tconst isImageType = acceptedImageMimeTypes.includes(file.type)\n\tconst isVideoType = acceptedVideoMimeTypes.includes(file.type)\n\tconst hash = getHashForBuffer(await file.arrayBuffer())\n\tassetId ??= AssetRecordType.createId(hash)\n\tconst assetInfo = await getMediaAssetInfoPartial(\n\t\tfile,\n\t\tassetId,\n\t\tisImageType,\n\t\tisVideoType,\n\t\tmaxImageDimension\n\t)\n\treturn assetInfo\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tAssetRecordType,\n\tDEFAULT_SUPPORTED_IMAGE_TYPES,\n\tDEFAULT_SUPPORT_VIDEO_TYPES,\n\tEditor,\n\tMediaHelpers,\n\tTLAsset,\n\tTLAssetId,\n\tTLBookmarkAsset,\n\tTLBookmarkShape,\n\tTLContent,\n\tTLFileExternalAsset,\n\tTLFileReplaceExternalContent,\n\tTLImageAsset,\n\tTLImageShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLTextShape,\n\tTLTextShapeProps,\n\tTLUrlExternalAsset,\n\tTLVideoAsset,\n\tTLVideoShape,\n\tVec,\n\tVecLike,\n\tassert,\n\tcreateShapeId,\n\tfetch,\n\tgetHashForBuffer,\n\tgetHashForString,\n\tmaybeSnapToGrid,\n\ttoRichText,\n} from '@tldraw/editor'\nimport { EmbedDefinition } from './defaultEmbedDefinitions'\nimport { EmbedShapeUtil } from './shapes/embed/EmbedShapeUtil'\nimport { getCroppedImageDataForReplacedImage } from './shapes/shared/crop'\nimport { FONT_FAMILIES, FONT_SIZES, TEXT_PROPS } from './shapes/shared/default-shape-constants'\nimport { TLUiToastsContextType } from './ui/context/toasts'\nimport { useTranslation } from './ui/hooks/useTranslation/useTranslation'\nimport { containBoxSize } from './utils/assets/assets'\nimport { putExcalidrawContent } from './utils/excalidraw/putExcalidrawContent'\nimport { renderRichTextFromHTML } from './utils/text/richText'\nimport { cleanupText, isRightToLeftLanguage } from './utils/text/text'\n\n/**\n * 5000px\n * @public\n */\nexport const DEFAULT_MAX_IMAGE_DIMENSION = 5000\n/**\n * 10mb\n * @public\n */\nexport const DEFAULT_MAX_ASSET_SIZE = 10 * 1024 * 1024\n\n/** @public */\nexport interface TLExternalContentProps {\n\t/**\n\t * The maximum dimension (width or height) of an image. Images larger than this will be rescaled\n\t * to fit. Defaults to infinity.\n\t */\n\tmaxImageDimension?: number\n\t/**\n\t * The maximum size (in bytes) of an asset. Assets larger than this will be rejected. Defaults\n\t * to 10mb (10 * 1024 * 1024).\n\t */\n\tmaxAssetSize?: number\n\t/**\n\t * The mime types of images that are allowed to be handled. Defaults to\n\t * DEFAULT_SUPPORTED_IMAGE_TYPES.\n\t */\n\tacceptedImageMimeTypes?: readonly string[]\n\t/**\n\t * The mime types of videos that are allowed to be handled. Defaults to\n\t * DEFAULT_SUPPORT_VIDEO_TYPES.\n\t */\n\tacceptedVideoMimeTypes?: readonly string[]\n}\n\n/** @public */\nexport interface TLDefaultExternalContentHandlerOpts extends TLExternalContentProps {\n\ttoasts: TLUiToastsContextType\n\tmsg: ReturnType<typeof useTranslation>\n}\n\n/** @public */\nexport function registerDefaultExternalContentHandlers(\n\teditor: Editor,\n\toptions: TLDefaultExternalContentHandlerOpts\n) {\n\t// files -> asset\n\teditor.registerExternalAssetHandler('file', async (externalAsset) => {\n\t\treturn defaultHandleExternalFileAsset(editor, externalAsset, options)\n\t})\n\n\t// urls -> bookmark asset\n\teditor.registerExternalAssetHandler('url', async (externalAsset) => {\n\t\treturn defaultHandleExternalUrlAsset(editor, externalAsset, options)\n\t})\n\n\t// svg text\n\teditor.registerExternalContentHandler('svg-text', async (externalContent) => {\n\t\treturn defaultHandleExternalSvgTextContent(editor, externalContent)\n\t})\n\n\t// embeds\n\teditor.registerExternalContentHandler<'embed', EmbedDefinition>('embed', (externalContent) => {\n\t\treturn defaultHandleExternalEmbedContent(editor, externalContent)\n\t})\n\n\t// files\n\teditor.registerExternalContentHandler('files', async (externalContent) => {\n\t\treturn defaultHandleExternalFileContent(editor, externalContent, options)\n\t})\n\n\t// file-replace -> asset\n\teditor.registerExternalContentHandler('file-replace', async (externalContent) => {\n\t\treturn defaultHandleExternalFileReplaceContent(editor, externalContent, options)\n\t})\n\n\t// text\n\teditor.registerExternalContentHandler('text', async (externalContent) => {\n\t\treturn defaultHandleExternalTextContent(editor, externalContent)\n\t})\n\n\t// url\n\teditor.registerExternalContentHandler('url', async (externalContent) => {\n\t\treturn defaultHandleExternalUrlContent(editor, externalContent, options)\n\t})\n\n\t// tldraw\n\teditor.registerExternalContentHandler('tldraw', async (externalContent) => {\n\t\treturn defaultHandleExternalTldrawContent(editor, externalContent)\n\t})\n\n\t// excalidraw\n\teditor.registerExternalContentHandler('excalidraw', async (externalContent) => {\n\t\treturn defaultHandleExternalExcalidrawContent(editor, externalContent)\n\t})\n}\n\n/** @public */\nexport async function defaultHandleExternalFileAsset(\n\teditor: Editor,\n\t{ file, assetId }: TLFileExternalAsset,\n\toptions: TLDefaultExternalContentHandlerOpts\n) {\n\tconst isSuccess = notifyIfFileNotAllowed(file, options)\n\tif (!isSuccess) assert(false, 'File checks failed')\n\n\tconst assetInfo = await getAssetInfo(file, options, assetId)\n\tconst result = await editor.uploadAsset(assetInfo, file)\n\tassetInfo.props.src = result.src\n\tif (result.meta) assetInfo.meta = { ...assetInfo.meta, ...result.meta }\n\n\treturn AssetRecordType.create(assetInfo)\n}\n\n/** @public */\nexport async function defaultHandleExternalFileReplaceContent(\n\teditor: Editor,\n\t{ file, shapeId, isImage }: TLFileReplaceExternalContent,\n\toptions: TLDefaultExternalContentHandlerOpts\n) {\n\tconst isSuccess = notifyIfFileNotAllowed(file, options)\n\tif (!isSuccess) assert(false, 'File checks failed')\n\n\tconst shape = editor.getShape(shapeId)\n\tif (!shape) assert(false, 'Shape not found')\n\n\tconst hash = getHashForBuffer(await file.arrayBuffer())\n\tconst assetId = AssetRecordType.createId(hash)\n\teditor.createTemporaryAssetPreview(assetId, file)\n\tconst assetInfoPartial = await getMediaAssetInfoPartial(\n\t\tfile,\n\t\tassetId,\n\t\tisImage /* isImage */,\n\t\t!isImage /* isVideo */\n\t)\n\teditor.createAssets([assetInfoPartial])\n\n\t// And update the shape\n\tif (shape.type === 'image') {\n\t\tconst imageShape = shape as TLImageShape\n\t\tconst currentCrop = imageShape.props.crop\n\n\t\t// Calculate new dimensions that preserve the current visual size of the cropped area\n\t\tlet newWidth = assetInfoPartial.props.w\n\t\tlet newHeight = assetInfoPartial.props.h\n\t\tlet newX = imageShape.x\n\t\tlet newY = imageShape.y\n\t\tlet finalCrop = currentCrop\n\n\t\tif (currentCrop) {\n\t\t\t// Use the dedicated function to calculate the new crop and dimensions\n\t\t\tconst result = getCroppedImageDataForReplacedImage(\n\t\t\t\timageShape,\n\t\t\t\tassetInfoPartial.props.w,\n\t\t\t\tassetInfoPartial.props.h\n\t\t\t)\n\n\t\t\tfinalCrop = result.crop\n\t\t\tnewWidth = result.w\n\t\t\tnewHeight = result.h\n\t\t\tnewX = result.x\n\t\t\tnewY = result.y\n\t\t}\n\n\t\teditor.updateShapes<TLImageShape>([\n\t\t\t{\n\t\t\t\tid: imageShape.id,\n\t\t\t\ttype: imageShape.type,\n\t\t\t\tprops: {\n\t\t\t\t\tassetId: assetId,\n\t\t\t\t\tcrop: finalCrop,\n\t\t\t\t\tw: newWidth,\n\t\t\t\t\th: newHeight,\n\t\t\t\t},\n\t\t\t\tx: newX,\n\t\t\t\ty: newY,\n\t\t\t},\n\t\t])\n\t} else if (shape.type === 'video') {\n\t\teditor.updateShapes<TLVideoShape>([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: {\n\t\t\t\t\tassetId: assetId,\n\t\t\t\t\tw: assetInfoPartial.props.w,\n\t\t\t\t\th: assetInfoPartial.props.h,\n\t\t\t\t},\n\t\t\t},\n\t\t])\n\t}\n\n\tconst asset = (await editor.getAssetForExternalContent({\n\t\ttype: 'file',\n\t\tfile,\n\t\tassetId,\n\t})) as TLAsset\n\n\teditor.updateAssets([{ ...asset, id: assetId }])\n\n\treturn asset\n}\n\n/** @public */\nexport async function defaultHandleExternalUrlAsset(\n\teditor: Editor,\n\t{ url }: TLUrlExternalAsset,\n\t{ toasts, msg }: TLDefaultExternalContentHandlerOpts\n): Promise<TLBookmarkAsset> {\n\tlet meta: { image: string; favicon: string; title: string; description: string }\n\n\ttry {\n\t\tconst resp = await fetch(url, {\n\t\t\tmethod: 'GET',\n\t\t\tmode: 'no-cors',\n\t\t})\n\t\tconst html = await resp.text()\n\t\tconst doc = new DOMParser().parseFromString(html, 'text/html')\n\t\tmeta = {\n\t\t\timage: doc.head.querySelector('meta[property=\"og:image\"]')?.getAttribute('content') ?? '',\n\t\t\tfavicon:\n\t\t\t\tdoc.head.querySelector('link[rel=\"apple-touch-icon\"]')?.getAttribute('href') ??\n\t\t\t\tdoc.head.querySelector('link[rel=\"icon\"]')?.getAttribute('href') ??\n\t\t\t\t'',\n\t\t\ttitle: doc.head.querySelector('meta[property=\"og:title\"]')?.getAttribute('content') ?? url,\n\t\t\tdescription:\n\t\t\t\tdoc.head.querySelector('meta[property=\"og:description\"]')?.getAttribute('content') ?? '',\n\t\t}\n\t\tif (!meta.image.startsWith('http')) {\n\t\t\tmeta.image = new URL(meta.image, url).href\n\t\t}\n\t\tif (!meta.favicon.startsWith('http')) {\n\t\t\tmeta.favicon = new URL(meta.favicon, url).href\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(error)\n\t\ttoasts.addToast({\n\t\t\ttitle: msg('assets.url.failed'),\n\t\t\tseverity: 'error',\n\t\t})\n\t\tmeta = { image: '', favicon: '', title: '', description: '' }\n\t}\n\n\t// Create the bookmark asset from the meta\n\treturn {\n\t\tid: AssetRecordType.createId(getHashForString(url)),\n\t\ttypeName: 'asset',\n\t\ttype: 'bookmark',\n\t\tprops: {\n\t\t\tsrc: url,\n\t\t\tdescription: meta.description,\n\t\t\timage: meta.image,\n\t\t\tfavicon: meta.favicon,\n\t\t\ttitle: meta.title,\n\t\t},\n\t\tmeta: {},\n\t} as TLBookmarkAsset\n}\n\n/** @public */\nexport async function defaultHandleExternalSvgTextContent(\n\teditor: Editor,\n\t{ point, text }: { point?: VecLike; text: string }\n) {\n\tconst position =\n\t\tpoint ??\n\t\t(editor.inputs.shiftKey\n\t\t\t? editor.inputs.currentPagePoint\n\t\t\t: editor.getViewportPageBounds().center)\n\n\tconst svg = new DOMParser().parseFromString(text, 'image/svg+xml').querySelector('svg')\n\tif (!svg) {\n\t\tthrow new Error('No <svg/> element present')\n\t}\n\n\tlet width = parseFloat(svg.getAttribute('width') || '0')\n\tlet height = parseFloat(svg.getAttribute('height') || '0')\n\n\tif (!(width && height)) {\n\t\tdocument.body.appendChild(svg)\n\t\tconst box = svg.getBoundingClientRect()\n\t\tdocument.body.removeChild(svg)\n\n\t\twidth = box.width\n\t\theight = box.height\n\t}\n\n\tconst asset = await editor.getAssetForExternalContent({\n\t\ttype: 'file',\n\t\tfile: new File([text], 'asset.svg', { type: 'image/svg+xml' }),\n\t})\n\n\tif (!asset) throw Error('Could not create an asset')\n\n\tcreateShapesForAssets(editor, [asset], position)\n}\n\n/** @public */\nexport function defaultHandleExternalEmbedContent<T>(\n\teditor: Editor,\n\t{ point, url, embed }: { point?: VecLike; url: string; embed: T }\n) {\n\tconst position =\n\t\tpoint ??\n\t\t(editor.inputs.shiftKey\n\t\t\t? editor.inputs.currentPagePoint\n\t\t\t: editor.getViewportPageBounds().center)\n\n\tconst { width, height } = embed as { width: number; height: number }\n\n\tconst id = createShapeId()\n\n\tconst newPoint = maybeSnapToGrid(\n\t\tnew Vec(position.x - (width || 450) / 2, position.y - (height || 450) / 2),\n\t\teditor\n\t)\n\tconst shapePartial: TLShapePartial = {\n\t\tid,\n\t\ttype: 'embed',\n\t\tx: newPoint.x,\n\t\ty: newPoint.y,\n\t\tprops: {\n\t\t\tw: width,\n\t\t\th: height,\n\t\t\turl,\n\t\t},\n\t}\n\n\tif (editor.canCreateShape(shapePartial)) {\n\t\teditor.createShape(shapePartial).select(id)\n\t}\n}\n\n/** @public */\nexport async function defaultHandleExternalFileContent(\n\teditor: Editor,\n\t{ point, files }: { point?: VecLike; files: File[] },\n\toptions: TLDefaultExternalContentHandlerOpts\n) {\n\tconst { acceptedImageMimeTypes = DEFAULT_SUPPORTED_IMAGE_TYPES, toasts, msg } = options\n\tif (files.length > editor.options.maxFilesAtOnce) {\n\t\ttoasts.addToast({ title: msg('assets.files.amount-too-big'), severity: 'error' })\n\t\treturn\n\t}\n\n\tconst position =\n\t\tpoint ??\n\t\t(editor.inputs.shiftKey\n\t\t\t? editor.inputs.currentPagePoint\n\t\t\t: editor.getViewportPageBounds().center)\n\n\tconst pagePoint = new Vec(position.x, position.y)\n\tconst assetPartials: TLAsset[] = []\n\tconst assetsToUpdate: {\n\t\tasset: TLAsset\n\t\tfile: File\n\t}[] = []\n\tfor (const file of files) {\n\t\tconst isSuccess = notifyIfFileNotAllowed(file, options)\n\t\tif (!isSuccess) continue\n\n\t\tconst assetInfo = await getAssetInfo(file, options)\n\t\tif (acceptedImageMimeTypes.includes(file.type)) {\n\t\t\teditor.createTemporaryAssetPreview(assetInfo.id, file)\n\t\t}\n\t\tassetPartials.push(assetInfo)\n\t\tassetsToUpdate.push({ asset: assetInfo, file })\n\t}\n\n\tPromise.allSettled(\n\t\tassetsToUpdate.map(async (assetAndFile) => {\n\t\t\ttry {\n\t\t\t\tconst newAsset = await editor.getAssetForExternalContent({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tfile: assetAndFile.file,\n\t\t\t\t})\n\n\t\t\t\tif (!newAsset) {\n\t\t\t\t\tthrow Error('Could not create an asset')\n\t\t\t\t}\n\n\t\t\t\t// Save the new asset under the old asset's id\n\t\t\t\teditor.updateAssets([{ ...newAsset, id: assetAndFile.asset.id }])\n\t\t\t} catch (error) {\n\t\t\t\ttoasts.addToast({\n\t\t\t\t\ttitle: msg('assets.files.upload-failed'),\n\t\t\t\t\tseverity: 'error',\n\t\t\t\t})\n\t\t\t\tconsole.error(error)\n\t\t\t\teditor.deleteAssets([assetAndFile.asset.id])\n\t\t\t\treturn\n\t\t\t}\n\t\t})\n\t)\n\n\tcreateShapesForAssets(editor, assetPartials, pagePoint)\n}\n\n/** @public */\nexport async function defaultHandleExternalTextContent(\n\teditor: Editor,\n\t{ point, text, html }: { point?: VecLike; text: string; html?: string }\n) {\n\tconst p =\n\t\tpoint ??\n\t\t(editor.inputs.shiftKey\n\t\t\t? editor.inputs.currentPagePoint\n\t\t\t: editor.getViewportPageBounds().center)\n\n\tconst defaultProps = editor.getShapeUtil<TLTextShape>('text').getDefaultProps()\n\n\tconst cleanedUpPlaintext = cleanupText(text)\n\tconst richTextToPaste = html\n\t\t? renderRichTextFromHTML(editor, html)\n\t\t: toRichText(cleanedUpPlaintext)\n\n\t// todo: discuss\n\t// If we have one shape with rich text selected, update the shape's text.\n\t// const onlySelectedShape = editor.getOnlySelectedShape()\n\t// if (onlySelectedShape && 'richText' in onlySelectedShape.props) {\n\t// \teditor.updateShapes([\n\t// \t\t{\n\t// \t\t\tid: onlySelectedShape.id,\n\t// \t\t\ttype: onlySelectedShape.type,\n\t// \t\t\tprops: {\n\t// \t\t\t\trichText: richTextToPaste,\n\t// \t\t\t},\n\t// \t\t},\n\t// \t])\n\n\t// \treturn\n\t// }\n\n\t// Measure the text with default values\n\tlet w: number\n\tlet h: number\n\tlet autoSize: boolean\n\tlet align = 'middle' as TLTextShapeProps['textAlign']\n\n\tconst htmlToMeasure = html ?? cleanedUpPlaintext.replace(/\\n/g, '<br>')\n\tconst isMultiLine = html\n\t\t? richTextToPaste.content.length > 1\n\t\t: cleanedUpPlaintext.split('\\n').length > 1\n\n\t// check whether the text contains the most common characters in RTL languages\n\tconst isRtl = isRightToLeftLanguage(cleanedUpPlaintext)\n\n\tif (isMultiLine) {\n\t\talign = isMultiLine ? (isRtl ? 'end' : 'start') : 'middle'\n\t}\n\n\tconst rawSize = editor.textMeasure.measureHtml(htmlToMeasure, {\n\t\t...TEXT_PROPS,\n\t\tfontFamily: FONT_FAMILIES[defaultProps.font],\n\t\tfontSize: FONT_SIZES[defaultProps.size],\n\t\tmaxWidth: null,\n\t})\n\n\tconst minWidth = Math.min(\n\t\tisMultiLine ? editor.getViewportPageBounds().width * 0.9 : 920,\n\t\tMath.max(200, editor.getViewportPageBounds().width * 0.9)\n\t)\n\n\tif (rawSize.w > minWidth) {\n\t\tconst shrunkSize = editor.textMeasure.measureHtml(htmlToMeasure, {\n\t\t\t...TEXT_PROPS,\n\t\t\tfontFamily: FONT_FAMILIES[defaultProps.font],\n\t\t\tfontSize: FONT_SIZES[defaultProps.size],\n\t\t\tmaxWidth: minWidth,\n\t\t})\n\t\tw = shrunkSize.w\n\t\th = shrunkSize.h\n\t\tautoSize = false\n\t\talign = isRtl ? 'end' : 'start'\n\t} else {\n\t\t// autosize is fine\n\t\tw = Math.max(rawSize.w, 10)\n\t\th = Math.max(rawSize.h, 10)\n\t\tautoSize = true\n\t}\n\n\tif (p.y - h / 2 < editor.getViewportPageBounds().minY + 40) {\n\t\tp.y = editor.getViewportPageBounds().minY + 40 + h / 2\n\t}\n\n\tconst newPoint = maybeSnapToGrid(new Vec(p.x - w / 2, p.y - h / 2), editor)\n\tconst shapeId = createShapeId()\n\n\t// Allow this to trigger the max shapes reached alert\n\teditor.createShapes<TLTextShape>([\n\t\t{\n\t\t\tid: shapeId,\n\t\t\ttype: 'text',\n\t\t\tx: newPoint.x,\n\t\t\ty: newPoint.y,\n\t\t\tprops: {\n\t\t\t\trichText: richTextToPaste,\n\t\t\t\t// if the text has more than one line, align it to the left\n\t\t\t\ttextAlign: align,\n\t\t\t\tautoSize,\n\t\t\t\tw,\n\t\t\t},\n\t\t},\n\t])\n}\n\n/** @public */\nexport async function defaultHandleExternalUrlContent(\n\teditor: Editor,\n\t{ point, url }: { point?: VecLike; url: string },\n\t{ toasts, msg }: TLDefaultExternalContentHandlerOpts\n) {\n\t// try to paste as an embed first\n\tconst embedUtil = editor.getShapeUtil('embed') as EmbedShapeUtil | undefined\n\tconst embedInfo = embedUtil?.getEmbedDefinition(url)\n\n\tif (embedInfo) {\n\t\treturn editor.putExternalContent({\n\t\t\ttype: 'embed',\n\t\t\turl: embedInfo.url,\n\t\t\tpoint,\n\t\t\tembed: embedInfo.definition,\n\t\t})\n\t}\n\n\tconst position =\n\t\tpoint ??\n\t\t(editor.inputs.shiftKey\n\t\t\t? editor.inputs.currentPagePoint\n\t\t\t: editor.getViewportPageBounds().center)\n\n\tconst assetId: TLAssetId = AssetRecordType.createId(getHashForString(url))\n\tconst shape = createEmptyBookmarkShape(editor, url, position)\n\n\t// Use an existing asset if we have one, or else else create a new one\n\tlet asset = editor.getAsset(assetId) as TLAsset\n\tlet shouldAlsoCreateAsset = false\n\tif (!asset) {\n\t\tshouldAlsoCreateAsset = true\n\t\ttry {\n\t\t\tconst bookmarkAsset = await editor.getAssetForExternalContent({ type: 'url', url })\n\t\t\tif (!bookmarkAsset) throw Error('Could not create an asset')\n\t\t\tasset = bookmarkAsset\n\t\t} catch {\n\t\t\ttoasts.addToast({\n\t\t\t\ttitle: msg('assets.url.failed'),\n\t\t\t\tseverity: 'error',\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t}\n\n\teditor.run(() => {\n\t\tif (shouldAlsoCreateAsset) {\n\t\t\teditor.createAssets([asset])\n\t\t}\n\n\t\teditor.updateShapes([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: {\n\t\t\t\t\tassetId: asset.id,\n\t\t\t\t},\n\t\t\t},\n\t\t])\n\t})\n}\n\n/** @public */\nexport async function defaultHandleExternalTldrawContent(\n\teditor: Editor,\n\t{ point, content }: { point?: VecLike; content: TLContent }\n) {\n\teditor.run(() => {\n\t\tconst selectionBoundsBefore = editor.getSelectionPageBounds()\n\t\teditor.markHistoryStoppingPoint('paste')\n\n\t\t// Unlock any locked root shapes on paste\n\t\tfor (const shape of content.shapes) {\n\t\t\tif (content.rootShapeIds.includes(shape.id)) {\n\t\t\t\tshape.isLocked = false\n\t\t\t}\n\t\t}\n\n\t\teditor.putContentOntoCurrentPage(content, {\n\t\t\tpoint: point,\n\t\t\tselect: true,\n\t\t})\n\t\tconst selectedBoundsAfter = editor.getSelectionPageBounds()\n\t\tif (\n\t\t\tselectionBoundsBefore &&\n\t\t\tselectedBoundsAfter &&\n\t\t\tselectionBoundsBefore?.collides(selectedBoundsAfter)\n\t\t) {\n\t\t\t// Creates a 'puff' to show content has been pasted\n\t\t\teditor.updateInstanceState({ isChangingStyle: true })\n\t\t\teditor.timers.setTimeout(() => {\n\t\t\t\teditor.updateInstanceState({ isChangingStyle: false })\n\t\t\t}, 150)\n\t\t}\n\t})\n}\n\n/** @public */\nexport async function defaultHandleExternalExcalidrawContent(\n\teditor: Editor,\n\t{ point, content }: { point?: VecLike; content: any }\n) {\n\teditor.run(() => {\n\t\tputExcalidrawContent(editor, content, point)\n\t})\n}\n\n/** @public */\nexport async function getMediaAssetInfoPartial(\n\tfile: File,\n\tassetId: TLAssetId,\n\tisImageType: boolean,\n\tisVideoType: boolean,\n\tmaxImageDimension?: number\n) {\n\tlet fileType = file.type\n\n\tif (file.type === 'video/quicktime') {\n\t\t// hack to make .mov videos work\n\t\tfileType = 'video/mp4'\n\t}\n\n\tconst size = isImageType\n\t\t? await MediaHelpers.getImageSize(file)\n\t\t: await MediaHelpers.getVideoSize(file)\n\n\tconst isAnimated = (await MediaHelpers.isAnimated(file)) || isVideoType\n\n\tconst assetInfo = {\n\t\tid: assetId,\n\t\ttype: isImageType ? 'image' : 'video',\n\t\ttypeName: 'asset',\n\t\tprops: {\n\t\t\tname: file.name,\n\t\t\tsrc: '',\n\t\t\tw: size.w,\n\t\t\th: size.h,\n\t\t\tfileSize: file.size,\n\t\t\tmimeType: fileType,\n\t\t\tisAnimated,\n\t\t},\n\t\tmeta: {},\n\t} as TLImageAsset | TLVideoAsset\n\n\tif (maxImageDimension && isFinite(maxImageDimension)) {\n\t\tconst size = { w: assetInfo.props.w, h: assetInfo.props.h }\n\t\tconst resizedSize = containBoxSize(size, { w: maxImageDimension, h: maxImageDimension })\n\t\tif (size !== resizedSize && MediaHelpers.isStaticImageType(file.type)) {\n\t\t\tassetInfo.props.w = resizedSize.w\n\t\t\tassetInfo.props.h = resizedSize.h\n\t\t}\n\t}\n\n\treturn assetInfo\n}\n\n/**\n * A helper function for an external content handler. It creates bookmarks,\n * images or video shapes corresponding to the type of assets provided.\n *\n * @param editor - The editor instance\n *\n * @param assets - An array of asset Ids\n *\n * @param position - the position at which to create the shapes\n *\n * @public\n */\nexport async function createShapesForAssets(\n\teditor: Editor,\n\tassets: TLAsset[],\n\tposition: VecLike\n): Promise<TLShapeId[]> {\n\tif (!assets.length) return []\n\n\tconst currentPoint = Vec.From(position)\n\tconst partials: TLShapePartial[] = []\n\n\tfor (let i = 0; i < assets.length; i++) {\n\t\tconst asset = assets[i]\n\t\tswitch (asset.type) {\n\t\t\tcase 'image': {\n\t\t\t\tpartials.push({\n\t\t\t\t\tid: createShapeId(),\n\t\t\t\t\ttype: 'image',\n\t\t\t\t\tx: currentPoint.x,\n\t\t\t\t\ty: currentPoint.y,\n\t\t\t\t\topacity: 1,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tassetId: asset.id,\n\t\t\t\t\t\tw: asset.props.w,\n\t\t\t\t\t\th: asset.props.h,\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\tcurrentPoint.x += asset.props.w\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'video': {\n\t\t\t\tpartials.push({\n\t\t\t\t\tid: createShapeId(),\n\t\t\t\t\ttype: 'video',\n\t\t\t\t\tx: currentPoint.x,\n\t\t\t\t\ty: currentPoint.y,\n\t\t\t\t\topacity: 1,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tassetId: asset.id,\n\t\t\t\t\t\tw: asset.props.w,\n\t\t\t\t\t\th: asset.props.h,\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\tcurrentPoint.x += asset.props.w\n\t\t\t}\n\t\t}\n\t}\n\n\teditor.run(() => {\n\t\t// Create any assets\n\t\tconst assetsToCreate = assets.filter((asset) => !editor.getAsset(asset.id))\n\n\t\teditor.store.atomic(() => {\n\t\t\tif (editor.canCreateShapes(partials)) {\n\t\t\t\tif (assetsToCreate.length) {\n\t\t\t\t\teditor.createAssets(assetsToCreate)\n\t\t\t\t}\n\n\t\t\t\t// Create the shapes\n\t\t\t\teditor.createShapes(partials).select(...partials.map((p) => p.id))\n\n\t\t\t\t// Re-position shapes so that the center of the group is at the provided point\n\t\t\t\tcenterSelectionAroundPoint(editor, position)\n\t\t\t}\n\t\t})\n\t})\n\n\treturn partials.map((p) => p.id)\n}\n\n/**\n * Repositions selected shapes do that the center of the group is\n * at the provided position\n *\n * @param editor - The editor instance\n *\n * @param position - the point to center the shapes around\n *\n * @public\n */\nexport function centerSelectionAroundPoint(editor: Editor, position: VecLike) {\n\t// Re-position shapes so that the center of the group is at the provided point\n\tconst viewportPageBounds = editor.getViewportPageBounds()\n\tlet selectionPageBounds = editor.getSelectionPageBounds()\n\n\tif (selectionPageBounds) {\n\t\tconst offset = selectionPageBounds!.center.sub(position)\n\n\t\teditor.updateShapes(\n\t\t\teditor.getSelectedShapes().map((shape) => {\n\t\t\t\tconst localRotation = editor.getShapeParentTransform(shape).decompose().rotation\n\t\t\t\tconst localDelta = Vec.Rot(offset, -localRotation)\n\t\t\t\treturn {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tx: shape.x! - localDelta.x,\n\t\t\t\t\ty: shape.y! - localDelta.y,\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t}\n\tselectionPageBounds = editor.getSelectionPageBounds()\n\t// align selection with the grid if necessary\n\tif (selectionPageBounds && editor.getInstanceState().isGridMode) {\n\t\tconst gridSize = editor.getDocumentSettings().gridSize\n\t\tconst topLeft = new Vec(selectionPageBounds.minX, selectionPageBounds.minY)\n\t\tconst gridSnappedPoint = topLeft.clone().snapToGrid(gridSize)\n\t\tconst delta = Vec.Sub(topLeft, gridSnappedPoint)\n\t\teditor.updateShapes(\n\t\t\teditor.getSelectedShapes().map((shape) => {\n\t\t\t\tconst newPoint = { x: shape.x! - delta.x, y: shape.y! - delta.y }\n\t\t\t\treturn {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\ty: newPoint.y,\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t}\n\t// Zoom out to fit the shapes, if necessary\n\tselectionPageBounds = editor.getSelectionPageBounds()\n\tif (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {\n\t\teditor.zoomToSelection({ animation: { duration: editor.options.animationMediumMs } })\n\t}\n}\n\n/** @public */\nexport function createEmptyBookmarkShape(\n\teditor: Editor,\n\turl: string,\n\tposition: VecLike\n): TLBookmarkShape {\n\tconst partial: TLShapePartial = {\n\t\tid: createShapeId(),\n\t\ttype: 'bookmark',\n\t\tx: position.x - 150,\n\t\ty: position.y - 160,\n\t\topacity: 1,\n\t\tprops: {\n\t\t\tassetId: null,\n\t\t\turl,\n\t\t},\n\t}\n\n\teditor.run(() => {\n\t\t// Allow this to trigger the max shapes reached alert\n\t\teditor.createShape(partial)\n\t\tif (!editor.getShape(partial.id)) return\n\t\teditor.select(partial.id)\n\t\tcenterSelectionAroundPoint(editor, position)\n\t})\n\n\treturn editor.getShape(partial.id) as TLBookmarkShape\n}\n\n/**\n * Checks if a file is allowed to be uploaded. If it is not, it will show a toast explaining why to the user.\n *\n * @param file - The file to check\n * @param options - The options for the external content handler\n * @returns True if the file is allowed, false otherwise\n * @public\n */\nexport function notifyIfFileNotAllowed(file: File, options: TLDefaultExternalContentHandlerOpts) {\n\tconst {\n\t\tacceptedImageMimeTypes = DEFAULT_SUPPORTED_IMAGE_TYPES,\n\t\tacceptedVideoMimeTypes = DEFAULT_SUPPORT_VIDEO_TYPES,\n\t\tmaxAssetSize = DEFAULT_MAX_ASSET_SIZE,\n\t\ttoasts,\n\t\tmsg,\n\t} = options\n\tconst isImageType = acceptedImageMimeTypes.includes(file.type)\n\tconst isVideoType = acceptedVideoMimeTypes.includes(file.type)\n\n\tif (!isImageType && !isVideoType) {\n\t\ttoasts.addToast({\n\t\t\ttitle: msg('assets.files.type-not-allowed'),\n\t\t\tseverity: 'error',\n\t\t})\n\t\treturn false\n\t}\n\n\tif (file.size > maxAssetSize) {\n\t\ttoasts.addToast({\n\t\t\ttitle: msg('assets.files.size-too-big'),\n\t\t\tseverity: 'error',\n\t\t})\n\t\treturn false\n\t}\n\n\t// Use mime type instead of file ext, this is because\n\t// window.navigator.clipboard does not preserve file names\n\t// of copied files.\n\tif (!file.type) {\n\t\ttoasts.addToast({\n\t\t\ttitle: msg('assets.files.upload-failed'),\n\t\t\tseverity: 'error',\n\t\t})\n\t\tconsole.error('No mime type')\n\t\treturn false\n\t}\n\n\treturn true\n}\n\n/** @public */\nexport async function getAssetInfo(\n\tfile: File,\n\toptions: TLDefaultExternalContentHandlerOpts,\n\tassetId?: TLAssetId\n) {\n\tconst {\n\t\tacceptedImageMimeTypes = DEFAULT_SUPPORTED_IMAGE_TYPES,\n\t\tacceptedVideoMimeTypes = DEFAULT_SUPPORT_VIDEO_TYPES,\n\t\tmaxImageDimension = DEFAULT_MAX_IMAGE_DIMENSION,\n\t} = options\n\n\tconst isImageType = acceptedImageMimeTypes.includes(file.type)\n\tconst isVideoType = acceptedVideoMimeTypes.includes(file.type)\n\tconst hash = getHashForBuffer(await file.arrayBuffer())\n\tassetId ??= AssetRecordType.createId(hash)\n\tconst assetInfo = await getMediaAssetInfoPartial(\n\t\tfile,\n\t\tassetId,\n\t\tisImageType,\n\t\tisVideoType,\n\t\tmaxImageDimension\n\t)\n\treturn assetInfo\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["size"]
7
7
  }
@@ -3,7 +3,6 @@ import { tlenv, useEditor, useReactor, useValue } from "@tldraw/editor";
3
3
  import classNames from "classnames";
4
4
  import React, { useMemo, useRef, useState } from "react";
5
5
  import { SkipToMainContent } from "./components/A11y.mjs";
6
- import { FollowingIndicator } from "./components/FollowingIndicator.mjs";
7
6
  import { TldrawUiButton } from "./components/primitives/Button/TldrawUiButton.mjs";
8
7
  import { TldrawUiButtonIcon } from "./components/primitives/Button/TldrawUiButtonIcon.mjs";
9
8
  import { PORTRAIT_BREAKPOINT, PORTRAIT_BREAKPOINTS } from "./constants.mjs";
@@ -54,10 +53,6 @@ const TldrawUiContent = React.memo(function TldrawUI() {
54
53
  NavigationPanel,
55
54
  HelperButtons,
56
55
  DebugPanel,
57
- CursorChatBubble,
58
- RichTextToolbar,
59
- ImageToolbar,
60
- VideoToolbar,
61
56
  Toasts,
62
57
  Dialogs,
63
58
  A11y
@@ -152,18 +147,24 @@ const TldrawUiContent = React.memo(function TldrawUI() {
152
147
  A11y && /* @__PURE__ */ jsx(A11y, {})
153
148
  ] })
154
149
  ] }),
155
- RichTextToolbar && /* @__PURE__ */ jsx(RichTextToolbar, {}),
156
- ImageToolbar && /* @__PURE__ */ jsx(ImageToolbar, {}),
157
- VideoToolbar && /* @__PURE__ */ jsx(VideoToolbar, {}),
158
150
  Toasts && /* @__PURE__ */ jsx(Toasts, {}),
159
- Dialogs && /* @__PURE__ */ jsx(Dialogs, {}),
160
- /* @__PURE__ */ jsx(FollowingIndicator, {}),
161
- CursorChatBubble && /* @__PURE__ */ jsx(CursorChatBubble, {})
151
+ Dialogs && /* @__PURE__ */ jsx(Dialogs, {})
162
152
  ]
163
153
  }
164
154
  );
165
155
  });
156
+ function TldrawUiInFrontOfTheCanvas() {
157
+ const { RichTextToolbar, ImageToolbar, VideoToolbar, CursorChatBubble, FollowingIndicator } = useTldrawUiComponents();
158
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
159
+ RichTextToolbar && /* @__PURE__ */ jsx(RichTextToolbar, {}),
160
+ ImageToolbar && /* @__PURE__ */ jsx(ImageToolbar, {}),
161
+ VideoToolbar && /* @__PURE__ */ jsx(VideoToolbar, {}),
162
+ FollowingIndicator && /* @__PURE__ */ jsx(FollowingIndicator, {}),
163
+ CursorChatBubble && /* @__PURE__ */ jsx(CursorChatBubble, {})
164
+ ] });
165
+ }
166
166
  export {
167
- TldrawUi
167
+ TldrawUi,
168
+ TldrawUiInFrontOfTheCanvas
168
169
  };
169
170
  //# sourceMappingURL=TldrawUi.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/ui/TldrawUi.tsx"],
4
- "sourcesContent": ["import { tlenv, useEditor, useReactor, useValue } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport React, { ReactNode, useMemo, useRef, useState } from 'react'\nimport { TLUiAssetUrlOverrides } from './assetUrls'\nimport { SkipToMainContent } from './components/A11y'\nimport { FollowingIndicator } from './components/FollowingIndicator'\nimport { TldrawUiButton } from './components/primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from './components/primitives/Button/TldrawUiButtonIcon'\nimport { PORTRAIT_BREAKPOINT, PORTRAIT_BREAKPOINTS } from './constants'\nimport {\n\tTLUiContextProviderProps,\n\tTldrawUiContextProvider,\n} from './context/TldrawUiContextProvider'\nimport { useActions } from './context/actions'\nimport { useBreakpoint } from './context/breakpoints'\nimport { TLUiComponents, useTldrawUiComponents } from './context/components'\nimport { useNativeClipboardEvents } from './hooks/useClipboardEvents'\nimport { useEditorEvents } from './hooks/useEditorEvents'\nimport { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts'\nimport { useReadonly } from './hooks/useReadonly'\nimport { useTranslation } from './hooks/useTranslation/useTranslation'\n\n/** @public */\nexport interface TldrawUiProps extends TLUiContextProviderProps {\n\t/**\n\t * The component's children.\n\t */\n\tchildren?: ReactNode\n\n\t/**\n\t * Whether to hide the user interface and only display the canvas.\n\t */\n\thideUi?: boolean\n\n\t/**\n\t * Overrides for the UI components.\n\t */\n\tcomponents?: TLUiComponents\n\n\t/**\n\t * Additional items to add to the debug menu (will be deprecated)\n\t */\n\trenderDebugMenuItems?(): React.ReactNode\n\n\t/** Asset URL override. */\n\tassetUrls?: TLUiAssetUrlOverrides\n}\n\n/**\n * @public\n * @react\n */\nexport const TldrawUi = React.memo(function TldrawUi({\n\trenderDebugMenuItems,\n\tchildren,\n\thideUi,\n\tcomponents,\n\t...rest\n}: TldrawUiProps) {\n\treturn (\n\t\t<TldrawUiContextProvider {...rest} components={components}>\n\t\t\t<TldrawUiInner hideUi={hideUi} renderDebugMenuItems={renderDebugMenuItems}>\n\t\t\t\t{children}\n\t\t\t</TldrawUiInner>\n\t\t</TldrawUiContextProvider>\n\t)\n})\n\ninterface TldrawUiContentProps {\n\thideUi?: boolean\n\tshareZone?: ReactNode\n\ttopZone?: ReactNode\n\trenderDebugMenuItems?(): React.ReactNode\n}\n\nconst TldrawUiInner = React.memo(function TldrawUiInner({\n\tchildren,\n\thideUi,\n\t...rest\n}: TldrawUiContentProps & { children: ReactNode }) {\n\t// The hideUi prop should prevent the UI from mounting.\n\t// If we ever need want the UI to mount and preserve state, then\n\t// we should change this behavior and hide the UI via CSS instead.\n\n\treturn (\n\t\t<>\n\t\t\t{children}\n\t\t\t{hideUi ? null : <TldrawUiContent {...rest} />}\n\t\t</>\n\t)\n})\n\nconst TldrawUiContent = React.memo(function TldrawUI() {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\tconst breakpoint = useBreakpoint()\n\tconst isReadonlyMode = useReadonly()\n\tconst isFocusMode = useValue('focus', () => editor.getInstanceState().isFocusMode, [editor])\n\tconst isDebugMode = useValue('debug', () => editor.getInstanceState().isDebugMode, [editor])\n\n\tconst {\n\t\tSharePanel,\n\t\tTopPanel,\n\t\tMenuPanel,\n\t\tStylePanel,\n\t\tToolbar,\n\t\tHelpMenu,\n\t\tNavigationPanel,\n\t\tHelperButtons,\n\t\tDebugPanel,\n\t\tCursorChatBubble,\n\t\tRichTextToolbar,\n\t\tImageToolbar,\n\t\tVideoToolbar,\n\t\tToasts,\n\t\tDialogs,\n\t\tA11y,\n\t} = useTldrawUiComponents()\n\n\tuseKeyboardShortcuts()\n\tuseNativeClipboardEvents()\n\tuseEditorEvents()\n\n\tconst rIsEditingAnything = useRef(false)\n\tconst rHidingTimeout = useRef(-1 as any)\n\tconst [hideToolbarWhileEditing, setHideToolbarWhileEditing] = useState(false)\n\n\tuseReactor(\n\t\t'update hide toolbar while delayed',\n\t\t() => {\n\t\t\tconst isMobileEnvironment = tlenv.isIos || tlenv.isAndroid\n\t\t\tif (!isMobileEnvironment) return\n\n\t\t\tconst editingShape = editor.getEditingShapeId()\n\t\t\tif (editingShape === null) {\n\t\t\t\tif (rIsEditingAnything.current) {\n\t\t\t\t\trIsEditingAnything.current = false\n\t\t\t\t\tclearTimeout(rHidingTimeout.current)\n\t\t\t\t\tif (tlenv.isAndroid) {\n\t\t\t\t\t\t// On Android, hide it after 150ms\n\t\t\t\t\t\trHidingTimeout.current = editor.timers.setTimeout(() => {\n\t\t\t\t\t\t\tsetHideToolbarWhileEditing(false)\n\t\t\t\t\t\t}, 150)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// On iOS, just hide it immediately\n\t\t\t\t\t\tsetHideToolbarWhileEditing(false)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (!rIsEditingAnything.current) {\n\t\t\t\trIsEditingAnything.current = true\n\t\t\t\tclearTimeout(rHidingTimeout.current)\n\t\t\t\tsetHideToolbarWhileEditing(true)\n\t\t\t}\n\t\t},\n\t\t[]\n\t)\n\n\tconst { 'toggle-focus-mode': toggleFocus } = useActions()\n\n\tconst { breakpointsAbove, breakpointsBelow } = useMemo(() => {\n\t\tconst breakpointsAbove = []\n\t\tconst breakpointsBelow = []\n\t\tfor (let bp = 0; bp < PORTRAIT_BREAKPOINTS.length; bp++) {\n\t\t\tif (bp <= breakpoint) {\n\t\t\t\tbreakpointsAbove.push(bp)\n\t\t\t} else {\n\t\t\t\tbreakpointsBelow.push(bp)\n\t\t\t}\n\t\t}\n\t\treturn { breakpointsAbove, breakpointsBelow }\n\t}, [breakpoint])\n\n\treturn (\n\t\t<div\n\t\t\tclassName={classNames('tlui-layout', {\n\t\t\t\t'tlui-layout__mobile': breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM,\n\t\t\t})}\n\t\t\t// When the virtual keyboard is opening we want it to hide immediately.\n\t\t\t// But when the virtual keyboard is closing we want to wait a bit before showing it again.\n\t\t\tdata-iseditinganything={hideToolbarWhileEditing}\n\t\t\tdata-breakpoint={breakpoint}\n\t\t\tdata-breakpoints-above={breakpointsAbove.join(' ')}\n\t\t\tdata-breakpoints-below={breakpointsBelow.join(' ')}\n\t\t>\n\t\t\t<SkipToMainContent />\n\t\t\t{isFocusMode ? (\n\t\t\t\t<div className=\"tlui-layout__top\">\n\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\tclassName=\"tlui-focus-button\"\n\t\t\t\t\t\ttitle={msg('focus-mode.toggle-focus-mode')}\n\t\t\t\t\t\tonClick={() => toggleFocus.onSelect('menu')}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TldrawUiButtonIcon icon=\"dot\" />\n\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"tlui-layout__top\">\n\t\t\t\t\t\t<div className=\"tlui-layout__top__left\">\n\t\t\t\t\t\t\t{MenuPanel && <MenuPanel />}\n\t\t\t\t\t\t\t{HelperButtons && <HelperButtons />}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"tlui-layout__top__center\">{TopPanel && <TopPanel />}</div>\n\t\t\t\t\t\t<div className=\"tlui-layout__top__right\">\n\t\t\t\t\t\t\t{SharePanel && <SharePanel />}\n\t\t\t\t\t\t\t{StylePanel && breakpoint >= PORTRAIT_BREAKPOINT.TABLET_SM && !isReadonlyMode && (\n\t\t\t\t\t\t\t\t<StylePanel />\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"tlui-layout__bottom\">\n\t\t\t\t\t\t<div className=\"tlui-layout__bottom__main\">\n\t\t\t\t\t\t\t{NavigationPanel && <NavigationPanel />}\n\t\t\t\t\t\t\t{Toolbar && <Toolbar />}\n\t\t\t\t\t\t\t{HelpMenu && <HelpMenu />}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{isDebugMode && DebugPanel && <DebugPanel />}\n\t\t\t\t\t\t{A11y && <A11y />}\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t)}\n\t\t\t{RichTextToolbar && <RichTextToolbar />}\n\t\t\t{ImageToolbar && <ImageToolbar />}\n\t\t\t{VideoToolbar && <VideoToolbar />}\n\t\t\t{Toasts && <Toasts />}\n\t\t\t{Dialogs && <Dialogs />}\n\t\t\t<FollowingIndicator />\n\t\t\t{CursorChatBubble && <CursorChatBubble />}\n\t\t</div>\n\t)\n})\n"],
5
- "mappings": "AA6DG,SAwBD,UAxBC,KAwBD,YAxBC;AA7DH,SAAS,OAAO,WAAW,YAAY,gBAAgB;AACvD,OAAO,gBAAgB;AACvB,OAAO,SAAoB,SAAS,QAAQ,gBAAgB;AAE5D,SAAS,yBAAyB;AAClC,SAAS,0BAA0B;AACnC,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AACnC,SAAS,qBAAqB,4BAA4B;AAC1D;AAAA,EAEC;AAAA,OACM;AACP,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAyB,6BAA6B;AACtD,SAAS,gCAAgC;AACzC,SAAS,uBAAuB;AAChC,SAAS,4BAA4B;AACrC,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAgCxB,MAAM,WAAW,MAAM,KAAK,SAASA,UAAS;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACJ,GAAkB;AACjB,SACC,oBAAC,2BAAyB,GAAG,MAAM,YAClC,8BAAC,iBAAc,QAAgB,sBAC7B,UACF,GACD;AAEF,CAAC;AASD,MAAM,gBAAgB,MAAM,KAAK,SAASC,eAAc;AAAA,EACvD;AAAA,EACA;AAAA,EACA,GAAG;AACJ,GAAmD;AAKlD,SACC,iCACE;AAAA;AAAA,IACA,SAAS,OAAO,oBAAC,mBAAiB,GAAG,MAAM;AAAA,KAC7C;AAEF,CAAC;AAED,MAAM,kBAAkB,MAAM,KAAK,SAAS,WAAW;AACtD,QAAM,SAAS,UAAU;AACzB,QAAM,MAAM,eAAe;AAC3B,QAAM,aAAa,cAAc;AACjC,QAAM,iBAAiB,YAAY;AACnC,QAAM,cAAc,SAAS,SAAS,MAAM,OAAO,iBAAiB,EAAE,aAAa,CAAC,MAAM,CAAC;AAC3F,QAAM,cAAc,SAAS,SAAS,MAAM,OAAO,iBAAiB,EAAE,aAAa,CAAC,MAAM,CAAC;AAE3F,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI,sBAAsB;AAE1B,uBAAqB;AACrB,2BAAyB;AACzB,kBAAgB;AAEhB,QAAM,qBAAqB,OAAO,KAAK;AACvC,QAAM,iBAAiB,OAAO,EAAS;AACvC,QAAM,CAAC,yBAAyB,0BAA0B,IAAI,SAAS,KAAK;AAE5E;AAAA,IACC;AAAA,IACA,MAAM;AACL,YAAM,sBAAsB,MAAM,SAAS,MAAM;AACjD,UAAI,CAAC,oBAAqB;AAE1B,YAAM,eAAe,OAAO,kBAAkB;AAC9C,UAAI,iBAAiB,MAAM;AAC1B,YAAI,mBAAmB,SAAS;AAC/B,6BAAmB,UAAU;AAC7B,uBAAa,eAAe,OAAO;AACnC,cAAI,MAAM,WAAW;AAEpB,2BAAe,UAAU,OAAO,OAAO,WAAW,MAAM;AACvD,yCAA2B,KAAK;AAAA,YACjC,GAAG,GAAG;AAAA,UACP,OAAO;AAEN,uCAA2B,KAAK;AAAA,UACjC;AAAA,QACD;AACA;AAAA,MACD;AAEA,UAAI,CAAC,mBAAmB,SAAS;AAChC,2BAAmB,UAAU;AAC7B,qBAAa,eAAe,OAAO;AACnC,mCAA2B,IAAI;AAAA,MAChC;AAAA,IACD;AAAA,IACA,CAAC;AAAA,EACF;AAEA,QAAM,EAAE,qBAAqB,YAAY,IAAI,WAAW;AAExD,QAAM,EAAE,kBAAkB,iBAAiB,IAAI,QAAQ,MAAM;AAC5D,UAAMC,oBAAmB,CAAC;AAC1B,UAAMC,oBAAmB,CAAC;AAC1B,aAAS,KAAK,GAAG,KAAK,qBAAqB,QAAQ,MAAM;AACxD,UAAI,MAAM,YAAY;AACrB,QAAAD,kBAAiB,KAAK,EAAE;AAAA,MACzB,OAAO;AACN,QAAAC,kBAAiB,KAAK,EAAE;AAAA,MACzB;AAAA,IACD;AACA,WAAO,EAAE,kBAAAD,mBAAkB,kBAAAC,kBAAiB;AAAA,EAC7C,GAAG,CAAC,UAAU,CAAC;AAEf,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAW,WAAW,eAAe;AAAA,QACpC,uBAAuB,aAAa,oBAAoB;AAAA,MACzD,CAAC;AAAA,MAGD,0BAAwB;AAAA,MACxB,mBAAiB;AAAA,MACjB,0BAAwB,iBAAiB,KAAK,GAAG;AAAA,MACjD,0BAAwB,iBAAiB,KAAK,GAAG;AAAA,MAEjD;AAAA,4BAAC,qBAAkB;AAAA,QAClB,cACA,oBAAC,SAAI,WAAU,oBACd;AAAA,UAAC;AAAA;AAAA,YACA,MAAK;AAAA,YACL,WAAU;AAAA,YACV,OAAO,IAAI,8BAA8B;AAAA,YACzC,SAAS,MAAM,YAAY,SAAS,MAAM;AAAA,YAE1C,8BAAC,sBAAmB,MAAK,OAAM;AAAA;AAAA,QAChC,GACD,IAEA,iCACC;AAAA,+BAAC,SAAI,WAAU,oBACd;AAAA,iCAAC,SAAI,WAAU,0BACb;AAAA,2BAAa,oBAAC,aAAU;AAAA,cACxB,iBAAiB,oBAAC,iBAAc;AAAA,eAClC;AAAA,YACA,oBAAC,SAAI,WAAU,4BAA4B,sBAAY,oBAAC,YAAS,GAAG;AAAA,YACpE,qBAAC,SAAI,WAAU,2BACb;AAAA,4BAAc,oBAAC,cAAW;AAAA,cAC1B,cAAc,cAAc,oBAAoB,aAAa,CAAC,kBAC9D,oBAAC,cAAW;AAAA,eAEd;AAAA,aACD;AAAA,UACA,qBAAC,SAAI,WAAU,uBACd;AAAA,iCAAC,SAAI,WAAU,6BACb;AAAA,iCAAmB,oBAAC,mBAAgB;AAAA,cACpC,WAAW,oBAAC,WAAQ;AAAA,cACpB,YAAY,oBAAC,YAAS;AAAA,eACxB;AAAA,YACC,eAAe,cAAc,oBAAC,cAAW;AAAA,YACzC,QAAQ,oBAAC,QAAK;AAAA,aAChB;AAAA,WACD;AAAA,QAEA,mBAAmB,oBAAC,mBAAgB;AAAA,QACpC,gBAAgB,oBAAC,gBAAa;AAAA,QAC9B,gBAAgB,oBAAC,gBAAa;AAAA,QAC9B,UAAU,oBAAC,UAAO;AAAA,QAClB,WAAW,oBAAC,WAAQ;AAAA,QACrB,oBAAC,sBAAmB;AAAA,QACnB,oBAAoB,oBAAC,oBAAiB;AAAA;AAAA;AAAA,EACxC;AAEF,CAAC;",
4
+ "sourcesContent": ["import { tlenv, useEditor, useReactor, useValue } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport React, { ReactNode, useMemo, useRef, useState } from 'react'\nimport { TLUiAssetUrlOverrides } from './assetUrls'\nimport { SkipToMainContent } from './components/A11y'\nimport { TldrawUiButton } from './components/primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from './components/primitives/Button/TldrawUiButtonIcon'\nimport { PORTRAIT_BREAKPOINT, PORTRAIT_BREAKPOINTS } from './constants'\nimport {\n\tTLUiContextProviderProps,\n\tTldrawUiContextProvider,\n} from './context/TldrawUiContextProvider'\nimport { useActions } from './context/actions'\nimport { useBreakpoint } from './context/breakpoints'\nimport { TLUiComponents, useTldrawUiComponents } from './context/components'\nimport { useNativeClipboardEvents } from './hooks/useClipboardEvents'\nimport { useEditorEvents } from './hooks/useEditorEvents'\nimport { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts'\nimport { useReadonly } from './hooks/useReadonly'\nimport { useTranslation } from './hooks/useTranslation/useTranslation'\n\n/** @public */\nexport interface TldrawUiProps extends TLUiContextProviderProps {\n\t/**\n\t * The component's children.\n\t */\n\tchildren?: ReactNode\n\n\t/**\n\t * Whether to hide the user interface and only display the canvas.\n\t */\n\thideUi?: boolean\n\n\t/**\n\t * Overrides for the UI components.\n\t */\n\tcomponents?: TLUiComponents\n\n\t/**\n\t * Additional items to add to the debug menu (will be deprecated)\n\t */\n\trenderDebugMenuItems?(): React.ReactNode\n\n\t/** Asset URL override. */\n\tassetUrls?: TLUiAssetUrlOverrides\n}\n\n/**\n * @public\n * @react\n */\nexport const TldrawUi = React.memo(function TldrawUi({\n\trenderDebugMenuItems,\n\tchildren,\n\thideUi,\n\tcomponents,\n\t...rest\n}: TldrawUiProps) {\n\treturn (\n\t\t<TldrawUiContextProvider {...rest} components={components}>\n\t\t\t<TldrawUiInner hideUi={hideUi} renderDebugMenuItems={renderDebugMenuItems}>\n\t\t\t\t{children}\n\t\t\t</TldrawUiInner>\n\t\t</TldrawUiContextProvider>\n\t)\n})\n\ninterface TldrawUiContentProps {\n\thideUi?: boolean\n\tshareZone?: ReactNode\n\ttopZone?: ReactNode\n\trenderDebugMenuItems?(): React.ReactNode\n}\n\nconst TldrawUiInner = React.memo(function TldrawUiInner({\n\tchildren,\n\thideUi,\n\t...rest\n}: TldrawUiContentProps & { children: ReactNode }) {\n\t// The hideUi prop should prevent the UI from mounting.\n\t// If we ever need want the UI to mount and preserve state, then\n\t// we should change this behavior and hide the UI via CSS instead.\n\n\treturn (\n\t\t<>\n\t\t\t{children}\n\t\t\t{hideUi ? null : <TldrawUiContent {...rest} />}\n\t\t</>\n\t)\n})\n\nconst TldrawUiContent = React.memo(function TldrawUI() {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\tconst breakpoint = useBreakpoint()\n\tconst isReadonlyMode = useReadonly()\n\tconst isFocusMode = useValue('focus', () => editor.getInstanceState().isFocusMode, [editor])\n\tconst isDebugMode = useValue('debug', () => editor.getInstanceState().isDebugMode, [editor])\n\n\tconst {\n\t\tSharePanel,\n\t\tTopPanel,\n\t\tMenuPanel,\n\t\tStylePanel,\n\t\tToolbar,\n\t\tHelpMenu,\n\t\tNavigationPanel,\n\t\tHelperButtons,\n\t\tDebugPanel,\n\t\tToasts,\n\t\tDialogs,\n\t\tA11y,\n\t} = useTldrawUiComponents()\n\n\tuseKeyboardShortcuts()\n\tuseNativeClipboardEvents()\n\tuseEditorEvents()\n\n\tconst rIsEditingAnything = useRef(false)\n\tconst rHidingTimeout = useRef(-1 as any)\n\tconst [hideToolbarWhileEditing, setHideToolbarWhileEditing] = useState(false)\n\n\tuseReactor(\n\t\t'update hide toolbar while delayed',\n\t\t() => {\n\t\t\tconst isMobileEnvironment = tlenv.isIos || tlenv.isAndroid\n\t\t\tif (!isMobileEnvironment) return\n\n\t\t\tconst editingShape = editor.getEditingShapeId()\n\t\t\tif (editingShape === null) {\n\t\t\t\tif (rIsEditingAnything.current) {\n\t\t\t\t\trIsEditingAnything.current = false\n\t\t\t\t\tclearTimeout(rHidingTimeout.current)\n\t\t\t\t\tif (tlenv.isAndroid) {\n\t\t\t\t\t\t// On Android, hide it after 150ms\n\t\t\t\t\t\trHidingTimeout.current = editor.timers.setTimeout(() => {\n\t\t\t\t\t\t\tsetHideToolbarWhileEditing(false)\n\t\t\t\t\t\t}, 150)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// On iOS, just hide it immediately\n\t\t\t\t\t\tsetHideToolbarWhileEditing(false)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (!rIsEditingAnything.current) {\n\t\t\t\trIsEditingAnything.current = true\n\t\t\t\tclearTimeout(rHidingTimeout.current)\n\t\t\t\tsetHideToolbarWhileEditing(true)\n\t\t\t}\n\t\t},\n\t\t[]\n\t)\n\n\tconst { 'toggle-focus-mode': toggleFocus } = useActions()\n\n\tconst { breakpointsAbove, breakpointsBelow } = useMemo(() => {\n\t\tconst breakpointsAbove = []\n\t\tconst breakpointsBelow = []\n\t\tfor (let bp = 0; bp < PORTRAIT_BREAKPOINTS.length; bp++) {\n\t\t\tif (bp <= breakpoint) {\n\t\t\t\tbreakpointsAbove.push(bp)\n\t\t\t} else {\n\t\t\t\tbreakpointsBelow.push(bp)\n\t\t\t}\n\t\t}\n\t\treturn { breakpointsAbove, breakpointsBelow }\n\t}, [breakpoint])\n\n\treturn (\n\t\t<div\n\t\t\tclassName={classNames('tlui-layout', {\n\t\t\t\t'tlui-layout__mobile': breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM,\n\t\t\t})}\n\t\t\t// When the virtual keyboard is opening we want it to hide immediately.\n\t\t\t// But when the virtual keyboard is closing we want to wait a bit before showing it again.\n\t\t\tdata-iseditinganything={hideToolbarWhileEditing}\n\t\t\tdata-breakpoint={breakpoint}\n\t\t\tdata-breakpoints-above={breakpointsAbove.join(' ')}\n\t\t\tdata-breakpoints-below={breakpointsBelow.join(' ')}\n\t\t>\n\t\t\t<SkipToMainContent />\n\t\t\t{isFocusMode ? (\n\t\t\t\t<div className=\"tlui-layout__top\">\n\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\tclassName=\"tlui-focus-button\"\n\t\t\t\t\t\ttitle={msg('focus-mode.toggle-focus-mode')}\n\t\t\t\t\t\tonClick={() => toggleFocus.onSelect('menu')}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TldrawUiButtonIcon icon=\"dot\" />\n\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"tlui-layout__top\">\n\t\t\t\t\t\t<div className=\"tlui-layout__top__left\">\n\t\t\t\t\t\t\t{MenuPanel && <MenuPanel />}\n\t\t\t\t\t\t\t{HelperButtons && <HelperButtons />}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"tlui-layout__top__center\">{TopPanel && <TopPanel />}</div>\n\t\t\t\t\t\t<div className=\"tlui-layout__top__right\">\n\t\t\t\t\t\t\t{SharePanel && <SharePanel />}\n\t\t\t\t\t\t\t{StylePanel && breakpoint >= PORTRAIT_BREAKPOINT.TABLET_SM && !isReadonlyMode && (\n\t\t\t\t\t\t\t\t<StylePanel />\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"tlui-layout__bottom\">\n\t\t\t\t\t\t<div className=\"tlui-layout__bottom__main\">\n\t\t\t\t\t\t\t{NavigationPanel && <NavigationPanel />}\n\t\t\t\t\t\t\t{Toolbar && <Toolbar />}\n\t\t\t\t\t\t\t{HelpMenu && <HelpMenu />}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{isDebugMode && DebugPanel && <DebugPanel />}\n\t\t\t\t\t\t{A11y && <A11y />}\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t)}\n\t\t\t{Toasts && <Toasts />}\n\t\t\t{Dialogs && <Dialogs />}\n\t\t</div>\n\t)\n})\n\n/** @public @react */\nexport function TldrawUiInFrontOfTheCanvas() {\n\tconst { RichTextToolbar, ImageToolbar, VideoToolbar, CursorChatBubble, FollowingIndicator } =\n\t\tuseTldrawUiComponents()\n\n\treturn (\n\t\t<>\n\t\t\t{RichTextToolbar && <RichTextToolbar />}\n\t\t\t{ImageToolbar && <ImageToolbar />}\n\t\t\t{VideoToolbar && <VideoToolbar />}\n\t\t\t{FollowingIndicator && <FollowingIndicator />}\n\t\t\t{CursorChatBubble && <CursorChatBubble />}\n\t\t</>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["TldrawUi", "TldrawUiInner", "breakpointsAbove", "breakpointsBelow"]
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useEditor, usePresence, useValue } from "@tldraw/editor";
3
- function FollowingIndicator() {
3
+ function DefaultFollowingIndicator() {
4
4
  const editor = useEditor();
5
5
  const followingUserId = useValue("follow", () => editor.getInstanceState().followingUserId, [
6
6
  editor
@@ -14,6 +14,6 @@ function FollowingIndicatorInner({ userId }) {
14
14
  return /* @__PURE__ */ jsx("div", { className: "tlui-following-indicator", style: { borderColor: presence.color } });
15
15
  }
16
16
  export {
17
- FollowingIndicator
17
+ DefaultFollowingIndicator
18
18
  };
19
- //# sourceMappingURL=FollowingIndicator.mjs.map
19
+ //# sourceMappingURL=DefaultFollowingIndicator.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/lib/ui/components/DefaultFollowingIndicator.tsx"],
4
+ "sourcesContent": ["import { useEditor, usePresence, useValue } from '@tldraw/editor'\n\n/** @public @react */\nexport function DefaultFollowingIndicator() {\n\tconst editor = useEditor()\n\tconst followingUserId = useValue('follow', () => editor.getInstanceState().followingUserId, [\n\t\teditor,\n\t])\n\tif (!followingUserId) return null\n\treturn <FollowingIndicatorInner userId={followingUserId} />\n}\n\nfunction FollowingIndicatorInner({ userId }: { userId: string }) {\n\tconst presence = usePresence(userId)\n\tif (!presence) return null\n\treturn <div className=\"tlui-following-indicator\" style={{ borderColor: presence.color }} />\n}\n"],
5
+ "mappings": "AASQ;AATR,SAAS,WAAW,aAAa,gBAAgB;AAG1C,SAAS,4BAA4B;AAC3C,QAAM,SAAS,UAAU;AACzB,QAAM,kBAAkB,SAAS,UAAU,MAAM,OAAO,iBAAiB,EAAE,iBAAiB;AAAA,IAC3F;AAAA,EACD,CAAC;AACD,MAAI,CAAC,gBAAiB,QAAO;AAC7B,SAAO,oBAAC,2BAAwB,QAAQ,iBAAiB;AAC1D;AAEA,SAAS,wBAAwB,EAAE,OAAO,GAAuB;AAChE,QAAM,WAAW,YAAY,MAAM;AACnC,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO,oBAAC,SAAI,WAAU,4BAA2B,OAAO,EAAE,aAAa,SAAS,MAAM,GAAG;AAC1F;",
6
+ "names": []
7
+ }
@@ -11,6 +11,7 @@ import {
11
11
  import { CursorChatBubble } from "../components/CursorChatBubble.mjs";
12
12
  import { DefaultDebugMenu } from "../components/DebugMenu/DefaultDebugMenu.mjs";
13
13
  import { DefaultDebugPanel } from "../components/DefaultDebugPanel.mjs";
14
+ import { DefaultFollowingIndicator } from "../components/DefaultFollowingIndicator.mjs";
14
15
  import { DefaultMenuPanel } from "../components/DefaultMenuPanel.mjs";
15
16
  import { DefaultDialogs } from "../components/Dialogs.mjs";
16
17
  import {
@@ -75,6 +76,7 @@ function TldrawUiComponentsProvider({
75
76
  Dialogs: DefaultDialogs,
76
77
  Toasts: DefaultToasts,
77
78
  A11y: DefaultA11yAnnouncer,
79
+ FollowingIndicator: DefaultFollowingIndicator,
78
80
  ..._overrides
79
81
  }),
80
82
  [_overrides, showCollaborationUi]
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/ui/context/components.tsx"],
4
- "sourcesContent": ["import { useShallowObjectIdentity } from '@tldraw/editor'\nimport { ComponentType, ReactNode, createContext, useContext, useMemo } from 'react'\nimport { DefaultA11yAnnouncer } from '../components/A11y'\nimport {\n\tDefaultActionsMenu,\n\tTLUiActionsMenuProps,\n} from '../components/ActionsMenu/DefaultActionsMenu'\nimport {\n\tDefaultContextMenu,\n\tTLUiContextMenuProps,\n} from '../components/ContextMenu/DefaultContextMenu'\nimport { CursorChatBubble } from '../components/CursorChatBubble'\nimport { DefaultDebugMenu } from '../components/DebugMenu/DefaultDebugMenu'\nimport { DefaultDebugPanel } from '../components/DefaultDebugPanel'\nimport { DefaultMenuPanel } from '../components/DefaultMenuPanel'\nimport { DefaultDialogs } from '../components/Dialogs'\nimport { TLUiHelpMenuProps } from '../components/HelpMenu/DefaultHelpMenu'\nimport {\n\tDefaultHelperButtons,\n\tTLUiHelperButtonsProps,\n} from '../components/HelperButtons/DefaultHelperButtons'\nimport {\n\tDefaultKeyboardShortcutsDialog,\n\tTLUiKeyboardShortcutsDialogProps,\n} from '../components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialog'\nimport { DefaultMainMenu, TLUiMainMenuProps } from '../components/MainMenu/DefaultMainMenu'\nimport { DefaultMinimap } from '../components/Minimap/DefaultMinimap'\nimport { DefaultNavigationPanel } from '../components/NavigationPanel/DefaultNavigationPanel'\nimport { DefaultPageMenu } from '../components/PageMenu/DefaultPageMenu'\nimport {\n\tDefaultQuickActions,\n\tTLUiQuickActionsProps,\n} from '../components/QuickActions/DefaultQuickActions'\nimport { DefaultSharePanel } from '../components/SharePanel/DefaultSharePanel'\nimport { DefaultStylePanel, TLUiStylePanelProps } from '../components/StylePanel/DefaultStylePanel'\nimport { DefaultToasts } from '../components/Toasts'\nimport { DefaultImageToolbar } from '../components/Toolbar/DefaultImageToolbar'\nimport {\n\tDefaultRichTextToolbar,\n\tTLUiRichTextToolbarProps,\n} from '../components/Toolbar/DefaultRichTextToolbar'\nimport { DefaultToolbar } from '../components/Toolbar/DefaultToolbar'\nimport { DefaultVideoToolbar } from '../components/Toolbar/DefaultVideoToolbar'\nimport { DefaultTopPanel } from '../components/TopPanel/DefaultTopPanel'\nimport { DefaultZoomMenu, TLUiZoomMenuProps } from '../components/ZoomMenu/DefaultZoomMenu'\nimport { useShowCollaborationUi } from '../hooks/useCollaborationStatus'\n\n/** @public */\nexport interface TLUiComponents {\n\tContextMenu?: ComponentType<TLUiContextMenuProps> | null\n\tActionsMenu?: ComponentType<TLUiActionsMenuProps> | null\n\tHelpMenu?: ComponentType<TLUiHelpMenuProps> | null\n\tZoomMenu?: ComponentType<TLUiZoomMenuProps> | null\n\tMainMenu?: ComponentType<TLUiMainMenuProps> | null\n\tMinimap?: ComponentType | null\n\tStylePanel?: ComponentType<TLUiStylePanelProps> | null\n\tPageMenu?: ComponentType | null\n\tNavigationPanel?: ComponentType | null\n\tToolbar?: ComponentType | null\n\tRichTextToolbar?: ComponentType<TLUiRichTextToolbarProps> | null\n\tImageToolbar?: ComponentType | null\n\tVideoToolbar?: ComponentType | null\n\tKeyboardShortcutsDialog?: ComponentType<TLUiKeyboardShortcutsDialogProps> | null\n\tQuickActions?: ComponentType<TLUiQuickActionsProps> | null\n\tHelperButtons?: ComponentType<TLUiHelperButtonsProps> | null\n\tDebugPanel?: ComponentType | null\n\tDebugMenu?: ComponentType | null\n\tMenuPanel?: ComponentType | null\n\tTopPanel?: ComponentType | null\n\tSharePanel?: ComponentType | null\n\tCursorChatBubble?: ComponentType | null\n\tDialogs?: ComponentType | null\n\tToasts?: ComponentType | null\n\tA11y?: ComponentType | null\n}\n\nconst TldrawUiComponentsContext = createContext<TLUiComponents | null>(null)\n\n/** @public */\nexport interface TLUiComponentsProviderProps {\n\toverrides?: TLUiComponents\n\tchildren: ReactNode\n}\n\n/** @public @react */\nexport function TldrawUiComponentsProvider({\n\toverrides = {},\n\tchildren,\n}: TLUiComponentsProviderProps) {\n\tconst _overrides = useShallowObjectIdentity(overrides)\n\tconst showCollaborationUi = useShowCollaborationUi()\n\n\treturn (\n\t\t<TldrawUiComponentsContext.Provider\n\t\t\tvalue={useMemo(\n\t\t\t\t() => ({\n\t\t\t\t\tContextMenu: DefaultContextMenu,\n\t\t\t\t\tActionsMenu: DefaultActionsMenu,\n\t\t\t\t\tHelpMenu: null,\n\t\t\t\t\tZoomMenu: DefaultZoomMenu,\n\t\t\t\t\tMainMenu: DefaultMainMenu,\n\t\t\t\t\tMinimap: DefaultMinimap,\n\t\t\t\t\tStylePanel: DefaultStylePanel,\n\t\t\t\t\tPageMenu: DefaultPageMenu,\n\t\t\t\t\tNavigationPanel: DefaultNavigationPanel,\n\t\t\t\t\tToolbar: DefaultToolbar,\n\t\t\t\t\tRichTextToolbar: DefaultRichTextToolbar,\n\t\t\t\t\tImageToolbar: DefaultImageToolbar,\n\t\t\t\t\tVideoToolbar: DefaultVideoToolbar,\n\t\t\t\t\tKeyboardShortcutsDialog: DefaultKeyboardShortcutsDialog,\n\t\t\t\t\tQuickActions: DefaultQuickActions,\n\t\t\t\t\tHelperButtons: DefaultHelperButtons,\n\t\t\t\t\tDebugPanel: DefaultDebugPanel,\n\t\t\t\t\tDebugMenu: DefaultDebugMenu,\n\t\t\t\t\tMenuPanel: DefaultMenuPanel,\n\t\t\t\t\tSharePanel: showCollaborationUi ? DefaultSharePanel : null,\n\t\t\t\t\tCursorChatBubble: showCollaborationUi ? CursorChatBubble : null,\n\t\t\t\t\tTopPanel: showCollaborationUi ? DefaultTopPanel : null,\n\t\t\t\t\tDialogs: DefaultDialogs,\n\t\t\t\t\tToasts: DefaultToasts,\n\t\t\t\t\tA11y: DefaultA11yAnnouncer,\n\t\t\t\t\t..._overrides,\n\t\t\t\t}),\n\t\t\t\t[_overrides, showCollaborationUi]\n\t\t\t)}\n\t\t>\n\t\t\t{children}\n\t\t</TldrawUiComponentsContext.Provider>\n\t)\n}\n\n/** @public */\nexport function useTldrawUiComponents() {\n\tconst components = useContext(TldrawUiComponentsContext)\n\tif (!components) {\n\t\tthrow new Error('useTldrawUiComponents must be used within a TldrawUiComponentsProvider')\n\t}\n\treturn components\n}\n"],
5
- "mappings": "AA6FE;AA7FF,SAAS,gCAAgC;AACzC,SAAmC,eAAe,YAAY,eAAe;AAC7E,SAAS,4BAA4B;AACrC;AAAA,EACC;AAAA,OAEM;AACP;AAAA,EACC;AAAA,OAEM;AACP,SAAS,wBAAwB;AACjC,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;AACjC,SAAS,sBAAsB;AAE/B;AAAA,EACC;AAAA,OAEM;AACP;AAAA,EACC;AAAA,OAEM;AACP,SAAS,uBAA0C;AACnD,SAAS,sBAAsB;AAC/B,SAAS,8BAA8B;AACvC,SAAS,uBAAuB;AAChC;AAAA,EACC;AAAA,OAEM;AACP,SAAS,yBAAyB;AAClC,SAAS,yBAA8C;AACvD,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC;AAAA,EACC;AAAA,OAEM;AACP,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,uBAAuB;AAChC,SAAS,uBAA0C;AACnD,SAAS,8BAA8B;AA+BvC,MAAM,4BAA4B,cAAqC,IAAI;AASpE,SAAS,2BAA2B;AAAA,EAC1C,YAAY,CAAC;AAAA,EACb;AACD,GAAgC;AAC/B,QAAM,aAAa,yBAAyB,SAAS;AACrD,QAAM,sBAAsB,uBAAuB;AAEnD,SACC;AAAA,IAAC,0BAA0B;AAAA,IAA1B;AAAA,MACA,OAAO;AAAA,QACN,OAAO;AAAA,UACN,aAAa;AAAA,UACb,aAAa;AAAA,UACb,UAAU;AAAA,UACV,UAAU;AAAA,UACV,UAAU;AAAA,UACV,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,iBAAiB;AAAA,UACjB,SAAS;AAAA,UACT,iBAAiB;AAAA,UACjB,cAAc;AAAA,UACd,cAAc;AAAA,UACd,yBAAyB;AAAA,UACzB,cAAc;AAAA,UACd,eAAe;AAAA,UACf,YAAY;AAAA,UACZ,WAAW;AAAA,UACX,WAAW;AAAA,UACX,YAAY,sBAAsB,oBAAoB;AAAA,UACtD,kBAAkB,sBAAsB,mBAAmB;AAAA,UAC3D,UAAU,sBAAsB,kBAAkB;AAAA,UAClD,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,GAAG;AAAA,QACJ;AAAA,QACA,CAAC,YAAY,mBAAmB;AAAA,MACjC;AAAA,MAEC;AAAA;AAAA,EACF;AAEF;AAGO,SAAS,wBAAwB;AACvC,QAAM,aAAa,WAAW,yBAAyB;AACvD,MAAI,CAAC,YAAY;AAChB,UAAM,IAAI,MAAM,wEAAwE;AAAA,EACzF;AACA,SAAO;AACR;",
4
+ "sourcesContent": ["import { useShallowObjectIdentity } from '@tldraw/editor'\nimport { ComponentType, ReactNode, createContext, useContext, useMemo } from 'react'\nimport { DefaultA11yAnnouncer } from '../components/A11y'\nimport {\n\tDefaultActionsMenu,\n\tTLUiActionsMenuProps,\n} from '../components/ActionsMenu/DefaultActionsMenu'\nimport {\n\tDefaultContextMenu,\n\tTLUiContextMenuProps,\n} from '../components/ContextMenu/DefaultContextMenu'\nimport { CursorChatBubble } from '../components/CursorChatBubble'\nimport { DefaultDebugMenu } from '../components/DebugMenu/DefaultDebugMenu'\nimport { DefaultDebugPanel } from '../components/DefaultDebugPanel'\nimport { DefaultFollowingIndicator } from '../components/DefaultFollowingIndicator'\nimport { DefaultMenuPanel } from '../components/DefaultMenuPanel'\nimport { DefaultDialogs } from '../components/Dialogs'\nimport { TLUiHelpMenuProps } from '../components/HelpMenu/DefaultHelpMenu'\nimport {\n\tDefaultHelperButtons,\n\tTLUiHelperButtonsProps,\n} from '../components/HelperButtons/DefaultHelperButtons'\nimport {\n\tDefaultKeyboardShortcutsDialog,\n\tTLUiKeyboardShortcutsDialogProps,\n} from '../components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialog'\nimport { DefaultMainMenu, TLUiMainMenuProps } from '../components/MainMenu/DefaultMainMenu'\nimport { DefaultMinimap } from '../components/Minimap/DefaultMinimap'\nimport { DefaultNavigationPanel } from '../components/NavigationPanel/DefaultNavigationPanel'\nimport { DefaultPageMenu } from '../components/PageMenu/DefaultPageMenu'\nimport {\n\tDefaultQuickActions,\n\tTLUiQuickActionsProps,\n} from '../components/QuickActions/DefaultQuickActions'\nimport { DefaultSharePanel } from '../components/SharePanel/DefaultSharePanel'\nimport { DefaultStylePanel, TLUiStylePanelProps } from '../components/StylePanel/DefaultStylePanel'\nimport { DefaultToasts } from '../components/Toasts'\nimport { DefaultImageToolbar } from '../components/Toolbar/DefaultImageToolbar'\nimport {\n\tDefaultRichTextToolbar,\n\tTLUiRichTextToolbarProps,\n} from '../components/Toolbar/DefaultRichTextToolbar'\nimport { DefaultToolbar } from '../components/Toolbar/DefaultToolbar'\nimport { DefaultVideoToolbar } from '../components/Toolbar/DefaultVideoToolbar'\nimport { DefaultTopPanel } from '../components/TopPanel/DefaultTopPanel'\nimport { DefaultZoomMenu, TLUiZoomMenuProps } from '../components/ZoomMenu/DefaultZoomMenu'\nimport { useShowCollaborationUi } from '../hooks/useCollaborationStatus'\n\n/** @public */\nexport interface TLUiComponents {\n\tContextMenu?: ComponentType<TLUiContextMenuProps> | null\n\tActionsMenu?: ComponentType<TLUiActionsMenuProps> | null\n\tHelpMenu?: ComponentType<TLUiHelpMenuProps> | null\n\tZoomMenu?: ComponentType<TLUiZoomMenuProps> | null\n\tMainMenu?: ComponentType<TLUiMainMenuProps> | null\n\tMinimap?: ComponentType | null\n\tStylePanel?: ComponentType<TLUiStylePanelProps> | null\n\tPageMenu?: ComponentType | null\n\tNavigationPanel?: ComponentType | null\n\tToolbar?: ComponentType | null\n\tRichTextToolbar?: ComponentType<TLUiRichTextToolbarProps> | null\n\tImageToolbar?: ComponentType | null\n\tVideoToolbar?: ComponentType | null\n\tKeyboardShortcutsDialog?: ComponentType<TLUiKeyboardShortcutsDialogProps> | null\n\tQuickActions?: ComponentType<TLUiQuickActionsProps> | null\n\tHelperButtons?: ComponentType<TLUiHelperButtonsProps> | null\n\tDebugPanel?: ComponentType | null\n\tDebugMenu?: ComponentType | null\n\tMenuPanel?: ComponentType | null\n\tTopPanel?: ComponentType | null\n\tSharePanel?: ComponentType | null\n\tCursorChatBubble?: ComponentType | null\n\tDialogs?: ComponentType | null\n\tToasts?: ComponentType | null\n\tA11y?: ComponentType | null\n\tFollowingIndicator?: ComponentType | null\n}\n\nconst TldrawUiComponentsContext = createContext<TLUiComponents | null>(null)\n\n/** @public */\nexport interface TLUiComponentsProviderProps {\n\toverrides?: TLUiComponents\n\tchildren: ReactNode\n}\n\n/** @public @react */\nexport function TldrawUiComponentsProvider({\n\toverrides = {},\n\tchildren,\n}: TLUiComponentsProviderProps) {\n\tconst _overrides = useShallowObjectIdentity(overrides)\n\tconst showCollaborationUi = useShowCollaborationUi()\n\n\treturn (\n\t\t<TldrawUiComponentsContext.Provider\n\t\t\tvalue={useMemo(\n\t\t\t\t() => ({\n\t\t\t\t\tContextMenu: DefaultContextMenu,\n\t\t\t\t\tActionsMenu: DefaultActionsMenu,\n\t\t\t\t\tHelpMenu: null,\n\t\t\t\t\tZoomMenu: DefaultZoomMenu,\n\t\t\t\t\tMainMenu: DefaultMainMenu,\n\t\t\t\t\tMinimap: DefaultMinimap,\n\t\t\t\t\tStylePanel: DefaultStylePanel,\n\t\t\t\t\tPageMenu: DefaultPageMenu,\n\t\t\t\t\tNavigationPanel: DefaultNavigationPanel,\n\t\t\t\t\tToolbar: DefaultToolbar,\n\t\t\t\t\tRichTextToolbar: DefaultRichTextToolbar,\n\t\t\t\t\tImageToolbar: DefaultImageToolbar,\n\t\t\t\t\tVideoToolbar: DefaultVideoToolbar,\n\t\t\t\t\tKeyboardShortcutsDialog: DefaultKeyboardShortcutsDialog,\n\t\t\t\t\tQuickActions: DefaultQuickActions,\n\t\t\t\t\tHelperButtons: DefaultHelperButtons,\n\t\t\t\t\tDebugPanel: DefaultDebugPanel,\n\t\t\t\t\tDebugMenu: DefaultDebugMenu,\n\t\t\t\t\tMenuPanel: DefaultMenuPanel,\n\t\t\t\t\tSharePanel: showCollaborationUi ? DefaultSharePanel : null,\n\t\t\t\t\tCursorChatBubble: showCollaborationUi ? CursorChatBubble : null,\n\t\t\t\t\tTopPanel: showCollaborationUi ? DefaultTopPanel : null,\n\t\t\t\t\tDialogs: DefaultDialogs,\n\t\t\t\t\tToasts: DefaultToasts,\n\t\t\t\t\tA11y: DefaultA11yAnnouncer,\n\t\t\t\t\tFollowingIndicator: DefaultFollowingIndicator,\n\t\t\t\t\t..._overrides,\n\t\t\t\t}),\n\t\t\t\t[_overrides, showCollaborationUi]\n\t\t\t)}\n\t\t>\n\t\t\t{children}\n\t\t</TldrawUiComponentsContext.Provider>\n\t)\n}\n\n/** @public */\nexport function useTldrawUiComponents() {\n\tconst components = useContext(TldrawUiComponentsContext)\n\tif (!components) {\n\t\tthrow new Error('useTldrawUiComponents must be used within a TldrawUiComponentsProvider')\n\t}\n\treturn components\n}\n"],
5
+ "mappings": "AA+FE;AA/FF,SAAS,gCAAgC;AACzC,SAAmC,eAAe,YAAY,eAAe;AAC7E,SAAS,4BAA4B;AACrC;AAAA,EACC;AAAA,OAEM;AACP;AAAA,EACC;AAAA,OAEM;AACP,SAAS,wBAAwB;AACjC,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAClC,SAAS,iCAAiC;AAC1C,SAAS,wBAAwB;AACjC,SAAS,sBAAsB;AAE/B;AAAA,EACC;AAAA,OAEM;AACP;AAAA,EACC;AAAA,OAEM;AACP,SAAS,uBAA0C;AACnD,SAAS,sBAAsB;AAC/B,SAAS,8BAA8B;AACvC,SAAS,uBAAuB;AAChC;AAAA,EACC;AAAA,OAEM;AACP,SAAS,yBAAyB;AAClC,SAAS,yBAA8C;AACvD,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC;AAAA,EACC;AAAA,OAEM;AACP,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,uBAAuB;AAChC,SAAS,uBAA0C;AACnD,SAAS,8BAA8B;AAgCvC,MAAM,4BAA4B,cAAqC,IAAI;AASpE,SAAS,2BAA2B;AAAA,EAC1C,YAAY,CAAC;AAAA,EACb;AACD,GAAgC;AAC/B,QAAM,aAAa,yBAAyB,SAAS;AACrD,QAAM,sBAAsB,uBAAuB;AAEnD,SACC;AAAA,IAAC,0BAA0B;AAAA,IAA1B;AAAA,MACA,OAAO;AAAA,QACN,OAAO;AAAA,UACN,aAAa;AAAA,UACb,aAAa;AAAA,UACb,UAAU;AAAA,UACV,UAAU;AAAA,UACV,UAAU;AAAA,UACV,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,iBAAiB;AAAA,UACjB,SAAS;AAAA,UACT,iBAAiB;AAAA,UACjB,cAAc;AAAA,UACd,cAAc;AAAA,UACd,yBAAyB;AAAA,UACzB,cAAc;AAAA,UACd,eAAe;AAAA,UACf,YAAY;AAAA,UACZ,WAAW;AAAA,UACX,WAAW;AAAA,UACX,YAAY,sBAAsB,oBAAoB;AAAA,UACtD,kBAAkB,sBAAsB,mBAAmB;AAAA,UAC3D,UAAU,sBAAsB,kBAAkB;AAAA,UAClD,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,oBAAoB;AAAA,UACpB,GAAG;AAAA,QACJ;AAAA,QACA,CAAC,YAAY,mBAAmB;AAAA,MACjC;AAAA,MAEC;AAAA;AAAA,EACF;AAEF;AAGO,SAAS,wBAAwB;AACvC,QAAM,aAAa,WAAW,yBAAyB;AACvD,MAAI,CAAC,YAAY;AAChB,UAAM,IAAI,MAAM,wEAAwE;AAAA,EACzF;AACA,SAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -1,8 +1,8 @@
1
- const version = "3.16.0-canary.f293c3bb58f5";
1
+ const version = "3.16.0-canary.f55016ece635";
2
2
  const publishDates = {
3
3
  major: "2024-09-13T14:36:29.063Z",
4
- minor: "2025-08-21T12:41:23.735Z",
5
- patch: "2025-08-21T12:41:23.735Z"
4
+ minor: "2025-08-26T12:45:19.828Z",
5
+ patch: "2025-08-26T12:45:19.828Z"
6
6
  };
7
7
  export {
8
8
  publishDates,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/ui/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.f293c3bb58f5'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-08-21T12:41:23.735Z',\n\tpatch: '2025-08-21T12:41:23.735Z',\n}\n"],
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.f55016ece635'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-08-26T12:45:19.828Z',\n\tpatch: '2025-08-26T12:45:19.828Z',\n}\n"],
5
5
  "mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tldraw",
3
3
  "description": "A tiny little drawing editor.",
4
- "version": "3.16.0-canary.f293c3bb58f5",
4
+ "version": "3.16.0-canary.f55016ece635",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
@@ -55,8 +55,8 @@
55
55
  "@tiptap/pm": "^2.9.1",
56
56
  "@tiptap/react": "^2.9.1",
57
57
  "@tiptap/starter-kit": "^2.9.1",
58
- "@tldraw/editor": "3.16.0-canary.f293c3bb58f5",
59
- "@tldraw/store": "3.16.0-canary.f293c3bb58f5",
58
+ "@tldraw/editor": "3.16.0-canary.f55016ece635",
59
+ "@tldraw/store": "3.16.0-canary.f55016ece635",
60
60
  "classnames": "^2.5.1",
61
61
  "hotkeys-js": "^3.13.9",
62
62
  "idb": "^7.1.1",
package/src/index.ts CHANGED
@@ -24,6 +24,7 @@ export { usePrefersReducedMotion } from './lib/shapes/shared/usePrefersReducedMo
24
24
  export { DefaultA11yAnnouncer, useSelectedShapesAnnouncer } from './lib/ui/components/A11y'
25
25
  export { AccessibilityMenu } from './lib/ui/components/AccessibilityMenu'
26
26
  export { ColorSchemeMenu } from './lib/ui/components/ColorSchemeMenu'
27
+ export { DefaultFollowingIndicator } from './lib/ui/components/DefaultFollowingIndicator'
27
28
  export { DefaultDialogs } from './lib/ui/components/Dialogs'
28
29
  export {
29
30
  TldrawUiColumn,
@@ -85,6 +86,7 @@ export {
85
86
  defaultHandleExternalUrlContent,
86
87
  getAssetInfo,
87
88
  getMediaAssetInfoPartial,
89
+ notifyIfFileNotAllowed,
88
90
  registerDefaultExternalContentHandlers,
89
91
  type TLDefaultExternalContentHandlerOpts,
90
92
  type TLExternalContentProps,
@@ -628,7 +630,7 @@ export {
628
630
  } from './lib/ui/hooks/useTranslation/useTranslation'
629
631
  export { type TLUiIconType } from './lib/ui/icon-types'
630
632
  export { useDefaultHelpers, type TLUiOverrideHelpers, type TLUiOverrides } from './lib/ui/overrides'
631
- export { TldrawUi, type TldrawUiProps } from './lib/ui/TldrawUi'
633
+ export { TldrawUi, TldrawUiInFrontOfTheCanvas, type TldrawUiProps } from './lib/ui/TldrawUi'
632
634
  export { containBoxSize, downsizeImage, type BoxWidthHeight } from './lib/utils/assets/assets'
633
635
  export { preloadFont, type TLTypeFace } from './lib/utils/assets/preload-font'
634
636
  export { getEmbedInfo, type TLEmbedResult } from './lib/utils/embeds/embeds'