kritzel-stencil 0.3.16 → 0.3.17

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 (227) hide show
  1. package/LICENSE.md +50 -0
  2. package/dist/cjs/index-Xav9JFHg.js +2 -2
  3. package/dist/cjs/index.cjs.js +7 -1
  4. package/dist/cjs/{kritzel-active-users_42.cjs.entry.js → kritzel-active-users_44.cjs.entry.js} +710 -145
  5. package/dist/cjs/loader.cjs.js +1 -1
  6. package/dist/cjs/{schema.constants-DJQTjcy7.js → schema.constants-DrHO_CYF.js} +1169 -171
  7. package/dist/cjs/stencil.cjs.js +1 -1
  8. package/dist/collection/classes/core/core.class.js +24 -0
  9. package/dist/collection/classes/handlers/context-menu.handler.js +24 -2
  10. package/dist/collection/classes/managers/license.manager.js +285 -0
  11. package/dist/collection/classes/managers/localization.manager.js +189 -0
  12. package/dist/collection/classes/objects/custom-element.class.js +2 -0
  13. package/dist/collection/classes/objects/group.class.js +7 -2
  14. package/dist/collection/classes/objects/image.class.js +10 -7
  15. package/dist/collection/classes/objects/line.class.js +3 -0
  16. package/dist/collection/classes/objects/path.class.js +13 -12
  17. package/dist/collection/classes/objects/selection-group.class.js +7 -2
  18. package/dist/collection/classes/objects/shape.class.js +3 -0
  19. package/dist/collection/classes/objects/text.class.js +4 -1
  20. package/dist/collection/classes/registries/icon-registry.class.js +1 -0
  21. package/dist/collection/classes/tools/brush-tool.class.js +1 -1
  22. package/dist/collection/collection-manifest.json +3 -1
  23. package/dist/collection/components/core/kritzel-editor/kritzel-editor.css +16 -0
  24. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +462 -60
  25. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +446 -16
  26. package/dist/collection/components/core/kritzel-watermark/kritzel-watermark.css +29 -0
  27. package/dist/collection/components/core/kritzel-watermark/kritzel-watermark.js +83 -0
  28. package/dist/collection/components/shared/kritzel-avatar/kritzel-avatar.js +3 -3
  29. package/dist/collection/components/shared/kritzel-button/kritzel-button.js +2 -2
  30. package/dist/collection/components/shared/kritzel-color/kritzel-color.js +2 -2
  31. package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js +1 -1
  32. package/dist/collection/components/shared/kritzel-font/kritzel-font.js +1 -1
  33. package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js +2 -1
  34. package/dist/collection/components/shared/kritzel-input/kritzel-input.js +1 -1
  35. package/dist/collection/components/shared/kritzel-master-detail/kritzel-master-detail.js +3 -3
  36. package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js +1 -1
  37. package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.js +2 -2
  38. package/dist/collection/components/shared/kritzel-numeric-input/kritzel-numeric-input.js +1 -1
  39. package/dist/collection/components/shared/kritzel-opacity-slider/kritzel-opacity-slider.js +1 -1
  40. package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js +1 -1
  41. package/dist/collection/components/shared/kritzel-slide-toggle/kritzel-slide-toggle.js +1 -1
  42. package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js +1 -1
  43. package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js +2 -1
  44. package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.js +2 -2
  45. package/dist/collection/components/ui/kritzel-back-to-content/kritzel-back-to-content.js +1 -1
  46. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +41 -6
  47. package/dist/collection/components/ui/kritzel-current-user/kritzel-current-user.js +36 -1
  48. package/dist/collection/components/ui/kritzel-current-user-dialog/kritzel-current-user-dialog.js +36 -1
  49. package/dist/collection/components/ui/kritzel-export/kritzel-export.js +44 -7
  50. package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.js +1 -1
  51. package/dist/collection/components/ui/kritzel-more-menu/kritzel-more-menu.js +36 -1
  52. package/dist/collection/components/ui/kritzel-settings/kritzel-settings.js +108 -14
  53. package/dist/collection/components/ui/kritzel-share-dialog/kritzel-share-dialog.js +38 -3
  54. package/dist/collection/components/ui/kritzel-tool-config/kritzel-tool-config.js +38 -3
  55. package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +36 -1
  56. package/dist/collection/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.js +38 -3
  57. package/dist/collection/components/ui/kritzel-zoom-panel/kritzel-zoom-panel.css +72 -0
  58. package/dist/collection/components/ui/kritzel-zoom-panel/kritzel-zoom-panel.js +173 -0
  59. package/dist/collection/constants/engine.constants.js +2 -0
  60. package/dist/collection/constants/license.constants.js +25 -0
  61. package/dist/collection/constants/version.js +1 -1
  62. package/dist/collection/helpers/localization.helper.js +25 -0
  63. package/dist/collection/helpers/math.helper.js +3 -0
  64. package/dist/collection/helpers/svg-export.helper.js +223 -26
  65. package/dist/collection/index.js +13 -0
  66. package/dist/collection/interfaces/localization.interface.js +1 -0
  67. package/dist/collection/locales/de-locale.js +119 -0
  68. package/dist/collection/locales/en-locale.js +120 -0
  69. package/dist/collection/locales/fr-locale.js +119 -0
  70. package/dist/collection/themes/dark-theme.js +18 -0
  71. package/dist/collection/themes/light-theme.js +18 -0
  72. package/dist/components/index.d.ts +4 -0
  73. package/dist/components/index.js +1 -1
  74. package/dist/components/kritzel-active-users.js +1 -1
  75. package/dist/components/kritzel-avatar.js +1 -1
  76. package/dist/components/kritzel-awareness-cursors.js +1 -1
  77. package/dist/components/kritzel-back-to-content.js +1 -1
  78. package/dist/components/kritzel-brush-style.js +1 -1
  79. package/dist/components/kritzel-button.js +1 -1
  80. package/dist/components/kritzel-color-palette.js +1 -1
  81. package/dist/components/kritzel-color.js +1 -1
  82. package/dist/components/kritzel-context-menu.js +1 -1
  83. package/dist/components/kritzel-controls.js +1 -1
  84. package/dist/components/kritzel-current-user-dialog.js +1 -1
  85. package/dist/components/kritzel-current-user.js +1 -1
  86. package/dist/components/kritzel-editor.js +1 -1
  87. package/dist/components/kritzel-engine.js +1 -1
  88. package/dist/components/kritzel-export.js +1 -1
  89. package/dist/components/kritzel-font-size.js +1 -1
  90. package/dist/components/kritzel-font.js +1 -1
  91. package/dist/components/kritzel-icon.js +1 -1
  92. package/dist/components/kritzel-input.js +1 -1
  93. package/dist/components/kritzel-login-dialog.js +1 -1
  94. package/dist/components/kritzel-master-detail.js +1 -1
  95. package/dist/components/kritzel-menu-item.js +1 -1
  96. package/dist/components/kritzel-menu.js +1 -1
  97. package/dist/components/kritzel-more-menu.js +1 -1
  98. package/dist/components/kritzel-numeric-input.js +1 -1
  99. package/dist/components/kritzel-opacity-slider.js +1 -1
  100. package/dist/components/kritzel-pill-tabs.js +1 -1
  101. package/dist/components/kritzel-portal.js +1 -1
  102. package/dist/components/kritzel-settings.js +1 -1
  103. package/dist/components/kritzel-share-dialog.js +1 -1
  104. package/dist/components/kritzel-slide-toggle.js +1 -1
  105. package/dist/components/kritzel-split-button.js +1 -1
  106. package/dist/components/kritzel-stroke-size.js +1 -1
  107. package/dist/components/kritzel-tool-config.js +1 -1
  108. package/dist/components/kritzel-tooltip.js +1 -1
  109. package/dist/components/kritzel-utility-panel.js +1 -1
  110. package/dist/components/kritzel-watermark.d.ts +11 -0
  111. package/dist/components/kritzel-watermark.js +1 -0
  112. package/dist/components/kritzel-workspace-manager.js +1 -1
  113. package/dist/components/kritzel-zoom-panel.d.ts +11 -0
  114. package/dist/components/kritzel-zoom-panel.js +1 -0
  115. package/dist/components/{p-B5xxfwKF.js → p-3HxnBrCM.js} +1 -1
  116. package/dist/components/p-6RjeGuvH.js +1 -0
  117. package/dist/components/p-7NsK0uHu.js +1 -0
  118. package/dist/components/{p-dcAernE1.js → p-BCNyR5Sw.js} +1 -1
  119. package/dist/components/{p-C2SX-XRr.js → p-BG6hOSrm.js} +1 -1
  120. package/dist/components/p-BKJSh8qQ.js +1 -0
  121. package/dist/components/{p-SptaSMno.js → p-BKvHg9cv.js} +1 -1
  122. package/dist/components/p-Bc55X65h.js +1 -0
  123. package/dist/components/p-BpnIvNvq.js +1 -0
  124. package/dist/components/p-BvRrA4hN.js +1 -0
  125. package/dist/components/{p-B2w8X7vn.js → p-BxpKq94F.js} +1 -1
  126. package/dist/components/{p-BFoK4W--.js → p-Bzv9Px8v.js} +1 -1
  127. package/dist/components/{p-COLHjboZ.js → p-C9HGoDHE.js} +1 -1
  128. package/dist/components/p-CEnEDaix.js +1 -0
  129. package/dist/components/p-CIcLzcfA.js +1 -0
  130. package/dist/components/p-CPtDfadX.js +1 -0
  131. package/dist/components/p-C_fKgKHu.js +9 -0
  132. package/dist/components/p-CdR76C4L.js +1 -0
  133. package/dist/components/p-Cu9KYyoq.js +1 -0
  134. package/dist/components/p-CyqRcqsO.js +1 -0
  135. package/dist/components/{p-UoPj5QjH.js → p-DDkmsPpV.js} +1 -1
  136. package/dist/components/{p-D-sRVAbQ.js → p-DI4vQRE3.js} +1 -1
  137. package/dist/components/{p-CJOhfMU5.js → p-DNdXJp8F.js} +1 -1
  138. package/dist/components/p-DX5K8xnh.js +1 -0
  139. package/dist/components/{p-DEy7zJCe.js → p-DZdgXCAx.js} +1 -1
  140. package/dist/components/p-DdH1cKED.js +1 -0
  141. package/dist/components/p-DdsSSqFY.js +1 -0
  142. package/dist/components/p-DgmtCdnL.js +1 -0
  143. package/dist/components/{p-BzYU3-MJ.js → p-DmWSRsjK.js} +1 -1
  144. package/dist/components/{p-Bj2laX89.js → p-Dz-Ti24X.js} +1 -1
  145. package/dist/components/{p-BiG1dxPS.js → p-F5_X4dZG.js} +1 -1
  146. package/dist/components/{p-x6doYeiI.js → p-IpoC5EEY.js} +1 -1
  147. package/dist/components/p-Jn6TNdfe.js +1 -0
  148. package/dist/components/{p-BfNHpqQ8.js → p-NuLP1xHe.js} +1 -1
  149. package/dist/components/{p-skWUIStn.js → p-SDZNC8GF.js} +1 -1
  150. package/dist/components/{p-BYmp9Ovv.js → p-U4oawa1x.js} +1 -1
  151. package/dist/components/{p-DM11KXUT.js → p-f8aW1ye7.js} +1 -1
  152. package/dist/components/p-v7dxxrL5.js +1 -0
  153. package/dist/components/p-vAeiXe6c.js +1 -0
  154. package/dist/esm/index-Dhio9uis.js +2 -2
  155. package/dist/esm/index.js +2 -2
  156. package/dist/esm/{kritzel-active-users_42.entry.js → kritzel-active-users_44.entry.js} +709 -146
  157. package/dist/esm/loader.js +1 -1
  158. package/dist/esm/{schema.constants-DiCnmIYK.js → schema.constants-DchTXG3V.js} +1163 -172
  159. package/dist/esm/stencil.js +1 -1
  160. package/dist/stencil/index.esm.js +1 -1
  161. package/dist/stencil/p-DchTXG3V.js +1 -0
  162. package/dist/stencil/p-c9a3807b.entry.js +9 -0
  163. package/dist/stencil/stencil.esm.js +1 -1
  164. package/dist/types/classes/core/core.class.d.ts +16 -0
  165. package/dist/types/classes/handlers/context-menu.handler.d.ts +13 -0
  166. package/dist/types/classes/managers/license.manager.d.ts +141 -0
  167. package/dist/types/classes/managers/localization.manager.d.ts +121 -0
  168. package/dist/types/classes/objects/custom-element.class.d.ts +2 -0
  169. package/dist/types/classes/objects/group.class.d.ts +6 -1
  170. package/dist/types/classes/objects/image.class.d.ts +1 -1
  171. package/dist/types/classes/objects/path.class.d.ts +3 -2
  172. package/dist/types/classes/objects/selection-group.class.d.ts +6 -1
  173. package/dist/types/classes/objects/shape.class.d.ts +2 -0
  174. package/dist/types/classes/objects/text.class.d.ts +2 -1
  175. package/dist/types/classes/tools/brush-tool.class.d.ts +1 -1
  176. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +53 -1
  177. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +55 -3
  178. package/dist/types/components/core/kritzel-watermark/kritzel-watermark.d.ts +20 -0
  179. package/dist/types/components/ui/kritzel-controls/kritzel-controls.d.ts +3 -0
  180. package/dist/types/components/ui/kritzel-current-user/kritzel-current-user.d.ts +3 -0
  181. package/dist/types/components/ui/kritzel-current-user-dialog/kritzel-current-user-dialog.d.ts +3 -0
  182. package/dist/types/components/ui/kritzel-export/kritzel-export.d.ts +4 -1
  183. package/dist/types/components/ui/kritzel-more-menu/kritzel-more-menu.d.ts +3 -0
  184. package/dist/types/components/ui/kritzel-settings/kritzel-settings.d.ts +16 -0
  185. package/dist/types/components/ui/kritzel-share-dialog/kritzel-share-dialog.d.ts +3 -0
  186. package/dist/types/components/ui/kritzel-tool-config/kritzel-tool-config.d.ts +3 -0
  187. package/dist/types/components/ui/kritzel-utility-panel/kritzel-utility-panel.d.ts +3 -0
  188. package/dist/types/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.d.ts +3 -0
  189. package/dist/types/components/ui/kritzel-zoom-panel/kritzel-zoom-panel.d.ts +20 -0
  190. package/dist/types/components.d.ts +445 -26
  191. package/dist/types/constants/engine.constants.d.ts +2 -0
  192. package/dist/types/constants/license.constants.d.ts +25 -0
  193. package/dist/types/constants/version.d.ts +1 -1
  194. package/dist/types/helpers/localization.helper.d.ts +18 -0
  195. package/dist/types/helpers/math.helper.d.ts +1 -0
  196. package/dist/types/helpers/svg-export.helper.d.ts +81 -7
  197. package/dist/types/index.d.ts +13 -0
  198. package/dist/types/interfaces/context-menu-item.interface.d.ts +7 -1
  199. package/dist/types/interfaces/line-options.interface.d.ts +2 -0
  200. package/dist/types/interfaces/localization.interface.d.ts +143 -0
  201. package/dist/types/interfaces/path-options.interface.d.ts +2 -0
  202. package/dist/types/interfaces/settings.interface.d.ts +3 -0
  203. package/dist/types/interfaces/theme.interface.d.ts +27 -2
  204. package/dist/types/locales/de-locale.d.ts +5 -0
  205. package/dist/types/locales/en-locale.d.ts +6 -0
  206. package/dist/types/locales/fr-locale.d.ts +5 -0
  207. package/package.json +4 -7
  208. package/dist/components/p-2xYAGd0I.js +0 -1
  209. package/dist/components/p-B2Os1ya_.js +0 -1
  210. package/dist/components/p-BTEV1WwT.js +0 -1
  211. package/dist/components/p-BbactVA0.js +0 -1
  212. package/dist/components/p-BqwqGFQY.js +0 -1
  213. package/dist/components/p-C0TN5IAi.js +0 -1
  214. package/dist/components/p-CFgkUYoO.js +0 -1
  215. package/dist/components/p-COgo9OWy.js +0 -1
  216. package/dist/components/p-CUPYGT8c.js +0 -1
  217. package/dist/components/p-CcyIAi9S.js +0 -1
  218. package/dist/components/p-Cj78L1Kk.js +0 -1
  219. package/dist/components/p-CkAVEdDw.js +0 -9
  220. package/dist/components/p-CmuNn1Tc.js +0 -1
  221. package/dist/components/p-DDYoDSrm.js +0 -1
  222. package/dist/components/p-DbB730vO.js +0 -1
  223. package/dist/components/p-DlwYHzSj.js +0 -1
  224. package/dist/components/p-FK7b3BGt.js +0 -1
  225. package/dist/components/p-J9_SwObO.js +0 -1
  226. package/dist/stencil/p-67775031.entry.js +0 -9
  227. package/dist/stencil/p-DiCnmIYK.js +0 -1
@@ -32,7 +32,6 @@ export class KritzelEditor {
32
32
  viewportBoundaryRight = Infinity;
33
33
  viewportBoundaryTop = -Infinity;
34
34
  viewportBoundaryBottom = Infinity;
35
- wheelEnabled = true;
36
35
  debugInfo = {
37
36
  showViewportInfo: false,
38
37
  showObjectInfo: false,
@@ -101,66 +100,66 @@ export class KritzelEditor {
101
100
  ];
102
101
  globalContextMenuItems = [
103
102
  {
104
- label: 'Paste',
103
+ label: 'menu.paste',
105
104
  icon: 'paste',
106
105
  disabled: async () => (await this.engineRef.getCopiedObjects()).length === 0,
107
106
  action: menu => this.engineRef.paste(menu.x, menu.y),
108
107
  },
109
108
  {
110
- label: 'Select All',
109
+ label: 'menu.selectAll',
111
110
  icon: 'select-all',
112
111
  disabled: async () => (await this.engineRef.getObjectsInViewport()).length === 0,
113
112
  action: () => this.selectAllObjectsInViewport(),
114
113
  },
115
114
  ];
116
115
  objectContextMenuItems = [
117
- { label: 'Copy', icon: 'copy', group: 'clipboard', action: () => this.engineRef.copy() },
118
- { label: 'Cut', icon: 'cut', group: 'clipboard', action: () => this.engineRef.cut() },
116
+ { label: 'menu.copy', icon: 'copy', group: 'clipboard', action: () => this.engineRef.copy() },
117
+ { label: 'menu.cut', icon: 'cut', group: 'clipboard', action: () => this.engineRef.cut() },
119
118
  {
120
- label: 'Paste',
119
+ label: 'menu.paste',
121
120
  icon: 'paste',
122
121
  group: 'clipboard',
123
122
  disabled: async () => (await this.engineRef.getCopiedObjects()).length === 0,
124
123
  action: (menu, _) => this.engineRef.paste(menu.x, menu.y),
125
124
  },
126
125
  {
127
- label: 'Order',
126
+ label: 'menu.order',
128
127
  icon: 'ordering',
129
128
  group: 'other',
130
129
  children: [
131
- { label: 'Bring to Front', icon: 'bring-to-front', action: () => this.engineRef.bringToFront() },
132
- { label: 'Send to Back', icon: 'send-to-back', action: () => this.engineRef.sendToBack() },
133
- { label: 'Move Up', icon: 'arrow-up-from-dot', action: () => this.engineRef.bringForward() },
134
- { label: 'Move Down', icon: 'arrow-down-from-dot', action: () => this.engineRef.sendBackward() },
130
+ { label: 'menu.bringToFront', icon: 'bring-to-front', action: () => this.engineRef.bringToFront() },
131
+ { label: 'menu.sendToBack', icon: 'send-to-back', action: () => this.engineRef.sendToBack() },
132
+ { label: 'menu.moveUp', icon: 'arrow-up-from-dot', action: () => this.engineRef.bringForward() },
133
+ { label: 'menu.moveDown', icon: 'arrow-down-from-dot', action: () => this.engineRef.sendBackward() },
135
134
  ],
136
135
  },
137
136
  {
138
- label: 'Align',
137
+ label: 'menu.align',
139
138
  icon: 'align',
140
139
  group: 'other',
141
140
  disabled: async () => (await this.engineRef.getSelectedObjects()).length < 2,
142
141
  children: [
143
- { label: 'Align Left', icon: 'align-start-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.StartHorizontal) },
144
- { label: 'Align Center Horizontally', icon: 'align-center-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterHorizontal) },
145
- { label: 'Align Right', icon: 'align-end-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.EndHorizontal) },
146
- { label: 'Align Top', icon: 'align-start-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.StartVertical) },
147
- { label: 'Align Center Vertically', icon: 'align-center-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterVertical) },
148
- { label: 'Align Bottom', icon: 'align-end-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.EndVertical) },
142
+ { label: 'menu.alignLeft', icon: 'align-start-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.StartHorizontal) },
143
+ { label: 'menu.alignCenterHorizontal', icon: 'align-center-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterHorizontal) },
144
+ { label: 'menu.alignRight', icon: 'align-end-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.EndHorizontal) },
145
+ { label: 'menu.alignTop', icon: 'align-start-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.StartVertical) },
146
+ { label: 'menu.alignCenterVertical', icon: 'align-center-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterVertical) },
147
+ { label: 'menu.alignBottom', icon: 'align-end-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.EndVertical) },
149
148
  ],
150
149
  },
151
150
  {
152
- label: 'Group',
151
+ label: 'menu.group',
153
152
  icon: 'group',
154
153
  group: 'other',
155
154
  children: [
156
155
  {
157
- label: 'Group',
156
+ label: 'menu.group',
158
157
  icon: 'group',
159
158
  disabled: async () => (await this.engineRef.getSelectedObjects()).length < 2,
160
159
  action: () => this.engineRef.group(),
161
160
  },
162
161
  {
163
- label: 'Ungroup',
162
+ label: 'menu.ungroup',
164
163
  icon: 'ungroup',
165
164
  disabled: async () => {
166
165
  const selectedObjects = await this.engineRef.getSelectedObjects();
@@ -171,23 +170,34 @@ export class KritzelEditor {
171
170
  ],
172
171
  },
173
172
  {
174
- label: 'Export',
173
+ label: 'menu.export',
175
174
  icon: 'download',
176
175
  group: 'export',
177
176
  children: [
178
- { label: 'Export as SVG', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsSvg() },
179
- { label: 'Export as PNG', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsPng() },
177
+ { label: 'menu.exportAsSvg', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsSvg() },
178
+ { label: 'menu.exportAsPng', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsPng() },
180
179
  ],
181
180
  },
182
- { label: 'Delete', icon: 'delete', group: 'edit', action: () => this.engineRef.delete() },
181
+ { label: 'menu.delete', icon: 'delete', group: 'edit', action: () => this.engineRef.delete() },
183
182
  ];
184
183
  themes;
185
184
  theme = 'light';
185
+ /** License key that, when valid, removes the "Powered by Kritzel" watermark. */
186
+ licenseKey;
187
+ /** The current locale (language) code applied to the editor, e.g. 'en', 'de', 'fr'. */
188
+ locale = 'en';
189
+ /** An array of available locale definitions (with optional partial term overrides). */
190
+ locales;
191
+ /** The locale used to resolve terms missing from the active locale. */
192
+ fallbackLocale = 'en';
186
193
  customSvgIcons = {};
194
+ isPanningEnabled = true;
195
+ isZoomingEnabled = true;
187
196
  isControlsVisible = true;
188
197
  isUtilityPanelVisible = true;
189
198
  isWorkspaceManagerVisible = true;
190
199
  isMoreMenuVisible = true;
200
+ isZoomPanelVisible = true;
191
201
  isObjectDistanceFadingActive = false;
192
202
  syncConfig = DEFAULT_SYNC_CONFIG;
193
203
  assetStorageConfig = DEFAULT_ASSET_STORAGE_CONFIG;
@@ -209,6 +219,7 @@ export class KritzelEditor {
209
219
  objectsUpdated;
210
220
  undoStateChange;
211
221
  themeChange;
222
+ localeChange;
212
223
  viewportChange;
213
224
  logout;
214
225
  login;
@@ -222,6 +233,11 @@ export class KritzelEditor {
222
233
  isVirtualKeyboardOpen = false;
223
234
  undoState = null;
224
235
  isBackToContentButtonVisible = false;
236
+ /** Localized strings for editor-owned UI (e.g. the more menu), resolved from the active locale. */
237
+ resolvedTerms = {};
238
+ /** Available locales as `{ code, label }` options for the settings language selector. */
239
+ availableLocaleOptions = [];
240
+ currentZoomPercent = 100;
225
241
  shortcuts = [];
226
242
  currentIsPublic = false;
227
243
  isEditorVisible = false;
@@ -285,6 +301,25 @@ export class KritzelEditor {
285
301
  onThemesChange() {
286
302
  this.applyTheme();
287
303
  }
304
+ onLocaleChange(newValue) {
305
+ if (this.engineRef) {
306
+ this.engineRef.setLocale(newValue);
307
+ this.engineRef.saveSettings(this.currentSettingsConfig);
308
+ void this.refreshLocalizedTerms();
309
+ }
310
+ }
311
+ /**
312
+ * Refreshes the editor-owned localized strings (e.g. the more menu and the
313
+ * strings forwarded to child UI components) from the engine's localization
314
+ * manager for the active locale.
315
+ */
316
+ async refreshLocalizedTerms() {
317
+ if (!this.engineRef) {
318
+ return;
319
+ }
320
+ this.resolvedTerms = await this.engineRef.getResolvedTerms();
321
+ this.availableLocaleOptions = await this.engineRef.getAvailableLocaleOptions();
322
+ }
288
323
  onTouchStart(event) {
289
324
  if (event.cancelable) {
290
325
  event.preventDefault();
@@ -543,6 +578,9 @@ export class KritzelEditor {
543
578
  this.activeWorkspace = event.detail.activeWorkspace;
544
579
  this.workspaces = event.detail.workspaces;
545
580
  this.currentIsPublic = await this.engineRef.getIsPublic();
581
+ await this.refreshLocalizedTerms();
582
+ const viewport = await this.engineRef.getViewport();
583
+ this.currentZoomPercent = this.getZoomPercentFromScale(viewport.scale);
546
584
  this.loadShortcuts();
547
585
  }
548
586
  handleWorkspacesChange(event) {
@@ -593,8 +631,15 @@ export class KritzelEditor {
593
631
  }
594
632
  handleViewportChange(event) {
595
633
  event.stopPropagation();
634
+ this.currentZoomPercent = this.getZoomPercentFromScale(event.detail.scale);
596
635
  this.viewportChange.emit(event.detail);
597
636
  }
637
+ getZoomPercentFromScale(scale) {
638
+ if (!Number.isFinite(scale) || scale <= 0) {
639
+ return 100;
640
+ }
641
+ return Math.round(scale * 100);
642
+ }
598
643
  handleAwarenessChange(event) {
599
644
  event.stopPropagation();
600
645
  this.awarenessChange.emit(event.detail);
@@ -604,6 +649,10 @@ export class KritzelEditor {
604
649
  this.scaleMax = event.detail.scaleMax;
605
650
  this.lockDrawingScale = event.detail.lockDrawingScale;
606
651
  this.theme = event.detail.theme;
652
+ if (typeof event.detail.locale === 'string' && event.detail.locale !== this.locale) {
653
+ this.locale = event.detail.locale;
654
+ this.localeChange.emit(event.detail.locale);
655
+ }
607
656
  this.viewportBoundaryLeft = event.detail.viewportBoundaryLeft ?? -Infinity;
608
657
  this.viewportBoundaryRight = event.detail.viewportBoundaryRight ?? Infinity;
609
658
  this.viewportBoundaryTop = event.detail.viewportBoundaryTop ?? -Infinity;
@@ -618,7 +667,7 @@ export class KritzelEditor {
618
667
  return [
619
668
  {
620
669
  id: 'share',
621
- label: 'Share',
670
+ label: this.resolvedTerms['menu.share'] ?? 'Share',
622
671
  icon: 'share',
623
672
  action: () => {
624
673
  if (!this.isLoggedIn && this.loginConfig) {
@@ -630,7 +679,7 @@ export class KritzelEditor {
630
679
  },
631
680
  {
632
681
  id: 'export',
633
- label: 'Export',
682
+ label: this.resolvedTerms['menu.export'] ?? 'Export',
634
683
  icon: 'upload',
635
684
  action: async () => {
636
685
  const preview = await this.engineRef.getScreenshot('png');
@@ -639,19 +688,19 @@ export class KritzelEditor {
639
688
  },
640
689
  {
641
690
  id: 'import',
642
- label: 'Import',
691
+ label: this.resolvedTerms['menu.import'] ?? 'Import',
643
692
  icon: 'download',
644
693
  action: () => this.engineRef.importFromFile(),
645
694
  },
646
695
  {
647
696
  id: 'settings',
648
- label: 'Settings',
697
+ label: this.resolvedTerms['menu.settings'] ?? 'Settings',
649
698
  icon: 'settings',
650
699
  action: () => this.settingsRef.open(),
651
700
  },
652
701
  {
653
702
  id: 'logout',
654
- label: 'Logout',
703
+ label: this.resolvedTerms['menu.logout'] ?? 'Logout',
655
704
  icon: 'log-out',
656
705
  color: '#ff3b30',
657
706
  isVisible: this.isLoggedIn,
@@ -691,6 +740,41 @@ export class KritzelEditor {
691
740
  async setLoginLoading(provider) {
692
741
  this.loginDialogRef?.setLoading(provider);
693
742
  }
743
+ /**
744
+ * Sets the active locale (language) and re-renders the UI.
745
+ * @param code - The locale code to activate, e.g. 'de'.
746
+ */
747
+ async setLocale(code) {
748
+ this.locale = code;
749
+ await this.engineRef?.setLocale(code);
750
+ }
751
+ /**
752
+ * Gets the currently active locale code.
753
+ */
754
+ async getLocale() {
755
+ return this.engineRef ? this.engineRef.getLocale() : this.locale;
756
+ }
757
+ /**
758
+ * Gets the list of available locale codes (built-in and registered).
759
+ */
760
+ async getAvailableLocales() {
761
+ return this.engineRef ? this.engineRef.getAvailableLocales() : [];
762
+ }
763
+ /**
764
+ * Registers additional locale definitions (with optional partial term overrides).
765
+ * @param locales - The locale definitions to register.
766
+ */
767
+ async registerLocales(locales) {
768
+ await this.engineRef?.registerLocales(locales);
769
+ }
770
+ /**
771
+ * Resolves a term key to its translated string for the active locale.
772
+ * @param key - The term key to resolve.
773
+ * @param vars - Optional values for `{placeholder}` interpolation.
774
+ */
775
+ async t(key, vars) {
776
+ return this.engineRef ? this.engineRef.t(key, vars) : key;
777
+ }
694
778
  getSettingsStorageKey() {
695
779
  return this.editorId ? `kritzel-settings-${this.editorId}` : 'kritzel-settings';
696
780
  }
@@ -711,6 +795,9 @@ export class KritzelEditor {
711
795
  if (typeof parsed.theme === 'string') {
712
796
  this.theme = parsed.theme;
713
797
  }
798
+ if (typeof parsed.locale === 'string') {
799
+ this.locale = parsed.locale;
800
+ }
714
801
  if (typeof parsed.viewportBoundaryLeft === 'number') {
715
802
  this.viewportBoundaryLeft = parsed.viewportBoundaryLeft;
716
803
  }
@@ -741,6 +828,7 @@ export class KritzelEditor {
741
828
  scaleMax: this.scaleMax,
742
829
  lockDrawingScale: this.lockDrawingScale,
743
830
  theme: this.theme,
831
+ locale: this.locale,
744
832
  viewportBoundaryLeft: this.viewportBoundaryLeft,
745
833
  viewportBoundaryRight: this.viewportBoundaryRight,
746
834
  viewportBoundaryTop: this.viewportBoundaryTop,
@@ -794,35 +882,35 @@ export class KritzelEditor {
794
882
  const isLoggedIn = this.isLoggedIn;
795
883
  const shouldShowCurrentUser = isLoggedIn;
796
884
  const shouldShowLoginButton = this.isReady && !!this.loginConfig && !isLoggedIn;
797
- return (h(Host, { key: 'ffacaea5d3df12a3a8b448d31db3c5949053156c', style: {
885
+ return (h(Host, { key: '72238560a0f0275c506f59220277fdff7ab92c13', style: {
798
886
  opacity: this.isEditorVisible ? '1' : '0',
799
887
  visibility: this.isEditorVisible ? 'visible' : 'hidden',
800
888
  transition: 'opacity 0.2s ease-in-out, visibility 0.2s ease-in-out',
801
- } }, h("div", { key: '669eafee25b4f84c39469738a1337c21ab03e388', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: 'd6feb4a71c3286830fbe53a533f283c8af9a0385', visible: this.isWorkspaceManagerVisible, workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: '5bd0e6263d51119b197292b69879c1ae437f92fc', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), h("kritzel-engine", { key: '468f17137c51c90fd61c9179d13c449b1ac8feb9', ref: el => {
889
+ } }, h("div", { key: '14fd50ad857199f3b6be708fc4263aa2e69067de', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: '8788631c804770c67110c7e7906fe2034438ef9b', 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: '1840374d7353af2b050822dcd9c54be46e326278', visible: this.isBackToContentButtonVisible, text: this.resolvedTerms['backToContent.label'] ?? 'Back to content', onBackToContent: () => this.backToContent() })), h("kritzel-engine", { key: 'cdde0b65c811ee28fb4266afb96005c1fed24323', ref: el => {
802
890
  if (el) {
803
891
  this.engineRef = el;
804
892
  }
805
- }, 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, wheelEnabled: this.wheelEnabled, theme: this.theme, themes: this.themes, 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) }), h("kritzel-controls", { key: '848c30b27fb916c8480b41745bd6ec844e0b23a2', visible: this.isControlsVisible, class: { 'keyboard-open': this.isVirtualKeyboardOpen }, ref: el => {
893
+ }, 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) }), h("kritzel-controls", { key: '9b91d0cc3b3afba8894bd852bac911178c0ca82d', visible: this.isControlsVisible, class: { 'keyboard-open': this.isVirtualKeyboardOpen }, ref: el => {
806
894
  if (el) {
807
895
  this.controlsRef = el;
808
896
  }
809
- }, controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'e998d60679c767d15617bd7ecde5ee77e781a92f', class: "top-right-buttons" }, h("kritzel-settings", { key: '43b9cdb2d10de789cc03d2a9ef5df870b8ca7bfe', ref: el => {
897
+ }, controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, terms: this.resolvedTerms, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: '01f63c615eec68696532926b6d1efe2443e2d46a', class: "bottom-left-buttons" }, h("kritzel-zoom-panel", { key: '73a1fc5b0892b88d6c0a7c5debb42b7bb3f03a84', visible: this.isZoomPanelVisible, disabled: !this.isZoomingEnabled, zoomPercent: this.currentZoomPercent, terms: this.resolvedTerms, onZoomIn: () => this.zoomIn(), onZoomOut: () => this.zoomOut() })), h("div", { key: '94776978ba9dd68b2c5f62b141c074852585a1cd', class: "top-right-buttons" }, h("kritzel-settings", { key: '665a74511f8e511602d4d3437927e03af2c3c01c', ref: el => {
810
898
  if (el) {
811
899
  this.settingsRef = el;
812
900
  }
813
- }, shortcuts: this.shortcuts, availableThemes: this.themes && this.themes.length > 0 ? this.themes.map(t => t.name) : ['light', 'dark'], settings: this.currentSettingsConfig, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: '74669624a1e5177125ef00e1667c880ce47cbce4', ref: el => {
901
+ }, 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: '6b52127d4634d92c3e7410a084f37970bd8c84e7', ref: el => {
814
902
  if (el) {
815
903
  this.exportRef = el;
816
904
  }
817
- }, workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '18d925f32d021ff6713accb22d0594d259d70f2e', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: 'bddd5c29c5f17cced47276c237c04cfdb711da38', user: this.user }), shouldShowLoginButton && (h("kritzel-button", { key: '4eb6c85459f59863d6e644ecf21c2295da71bafc', onButtonClick: () => this.loginDialogRef?.open() }, "Sign in")), h("kritzel-more-menu", { key: 'a5a323ec248bebc7bc07898f344e0926fac8db17', items: this.moreMenuItems, visible: this.isMoreMenuVisible }), h("kritzel-share-dialog", { key: '8cb3ddad95d36f5b7ad59d8c4f057df93cb2bfe3', ref: el => {
905
+ }, 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: '002a01d361137f867efc2a0c91a6c0e9619d4359', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '6a9e0ad77997cbb10981d58afb176a7f7f4938aa', user: this.user, terms: this.resolvedTerms }), shouldShowLoginButton && (h("kritzel-button", { key: '5ba13725105d0af68c51fec455569ac7bbeaecde', onButtonClick: () => this.loginDialogRef?.open() }, this.resolvedTerms['login.dialogTitle'] ?? 'Sign in')), h("kritzel-more-menu", { key: 'f392a518fef108b395eb6d6681af9e06827e3780', items: this.moreMenuItems, visible: this.isMoreMenuVisible, terms: this.resolvedTerms }), h("kritzel-share-dialog", { key: '845a3153f5fd9b419f7d0b81be85f5e1ea0051cc', ref: el => {
818
906
  if (el) {
819
907
  this.shareDialogRef = el;
820
908
  }
821
- }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: '35395d0faadcfeb021fba685aa46e180e47d2be2', ref: el => {
909
+ }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, terms: this.resolvedTerms, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: '5a7b149d8e2c2acbda3d7818d8576d8ad249ef23', ref: el => {
822
910
  if (el) {
823
911
  this.loginDialogRef = el;
824
912
  }
825
- }, providers: this.loginConfig.providers, dialogTitle: this.loginConfig.title, subtitle: this.loginConfig.subtitle, onProviderLogin: this.handleProviderLogin })))));
913
+ }, providers: this.loginConfig.providers, dialogTitle: this.loginConfig.title ?? this.resolvedTerms['login.dialogTitle'] ?? 'Sign in', subtitle: this.loginConfig.subtitle, onProviderLogin: this.handleProviderLogin })))));
826
914
  }
827
915
  static get is() { return "kritzel-editor"; }
828
916
  static get originalStyleUrls() {
@@ -977,26 +1065,6 @@ export class KritzelEditor {
977
1065
  "attribute": "viewport-boundary-bottom",
978
1066
  "defaultValue": "Infinity"
979
1067
  },
980
- "wheelEnabled": {
981
- "type": "boolean",
982
- "mutable": true,
983
- "complexType": {
984
- "original": "boolean",
985
- "resolved": "boolean",
986
- "references": {}
987
- },
988
- "required": false,
989
- "optional": false,
990
- "docs": {
991
- "tags": [],
992
- "text": ""
993
- },
994
- "getter": false,
995
- "setter": false,
996
- "reflect": false,
997
- "attribute": "wheel-enabled",
998
- "defaultValue": "true"
999
- },
1000
1068
  "debugInfo": {
1001
1069
  "type": "unknown",
1002
1070
  "mutable": true,
@@ -1118,7 +1186,7 @@ export class KritzelEditor {
1118
1186
  },
1119
1187
  "getter": false,
1120
1188
  "setter": false,
1121
- "defaultValue": "[\n {\n label: 'Paste',\n icon: 'paste',\n disabled: async () => (await this.engineRef.getCopiedObjects()).length === 0,\n action: menu => this.engineRef.paste(menu.x, menu.y),\n },\n {\n label: 'Select All',\n icon: 'select-all',\n disabled: async () => (await this.engineRef.getObjectsInViewport()).length === 0,\n action: () => this.selectAllObjectsInViewport(),\n },\n ]"
1189
+ "defaultValue": "[\n {\n label: 'menu.paste',\n icon: 'paste',\n disabled: async () => (await this.engineRef.getCopiedObjects()).length === 0,\n action: menu => this.engineRef.paste(menu.x, menu.y),\n },\n {\n label: 'menu.selectAll',\n icon: 'select-all',\n disabled: async () => (await this.engineRef.getObjectsInViewport()).length === 0,\n action: () => this.selectAllObjectsInViewport(),\n },\n ]"
1122
1190
  },
1123
1191
  "objectContextMenuItems": {
1124
1192
  "type": "unknown",
@@ -1143,7 +1211,7 @@ export class KritzelEditor {
1143
1211
  },
1144
1212
  "getter": false,
1145
1213
  "setter": false,
1146
- "defaultValue": "[\n { label: 'Copy', icon: 'copy', group: 'clipboard', action: () => this.engineRef.copy() },\n { label: 'Cut', icon: 'cut', group: 'clipboard', action: () => this.engineRef.cut() },\n {\n label: 'Paste',\n icon: 'paste',\n group: 'clipboard',\n disabled: async () => (await this.engineRef.getCopiedObjects()).length === 0,\n action: (menu, _) => this.engineRef.paste(menu.x, menu.y),\n },\n {\n label: 'Order',\n icon: 'ordering',\n group: 'other',\n children: [\n { label: 'Bring to Front', icon: 'bring-to-front', action: () => this.engineRef.bringToFront() },\n { label: 'Send to Back', icon: 'send-to-back', action: () => this.engineRef.sendToBack() },\n { label: 'Move Up', icon: 'arrow-up-from-dot', action: () => this.engineRef.bringForward() },\n { label: 'Move Down', icon: 'arrow-down-from-dot', action: () => this.engineRef.sendBackward() },\n ],\n },\n {\n label: 'Align',\n icon: 'align',\n group: 'other',\n disabled: async () => (await this.engineRef.getSelectedObjects()).length < 2,\n children: [\n { label: 'Align Left', icon: 'align-start-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.StartHorizontal) },\n { label: 'Align Center Horizontally', icon: 'align-center-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterHorizontal) },\n { label: 'Align Right', icon: 'align-end-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.EndHorizontal) },\n { label: 'Align Top', icon: 'align-start-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.StartVertical) },\n { label: 'Align Center Vertically', icon: 'align-center-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterVertical) },\n { label: 'Align Bottom', icon: 'align-end-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.EndVertical) },\n ],\n },\n {\n label: 'Group',\n icon: 'group',\n group: 'other',\n children: [\n {\n label: 'Group',\n icon: 'group',\n disabled: async () => (await this.engineRef.getSelectedObjects()).length < 2,\n action: () => this.engineRef.group(),\n },\n {\n label: 'Ungroup',\n icon: 'ungroup',\n disabled: async () => {\n const selectedObjects = await this.engineRef.getSelectedObjects();\n return !selectedObjects.some(obj => obj.__class__ === 'KritzelGroup');\n },\n action: () => this.engineRef.ungroup(),\n },\n ],\n },\n {\n label: 'Export',\n icon: 'download',\n group: 'export',\n children: [\n { label: 'Export as SVG', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsSvg() },\n { label: 'Export as PNG', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsPng() },\n ],\n },\n { label: 'Delete', icon: 'delete', group: 'edit', action: () => this.engineRef.delete() },\n ]"
1214
+ "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 disabled: async () => (await this.engineRef.getCopiedObjects()).length === 0,\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 disabled: async () => (await this.engineRef.getSelectedObjects()).length < 2,\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 disabled: async () => (await this.engineRef.getSelectedObjects()).length < 2,\n action: () => this.engineRef.group(),\n },\n {\n label: 'menu.ungroup',\n icon: 'ungroup',\n disabled: async () => {\n const selectedObjects = await this.engineRef.getSelectedObjects();\n return !selectedObjects.some(obj => obj.__class__ === 'KritzelGroup');\n },\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 ]"
1147
1215
  },
1148
1216
  "themes": {
1149
1217
  "type": "unknown",
@@ -1196,6 +1264,103 @@ export class KritzelEditor {
1196
1264
  "attribute": "theme",
1197
1265
  "defaultValue": "'light'"
1198
1266
  },
1267
+ "licenseKey": {
1268
+ "type": "string",
1269
+ "mutable": false,
1270
+ "complexType": {
1271
+ "original": "string",
1272
+ "resolved": "string",
1273
+ "references": {}
1274
+ },
1275
+ "required": false,
1276
+ "optional": true,
1277
+ "docs": {
1278
+ "tags": [],
1279
+ "text": "License key that, when valid, removes the \"Powered by Kritzel\" watermark."
1280
+ },
1281
+ "getter": false,
1282
+ "setter": false,
1283
+ "reflect": false,
1284
+ "attribute": "license-key"
1285
+ },
1286
+ "locale": {
1287
+ "type": "string",
1288
+ "mutable": true,
1289
+ "complexType": {
1290
+ "original": "LocaleCode",
1291
+ "resolved": "\"de\" | \"en\" | \"fr\" | string & {}",
1292
+ "references": {
1293
+ "LocaleCode": {
1294
+ "location": "import",
1295
+ "path": "../../../interfaces/localization.interface",
1296
+ "id": "src/interfaces/localization.interface.ts::LocaleCode",
1297
+ "referenceLocation": "LocaleCode"
1298
+ }
1299
+ }
1300
+ },
1301
+ "required": false,
1302
+ "optional": false,
1303
+ "docs": {
1304
+ "tags": [],
1305
+ "text": "The current locale (language) code applied to the editor, e.g. 'en', 'de', 'fr'."
1306
+ },
1307
+ "getter": false,
1308
+ "setter": false,
1309
+ "reflect": false,
1310
+ "attribute": "locale",
1311
+ "defaultValue": "'en'"
1312
+ },
1313
+ "locales": {
1314
+ "type": "unknown",
1315
+ "mutable": false,
1316
+ "complexType": {
1317
+ "original": "KritzelLocale[]",
1318
+ "resolved": "KritzelLocale[]",
1319
+ "references": {
1320
+ "KritzelLocale": {
1321
+ "location": "import",
1322
+ "path": "../../../interfaces/localization.interface",
1323
+ "id": "src/interfaces/localization.interface.ts::KritzelLocale",
1324
+ "referenceLocation": "KritzelLocale"
1325
+ }
1326
+ }
1327
+ },
1328
+ "required": false,
1329
+ "optional": true,
1330
+ "docs": {
1331
+ "tags": [],
1332
+ "text": "An array of available locale definitions (with optional partial term overrides)."
1333
+ },
1334
+ "getter": false,
1335
+ "setter": false
1336
+ },
1337
+ "fallbackLocale": {
1338
+ "type": "string",
1339
+ "mutable": false,
1340
+ "complexType": {
1341
+ "original": "LocaleCode",
1342
+ "resolved": "\"de\" | \"en\" | \"fr\" | string & {}",
1343
+ "references": {
1344
+ "LocaleCode": {
1345
+ "location": "import",
1346
+ "path": "../../../interfaces/localization.interface",
1347
+ "id": "src/interfaces/localization.interface.ts::LocaleCode",
1348
+ "referenceLocation": "LocaleCode"
1349
+ }
1350
+ }
1351
+ },
1352
+ "required": false,
1353
+ "optional": false,
1354
+ "docs": {
1355
+ "tags": [],
1356
+ "text": "The locale used to resolve terms missing from the active locale."
1357
+ },
1358
+ "getter": false,
1359
+ "setter": false,
1360
+ "reflect": false,
1361
+ "attribute": "fallback-locale",
1362
+ "defaultValue": "'en'"
1363
+ },
1199
1364
  "customSvgIcons": {
1200
1365
  "type": "unknown",
1201
1366
  "mutable": false,
@@ -1219,6 +1384,46 @@ export class KritzelEditor {
1219
1384
  "setter": false,
1220
1385
  "defaultValue": "{}"
1221
1386
  },
1387
+ "isPanningEnabled": {
1388
+ "type": "boolean",
1389
+ "mutable": true,
1390
+ "complexType": {
1391
+ "original": "boolean",
1392
+ "resolved": "boolean",
1393
+ "references": {}
1394
+ },
1395
+ "required": false,
1396
+ "optional": false,
1397
+ "docs": {
1398
+ "tags": [],
1399
+ "text": ""
1400
+ },
1401
+ "getter": false,
1402
+ "setter": false,
1403
+ "reflect": false,
1404
+ "attribute": "is-panning-enabled",
1405
+ "defaultValue": "true"
1406
+ },
1407
+ "isZoomingEnabled": {
1408
+ "type": "boolean",
1409
+ "mutable": true,
1410
+ "complexType": {
1411
+ "original": "boolean",
1412
+ "resolved": "boolean",
1413
+ "references": {}
1414
+ },
1415
+ "required": false,
1416
+ "optional": false,
1417
+ "docs": {
1418
+ "tags": [],
1419
+ "text": ""
1420
+ },
1421
+ "getter": false,
1422
+ "setter": false,
1423
+ "reflect": false,
1424
+ "attribute": "is-zooming-enabled",
1425
+ "defaultValue": "true"
1426
+ },
1222
1427
  "isControlsVisible": {
1223
1428
  "type": "boolean",
1224
1429
  "mutable": false,
@@ -1299,6 +1504,26 @@ export class KritzelEditor {
1299
1504
  "attribute": "is-more-menu-visible",
1300
1505
  "defaultValue": "true"
1301
1506
  },
1507
+ "isZoomPanelVisible": {
1508
+ "type": "boolean",
1509
+ "mutable": false,
1510
+ "complexType": {
1511
+ "original": "boolean",
1512
+ "resolved": "boolean",
1513
+ "references": {}
1514
+ },
1515
+ "required": false,
1516
+ "optional": false,
1517
+ "docs": {
1518
+ "tags": [],
1519
+ "text": ""
1520
+ },
1521
+ "getter": false,
1522
+ "setter": false,
1523
+ "reflect": false,
1524
+ "attribute": "is-zoom-panel-visible",
1525
+ "defaultValue": "true"
1526
+ },
1302
1527
  "isObjectDistanceFadingActive": {
1303
1528
  "type": "boolean",
1304
1529
  "mutable": false,
@@ -1485,6 +1710,9 @@ export class KritzelEditor {
1485
1710
  "isVirtualKeyboardOpen": {},
1486
1711
  "undoState": {},
1487
1712
  "isBackToContentButtonVisible": {},
1713
+ "resolvedTerms": {},
1714
+ "availableLocaleOptions": {},
1715
+ "currentZoomPercent": {},
1488
1716
  "shortcuts": {},
1489
1717
  "currentIsPublic": {},
1490
1718
  "isEditorVisible": {}
@@ -1667,6 +1895,28 @@ export class KritzelEditor {
1667
1895
  }
1668
1896
  }
1669
1897
  }
1898
+ }, {
1899
+ "method": "localeChange",
1900
+ "name": "localeChange",
1901
+ "bubbles": true,
1902
+ "cancelable": true,
1903
+ "composed": true,
1904
+ "docs": {
1905
+ "tags": [],
1906
+ "text": ""
1907
+ },
1908
+ "complexType": {
1909
+ "original": "LocaleCode",
1910
+ "resolved": "\"de\" | \"en\" | \"fr\" | string & {}",
1911
+ "references": {
1912
+ "LocaleCode": {
1913
+ "location": "import",
1914
+ "path": "../../../interfaces/localization.interface",
1915
+ "id": "src/interfaces/localization.interface.ts::LocaleCode",
1916
+ "referenceLocation": "LocaleCode"
1917
+ }
1918
+ }
1919
+ }
1670
1920
  }, {
1671
1921
  "method": "viewportChange",
1672
1922
  "name": "viewportChange",
@@ -3406,6 +3656,155 @@ export class KritzelEditor {
3406
3656
  "text": "",
3407
3657
  "tags": []
3408
3658
  }
3659
+ },
3660
+ "setLocale": {
3661
+ "complexType": {
3662
+ "signature": "(code: LocaleCode) => Promise<void>",
3663
+ "parameters": [{
3664
+ "name": "code",
3665
+ "type": "(string & {}) | \"en\" | \"de\" | \"fr\"",
3666
+ "docs": "- The locale code to activate, e.g. 'de'."
3667
+ }],
3668
+ "references": {
3669
+ "Promise": {
3670
+ "location": "global",
3671
+ "id": "global::Promise"
3672
+ },
3673
+ "LocaleCode": {
3674
+ "location": "import",
3675
+ "path": "../../../interfaces/localization.interface",
3676
+ "id": "src/interfaces/localization.interface.ts::LocaleCode",
3677
+ "referenceLocation": "LocaleCode"
3678
+ }
3679
+ },
3680
+ "return": "Promise<void>"
3681
+ },
3682
+ "docs": {
3683
+ "text": "Sets the active locale (language) and re-renders the UI.",
3684
+ "tags": [{
3685
+ "name": "param",
3686
+ "text": "code - The locale code to activate, e.g. 'de'."
3687
+ }]
3688
+ }
3689
+ },
3690
+ "getLocale": {
3691
+ "complexType": {
3692
+ "signature": "() => Promise<LocaleCode>",
3693
+ "parameters": [],
3694
+ "references": {
3695
+ "Promise": {
3696
+ "location": "global",
3697
+ "id": "global::Promise"
3698
+ },
3699
+ "LocaleCode": {
3700
+ "location": "import",
3701
+ "path": "../../../interfaces/localization.interface",
3702
+ "id": "src/interfaces/localization.interface.ts::LocaleCode",
3703
+ "referenceLocation": "LocaleCode"
3704
+ }
3705
+ },
3706
+ "return": "Promise<LocaleCode>"
3707
+ },
3708
+ "docs": {
3709
+ "text": "Gets the currently active locale code.",
3710
+ "tags": []
3711
+ }
3712
+ },
3713
+ "getAvailableLocales": {
3714
+ "complexType": {
3715
+ "signature": "() => Promise<LocaleCode[]>",
3716
+ "parameters": [],
3717
+ "references": {
3718
+ "Promise": {
3719
+ "location": "global",
3720
+ "id": "global::Promise"
3721
+ },
3722
+ "LocaleCode": {
3723
+ "location": "import",
3724
+ "path": "../../../interfaces/localization.interface",
3725
+ "id": "src/interfaces/localization.interface.ts::LocaleCode",
3726
+ "referenceLocation": "LocaleCode"
3727
+ }
3728
+ },
3729
+ "return": "Promise<LocaleCode[]>"
3730
+ },
3731
+ "docs": {
3732
+ "text": "Gets the list of available locale codes (built-in and registered).",
3733
+ "tags": []
3734
+ }
3735
+ },
3736
+ "registerLocales": {
3737
+ "complexType": {
3738
+ "signature": "(locales: KritzelLocale[]) => Promise<void>",
3739
+ "parameters": [{
3740
+ "name": "locales",
3741
+ "type": "KritzelLocale[]",
3742
+ "docs": "- The locale definitions to register."
3743
+ }],
3744
+ "references": {
3745
+ "Promise": {
3746
+ "location": "global",
3747
+ "id": "global::Promise"
3748
+ },
3749
+ "KritzelLocale": {
3750
+ "location": "import",
3751
+ "path": "../../../interfaces/localization.interface",
3752
+ "id": "src/interfaces/localization.interface.ts::KritzelLocale",
3753
+ "referenceLocation": "KritzelLocale"
3754
+ }
3755
+ },
3756
+ "return": "Promise<void>"
3757
+ },
3758
+ "docs": {
3759
+ "text": "Registers additional locale definitions (with optional partial term overrides).",
3760
+ "tags": [{
3761
+ "name": "param",
3762
+ "text": "locales - The locale definitions to register."
3763
+ }]
3764
+ }
3765
+ },
3766
+ "t": {
3767
+ "complexType": {
3768
+ "signature": "(key: KritzelTermKey, vars?: KritzelTermVars) => Promise<string>",
3769
+ "parameters": [{
3770
+ "name": "key",
3771
+ "type": "keyof KritzelTerms",
3772
+ "docs": "- The term key to resolve."
3773
+ }, {
3774
+ "name": "vars",
3775
+ "type": "{ [x: string]: string | number; }",
3776
+ "docs": "- Optional values for `{placeholder}` interpolation."
3777
+ }],
3778
+ "references": {
3779
+ "Promise": {
3780
+ "location": "global",
3781
+ "id": "global::Promise"
3782
+ },
3783
+ "KritzelTermKey": {
3784
+ "location": "import",
3785
+ "path": "../../../interfaces/localization.interface",
3786
+ "id": "src/interfaces/localization.interface.ts::KritzelTermKey",
3787
+ "referenceLocation": "KritzelTermKey"
3788
+ },
3789
+ "KritzelTermVars": {
3790
+ "location": "import",
3791
+ "path": "../../../interfaces/localization.interface",
3792
+ "id": "src/interfaces/localization.interface.ts::KritzelTermVars",
3793
+ "referenceLocation": "KritzelTermVars"
3794
+ }
3795
+ },
3796
+ "return": "Promise<string>"
3797
+ },
3798
+ "docs": {
3799
+ "text": "Resolves a term key to its translated string for the active locale.",
3800
+ "tags": [{
3801
+ "name": "param",
3802
+ "text": "key - The term key to resolve."
3803
+ }, {
3804
+ "name": "param",
3805
+ "text": "vars - Optional values for `{placeholder}` interpolation."
3806
+ }]
3807
+ }
3409
3808
  }
3410
3809
  };
3411
3810
  }
@@ -3432,6 +3831,9 @@ export class KritzelEditor {
3432
3831
  }, {
3433
3832
  "propName": "themes",
3434
3833
  "methodName": "onThemesChange"
3834
+ }, {
3835
+ "propName": "locale",
3836
+ "methodName": "onLocaleChange"
3435
3837
  }];
3436
3838
  }
3437
3839
  static get listeners() {