@tldraw/editor 5.4.0-canary.ea38889d4bb7 → 5.4.0-canary.ea63b7dd670b

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 (62) hide show
  1. package/dist-cjs/index.js +1 -1
  2. package/dist-cjs/lib/config/createTLStore.js +1 -1
  3. package/dist-cjs/lib/config/createTLStore.js.map +2 -2
  4. package/dist-cjs/lib/editor/Editor.js +44 -64
  5. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  6. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +3 -3
  7. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
  8. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +1 -1
  9. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
  10. package/dist-cjs/lib/hooks/useCanvasEvents.js +2 -0
  11. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  12. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +1 -0
  13. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
  14. package/dist-cjs/lib/hooks/usePeerIds.js +2 -1
  15. package/dist-cjs/lib/hooks/usePeerIds.js.map +2 -2
  16. package/dist-cjs/lib/utils/deepLinks.js +5 -1
  17. package/dist-cjs/lib/utils/deepLinks.js.map +2 -2
  18. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +17 -0
  19. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
  20. package/dist-cjs/lib/utils/sync/alerts.js +1 -1
  21. package/dist-cjs/lib/utils/sync/alerts.js.map +1 -1
  22. package/dist-cjs/version.js +3 -3
  23. package/dist-cjs/version.js.map +1 -1
  24. package/dist-esm/index.mjs +1 -1
  25. package/dist-esm/lib/config/createTLStore.mjs +1 -1
  26. package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
  27. package/dist-esm/lib/editor/Editor.mjs +45 -64
  28. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  29. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +3 -3
  30. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
  31. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +1 -1
  32. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
  33. package/dist-esm/lib/hooks/useCanvasEvents.mjs +2 -0
  34. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  35. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +1 -0
  36. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
  37. package/dist-esm/lib/hooks/usePeerIds.mjs +2 -1
  38. package/dist-esm/lib/hooks/usePeerIds.mjs.map +2 -2
  39. package/dist-esm/lib/utils/deepLinks.mjs +5 -1
  40. package/dist-esm/lib/utils/deepLinks.mjs.map +2 -2
  41. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +17 -0
  42. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
  43. package/dist-esm/lib/utils/sync/alerts.mjs +1 -1
  44. package/dist-esm/lib/utils/sync/alerts.mjs.map +1 -1
  45. package/dist-esm/version.mjs +3 -3
  46. package/dist-esm/version.mjs.map +1 -1
  47. package/package.json +7 -7
  48. package/src/lib/config/createTLStore.ts +1 -1
  49. package/src/lib/editor/Editor.ts +79 -91
  50. package/src/lib/editor/managers/ClickManager/ClickManager.ts +5 -3
  51. package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +4 -1
  52. package/src/lib/hooks/useCanvasEvents.ts +2 -0
  53. package/src/lib/hooks/usePassThroughWheelEvents.ts +3 -0
  54. package/src/lib/hooks/usePeerIds.ts +2 -1
  55. package/src/lib/test/useCanvasEvents.test.tsx +74 -0
  56. package/src/lib/test/usePassThroughWheelEvents.test.tsx +25 -2
  57. package/src/lib/utils/deepLinks.test.ts +15 -0
  58. package/src/lib/utils/deepLinks.ts +7 -1
  59. package/src/lib/utils/sync/TLLocalSyncClient.test.ts +56 -0
  60. package/src/lib/utils/sync/TLLocalSyncClient.ts +24 -0
  61. package/src/lib/utils/sync/alerts.ts +1 -1
  62. package/src/version.ts +3 -3
package/dist-cjs/index.js CHANGED
@@ -392,7 +392,7 @@ var import_uniq = require("./lib/utils/uniq");
392
392
  var import_defaultThemes2 = require("./lib/editor/managers/ThemeManager/defaultThemes");
393
393
  (0, import_utils.registerTldrawLibraryVersion)(
394
394
  "@tldraw/editor",
395
- "5.4.0-canary.ea38889d4bb7",
395
+ "5.4.0-canary.ea63b7dd670b",
396
396
  "cjs"
397
397
  );
398
398
  //# sourceMappingURL=index.js.map
@@ -98,7 +98,7 @@ function createTLStore({
98
98
  },
99
99
  onMount: (editor) => {
100
100
  (0, import_utils.assert)(editor instanceof import_Editor.Editor);
101
- onMount?.(editor);
101
+ return onMount?.(editor);
102
102
  },
103
103
  collaboration
104
104
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/config/createTLStore.ts"],
4
- "sourcesContent": ["import { Signal, computed } from '@tldraw/state'\nimport { HistoryEntry, MigrationSequence, SerializedStore, Store, StoreSchema } from '@tldraw/store'\nimport {\n\tCustomRecordInfo,\n\tSchemaPropsInfo,\n\tTLAssetStore,\n\tTLRecord,\n\tTLStore,\n\tTLStoreProps,\n\tTLStoreSnapshot,\n\tTLThemes,\n\tTLUser,\n\tTLUserStore,\n\tUserRecordType,\n\tcreateCachedUserResolve,\n\tcreateTLSchema,\n\tcreateUserId,\n\tregisterColorsFromThemes,\n\tregisterFontsFromThemes,\n} from '@tldraw/tlschema'\nimport { FileHelpers, assert } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { resolveThemes } from '../editor/managers/ThemeManager/ThemeManager'\nimport { TLAnyAssetUtilConstructor, checkAssets } from './defaultAssets'\nimport { TLAnyBindingUtilConstructor, checkBindings } from './defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from './defaultShapes'\nimport { TLEditorSnapshot, loadSnapshot } from './TLEditorSnapshot'\nimport { defaultUserPreferences, getUserPreferences } from './TLUserPreferences'\n\n/** @public */\nexport interface TLStoreBaseOptions {\n\t/** The initial data for the store. */\n\tinitialData?: SerializedStore<TLRecord>\n\n\t/** A snapshot of initial data to migrate and load into the store. */\n\tsnapshot?: Partial<TLEditorSnapshot> | TLStoreSnapshot\n\n\t/** The default name for the store. */\n\tdefaultName?: string\n\n\t/** How should this store upload & resolve assets? */\n\tassets?: TLAssetStore\n\n\t/**\n\t * Named theme definitions. When provided, custom color names are automatically\n\t * registered before the store is constructed so persisted data with those\n\t * colors passes validation on load.\n\t */\n\tthemes?: Partial<TLThemes>\n\n\t/** How should this store resolve users for attribution? */\n\tusers?: TLUserStore\n\n\t/** Called when the store is connected to an {@link @tldraw/editor#Editor}. */\n\tonMount?(editor: Editor): void | (() => void)\n}\n\n/** @public */\nexport type TLStoreSchemaOptions =\n\t| {\n\t\t\tschema?: StoreSchema<TLRecord, TLStoreProps>\n\t }\n\t| {\n\t\t\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t\t\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t\t\tassetUtils?: readonly TLAnyAssetUtilConstructor[]\n\t\t\tmigrations?: readonly MigrationSequence[]\n\t\t\trecords?: Record<string, CustomRecordInfo>\n\t }\n\n/** @public */\nexport type TLStoreOptions = TLStoreBaseOptions & {\n\tid?: string\n\t/** Collaboration options for the store. */\n\tcollaboration?: {\n\t\tstatus: Signal<'online' | 'offline'> | null\n\t\tmode?: Signal<'readonly' | 'readwrite'> | null\n\t}\n} & TLStoreSchemaOptions\n\n/** @public */\nexport type TLStoreEventInfo = HistoryEntry<TLRecord>\n\nconst defaultAssetResolve: NonNullable<TLAssetStore['resolve']> = (asset) => asset.props.src\n\nconst _defaultCurrentUser: Signal<TLUser | null> = computed('defaultCurrentUser', () => {\n\tconst prefs = getUserPreferences()\n\tif (!prefs.id) return null\n\treturn UserRecordType.create({\n\t\tid: createUserId(prefs.id),\n\t\tname: prefs.name ?? '',\n\t\tcolor: prefs.color ?? defaultUserPreferences.color,\n\t})\n})\n\n/** @public */\nexport const defaultUserStore: TLUserStore = {\n\tcurrentUser: _defaultCurrentUser,\n}\n\n/** @public */\nexport const inlineBase64AssetStore: TLAssetStore = {\n\tupload: async (_, file) => {\n\t\treturn { src: await FileHelpers.blobToDataUrl(file) }\n\t},\n}\n\n/**\n * A helper for creating a TLStore schema from either an object with shapeUtils, bindingUtils, and\n * migrations, or a schema.\n *\n * @param opts - Options for creating the schema.\n *\n * @public\n */\nexport function createTLSchemaFromUtils(\n\topts: TLStoreSchemaOptions\n): StoreSchema<TLRecord, TLStoreProps> {\n\tif ('schema' in opts && opts.schema) return opts.schema\n\n\treturn createTLSchema({\n\t\tshapes:\n\t\t\t'shapeUtils' in opts && opts.shapeUtils\n\t\t\t\t? utilsToMap(checkShapesAndAddCore(opts.shapeUtils))\n\t\t\t\t: undefined,\n\t\tbindings:\n\t\t\t'bindingUtils' in opts && opts.bindingUtils\n\t\t\t\t? utilsToMap(checkBindings(opts.bindingUtils))\n\t\t\t\t: undefined,\n\t\tassets:\n\t\t\t'assetUtils' in opts && opts.assetUtils\n\t\t\t\t? utilsToMap(checkAssets(opts.assetUtils))\n\t\t\t\t: undefined,\n\t\trecords: 'records' in opts ? opts.records : undefined,\n\t\tmigrations: 'migrations' in opts ? opts.migrations : undefined,\n\t})\n}\n\n/**\n * A helper for creating a TLStore.\n *\n * @param opts - Options for creating the store.\n *\n * @public\n */\nexport function createTLStore({\n\tinitialData,\n\tdefaultName = '',\n\tid,\n\tassets = inlineBase64AssetStore,\n\tusers = defaultUserStore,\n\tonMount,\n\tcollaboration,\n\tthemes,\n\t...rest\n}: TLStoreOptions = {}): TLStore {\n\tconst resolvedThemes = resolveThemes(themes)\n\tregisterColorsFromThemes(resolvedThemes)\n\tregisterFontsFromThemes(resolvedThemes)\n\tconst schema = createTLSchemaFromUtils(rest)\n\n\tconst store = new Store({\n\t\tid,\n\t\tschema,\n\t\tinitialData,\n\t\tprops: {\n\t\t\tdefaultName,\n\t\t\tassets: {\n\t\t\t\tupload: assets.upload,\n\t\t\t\tresolve: assets.resolve ?? defaultAssetResolve,\n\t\t\t\tremove: assets.remove ?? (() => Promise.resolve()),\n\t\t\t},\n\t\t\tusers: {\n\t\t\t\tcurrentUser: users.currentUser,\n\t\t\t\tresolve:\n\t\t\t\t\tusers.resolve ??\n\t\t\t\t\tcreateCachedUserResolve((userId) => {\n\t\t\t\t\t\tconst current = users.currentUser.get()\n\t\t\t\t\t\treturn current && current.id === createUserId(userId) ? current : null\n\t\t\t\t\t}),\n\t\t\t},\n\t\t\tonMount: (editor) => {\n\t\t\t\tassert(editor instanceof Editor)\n\t\t\t\tonMount?.(editor)\n\t\t\t},\n\t\t\tcollaboration,\n\t\t},\n\t})\n\n\tif (rest.snapshot) {\n\t\tif (initialData) throw new Error('Cannot provide both initialData and snapshot')\n\t\tloadSnapshot(store, rest.snapshot, { forceOverwriteSessionState: true })\n\t}\n\n\treturn store\n}\n\nfunction utilsToMap<T extends SchemaPropsInfo & { type: string }>(utils: T[]) {\n\treturn Object.fromEntries(\n\t\tutils.map((s): [string, SchemaPropsInfo] => [\n\t\t\ts.type,\n\t\t\t{\n\t\t\t\tprops: s.props,\n\t\t\t\tmigrations: s.migrations,\n\t\t\t},\n\t\t])\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Signal, computed } from '@tldraw/state'\nimport { HistoryEntry, MigrationSequence, SerializedStore, Store, StoreSchema } from '@tldraw/store'\nimport {\n\tCustomRecordInfo,\n\tSchemaPropsInfo,\n\tTLAssetStore,\n\tTLRecord,\n\tTLStore,\n\tTLStoreProps,\n\tTLStoreSnapshot,\n\tTLThemes,\n\tTLUser,\n\tTLUserStore,\n\tUserRecordType,\n\tcreateCachedUserResolve,\n\tcreateTLSchema,\n\tcreateUserId,\n\tregisterColorsFromThemes,\n\tregisterFontsFromThemes,\n} from '@tldraw/tlschema'\nimport { FileHelpers, assert } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { resolveThemes } from '../editor/managers/ThemeManager/ThemeManager'\nimport { TLAnyAssetUtilConstructor, checkAssets } from './defaultAssets'\nimport { TLAnyBindingUtilConstructor, checkBindings } from './defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from './defaultShapes'\nimport { TLEditorSnapshot, loadSnapshot } from './TLEditorSnapshot'\nimport { defaultUserPreferences, getUserPreferences } from './TLUserPreferences'\n\n/** @public */\nexport interface TLStoreBaseOptions {\n\t/** The initial data for the store. */\n\tinitialData?: SerializedStore<TLRecord>\n\n\t/** A snapshot of initial data to migrate and load into the store. */\n\tsnapshot?: Partial<TLEditorSnapshot> | TLStoreSnapshot\n\n\t/** The default name for the store. */\n\tdefaultName?: string\n\n\t/** How should this store upload & resolve assets? */\n\tassets?: TLAssetStore\n\n\t/**\n\t * Named theme definitions. When provided, custom color names are automatically\n\t * registered before the store is constructed so persisted data with those\n\t * colors passes validation on load.\n\t */\n\tthemes?: Partial<TLThemes>\n\n\t/** How should this store resolve users for attribution? */\n\tusers?: TLUserStore\n\n\t/** Called when the store is connected to an {@link @tldraw/editor#Editor}. */\n\tonMount?(editor: Editor): void | (() => void)\n}\n\n/** @public */\nexport type TLStoreSchemaOptions =\n\t| {\n\t\t\tschema?: StoreSchema<TLRecord, TLStoreProps>\n\t }\n\t| {\n\t\t\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t\t\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t\t\tassetUtils?: readonly TLAnyAssetUtilConstructor[]\n\t\t\tmigrations?: readonly MigrationSequence[]\n\t\t\trecords?: Record<string, CustomRecordInfo>\n\t }\n\n/** @public */\nexport type TLStoreOptions = TLStoreBaseOptions & {\n\tid?: string\n\t/** Collaboration options for the store. */\n\tcollaboration?: {\n\t\tstatus: Signal<'online' | 'offline'> | null\n\t\tmode?: Signal<'readonly' | 'readwrite'> | null\n\t}\n} & TLStoreSchemaOptions\n\n/** @public */\nexport type TLStoreEventInfo = HistoryEntry<TLRecord>\n\nconst defaultAssetResolve: NonNullable<TLAssetStore['resolve']> = (asset) => asset.props.src\n\nconst _defaultCurrentUser: Signal<TLUser | null> = computed('defaultCurrentUser', () => {\n\tconst prefs = getUserPreferences()\n\tif (!prefs.id) return null\n\treturn UserRecordType.create({\n\t\tid: createUserId(prefs.id),\n\t\tname: prefs.name ?? '',\n\t\tcolor: prefs.color ?? defaultUserPreferences.color,\n\t})\n})\n\n/** @public */\nexport const defaultUserStore: TLUserStore = {\n\tcurrentUser: _defaultCurrentUser,\n}\n\n/** @public */\nexport const inlineBase64AssetStore: TLAssetStore = {\n\tupload: async (_, file) => {\n\t\treturn { src: await FileHelpers.blobToDataUrl(file) }\n\t},\n}\n\n/**\n * A helper for creating a TLStore schema from either an object with shapeUtils, bindingUtils, and\n * migrations, or a schema.\n *\n * @param opts - Options for creating the schema.\n *\n * @public\n */\nexport function createTLSchemaFromUtils(\n\topts: TLStoreSchemaOptions\n): StoreSchema<TLRecord, TLStoreProps> {\n\tif ('schema' in opts && opts.schema) return opts.schema\n\n\treturn createTLSchema({\n\t\tshapes:\n\t\t\t'shapeUtils' in opts && opts.shapeUtils\n\t\t\t\t? utilsToMap(checkShapesAndAddCore(opts.shapeUtils))\n\t\t\t\t: undefined,\n\t\tbindings:\n\t\t\t'bindingUtils' in opts && opts.bindingUtils\n\t\t\t\t? utilsToMap(checkBindings(opts.bindingUtils))\n\t\t\t\t: undefined,\n\t\tassets:\n\t\t\t'assetUtils' in opts && opts.assetUtils\n\t\t\t\t? utilsToMap(checkAssets(opts.assetUtils))\n\t\t\t\t: undefined,\n\t\trecords: 'records' in opts ? opts.records : undefined,\n\t\tmigrations: 'migrations' in opts ? opts.migrations : undefined,\n\t})\n}\n\n/**\n * A helper for creating a TLStore.\n *\n * @param opts - Options for creating the store.\n *\n * @public\n */\nexport function createTLStore({\n\tinitialData,\n\tdefaultName = '',\n\tid,\n\tassets = inlineBase64AssetStore,\n\tusers = defaultUserStore,\n\tonMount,\n\tcollaboration,\n\tthemes,\n\t...rest\n}: TLStoreOptions = {}): TLStore {\n\tconst resolvedThemes = resolveThemes(themes)\n\tregisterColorsFromThemes(resolvedThemes)\n\tregisterFontsFromThemes(resolvedThemes)\n\tconst schema = createTLSchemaFromUtils(rest)\n\n\tconst store = new Store({\n\t\tid,\n\t\tschema,\n\t\tinitialData,\n\t\tprops: {\n\t\t\tdefaultName,\n\t\t\tassets: {\n\t\t\t\tupload: assets.upload,\n\t\t\t\tresolve: assets.resolve ?? defaultAssetResolve,\n\t\t\t\tremove: assets.remove ?? (() => Promise.resolve()),\n\t\t\t},\n\t\t\tusers: {\n\t\t\t\tcurrentUser: users.currentUser,\n\t\t\t\tresolve:\n\t\t\t\t\tusers.resolve ??\n\t\t\t\t\tcreateCachedUserResolve((userId) => {\n\t\t\t\t\t\tconst current = users.currentUser.get()\n\t\t\t\t\t\treturn current && current.id === createUserId(userId) ? current : null\n\t\t\t\t\t}),\n\t\t\t},\n\t\t\tonMount: (editor) => {\n\t\t\t\tassert(editor instanceof Editor)\n\t\t\t\treturn onMount?.(editor)\n\t\t\t},\n\t\t\tcollaboration,\n\t\t},\n\t})\n\n\tif (rest.snapshot) {\n\t\tif (initialData) throw new Error('Cannot provide both initialData and snapshot')\n\t\tloadSnapshot(store, rest.snapshot, { forceOverwriteSessionState: true })\n\t}\n\n\treturn store\n}\n\nfunction utilsToMap<T extends SchemaPropsInfo & { type: string }>(utils: T[]) {\n\treturn Object.fromEntries(\n\t\tutils.map((s): [string, SchemaPropsInfo] => [\n\t\t\ts.type,\n\t\t\t{\n\t\t\t\tprops: s.props,\n\t\t\t\tmigrations: s.migrations,\n\t\t\t},\n\t\t])\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -257,6 +257,10 @@ class Editor extends import_eventemitter3.default {
257
257
  if (!nextPageState) nextPageState = { ...prevPageState };
258
258
  nextPageState.editingShapeId = null;
259
259
  }
260
+ if (prevPageState.croppingShapeId && shapesNoLongerInPage.has(prevPageState.croppingShapeId)) {
261
+ if (!nextPageState) nextPageState = { ...prevPageState };
262
+ nextPageState.croppingShapeId = null;
263
+ }
260
264
  const hintingShapeIds = prevPageState.hintingShapeIds.filter(
261
265
  (id) => !shapesNoLongerInPage.has(id)
262
266
  );
@@ -587,7 +591,10 @@ class Editor extends import_eventemitter3.default {
587
591
  const mode = this.store.props.collaboration.mode;
588
592
  this.disposables.add(
589
593
  (0, import_state.react)("update collaboration mode", () => {
590
- this.store.put([{ ...this.getInstanceState(), isReadonly: mode.get() === "readonly" }]);
594
+ const isReadonly = mode.get() === "readonly";
595
+ (0, import_state.unsafe__withoutCapture)(
596
+ () => this._updateInstanceState({ isReadonly }, { history: "ignore" })
597
+ );
591
598
  })
592
599
  );
593
600
  }
@@ -1956,42 +1963,28 @@ class Editor extends import_eventemitter3.default {
1956
1963
  */
1957
1964
  setEditingShape(shape) {
1958
1965
  const id = typeof shape === "string" ? shape : shape?.id ?? null;
1959
- if (!id) {
1966
+ if (id && !this.canEditShape(id)) return this;
1967
+ this.run(() => {
1968
+ const prevEditingShapeId = this.getEditingShapeId();
1969
+ if (prevEditingShapeId) {
1970
+ const prevEditingShape = this.getShape(prevEditingShapeId);
1971
+ if (prevEditingShape) {
1972
+ this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1973
+ }
1974
+ }
1960
1975
  this.run(
1961
1976
  () => {
1962
- const prevEditingShapeId = this.getEditingShapeId();
1963
- if (prevEditingShapeId) {
1964
- const prevEditingShape = this.getShape(prevEditingShapeId);
1965
- if (prevEditingShape) {
1966
- this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1967
- }
1968
- }
1969
1977
  this._updateCurrentPageState({ editingShapeId: null });
1970
1978
  this._currentRichTextEditor.set(null);
1979
+ if (!id) return;
1980
+ this.select(id);
1981
+ this._updateCurrentPageState({ editingShapeId: id });
1982
+ const nextEditingShape = this.getShape(id);
1983
+ this.getShapeUtil(nextEditingShape).onEditStart?.(nextEditingShape);
1971
1984
  },
1972
1985
  { history: "ignore" }
1973
1986
  );
1974
- return this;
1975
- }
1976
- if (!this.canEditShape(id)) return this;
1977
- this.run(
1978
- () => {
1979
- const prevEditingShapeId = this.getEditingShapeId();
1980
- if (prevEditingShapeId) {
1981
- const prevEditingShape = this.getShape(prevEditingShapeId);
1982
- if (prevEditingShape) {
1983
- this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1984
- }
1985
- }
1986
- this._updateCurrentPageState({ editingShapeId: null });
1987
- this._currentRichTextEditor.set(null);
1988
- this.select(id);
1989
- this._updateCurrentPageState({ editingShapeId: id });
1990
- const nextEditingShape = this.getShape(id);
1991
- this.getShapeUtil(nextEditingShape).onEditStart?.(nextEditingShape);
1992
- },
1993
- { history: "ignore" }
1994
- );
1987
+ });
1995
1988
  return this;
1996
1989
  }
1997
1990
  // Rich text editor
@@ -2097,19 +2090,12 @@ class Editor extends import_eventemitter3.default {
2097
2090
  * @public
2098
2091
  */
2099
2092
  setErasingShapes(shapes) {
2100
- const ids = typeof shapes[0] === "string" ? shapes : shapes.map((shape) => shape.id);
2093
+ const ids = typeof shapes[0] === "string" ? shapes.slice() : shapes.map((shape) => shape.id);
2101
2094
  ids.sort();
2102
2095
  const erasingShapeIds = this.getErasingShapeIds();
2103
2096
  this.run(
2104
2097
  () => {
2105
- if (ids.length === erasingShapeIds.length) {
2106
- for (let i = 0; i < ids.length; i++) {
2107
- if (ids[i] !== erasingShapeIds[i]) {
2108
- this._updateCurrentPageState({ erasingShapeIds: ids });
2109
- break;
2110
- }
2111
- }
2112
- } else {
2098
+ if (!(0, import_utils.areArraysShallowEqual)(ids, erasingShapeIds)) {
2113
2099
  this._updateCurrentPageState({ erasingShapeIds: ids });
2114
2100
  }
2115
2101
  },
@@ -2142,6 +2128,7 @@ class Editor extends import_eventemitter3.default {
2142
2128
  if (!_shape) return false;
2143
2129
  const util = this.getShapeUtil(_shape);
2144
2130
  if (!util.canCrop(_shape)) return false;
2131
+ if (this.getIsReadonly()) return false;
2145
2132
  if (this.isShapeOrAncestorLocked(_shape)) return false;
2146
2133
  return true;
2147
2134
  }
@@ -2351,7 +2338,7 @@ class Editor extends import_eventemitter3.default {
2351
2338
  ...this._cameraOptions.__unsafe__getWithoutCapture(),
2352
2339
  ...opts
2353
2340
  });
2354
- if (next.zoomSteps?.length < 1) next.zoomSteps = [1];
2341
+ if (!next.zoomSteps || next.zoomSteps.length < 1) next.zoomSteps = [1];
2355
2342
  this._cameraOptions.set(next);
2356
2343
  this.setCamera(this.getCamera());
2357
2344
  return this;
@@ -2372,8 +2359,8 @@ class Editor extends import_eventemitter3.default {
2372
2359
  const vsb = this.getViewportScreenBounds();
2373
2360
  if (cameraOptions.constraints) {
2374
2361
  const { constraints } = cameraOptions;
2375
- const py = Math.min(constraints.padding.y, vsb.w / 2);
2376
- const px = Math.min(constraints.padding.x, vsb.h / 2);
2362
+ const px = Math.min(constraints.padding.x, vsb.w / 2);
2363
+ const py = Math.min(constraints.padding.y, vsb.h / 2);
2377
2364
  const bounds = import_Box.Box.From(cameraOptions.constraints.bounds);
2378
2365
  const zx = (vsb.w - px * 2) / bounds.w;
2379
2366
  const zy = (vsb.h - py * 2) / bounds.h;
@@ -2412,12 +2399,12 @@ class Editor extends import_eventemitter3.default {
2412
2399
  break;
2413
2400
  }
2414
2401
  case "inside": {
2415
- if (z < zx) x = (0, import_utils2.clamp)(x, minX, (vsb.w - px) / z - bounds.w);
2402
+ if (z < zx) x = (0, import_utils2.clamp)(x, minX, (vsb.w - px) / z - bounds.w - bounds.x);
2416
2403
  else x = (0, import_utils2.clamp)(x, minX + freeW, minX);
2417
2404
  break;
2418
2405
  }
2419
2406
  case "outside": {
2420
- x = (0, import_utils2.clamp)(x, px / z - bounds.w, (vsb.w - px) / z);
2407
+ x = (0, import_utils2.clamp)(x, px / z - bounds.w - bounds.x, (vsb.w - px) / z - bounds.x);
2421
2408
  break;
2422
2409
  }
2423
2410
  case "free": {
@@ -2438,12 +2425,12 @@ class Editor extends import_eventemitter3.default {
2438
2425
  break;
2439
2426
  }
2440
2427
  case "inside": {
2441
- if (z < zy) y = (0, import_utils2.clamp)(y, minY, (vsb.h - py) / z - bounds.h);
2428
+ if (z < zy) y = (0, import_utils2.clamp)(y, minY, (vsb.h - py) / z - bounds.h - bounds.y);
2442
2429
  else y = (0, import_utils2.clamp)(y, minY + freeH, minY);
2443
2430
  break;
2444
2431
  }
2445
2432
  case "outside": {
2446
- y = (0, import_utils2.clamp)(y, py / z - bounds.h, (vsb.h - py) / z);
2433
+ y = (0, import_utils2.clamp)(y, py / z - bounds.h - bounds.y, (vsb.h - py) / z - bounds.y);
2447
2434
  break;
2448
2435
  }
2449
2436
  case "free": {
@@ -4055,7 +4042,9 @@ class Editor extends import_eventemitter3.default {
4055
4042
  if (pageMask) {
4056
4043
  if (pageMask.length === 0) return void 0;
4057
4044
  const { corners } = pageBounds;
4058
- if (corners.every((p, i) => p && import_Vec.Vec.Equals(p, pageMask[i]))) return pageBounds.clone();
4045
+ if (pageMask.length === corners.length && corners.every((p, i) => import_Vec.Vec.Equals(p, pageMask[i]))) {
4046
+ return pageBounds.clone();
4047
+ }
4059
4048
  const intersection = (0, import_intersect.intersectPolygonPolygon)(pageMask, corners);
4060
4049
  if (!intersection) return;
4061
4050
  return import_Box.Box.FromPoints(intersection);
@@ -4294,7 +4283,7 @@ class Editor extends import_eventemitter3.default {
4294
4283
  const pointInShapeSpace = this.getPointInShapeSpace(shape, point);
4295
4284
  const shapeUtil = this.getShapeUtil(shape);
4296
4285
  const isShapeFrameLike = this.isShapeFrameLike(shape);
4297
- if (isShapeFrameLike || (this.isShapeOfType(shape, "note") || this.isShapeOfType(shape, "arrow") || this.isShapeOfType(shape, "geo") && shape.props.fill === "none") && shapeUtil.getText(shape)?.trim()) {
4286
+ if (isGroup && (isShapeFrameLike || (this.isShapeOfType(shape, "note") || this.isShapeOfType(shape, "arrow") || this.isShapeOfType(shape, "geo") && shape.props.fill === "none") && shapeUtil.getText(shape)?.trim())) {
4298
4287
  for (const childGeometry of geometry.children) {
4299
4288
  if (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {
4300
4289
  return shape;
@@ -5217,26 +5206,17 @@ class Editor extends import_eventemitter3.default {
5217
5206
  toggleLock(shapes) {
5218
5207
  const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
5219
5208
  if (this.getIsReadonly() || ids.length === 0) return this;
5220
- let allLocked = true, allUnlocked = true;
5209
+ let allLocked = true;
5221
5210
  const shapesToToggle = [];
5222
5211
  for (const id of ids) {
5223
5212
  const shape = this.getShape(id);
5224
5213
  if (shape) {
5225
5214
  shapesToToggle.push(shape);
5226
- if (shape.isLocked) {
5227
- allUnlocked = false;
5228
- } else {
5229
- allLocked = false;
5230
- }
5215
+ if (!shape.isLocked) allLocked = false;
5231
5216
  }
5232
5217
  }
5233
5218
  this.run(() => {
5234
- if (allUnlocked) {
5235
- this.updateShapes(
5236
- shapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))
5237
- );
5238
- this.setSelectedShapes([]);
5239
- } else if (allLocked) {
5219
+ if (allLocked) {
5240
5220
  this.updateShapes(
5241
5221
  shapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: false }))
5242
5222
  );
@@ -5244,6 +5224,7 @@ class Editor extends import_eventemitter3.default {
5244
5224
  this.updateShapes(
5245
5225
  shapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))
5246
5226
  );
5227
+ this.setSelectedShapes([]);
5247
5228
  }
5248
5229
  });
5249
5230
  return this;
@@ -5600,7 +5581,7 @@ class Editor extends import_eventemitter3.default {
5600
5581
  }
5601
5582
  const commonBounds = import_Box.Box.Common(allBounds);
5602
5583
  const maxWidth = commonBounds.width;
5603
- shapeClustersToPack.sort((a, b) => a.pageBounds.width - b.pageBounds.width).sort((a, b) => a.pageBounds.height - b.pageBounds.height);
5584
+ shapeClustersToPack.sort((a, b) => b.pageBounds.width - a.pageBounds.width).sort((a, b) => b.pageBounds.height - a.pageBounds.height);
5604
5585
  const startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth);
5605
5586
  const spaces = [new import_Box.Box(commonBounds.x, commonBounds.y, startWidth, Infinity)];
5606
5587
  let width = 0;
@@ -8725,10 +8706,9 @@ function withIsolatedShapes(editor, shapeIds, callback) {
8725
8706
  }
8726
8707
  function getCameraFitXFitY(editor, cameraOptions) {
8727
8708
  if (!cameraOptions.constraints) throw Error("Should have constraints here");
8728
- const {
8729
- padding: { x: px, y: py }
8730
- } = cameraOptions.constraints;
8731
8709
  const vsb = editor.getViewportScreenBounds();
8710
+ const px = Math.min(cameraOptions.constraints.padding.x, vsb.w / 2);
8711
+ const py = Math.min(cameraOptions.constraints.padding.y, vsb.h / 2);
8732
8712
  const bounds = import_Box.Box.From(cameraOptions.constraints.bounds);
8733
8713
  const zx = (vsb.w - px * 2) / bounds.w;
8734
8714
  const zy = (vsb.h - py * 2) / bounds.h;