kritzel-stencil 0.4.8 → 0.4.9

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 (91) hide show
  1. package/dist/cjs/index.cjs.js +9 -1
  2. package/dist/cjs/kritzel-active-users_47.cjs.entry.js +1386 -1250
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/{schema.constants-gDeS7USU.js → schema.constants-ByNZ_qAj.js} +61 -0
  5. package/dist/cjs/stencil.cjs.js +1 -1
  6. package/dist/collection/classes/objects/image.class.js +9 -0
  7. package/dist/collection/classes/objects/path.class.js +9 -0
  8. package/dist/collection/classes/objects/shape.class.js +9 -0
  9. package/dist/collection/classes/providers/sync/broadcast-sync-provider.class.js +1 -0
  10. package/dist/collection/classes/providers/sync/hocuspocus-sync-provider.class.js +2 -0
  11. package/dist/collection/classes/providers/sync/in-memory-sync-provider.class.js +1 -0
  12. package/dist/collection/classes/providers/sync/indexeddb-sync-provider.class.js +1 -0
  13. package/dist/collection/classes/providers/sync/websocket-sync-provider.class.js +2 -0
  14. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +197 -67
  15. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +136 -169
  16. package/dist/collection/components/ui/kritzel-export/kritzel-export.js +1 -1
  17. package/dist/collection/components/ui/kritzel-loading-overlay/kritzel-loading-overlay.js +1 -1
  18. package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.js +1 -1
  19. package/dist/collection/components/ui/kritzel-more-menu/kritzel-more-menu.js +90 -4
  20. package/dist/collection/components/ui/kritzel-settings/kritzel-settings.js +1 -1
  21. package/dist/collection/components/ui/kritzel-share-dialog/kritzel-share-dialog.js +2 -2
  22. package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +1 -1
  23. package/dist/collection/components/ui/kritzel-zoom-panel/kritzel-zoom-panel.js +1 -1
  24. package/dist/collection/constants/version.js +1 -1
  25. package/dist/collection/helpers/object.helper.js +11 -0
  26. package/dist/collection/index.js +1 -0
  27. package/dist/collection/interfaces/object-export.interface.js +1 -0
  28. package/dist/collection/interfaces/sync-config.interface.js +21 -1
  29. package/dist/components/index.js +10 -3
  30. package/dist/components/kritzel-awareness-cursors.js +1 -1
  31. package/dist/components/kritzel-controls.js +1 -1
  32. package/dist/components/kritzel-editor.js +175 -78
  33. package/dist/components/kritzel-engine.js +1 -1
  34. package/dist/components/kritzel-export.js +1 -1
  35. package/dist/components/kritzel-loading-overlay.js +1 -1
  36. package/dist/components/kritzel-login-dialog.js +1 -1
  37. package/dist/components/kritzel-menu-item.js +1 -1
  38. package/dist/components/kritzel-menu.js +1 -1
  39. package/dist/components/kritzel-more-menu.js +1 -1
  40. package/dist/components/kritzel-portal.js +1 -1
  41. package/dist/components/kritzel-settings.js +1 -1
  42. package/dist/components/kritzel-share-dialog.js +1 -1
  43. package/dist/components/kritzel-split-button.js +1 -1
  44. package/dist/components/kritzel-utility-panel.js +1 -1
  45. package/dist/components/kritzel-workspace-manager.js +1 -1
  46. package/dist/components/kritzel-zoom-panel.js +1 -1
  47. package/dist/components/{p-DwY5pghH.js → p-6rQICkGr.js} +1 -1
  48. package/dist/components/{p-BknTMcbz.js → p-8ScektIm.js} +1 -1
  49. package/dist/components/{p-DkY7pIg5.js → p-BRGufCki.js} +95 -6
  50. package/dist/components/{p-BKOsmXB5.js → p-BqWiEmYI.js} +1 -1
  51. package/dist/components/{p-BLOPBDUF.js → p-C2CeSrTm.js} +1 -1
  52. package/dist/components/{p-DDbO5q-e.js → p-CXJZxJvp.js} +4 -4
  53. package/dist/components/{p-7Rt7ml3v.js → p-Cj0NElII.js} +1 -1
  54. package/dist/components/{p-BVEGQLBD.js → p-CoY7emAj.js} +1 -1
  55. package/dist/components/{p-DgA865Tp.js → p-D7H8oxZb.js} +2 -2
  56. package/dist/components/{p-Dd-pMvlr.js → p-DPONTran.js} +11 -0
  57. package/dist/components/{p-BMRln59F.js → p-DW7WW4EN.js} +2 -2
  58. package/dist/components/{p-D8TOEhPY.js → p-DuVkk58V.js} +2 -2
  59. package/dist/components/{p-OLfoATNk.js → p-U9FjWrp-.js} +1 -1
  60. package/dist/components/{p-D8bHNNEm.js → p-ZPPtEla5.js} +1227 -1218
  61. package/dist/components/{p-COjsYPir.js → p-dVfh-Sy9.js} +1 -1
  62. package/dist/components/{p-0H4HOJjy.js → p-lQ7nfhOy.js} +10 -1
  63. package/dist/esm/index.js +9 -2
  64. package/dist/esm/kritzel-active-users_47.entry.js +1386 -1250
  65. package/dist/esm/loader.js +1 -1
  66. package/dist/esm/{schema.constants-Rpm1NA9u.js → schema.constants-1t45c2_U.js} +61 -1
  67. package/dist/esm/stencil.js +1 -1
  68. package/dist/stencil/index.esm.js +9 -2
  69. package/dist/stencil/{p-Rpm1NA9u.js → p-1t45c2_U.js} +61 -1
  70. package/dist/stencil/{p-8c1b7b08.entry.js → p-f5f088ea.entry.js} +1386 -1250
  71. package/dist/stencil/stencil.esm.js +1 -1
  72. package/dist/types/classes/objects/image.class.d.ts +3 -0
  73. package/dist/types/classes/objects/path.class.d.ts +3 -0
  74. package/dist/types/classes/objects/shape.class.d.ts +3 -0
  75. package/dist/types/classes/providers/sync/broadcast-sync-provider.class.d.ts +1 -0
  76. package/dist/types/classes/providers/sync/hocuspocus-sync-provider.class.d.ts +1 -0
  77. package/dist/types/classes/providers/sync/in-memory-sync-provider.class.d.ts +1 -0
  78. package/dist/types/classes/providers/sync/indexeddb-sync-provider.class.d.ts +1 -0
  79. package/dist/types/classes/providers/sync/websocket-sync-provider.class.d.ts +1 -0
  80. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +15 -3
  81. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +16 -34
  82. package/dist/types/components/ui/kritzel-more-menu/kritzel-more-menu.d.ts +10 -1
  83. package/dist/types/components.d.ts +27 -26
  84. package/dist/types/constants/version.d.ts +1 -1
  85. package/dist/types/helpers/object.helper.d.ts +4 -0
  86. package/dist/types/index.d.ts +1 -0
  87. package/dist/types/interfaces/menu-item.interface.d.ts +1 -1
  88. package/dist/types/interfaces/object-export.interface.d.ts +20 -0
  89. package/dist/types/interfaces/sync-config.interface.d.ts +5 -0
  90. package/dist/types/interfaces/sync-provider.interface.d.ts +5 -0
  91. package/package.json +1 -1
@@ -16,6 +16,7 @@ import { DEFAULT_SHAPE_CONFIG } from "../../../configs/default-shape-tool.config
16
16
  import { ABSOLUTE_SCALE_MAX, ABSOLUTE_SCALE_MIN } from "../../../constants/engine.constants";
17
17
  import { KritzelKeyboardHelper } from "../../../helpers/keyboard.helper";
18
18
  import { KritzelDevicesHelper } from "../../../helpers/devices.helper";
19
+ import { hasRemoteSyncProvider } from "../../../interfaces/sync-config.interface";
19
20
  import { DEFAULT_ASSET_STORAGE_CONFIG } from "../../..";
20
21
  import { DEFAULT_SYNC_CONFIG } from "../../../configs/default-sync.config";
21
22
  import { ThemeHelper } from "../../../helpers/theme.helper";
@@ -123,6 +124,19 @@ export class KritzelEditor {
123
124
  group: 'clipboard',
124
125
  action: (menu, _) => this.engineRef.paste(menu.x, menu.y),
125
126
  },
127
+ {
128
+ label: 'menu.export',
129
+ icon: 'upload',
130
+ group: 'clipboard',
131
+ visible: (_, objects) => this.canExportObjects(objects),
132
+ action: (_, objects) => {
133
+ const format = this.getPreferredExportFormat(objects);
134
+ if (!format) {
135
+ return;
136
+ }
137
+ void this.engineRef.exportSelectedObject(format);
138
+ },
139
+ },
126
140
  {
127
141
  label: 'menu.order',
128
142
  icon: 'ordering',
@@ -164,16 +178,43 @@ export class KritzelEditor {
164
178
  },
165
179
  ],
166
180
  },
181
+ { label: 'menu.delete', icon: 'delete', group: 'edit', action: () => this.engineRef.delete() },
182
+ ];
183
+ moreMenuItems = [
184
+ {
185
+ id: 'share',
186
+ label: 'menu.share',
187
+ icon: 'share',
188
+ isVisible: async () => hasRemoteSyncProvider(this.syncConfig),
189
+ action: () => {
190
+ if (!this.isLoggedIn && this.loginConfig) {
191
+ this.openLoginDialog();
192
+ return;
193
+ }
194
+ this.shareDialogRef.open();
195
+ },
196
+ },
167
197
  {
198
+ id: 'export',
168
199
  label: 'menu.export',
200
+ icon: 'upload',
201
+ action: async () => {
202
+ const preview = await this.engineRef.getScreenshot('png');
203
+ this.exportRef.open(preview ?? undefined);
204
+ },
205
+ },
206
+ {
207
+ id: 'import',
208
+ label: 'menu.import',
169
209
  icon: 'download',
170
- group: 'export',
171
- children: [
172
- { label: 'menu.exportAsSvg', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsSvg() },
173
- { label: 'menu.exportAsPng', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsPng() },
174
- ],
210
+ action: () => this.engineRef.importFromFile(),
211
+ },
212
+ {
213
+ id: 'settings',
214
+ label: 'menu.settings',
215
+ icon: 'settings',
216
+ action: () => this.settingsRef.open(),
175
217
  },
176
- { label: 'menu.delete', icon: 'delete', group: 'edit', action: () => this.engineRef.delete() },
177
218
  ];
178
219
  themes;
179
220
  theme = 'light';
@@ -245,6 +286,7 @@ export class KritzelEditor {
245
286
  isNotificationDismissing = false;
246
287
  contextMenuState;
247
288
  normalizedControls = [];
289
+ resolvedMoreMenuItems = [];
248
290
  notificationDismissTimeout;
249
291
  notificationDismissAnimationTimeout;
250
292
  notificationDisplayDurationMs = 5000;
@@ -287,6 +329,18 @@ export class KritzelEditor {
287
329
  onControlsChange(newValue) {
288
330
  this.normalizedControls = this.normalizeControls(newValue);
289
331
  }
332
+ onMoreMenuItemsChange() {
333
+ this.recomputeMoreMenuItems();
334
+ }
335
+ onSyncConfigChange() {
336
+ this.recomputeMoreMenuItems();
337
+ }
338
+ onLoginConfigChange() {
339
+ this.recomputeMoreMenuItems();
340
+ }
341
+ onUserChange() {
342
+ this.recomputeMoreMenuItems();
343
+ }
290
344
  onActiveWorkspaceIdChange(newId) {
291
345
  // If no ID is provided, do nothing (allows other logic to control activeWorkspace)
292
346
  if (!newId) {
@@ -336,6 +390,7 @@ export class KritzelEditor {
336
390
  }
337
391
  this.resolvedTerms = await this.engineRef.getResolvedTerms();
338
392
  this.availableLocaleOptions = await this.engineRef.getAvailableLocaleOptions();
393
+ this.recomputeMoreMenuItems();
339
394
  }
340
395
  onTouchStart(event) {
341
396
  if (event.cancelable) {
@@ -496,11 +551,14 @@ export class KritzelEditor {
496
551
  async exportViewportAsSvg(options) {
497
552
  return this.engineRef.exportViewportAsSvg(options);
498
553
  }
499
- async exportSelectedObjectsAsPng() {
500
- return this.engineRef.exportSelectedObjectsAsPng();
554
+ async getSelectedObjectSupportedExportFormats() {
555
+ return this.engineRef.getSelectedObjectSupportedExportFormats();
556
+ }
557
+ async canExportSelectedObjectAs(format) {
558
+ return this.engineRef.canExportSelectedObjectAs(format);
501
559
  }
502
- async exportSelectedObjectsAsSvg() {
503
- return this.engineRef.exportSelectedObjectsAsSvg();
560
+ async exportSelectedObject(format) {
561
+ return this.engineRef.exportSelectedObject(format);
504
562
  }
505
563
  async downloadAsJson(filename) {
506
564
  return this.engineRef.downloadAsJson(filename);
@@ -567,6 +625,7 @@ export class KritzelEditor {
567
625
  currentUserDialogRef;
568
626
  componentWillLoad() {
569
627
  this.normalizedControls = this.normalizeControls(this.controls);
628
+ this.recomputeMoreMenuItems();
570
629
  this.loadSettingsFromStorage();
571
630
  this.applyTheme();
572
631
  }
@@ -587,13 +646,18 @@ export class KritzelEditor {
587
646
  };
588
647
  });
589
648
  }
649
+ recomputeMoreMenuItems() {
650
+ if (this.moreMenuItems) {
651
+ this.resolvedMoreMenuItems = this.moreMenuItems;
652
+ return;
653
+ }
654
+ }
590
655
  applyTheme() {
591
656
  const themeObj = this.resolveThemeObject();
592
657
  ThemeHelper.applyThemeToElement(this.host, themeObj);
593
658
  }
594
659
  resolveThemeObject() {
595
- return this.themes?.find(t => t.name === this.theme)
596
- ?? (this.theme === 'dark' ? darkTheme : lightTheme);
660
+ return this.themes?.find(t => t.name === this.theme) ?? (this.theme === 'dark' ? darkTheme : lightTheme);
597
661
  }
598
662
  componentDidLoad() {
599
663
  this.registerCustomSvgIcons();
@@ -628,7 +692,7 @@ export class KritzelEditor {
628
692
  syncConfig: this.syncConfig,
629
693
  assetStorageConfig: this.assetStorageConfig,
630
694
  loginConfig: this.loginConfig,
631
- theme: this.theme
695
+ theme: this.theme,
632
696
  });
633
697
  }
634
698
  async onEngineReady(event) {
@@ -791,43 +855,6 @@ export class KritzelEditor {
791
855
  }
792
856
  this.themeChange.emit(event.detail.theme);
793
857
  }
794
- get moreMenuItems() {
795
- return [
796
- {
797
- id: 'share',
798
- label: this.resolvedTerms['menu.share'] ?? 'Share',
799
- icon: 'share',
800
- action: () => {
801
- if (!this.isLoggedIn && this.loginConfig) {
802
- this.openLoginDialog();
803
- return;
804
- }
805
- this.shareDialogRef.open();
806
- },
807
- },
808
- {
809
- id: 'export',
810
- label: this.resolvedTerms['menu.export'] ?? 'Export',
811
- icon: 'upload',
812
- action: async () => {
813
- const preview = await this.engineRef.getScreenshot('png');
814
- this.exportRef.open(preview ?? undefined);
815
- },
816
- },
817
- {
818
- id: 'import',
819
- label: this.resolvedTerms['menu.import'] ?? 'Import',
820
- icon: 'download',
821
- action: () => this.engineRef.importFromFile(),
822
- },
823
- {
824
- id: 'settings',
825
- label: this.resolvedTerms['menu.settings'] ?? 'Settings',
826
- icon: 'settings',
827
- action: () => this.settingsRef.open(),
828
- }
829
- ];
830
- }
831
858
  handleToggleIsPublic = async (event) => {
832
859
  const isPublic = event.detail;
833
860
  const activeWorkspace = await this.engineRef.getActiveWorkspace();
@@ -857,6 +884,28 @@ export class KritzelEditor {
857
884
  get isLoggedIn() {
858
885
  return !!this.user && !this.user.isGuest;
859
886
  }
887
+ canExportObjectsAs(objects, format) {
888
+ if (!objects || objects.length !== 1) {
889
+ return false;
890
+ }
891
+ const [selected] = objects;
892
+ if (!ObjectHelper.isKritzelExportable(selected)) {
893
+ return false;
894
+ }
895
+ return selected.getSupportedExportFormats().includes(format);
896
+ }
897
+ canExportObjects(objects) {
898
+ return this.canExportObjectsAs(objects, 'png') || this.canExportObjectsAs(objects, 'svg');
899
+ }
900
+ getPreferredExportFormat(objects) {
901
+ if (this.canExportObjectsAs(objects, 'png')) {
902
+ return 'png';
903
+ }
904
+ if (this.canExportObjectsAs(objects, 'svg')) {
905
+ return 'svg';
906
+ }
907
+ return null;
908
+ }
860
909
  async openLoginDialog() {
861
910
  this.loginDialogRef?.open();
862
911
  }
@@ -1033,41 +1082,41 @@ export class KritzelEditor {
1033
1082
  const isLoggedIn = this.isLoggedIn;
1034
1083
  const shouldShowCurrentUser = isLoggedIn;
1035
1084
  const shouldShowLoginButton = this.isReady && !!this.loginConfig && !isLoggedIn;
1036
- return (h(Host, { key: 'ab06876e3a07e97c3788113ffd0483bbb2819d5b' }, h("div", { key: 'e393eacfad2b224a720e5a97b047af8dd3ce97a5', class: "editor-content", style: {
1085
+ return (h(Host, { key: '3119d6909544f0d15bd805f65ccf3f18469dc11d' }, h("div", { key: '7528eec8df968cd7814a2343fa3aa792802b9856', class: "editor-content", style: {
1037
1086
  opacity: this.isEditorVisible ? '1' : '0',
1038
1087
  visibility: this.isEditorVisible ? 'visible' : 'hidden',
1039
1088
  transition: 'opacity 0.2s ease-in-out, visibility 0.2s ease-in-out',
1040
- } }, h("div", { key: 'd9dcbd6859bea28d75c7f8b0cc26ea3ba58b2433', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: '945953a6c95520316c4e0f35503a824414bd3c7a', visible: this.isWorkspaceManagerVisible, workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, terms: this.resolvedTerms, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: '8b345bf6ce0ec33ca35f1f630af2050b95bc6b74', visible: this.isBackToContentButtonVisible, text: this.resolvedTerms['backToContent.label'] ?? 'Back to content', onBackToContent: () => this.backToContent() })), this.activeNotification && (h("div", { key: '1b965de38a7f1f40d5d91431801e873289416924', class: "top-center-notification-layer", role: "presentation" }, h("div", { key: 'f165dc7acc5e1bc7923fec217ebc16fe4a3f2ece', class: { 'top-center-notification-container': true, 'is-dismissing': this.isNotificationDismissing }, role: "presentation" }, h("kritzel-notification-card", { key: 'c5cf7edc1f921e35310c89449f5a043dda171a04', notification: this.activeNotification, locale: this.locale, onDismiss: this.dismissNotification, onHoverChange: event => this.handleNotificationHoverChange(event) })))), this.contextMenuState && this.contextMenuState.items.length > 0 && (h("kritzel-context-menu", { key: 'fc3417276f0034e7fc7e8360d3f3ce57106146b2', class: "context-menu", items: this.contextMenuState.items, objects: this.contextMenuState.objects, style: {
1089
+ } }, h("div", { key: '71f0dba52cddc6e28ea7f7b3b6ff78c32aa19acf', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: '579826701b13fb4b12dbdbf0b31b05031f01c3d1', visible: this.isWorkspaceManagerVisible, workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, terms: this.resolvedTerms, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: '84fb52fba5f898cf1034780f87f7ce49d370cdfe', visible: this.isBackToContentButtonVisible, text: this.resolvedTerms['backToContent.label'] ?? 'Back to content', onBackToContent: () => this.backToContent() })), this.activeNotification && (h("div", { key: 'ecca20769db06f56bd52199b04f9e44c74bf525d', class: "top-center-notification-layer", role: "presentation" }, h("div", { key: 'aa2232646d7d77d70af04c8b413e2eb8033a00eb', class: { 'top-center-notification-container': true, 'is-dismissing': this.isNotificationDismissing }, role: "presentation" }, h("kritzel-notification-card", { key: 'fa111382e6fdebf8e5944c6148cad9583bc8b68d', notification: this.activeNotification, locale: this.locale, onDismiss: this.dismissNotification, onHoverChange: event => this.handleNotificationHoverChange(event) })))), this.contextMenuState && this.contextMenuState.items.length > 0 && (h("kritzel-context-menu", { key: '420caf2b6bfb79f3ebda3537cc379f8735eb8c09', class: "context-menu", items: this.contextMenuState.items, objects: this.contextMenuState.objects, style: {
1041
1090
  position: 'absolute',
1042
1091
  left: `${this.contextMenuState.position.x}px`,
1043
1092
  top: `${this.contextMenuState.position.y}px`,
1044
1093
  zIndex: '10002',
1045
- }, onActionSelected: event => this.handleContextMenuActionSelected(event), onClose: () => this.hideContextMenu() })), h("kritzel-engine", { key: '0c9df0386d38a87f50d324cfc51307a1cb947a58', ref: el => {
1094
+ }, onActionSelected: event => this.handleContextMenuActionSelected(event), onClose: () => this.hideContextMenu() })), h("kritzel-engine", { key: 'd10589d02c626712e10f55b07f716907d83b28c1', ref: el => {
1046
1095
  if (el) {
1047
1096
  this.engineRef = el;
1048
1097
  }
1049
- }, workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, assetStorageConfig: this.assetStorageConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, isObjectDistanceFadingActive: this.isObjectDistanceFadingActive, scaleMin: this.scaleMin, cursorTarget: this.cursorTarget, isLoading: this.isLoading, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, isPanningEnabled: this.isPanningEnabled, isZoomingEnabled: this.isZoomingEnabled, theme: this.theme, themes: this.themes, licenseKey: this.licenseKey, locale: this.locale, locales: this.locales, fallbackLocale: this.fallbackLocale, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event), onNotificationsChange: event => this.handleNotificationsChange(event), onContextMenuStateChange: event => this.handleContextMenuStateChange(event) }), h("kritzel-controls", { key: '46d8e9c45c7bed24fc02d17c8fef836d596088d7', visible: this.isControlsVisible, class: { 'keyboard-open': this.isVirtualKeyboardOpen }, ref: el => {
1098
+ }, workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, assetStorageConfig: this.assetStorageConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, isObjectDistanceFadingActive: this.isObjectDistanceFadingActive, scaleMin: this.scaleMin, cursorTarget: this.cursorTarget, isLoading: this.isLoading, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, isPanningEnabled: this.isPanningEnabled, isZoomingEnabled: this.isZoomingEnabled, theme: this.theme, themes: this.themes, licenseKey: this.licenseKey, locale: this.locale, locales: this.locales, fallbackLocale: this.fallbackLocale, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event), onNotificationsChange: event => this.handleNotificationsChange(event), onContextMenuStateChange: event => this.handleContextMenuStateChange(event) }), h("kritzel-controls", { key: '121480e948808fe6a44a94511becb834f9249897', visible: this.isControlsVisible, class: { 'keyboard-open': this.isVirtualKeyboardOpen }, ref: el => {
1050
1099
  if (el) {
1051
1100
  this.controlsRef = el;
1052
1101
  }
1053
- }, controls: this.normalizedControls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, terms: this.resolvedTerms, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'e3ef94509a82fe435f827b66cf1813969b7dec66', class: "bottom-left-buttons" }, h("kritzel-zoom-panel", { key: '4e6cbdf85f550e6e3037dce3b910c0582ea0320b', visible: this.isZoomPanelVisible, disabled: !this.isZoomingEnabled, zoomPercent: this.currentZoomPercent, terms: this.resolvedTerms, onZoomIn: () => this.zoomIn(), onZoomOut: () => this.zoomOut() })), h("div", { key: 'a62df7f8a68cbed728b701894a5284c2bff39e1e', class: "top-right-buttons" }, h("kritzel-settings", { key: '0b6daf9ff43551df9f86431d398a32913a845925', ref: el => {
1102
+ }, controls: this.normalizedControls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, terms: this.resolvedTerms, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'e84f31858a6a45fb9f7bcc3686122b349551618b', class: "bottom-left-buttons" }, h("kritzel-zoom-panel", { key: 'a25d93767a124e1a2fdcdd4b77706ec7d032234c', visible: this.isZoomPanelVisible, disabled: !this.isZoomingEnabled, zoomPercent: this.currentZoomPercent, terms: this.resolvedTerms, onZoomIn: () => this.zoomIn(), onZoomOut: () => this.zoomOut() })), h("div", { key: '49810743d464d4e019670859f6ed31d9c12cd560', class: "top-right-buttons" }, h("kritzel-settings", { key: '57daff63b4ec1de36f94be99948d0d0aa091c522', ref: el => {
1054
1103
  if (el) {
1055
1104
  this.settingsRef = el;
1056
1105
  }
1057
- }, shortcuts: this.shortcuts, availableThemes: this.themes && this.themes.length > 0 ? this.themes.map(t => t.name) : ['light', 'dark'], availableLocales: this.availableLocaleOptions, settings: this.currentSettingsConfig, terms: this.resolvedTerms, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: '29d02ffd3358fe91d27435cc3fdd5f8ac2ad7cf5', ref: el => {
1106
+ }, shortcuts: this.shortcuts, availableThemes: this.themes && this.themes.length > 0 ? this.themes.map(t => t.name) : ['light', 'dark'], availableLocales: this.availableLocaleOptions, settings: this.currentSettingsConfig, terms: this.resolvedTerms, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: 'cad9614f0e439713e96108476ed3c400c14546cc', ref: el => {
1058
1107
  if (el) {
1059
1108
  this.exportRef = el;
1060
1109
  }
1061
- }, workspaceName: this.activeWorkspace?.name || 'workspace', terms: this.resolvedTerms, onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '729ca599e46654bc1429b5d91ff73f26d9b6e7bb', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '84c07268072418a82cf504f16803c59a1e37c0ae', user: this.user, terms: this.resolvedTerms, onClick: () => this.currentUserDialogRef?.open() }), shouldShowCurrentUser && (h("kritzel-current-user-dialog", { key: '55189e3da7899628b252e7995b20bc422fce2d5c', ref: el => {
1110
+ }, workspaceName: this.activeWorkspace?.name || 'workspace', terms: this.resolvedTerms, onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '191775e6c3f62391e4c62cb8039ace51b4853555', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '385264c0ebb74eb1c3e3793ad889b8bd84ec1920', user: this.user, terms: this.resolvedTerms, onClick: () => this.currentUserDialogRef?.open() }), shouldShowCurrentUser && (h("kritzel-current-user-dialog", { key: '065b583dd31019fe88739171089414123af7d640', ref: el => {
1062
1111
  if (el) {
1063
1112
  this.currentUserDialogRef = el;
1064
1113
  this.currentUserDialogRef.addEventListener('logoutRequest', this.handleCurrentUserLogout);
1065
1114
  }
1066
- }, user: this.user, terms: this.resolvedTerms })), shouldShowLoginButton && (h("kritzel-button", { key: 'a55d85769bad635fcc7934f584bf1bf74c1e7ea6', onButtonClick: () => this.loginDialogRef?.open() }, this.resolvedTerms['login.dialogTitle'] ?? 'Sign in')), h("kritzel-more-menu", { key: '67dd879ec3c55c98e32f6112ca53d925f47b56b4', items: this.moreMenuItems, visible: this.isMoreMenuVisible, terms: this.resolvedTerms }), h("kritzel-share-dialog", { key: '5f13130099110eb472022099219e15877ceceb57', ref: el => {
1115
+ }, user: this.user, terms: this.resolvedTerms })), shouldShowLoginButton && h("kritzel-button", { key: 'b655001273147d58f299983c9512d10ee16847a1', onButtonClick: () => this.loginDialogRef?.open() }, this.resolvedTerms['login.dialogTitle'] ?? 'Sign in'), h("kritzel-more-menu", { key: '265cd05a2e62fb3a16beae85a82a81e69410f284', items: this.resolvedMoreMenuItems, visible: this.isMoreMenuVisible, terms: this.resolvedTerms }), h("kritzel-share-dialog", { key: '0c441b88aab039e4f9eb86d226670732f0635446', ref: el => {
1067
1116
  if (el) {
1068
1117
  this.shareDialogRef = el;
1069
1118
  }
1070
- }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, terms: this.resolvedTerms, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: 'cda0fcdcad75de8730ce10bda425cc0fbe01429a', ref: el => {
1119
+ }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, terms: this.resolvedTerms, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: '3e06e1b33c3dc98cfa8f76641acdb5a3ea51c1d5', ref: el => {
1071
1120
  if (el) {
1072
1121
  this.loginDialogRef = el;
1073
1122
  }
@@ -1372,7 +1421,32 @@ export class KritzelEditor {
1372
1421
  },
1373
1422
  "getter": false,
1374
1423
  "setter": false,
1375
- "defaultValue": "[\n { label: 'menu.copy', icon: 'copy', group: 'clipboard', action: () => this.engineRef.copy() },\n { label: 'menu.cut', icon: 'cut', group: 'clipboard', action: () => this.engineRef.cut() },\n {\n label: 'menu.paste',\n icon: 'paste',\n group: 'clipboard',\n action: (menu, _) => this.engineRef.paste(menu.x, menu.y),\n },\n {\n label: 'menu.order',\n icon: 'ordering',\n group: 'other',\n children: [\n { label: 'menu.bringToFront', icon: 'bring-to-front', action: () => this.engineRef.bringToFront() },\n { label: 'menu.sendToBack', icon: 'send-to-back', action: () => this.engineRef.sendToBack() },\n { label: 'menu.moveUp', icon: 'arrow-up-from-dot', action: () => this.engineRef.bringForward() },\n { label: 'menu.moveDown', icon: 'arrow-down-from-dot', action: () => this.engineRef.sendBackward() },\n ],\n },\n {\n label: 'menu.align',\n icon: 'align',\n group: 'other',\n children: [\n { label: 'menu.alignLeft', icon: 'align-start-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.StartHorizontal) },\n { label: 'menu.alignCenterHorizontal', icon: 'align-center-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterHorizontal) },\n { label: 'menu.alignRight', icon: 'align-end-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.EndHorizontal) },\n { label: 'menu.alignTop', icon: 'align-start-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.StartVertical) },\n { label: 'menu.alignCenterVertical', icon: 'align-center-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterVertical) },\n { label: 'menu.alignBottom', icon: 'align-end-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.EndVertical) },\n ],\n },\n {\n label: 'menu.group',\n icon: 'group',\n group: 'other',\n children: [\n {\n label: 'menu.group',\n icon: 'group',\n action: () => this.engineRef.group(),\n },\n {\n label: 'menu.ungroup',\n icon: 'ungroup',\n action: () => this.engineRef.ungroup(),\n },\n ],\n },\n {\n label: 'menu.export',\n icon: 'download',\n group: 'export',\n children: [\n { label: 'menu.exportAsSvg', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsSvg() },\n { label: 'menu.exportAsPng', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsPng() },\n ],\n },\n { label: 'menu.delete', icon: 'delete', group: 'edit', action: () => this.engineRef.delete() },\n ]"
1424
+ "defaultValue": "[\n { label: 'menu.copy', icon: 'copy', group: 'clipboard', action: () => this.engineRef.copy() },\n { label: 'menu.cut', icon: 'cut', group: 'clipboard', action: () => this.engineRef.cut() },\n {\n label: 'menu.paste',\n icon: 'paste',\n group: 'clipboard',\n action: (menu, _) => this.engineRef.paste(menu.x, menu.y),\n },\n {\n label: 'menu.export',\n icon: 'upload',\n group: 'clipboard',\n visible: (_, objects) => this.canExportObjects(objects),\n action: (_, objects) => {\n const format = this.getPreferredExportFormat(objects);\n if (!format) {\n return;\n }\n\n void this.engineRef.exportSelectedObject(format);\n },\n },\n {\n label: 'menu.order',\n icon: 'ordering',\n group: 'other',\n children: [\n { label: 'menu.bringToFront', icon: 'bring-to-front', action: () => this.engineRef.bringToFront() },\n { label: 'menu.sendToBack', icon: 'send-to-back', action: () => this.engineRef.sendToBack() },\n { label: 'menu.moveUp', icon: 'arrow-up-from-dot', action: () => this.engineRef.bringForward() },\n { label: 'menu.moveDown', icon: 'arrow-down-from-dot', action: () => this.engineRef.sendBackward() },\n ],\n },\n {\n label: 'menu.align',\n icon: 'align',\n group: 'other',\n children: [\n { label: 'menu.alignLeft', icon: 'align-start-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.StartHorizontal) },\n { label: 'menu.alignCenterHorizontal', icon: 'align-center-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterHorizontal) },\n { label: 'menu.alignRight', icon: 'align-end-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.EndHorizontal) },\n { label: 'menu.alignTop', icon: 'align-start-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.StartVertical) },\n { label: 'menu.alignCenterVertical', icon: 'align-center-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterVertical) },\n { label: 'menu.alignBottom', icon: 'align-end-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.EndVertical) },\n ],\n },\n {\n label: 'menu.group',\n icon: 'group',\n group: 'other',\n children: [\n {\n label: 'menu.group',\n icon: 'group',\n action: () => this.engineRef.group(),\n },\n {\n label: 'menu.ungroup',\n icon: 'ungroup',\n action: () => this.engineRef.ungroup(),\n },\n ],\n },\n { label: 'menu.delete', icon: 'delete', group: 'edit', action: () => this.engineRef.delete() },\n ]"
1425
+ },
1426
+ "moreMenuItems": {
1427
+ "type": "unknown",
1428
+ "mutable": false,
1429
+ "complexType": {
1430
+ "original": "IKritzelMenuItem[]",
1431
+ "resolved": "IKritzelMenuItem<any>[]",
1432
+ "references": {
1433
+ "IKritzelMenuItem": {
1434
+ "location": "import",
1435
+ "path": "../../../interfaces/menu-item.interface",
1436
+ "id": "src/interfaces/menu-item.interface.ts::IKritzelMenuItem",
1437
+ "referenceLocation": "IKritzelMenuItem"
1438
+ }
1439
+ }
1440
+ },
1441
+ "required": false,
1442
+ "optional": true,
1443
+ "docs": {
1444
+ "tags": [],
1445
+ "text": ""
1446
+ },
1447
+ "getter": false,
1448
+ "setter": false,
1449
+ "defaultValue": "[\n {\n id: 'share',\n label: 'menu.share',\n icon: 'share',\n isVisible: async () => hasRemoteSyncProvider(this.syncConfig),\n action: () => {\n if (!this.isLoggedIn && this.loginConfig) {\n this.openLoginDialog();\n return;\n }\n this.shareDialogRef.open();\n },\n },\n {\n id: 'export',\n label: 'menu.export',\n icon: 'upload',\n action: async () => {\n const preview = await this.engineRef.getScreenshot('png');\n this.exportRef.open(preview ?? undefined);\n },\n },\n {\n id: 'import',\n label: 'menu.import',\n icon: 'download',\n action: () => this.engineRef.importFromFile(),\n },\n {\n id: 'settings',\n label: 'menu.settings',\n icon: 'settings',\n action: () => this.settingsRef.open(),\n },\n ]"
1376
1450
  },
1377
1451
  "themes": {
1378
1452
  "type": "unknown",
@@ -1905,7 +1979,8 @@ export class KritzelEditor {
1905
1979
  "activeNotification": {},
1906
1980
  "isNotificationDismissing": {},
1907
1981
  "contextMenuState": {},
1908
- "normalizedControls": {}
1982
+ "normalizedControls": {},
1983
+ "resolvedMoreMenuItems": {}
1909
1984
  };
1910
1985
  }
1911
1986
  static get events() {
@@ -3491,31 +3566,74 @@ export class KritzelEditor {
3491
3566
  "tags": []
3492
3567
  }
3493
3568
  },
3494
- "exportSelectedObjectsAsPng": {
3569
+ "getSelectedObjectSupportedExportFormats": {
3495
3570
  "complexType": {
3496
- "signature": "() => Promise<void>",
3571
+ "signature": "() => Promise<KritzelObjectExportFormat[]>",
3497
3572
  "parameters": [],
3498
3573
  "references": {
3499
3574
  "Promise": {
3500
3575
  "location": "global",
3501
3576
  "id": "global::Promise"
3577
+ },
3578
+ "KritzelObjectExportFormat": {
3579
+ "location": "import",
3580
+ "path": "../../../interfaces/object-export.interface",
3581
+ "id": "src/interfaces/object-export.interface.ts::KritzelObjectExportFormat",
3582
+ "referenceLocation": "KritzelObjectExportFormat"
3502
3583
  }
3503
3584
  },
3504
- "return": "Promise<void>"
3585
+ "return": "Promise<KritzelObjectExportFormat[]>"
3505
3586
  },
3506
3587
  "docs": {
3507
3588
  "text": "",
3508
3589
  "tags": []
3509
3590
  }
3510
3591
  },
3511
- "exportSelectedObjectsAsSvg": {
3592
+ "canExportSelectedObjectAs": {
3512
3593
  "complexType": {
3513
- "signature": "() => Promise<void>",
3514
- "parameters": [],
3594
+ "signature": "(format: KritzelObjectExportFormat) => Promise<boolean>",
3595
+ "parameters": [{
3596
+ "name": "format",
3597
+ "type": "\"svg\" | \"png\"",
3598
+ "docs": ""
3599
+ }],
3515
3600
  "references": {
3516
3601
  "Promise": {
3517
3602
  "location": "global",
3518
3603
  "id": "global::Promise"
3604
+ },
3605
+ "KritzelObjectExportFormat": {
3606
+ "location": "import",
3607
+ "path": "../../../interfaces/object-export.interface",
3608
+ "id": "src/interfaces/object-export.interface.ts::KritzelObjectExportFormat",
3609
+ "referenceLocation": "KritzelObjectExportFormat"
3610
+ }
3611
+ },
3612
+ "return": "Promise<boolean>"
3613
+ },
3614
+ "docs": {
3615
+ "text": "",
3616
+ "tags": []
3617
+ }
3618
+ },
3619
+ "exportSelectedObject": {
3620
+ "complexType": {
3621
+ "signature": "(format: KritzelObjectExportFormat) => Promise<void>",
3622
+ "parameters": [{
3623
+ "name": "format",
3624
+ "type": "\"svg\" | \"png\"",
3625
+ "docs": ""
3626
+ }],
3627
+ "references": {
3628
+ "Promise": {
3629
+ "location": "global",
3630
+ "id": "global::Promise"
3631
+ },
3632
+ "KritzelObjectExportFormat": {
3633
+ "location": "import",
3634
+ "path": "../../../interfaces/object-export.interface",
3635
+ "id": "src/interfaces/object-export.interface.ts::KritzelObjectExportFormat",
3636
+ "referenceLocation": "KritzelObjectExportFormat"
3519
3637
  }
3520
3638
  },
3521
3639
  "return": "Promise<void>"
@@ -4096,6 +4214,18 @@ export class KritzelEditor {
4096
4214
  }, {
4097
4215
  "propName": "controls",
4098
4216
  "methodName": "onControlsChange"
4217
+ }, {
4218
+ "propName": "moreMenuItems",
4219
+ "methodName": "onMoreMenuItemsChange"
4220
+ }, {
4221
+ "propName": "syncConfig",
4222
+ "methodName": "onSyncConfigChange"
4223
+ }, {
4224
+ "propName": "loginConfig",
4225
+ "methodName": "onLoginConfigChange"
4226
+ }, {
4227
+ "propName": "user",
4228
+ "methodName": "onUserChange"
4099
4229
  }, {
4100
4230
  "propName": "activeWorkspaceId",
4101
4231
  "methodName": "onActiveWorkspaceIdChange"