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
@@ -1,2 +1,4 @@
1
1
  export declare const ABSOLUTE_SCALE_MAX = 1000;
2
2
  export declare const ABSOLUTE_SCALE_MIN = 0.0001;
3
+ /** Destination opened when the "Powered by Kritzel" watermark is clicked. */
4
+ export declare const KRITZEL_WEBSITE_URL = "https://kritzel.io";
@@ -0,0 +1,25 @@
1
+ /**
2
+ * License verification constants.
3
+ *
4
+ * Kritzel licenses are offline Ed25519 signed tokens. The owner signs each
5
+ * customer's token with a private key that never leaves their machine
6
+ * (see scripts/license/); the library verifies tokens against the public key
7
+ * below. The public key is safe to ship — it can only *verify* signatures,
8
+ * never forge them.
9
+ */
10
+ /**
11
+ * Token format version prefix. A valid license key looks like:
12
+ *
13
+ * KRTZL1.<base64url(payload JSON)>.<base64url(ed25519 signature)>
14
+ *
15
+ * Bump the version (and this prefix) if the token scheme ever changes.
16
+ */
17
+ export declare const KRITZEL_LICENSE_TOKEN_PREFIX = "KRTZL1.";
18
+ /**
19
+ * Raw 32-byte Ed25519 public key (base64url) used to verify license tokens.
20
+ *
21
+ * Generate the matching key pair with `npm run license:keygen` and paste the
22
+ * printed public key here. Replacing this value invalidates every license
23
+ * signed with the previous key.
24
+ */
25
+ export declare const KRITZEL_LICENSE_PUBLIC_KEY = "I-pYJlxDEjT94rwSaqhXW5Sv__fMKS-JKKnV3pg0PaM";
@@ -3,4 +3,4 @@
3
3
  * This file is auto-generated by the version bump scripts.
4
4
  * Do not modify manually.
5
5
  */
6
- export declare const KRITZEL_VERSION = "0.3.16";
6
+ export declare const KRITZEL_VERSION = "0.3.17";
@@ -0,0 +1,18 @@
1
+ import { KritzelTermVars } from '../interfaces/localization.interface';
2
+ /**
3
+ * Pure static utilities for localization term resolution.
4
+ */
5
+ export declare class LocalizationHelper {
6
+ /**
7
+ * Interpolates `{placeholder}` tokens in a term template with the provided
8
+ * variables. Tokens without a matching variable are left untouched.
9
+ *
10
+ * @param template - The raw term string, e.g. `'Expires {date}'`
11
+ * @param vars - Map of placeholder names to replacement values
12
+ * @returns The interpolated string
13
+ *
14
+ * @example
15
+ * LocalizationHelper.interpolate('Hello {name}', { name: 'Ada' }); // 'Hello Ada'
16
+ */
17
+ static interpolate(template: string, vars?: KritzelTermVars): string;
18
+ }
@@ -1,3 +1,4 @@
1
1
  export declare class KritzelMathHelper {
2
2
  static average(a: number, b: number): number;
3
+ static degreesToRadians(degrees: number): number;
3
4
  }
@@ -11,6 +11,28 @@ export interface SvgExportOptions {
11
11
  padding?: number;
12
12
  /** Whether to include XML declaration. Defaults to true. */
13
13
  includeXmlDeclaration?: boolean;
14
+ /**
15
+ * Enables raster-safe serialization for objects that normally rely on
16
+ * `<foreignObject>` (currently text). Use this when the generated SVG is
17
+ * rendered into an `<img>` and then drawn to a canvas for PNG export.
18
+ */
19
+ rasterSafeForCanvas?: boolean;
20
+ /**
21
+ * Map of image object id -> inlined `data:` URL used to embed image
22
+ * bytes directly into the exported markup. Required for the bytes to
23
+ * survive rasterization (e.g. SVG -> PNG), because browsers refuse to
24
+ * load external/`blob:` resources referenced from an SVG loaded into
25
+ * an `<img>` element. Populate via {@link KritzelSvgExportHelper.resolveImageDataUrls}.
26
+ */
27
+ imageDataUrls?: Map<string, string>;
28
+ }
29
+ /**
30
+ * Minimal structural contract for the asset resolver dependency used by
31
+ * the export inlining path. Declared structurally to keep this helper
32
+ * decoupled from the concrete resolver implementation.
33
+ */
34
+ export interface SvgExportAssetResolver {
35
+ fetchBlob(id: string): Promise<Blob>;
14
36
  }
15
37
  /**
16
38
  * Helper class for exporting Kritzel objects to SVG format.
@@ -37,6 +59,34 @@ export declare class KritzelSvgExportHelper {
37
59
  * @returns Flat array of all objects including group children
38
60
  */
39
61
  private static flattenObjects;
62
+ /**
63
+ * Resolves every image referenced by the given objects (including those
64
+ * nested inside groups) to an inlined `data:` URL, keyed by object id.
65
+ *
66
+ * This is required for export flows that rasterize the SVG (e.g. PNG
67
+ * export): an SVG loaded into an `<img>` element will NOT load external
68
+ * or `blob:` resources, so a `<image href="blob:...">` renders as a
69
+ * broken-image placeholder. Embedding the bytes as a base64 `data:` URL
70
+ * makes the image self-contained and survive rasterization.
71
+ *
72
+ * Resolution is best-effort: images that fail to resolve are simply
73
+ * omitted from the map, and the SVG falls back to whatever `href` the
74
+ * synchronous path would have produced.
75
+ * @param objects - Objects to inline images for
76
+ * @param assetResolver - Resolver used to fetch asset bytes; optional
77
+ * @returns Map of image object id -> inlined `data:` URL
78
+ */
79
+ static resolveImageDataUrls(objects: KritzelBaseObject[], assetResolver?: SvgExportAssetResolver): Promise<Map<string, string>>;
80
+ /**
81
+ * Reads a Blob into a base64 `data:` URL.
82
+ * @param blob - The blob to encode
83
+ * @returns Promise resolving to the data URL string
84
+ */
85
+ private static blobToDataUrl;
86
+ /**
87
+ * Encodes a byte array to base64 across browser and Node-like runtimes.
88
+ */
89
+ private static uint8ToBase64;
40
90
  /**
41
91
  * Collects SVG defs (markers, patterns, etc.) needed by the objects.
42
92
  * @param objects - Objects to collect defs for
@@ -56,9 +106,10 @@ export declare class KritzelSvgExportHelper {
56
106
  * Converts a Kritzel object to its SVG element representation.
57
107
  * @param object - The object to convert
58
108
  * @param theme - Theme for color resolution
109
+ * @param imageDataUrls - Optional map of image id -> inlined data URL
59
110
  * @returns SVG element string, or empty string if object type is not supported
60
111
  */
61
- static objectToSvgElement(object: KritzelBaseObject, theme?: ThemeName): string;
112
+ static objectToSvgElement(object: KritzelBaseObject, theme?: ThemeName, imageDataUrls?: Map<string, string>, rasterSafeForCanvas?: boolean): string;
62
113
  /**
63
114
  * Converts a KritzelPath to SVG.
64
115
  * @param path - The path object
@@ -87,18 +138,27 @@ export declare class KritzelSvgExportHelper {
87
138
  * @returns SVG element string
88
139
  */
89
140
  private static textToSvg;
141
+ /**
142
+ * Converts a KritzelText to SVG using pure SVG text primitives.
143
+ * This path avoids `<foreignObject>`, which taints canvases when the
144
+ * generated SVG is rasterized through `<img>` and `drawImage`.
145
+ */
146
+ private static textToSvgRasterSafe;
90
147
  /**
91
148
  * Converts a KritzelImage to SVG.
92
149
  *
93
- * Uses `resolvedSrc` when available (populated by the renderer via the
94
- * asset resolver), falling back to the legacy inline `src` field for
150
+ * Prefers an inlined `data:` URL from `imageDataUrls` (keyed by object
151
+ * id) when provided, so the embedded bytes survive rasterization to
152
+ * PNG. Falls back to `resolvedSrc` (populated by the renderer via the
153
+ * asset resolver) and finally the legacy inline `src` field for
95
154
  * documents persisted before the asset layer existed.
96
155
  *
97
- * Note: SVG export is synchronous and cannot await asset bytes from a
98
- * remote provider. Callers that need the fully rasterized image bytes
99
- * embedded in the exported SVG should pre-resolve assets via
100
- * `core.assetResolver.fetchBlob` and inline them as data URLs.
156
+ * Note: a `blob:` `resolvedSrc` renders correctly on-canvas but becomes
157
+ * a broken-image placeholder once the SVG is loaded into an `<img>` and
158
+ * drawn to a canvas. Callers that rasterize the SVG must pass
159
+ * `imageDataUrls` (see {@link KritzelSvgExportHelper.resolveImageDataUrls}).
101
160
  * @param image - The image object
161
+ * @param imageDataUrls - Optional map of image id -> inlined data URL
102
162
  * @returns SVG element string
103
163
  */
104
164
  private static imageToSvg;
@@ -106,6 +166,7 @@ export declare class KritzelSvgExportHelper {
106
166
  * Converts a KritzelGroup to SVG by recursively converting children.
107
167
  * @param group - The group object
108
168
  * @param theme - Theme for color resolution
169
+ * @param imageDataUrls - Optional map of image id -> inlined data URL
109
170
  * @returns SVG element string
110
171
  */
111
172
  private static groupToSvg;
@@ -116,6 +177,10 @@ export declare class KritzelSvgExportHelper {
116
177
  * @returns Transform attribute value string
117
178
  */
118
179
  private static buildTransform;
180
+ /**
181
+ * Returns a safe non-zero scale for export geometry calculations.
182
+ */
183
+ private static getObjectScale;
119
184
  /**
120
185
  * Converts ProseMirror JSON content to HTML string.
121
186
  * @param content - ProseMirror document JSON
@@ -131,6 +196,15 @@ export declare class KritzelSvgExportHelper {
131
196
  * @returns HTML string
132
197
  */
133
198
  private static nodeToHtml;
199
+ /**
200
+ * Converts ProseMirror JSON content to plain-text lines.
201
+ * Used by raster-safe SVG export, which cannot depend on HTML/foreignObject.
202
+ */
203
+ private static prosemirrorToPlainTextLines;
204
+ /**
205
+ * Converts a ProseMirror node tree into plain text.
206
+ */
207
+ private static nodeToPlainText;
134
208
  /**
135
209
  * Applies a ProseMirror mark to text.
136
210
  * @param text - The text to wrap
@@ -17,6 +17,7 @@ export * from './classes/objects/image.class';
17
17
  export * from './classes/objects/line.class';
18
18
  export * from './classes/objects/group.class';
19
19
  export * from './classes/objects/shape.class';
20
+ export * from './classes/tools/base-tool.class';
20
21
  export * from './classes/tools/brush-tool.class';
21
22
  export * from './classes/tools/line-tool.class';
22
23
  export * from './classes/tools/eraser-tool.class';
@@ -37,6 +38,8 @@ export * from './classes/providers/assets/presigned-asset-provider.class';
37
38
  export * from './classes/core/workspace.class';
38
39
  export * from './classes/managers/anchor.manager';
39
40
  export * from './classes/managers/theme.manager';
41
+ export * from './classes/managers/localization.manager';
42
+ export * from './classes/managers/license.manager';
40
43
  export * from './interfaces/toolbar-control.interface';
41
44
  export * from './interfaces/menu-item.interface';
42
45
  export * from './interfaces/object-change-event.interface';
@@ -51,13 +54,23 @@ export * from './interfaces/anchor.interface';
51
54
  export * from './interfaces/viewport-state.interface';
52
55
  export * from './interfaces/user.interface';
53
56
  export * from './interfaces/theme.interface';
57
+ export * from './interfaces/localization.interface';
54
58
  export * from './interfaces/shortcut.interface';
59
+ export * from './interfaces/undo-state.interface';
60
+ export * from './interfaces/share.interface';
61
+ export * from './interfaces/engine-state.interface';
62
+ export * from './interfaces/debug-info.interface';
63
+ export * from './interfaces/bounding-box.interface';
64
+ export * from './interfaces/polygon.interface';
55
65
  export * from './configs/default-brush-tool.config';
56
66
  export * from './configs/default-text-tool.config';
57
67
  export * from './configs/default-line-tool.config';
58
68
  export * from './configs/default-asset-storage.config';
59
69
  export * from './themes/light-theme';
60
70
  export * from './themes/dark-theme';
71
+ export * from './locales/en-locale';
72
+ export * from './locales/de-locale';
73
+ export * from './locales/fr-locale';
61
74
  export * from './enums/alignment.enum';
62
75
  export * from './enums/shape-type.enum';
63
76
  export * from './interfaces/migration.interface';
@@ -1,6 +1,12 @@
1
1
  import { KritzelBaseObject } from "../classes/objects/base-object.class";
2
+ import { KritzelTermKey } from "./localization.interface";
2
3
  export interface ContextMenuItem {
3
- label: string;
4
+ /**
5
+ * The item label. Always resolved through the active locale: pass a
6
+ * {@link KritzelTermKey} (e.g. `'menu.copy'`) to display its translation, or
7
+ * any other string to use it verbatim. Known term keys are autocompleted.
8
+ */
9
+ label: KritzelTermKey | (string & NonNullable<unknown>);
4
10
  action?: (menu: {
5
11
  x: number;
6
12
  y: number;
@@ -10,6 +10,8 @@ export interface KritzelLineOptions {
10
10
  controlY?: number;
11
11
  translateX?: number;
12
12
  translateY?: number;
13
+ /** Rotation in degrees at initialization time. */
14
+ rotation?: number;
13
15
  scale?: number;
14
16
  stroke?: ThemeAwareColor;
15
17
  strokeWidth?: number;
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Canonical locale identifier type for available locales.
3
+ * Locales are identified by their code (e.g. 'en', 'de', 'fr').
4
+ * The union is open so consumers can register additional locale codes.
5
+ */
6
+ export type LocaleCode = 'en' | 'de' | 'fr' | (string & NonNullable<unknown>);
7
+ /**
8
+ * Typed map of all known user-visible UI term keys to their translated strings.
9
+ *
10
+ * Keys are namespaced with a dotted prefix (e.g. `menu.copy`, `settings.title`)
11
+ * to group related strings. Using a closed interface gives full compile-time
12
+ * safety: typos in term keys are caught by the compiler and editors can
13
+ * autocomplete the available keys.
14
+ */
15
+ export interface KritzelTerms {
16
+ 'menu.copy': string;
17
+ 'menu.cut': string;
18
+ 'menu.paste': string;
19
+ 'menu.selectAll': string;
20
+ 'menu.order': string;
21
+ 'menu.bringToFront': string;
22
+ 'menu.sendToBack': string;
23
+ 'menu.moveUp': string;
24
+ 'menu.moveDown': string;
25
+ 'menu.align': string;
26
+ 'menu.alignLeft': string;
27
+ 'menu.alignCenterHorizontal': string;
28
+ 'menu.alignRight': string;
29
+ 'menu.alignTop': string;
30
+ 'menu.alignCenterVertical': string;
31
+ 'menu.alignBottom': string;
32
+ 'menu.group': string;
33
+ 'menu.ungroup': string;
34
+ 'menu.export': string;
35
+ 'menu.exportAsSvg': string;
36
+ 'menu.exportAsPng': string;
37
+ 'menu.delete': string;
38
+ 'menu.share': string;
39
+ 'menu.import': string;
40
+ 'menu.settings': string;
41
+ 'menu.logout': string;
42
+ 'settings.dialogTitle': string;
43
+ 'settings.categories.general': string;
44
+ 'settings.categories.viewport': string;
45
+ 'settings.categories.shortcuts': string;
46
+ 'settings.categories.developer': string;
47
+ 'settings.categories.about': string;
48
+ 'settings.general.title': string;
49
+ 'settings.general.theme.label': string;
50
+ 'settings.general.theme.description': string;
51
+ 'settings.general.language.label': string;
52
+ 'settings.general.language.description': string;
53
+ 'settings.general.lockDrawingScale.label': string;
54
+ 'settings.general.lockDrawingScale.description': string;
55
+ 'settings.viewport.title': string;
56
+ 'settings.viewport.minZoom.label': string;
57
+ 'settings.viewport.minZoom.description': string;
58
+ 'settings.viewport.maxZoom.label': string;
59
+ 'settings.viewport.maxZoom.description': string;
60
+ 'settings.viewport.boundaryLeft.label': string;
61
+ 'settings.viewport.boundaryLeft.description': string;
62
+ 'settings.viewport.boundaryRight.label': string;
63
+ 'settings.viewport.boundaryRight.description': string;
64
+ 'settings.viewport.boundaryTop.label': string;
65
+ 'settings.viewport.boundaryTop.description': string;
66
+ 'settings.viewport.boundaryBottom.label': string;
67
+ 'settings.viewport.boundaryBottom.description': string;
68
+ 'settings.viewport.boundaryPlaceholder': string;
69
+ 'settings.shortcuts.title': string;
70
+ 'settings.developer.title': string;
71
+ 'settings.developer.showViewportInfo.label': string;
72
+ 'settings.developer.showViewportInfo.description': string;
73
+ 'settings.developer.showObjectInfo.label': string;
74
+ 'settings.developer.showObjectInfo.description': string;
75
+ 'settings.developer.showSyncProviderInfo.label': string;
76
+ 'settings.developer.showSyncProviderInfo.description': string;
77
+ 'settings.developer.showMigrationInfo.label': string;
78
+ 'settings.developer.showMigrationInfo.description': string;
79
+ 'settings.about.title': string;
80
+ 'settings.about.description': string;
81
+ 'export.dialogTitle': string;
82
+ 'export.tabs.viewport': string;
83
+ 'export.tabs.workspace': string;
84
+ 'export.format.label': string;
85
+ 'export.filename.label': string;
86
+ 'export.filename.placeholder': string;
87
+ 'export.exportButton': string;
88
+ 'workspace.sharedTooltip': string;
89
+ 'workspace.rename': string;
90
+ 'workspace.delete': string;
91
+ 'zoom.zoomIn': string;
92
+ 'zoom.zoomOut': string;
93
+ 'utility.undo': string;
94
+ 'utility.redo': string;
95
+ 'utility.delete': string;
96
+ 'share.dialogTitle': string;
97
+ 'share.linkSharing.label': string;
98
+ 'share.linkSharing.enabledDescription': string;
99
+ 'share.linkSharing.disabledDescription': string;
100
+ 'share.linkSharing.toggleLabel': string;
101
+ 'share.copyLink.title': string;
102
+ 'share.copyLink.copied': string;
103
+ 'login.dialogTitle': string;
104
+ 'currentUser.dialogTitle': string;
105
+ 'backToContent.label': string;
106
+ 'toolConfig.collapse': string;
107
+ 'toolConfig.expand': string;
108
+ 'moreMenu.ariaLabel': string;
109
+ 'engine.loading': string;
110
+ 'watermark.poweredBy': string;
111
+ }
112
+ /**
113
+ * A localization key. Restricted to the known {@link KritzelTerms} keys so that
114
+ * lookups are validated at compile time.
115
+ */
116
+ export type KritzelTermKey = keyof KritzelTerms;
117
+ /**
118
+ * Definition of a single locale.
119
+ *
120
+ * `terms` is a `Partial<KritzelTerms>`, so a locale may override only a subset
121
+ * of the available terms. Any missing term is resolved through the fallback
122
+ * chain (see {@link KritzelLocalizationManager}). This mirrors the theming API,
123
+ * allowing consumers to spread a built-in locale and override specific keys:
124
+ *
125
+ * ```ts
126
+ * const myDe: KritzelLocale = {
127
+ * code: 'de',
128
+ * terms: { ...DE_LOCALE.terms, 'menu.copy': 'Duplizieren' },
129
+ * };
130
+ * ```
131
+ */
132
+ export interface KritzelLocale {
133
+ /** Canonical locale code, e.g. 'en', 'de', 'fr'. */
134
+ code: LocaleCode;
135
+ /** Optional human-readable display name shown in the language selector, e.g. 'Deutsch'. */
136
+ label?: string;
137
+ /** Partial map of term keys to translated strings. Missing keys fall back. */
138
+ terms: Partial<KritzelTerms>;
139
+ }
140
+ /**
141
+ * Values used to interpolate `{placeholder}` tokens inside a translated term.
142
+ */
143
+ export type KritzelTermVars = Record<string, string | number>;
@@ -3,6 +3,8 @@ export interface KritzelPathOptions {
3
3
  points: number[][];
4
4
  translateX?: number;
5
5
  translateY?: number;
6
+ /** Rotation in degrees at initialization time. */
7
+ rotation?: number;
6
8
  scale?: number;
7
9
  stroke?: ThemeAwareColor;
8
10
  strokeWidth?: number;
@@ -1,5 +1,6 @@
1
1
  import { KritzelDebugInfo } from './debug-info.interface';
2
2
  import { ThemeName } from './theme.interface';
3
+ import { LocaleCode } from './localization.interface';
3
4
  export interface KritzelSettingsConfig {
4
5
  /** Minimum zoom level allowed (0.0001 to 1) */
5
6
  scaleMin: number;
@@ -9,6 +10,8 @@ export interface KritzelSettingsConfig {
9
10
  lockDrawingScale: boolean;
10
11
  /** The current theme name */
11
12
  theme: ThemeName;
13
+ /** The current locale (language) code */
14
+ locale: LocaleCode;
12
15
  /** Left boundary of the viewport in world coordinates */
13
16
  viewportBoundaryLeft: number;
14
17
  /** Right boundary of the viewport in world coordinates */
@@ -12,10 +12,10 @@ export interface KritzelTheme {
12
12
  global?: {
13
13
  cursorTrailColor?: string;
14
14
  cursorTrailOpacity?: string;
15
- fontFamily?: string;
16
- borderColor?: string;
17
15
  dividerColor?: string;
18
16
  focusColor?: string;
17
+ fontFamily?: string;
18
+ borderColor?: string;
19
19
  focusRingColor?: string;
20
20
  iconColor?: string;
21
21
  pointerCursor?: string;
@@ -466,4 +466,29 @@ export interface KritzelTheme {
466
466
  buttonHoverBackgroundColor?: string;
467
467
  separatorColor?: string;
468
468
  };
469
+ /** Watermark variables */
470
+ watermark?: {
471
+ background?: string;
472
+ borderRadius?: string;
473
+ boxShadow?: string;
474
+ color?: string;
475
+ fontSize?: string;
476
+ offsetBottom?: string;
477
+ offsetRight?: string;
478
+ opacity?: string;
479
+ };
480
+ /** Zoom panel variables */
481
+ zoomPanel?: {
482
+ backgroundColor?: string;
483
+ border?: string;
484
+ borderRadius?: string;
485
+ boxShadow?: string;
486
+ buttonActiveBackgroundColor?: string;
487
+ buttonBorderRadius?: string;
488
+ buttonHoverBackgroundColor?: string;
489
+ buttonSize?: string;
490
+ gap?: string;
491
+ iconColor?: string;
492
+ padding?: string;
493
+ };
469
494
  }
@@ -0,0 +1,5 @@
1
+ import { KritzelLocale } from '../interfaces/localization.interface';
2
+ /**
3
+ * Built-in German locale.
4
+ */
5
+ export declare const DE_LOCALE: KritzelLocale;
@@ -0,0 +1,6 @@
1
+ import { KritzelLocale } from '../interfaces/localization.interface';
2
+ /**
3
+ * Built-in English locale (default). Provides a complete set of term values
4
+ * that act as the ultimate fallback when other locales omit a key.
5
+ */
6
+ export declare const EN_LOCALE: KritzelLocale;
@@ -0,0 +1,5 @@
1
+ import { KritzelLocale } from '../interfaces/localization.interface';
2
+ /**
3
+ * Built-in French locale.
4
+ */
5
+ export declare const FR_LOCALE: KritzelLocale;
package/package.json CHANGED
@@ -1,7 +1,9 @@
1
1
  {
2
2
  "name": "kritzel-stencil",
3
- "version": "0.3.16",
4
- "description": "Stencil Component Starter",
3
+ "version": "0.3.17",
4
+ "homepage": "https://kritzel.io/",
5
+ "description": "Build infinite canvas experiences in minutes.",
6
+ "license": "SEE LICENSE IN LICENSE.md",
5
7
  "main": "dist/index.cjs.js",
6
8
  "module": "dist/index.js",
7
9
  "types": "dist/types/index.d.ts",
@@ -30,10 +32,6 @@
30
32
  "require": "./dist/components/*"
31
33
  }
32
34
  },
33
- "repository": {
34
- "type": "git",
35
- "url": "https://github.com/kasual1/kritzel.git"
36
- },
37
35
  "files": [
38
36
  "dist/",
39
37
  "loader/"
@@ -47,7 +45,6 @@
47
45
  "bump": "npm version patch",
48
46
  "release": "npm publish"
49
47
  },
50
- "license": "MIT",
51
48
  "dependencies": {
52
49
  "@hocuspocus/provider": "^3.4.0",
53
50
  "@types/lodash": "^4.17.20",
@@ -1 +0,0 @@
1
- const o=[{light:"#000000",dark:"#ffffff",label:"Primary"},{light:"#ff5252",dark:"#ff5252"},{light:"#ffbc00",dark:"#ffbc00"},{light:"#00c853",dark:"#00c853"},{light:"#0000FF",dark:"#0000FF"},{light:"#d500f9",dark:"#d500f9"},{light:"#fafafa",dark:"#212121",label:"Background"},{light:"#a52714",dark:"#a52714"},{light:"#ee8100",dark:"#ee8100"},{light:"#558b2f",dark:"#558b2f"},{light:"#01579b",dark:"#01579b"},{light:"#8e24aa",dark:"#8e24aa"},{light:"#90a4ae",dark:"#607d8b",label:"Neutral"},{light:"#ff4081",dark:"#ff4081"},{light:"#ff6e40",dark:"#ff6e40"},{light:"#aeea00",dark:"#aeea00"},{light:"#304ffe",dark:"#304ffe"},{light:"#7c4dff",dark:"#7c4dff"},{light:"#cfd8dc",dark:"#455a64"},{light:"#f8bbd0",dark:"#ec407a"},{light:"#ffccbc",dark:"#ff7043"},{light:"#f0f4c3",dark:"#c0ca33"},{light:"#9fa8da",dark:"#5c6bc0"},{light:"#d1c4e9",dark:"#9575cd"}],e={name:"light",global:{borderColor:"#ebebeb",dividerColor:"#e0e0e0",focusColor:"#333333",focusRingColor:"#333333",iconColor:"currentColor",scrollbarThumbColor:"#ebebeb",textPrimary:"#000000",textSecondary:"#333333"},pillTabs:{background:"#f0f0f0",tabBackground:"transparent",tabBackgroundHover:"rgba(0, 0, 0, 0.05)",tabBackgroundSelected:"#ffffff",tabShadowSelected:"0 1px 3px rgba(0, 0, 0, 0.1)",tabTextColor:"#666666",tabTextColorSelected:"#000000"},textInput:{background:"#ffffff",borderColor:"#dbdbdb",borderRadius:"6px",focusBorderColor:"#333333",hoverBorderColor:"#cccccc",labelColor:"#333333",placeholderColor:"#999999",selectionBackground:"#007AFF",selectionColor:"#ffffff",suffixBackground:"#f5f5f5",suffixColor:"#666666",textColor:"#333333"},selection:{borderColor:"#007AFF",boxBackgroundColor:"rgba(0, 122, 255, 0.2)",boxBorderColor:"rgba(0, 122, 255, 0.5)",handleColor:"#ffffff",handleStrokeColor:"#007AFF"},checkerboard:{colorDark:"#cccccc",colorLight:"#ffffff"},backToContent:{activeBackgroundColor:"hsl(0, 0%, 0%, 8.6%)",backgroundColor:"#ffffff",border:"1px solid #ebebeb",boxShadow:"0 0 3px rgba(0, 0, 0, 0.08)",color:"#000000",hoverBackgroundColor:"hsl(0, 0%, 0%, 4.3%)"},colorPalette:{circleBorderColor:"#dddcdc",hoverBackgroundColor:"#ebebeb",selectedBackgroundColor:"#ebebeb"},contextMenu:{backgroundColor:"#ffffff",border:"1px solid #ebebeb",boxShadow:"0 1px 6px rgba(0, 0, 0, 0.12)",dividerColor:"rgba(0, 0, 0, 0.1)",itemActiveBackgroundColor:"hsl(0, 0%, 0%, 8.6%)",itemColor:"#333333",itemDisabledColor:"#aaaaaa",itemHoverBackgroundColor:"hsl(0, 0%, 0%, 4.3%)"},controls:{backgroundColor:"#ffffff",border:"1px solid #ebebeb",boxShadow:"0 0 3px rgba(0, 0, 0, 0.08)",controlActiveBackgroundColor:"hsl(0, 0%, 0%, 8.6%)",controlColor:"#000000",controlHoverBackgroundColor:"hsl(0, 0%, 0%, 4.3%)",controlSelectedBackgroundColor:"#007AFF",controlSelectedColor:"#ffffff",separatorColor:"#ebebeb"},currentUserDialog:{emailColor:"#666666",nameColor:"#333333"},dialog:{backdropColor:"rgba(0, 0, 0, 0.4)",backgroundColor:"#ffffff",border:"1px solid #ebebeb",boxShadow:"0 4px 24px rgba(0, 0, 0, 0.15)",closeButtonActiveBackground:"hsl(0, 0%, 0%, 8.6%)",closeButtonBackground:"transparent",closeButtonColor:"#333333",closeButtonHoverBackground:"hsl(0, 0%, 0%, 4.3%)",closeButtonHoverColor:"#000000",fontFamily:"inherit",footerBorder:"1px solid #ebebeb",headerBorder:"1px solid #ebebeb",titleColor:"#000000"},loginDialog:{buttonActiveBackground:"#ebebeb",buttonBackground:"#ffffff",buttonBorderColor:"#e0e0e0",buttonHoverBackground:"#f5f5f5",buttonHoverBorderColor:"#cccccc",buttonTextColor:"#333333",spinnerActiveColor:"#333333",spinnerColor:"#cccccc",subtitleColor:"#666666"},dropdown:{accentColor:"#007bff",background:"#ffffff",borderColor:"#dbdbdb",borderRadius:"6px",hoverBorderColor:"#cccccc",hoverBackgroundColor:"#f0f0f0",menuBorderRadius:"6px",selectedBackgroundColor:"#007bff1a",textColor:"#333333"},engine:{backgroundColor:"#ffffff",loadingOverlayBackground:"rgba(255, 255, 255, 0.85)",loadingOverlayColor:"#333333",loadingOverlaySpinnerActiveColor:"#333333",loadingOverlaySpinnerColor:"#cccccc"},snap:{indicatorFill:"rgba(59, 130, 246, 0.3)",indicatorStroke:"#007bff",lineStroke:"rgba(0, 0, 0, 0.2)"},fontSize:{hoverBackgroundColor:"#ebebeb",selectedBackgroundColor:"#ebebeb",textColor:"#333333"},lineEndings:{hoverBackgroundColor:"#ebebeb",labelColor:"#666666",optionBackground:"#ffffff",selectedBackgroundColor:"#ebebeb"},masterDetail:{backButtonColor:"#333333",backgroundColor:"#ffffff",detailBackgroundColor:"#ffffff",detailFocusOutline:"2px solid #333333",menuBackgroundColor:"#ffffff",menuBorderRight:"1px solid #ebebeb",menuItemActiveBackgroundColor:"hsl(0, 0%, 0%, 8.6%)",menuItemBackgroundColor:"transparent",menuItemChevronColor:"#aaaaaa",menuItemColor:"#333333",menuItemDisabledColor:"#aaaaaa",menuItemFocusOutline:"2px solid #333333",menuItemHoverBackgroundColor:"hsl(0, 0%, 0%, 4.3%)",menuItemSelectedBackgroundColor:"#007AFF",menuItemSelectedColor:"#ffffff",menuItemSelectedHoverBackgroundColor:"#007AFF"},menu:{backgroundColor:"#ffffff",border:"1px solid #ebebeb",boxShadow:"0 0 3px rgba(0, 0, 0, 0.08)",itemButtonHoverBackgroundColor:"hsl(0, 0%, 0%, 4.3%)",itemChildOpenBackgroundColor:"hsl(0, 0%, 0%, 3%)",itemColor:"#333333",itemEditingBackgroundColor:"#f0f0f0",itemInputBorder:"1px solid #333333",itemInputBorderColorOnSelected:"#ffffff",itemInputCaretColor:"#333333",itemInputCaretColorOnSelected:"#ffffff",itemInputSelectionColor:"#007aff",itemInputSelectionColorOnSelected:"rgba(255, 255, 255, 0.55)",itemInputSelectionTextColor:"#ffffff",itemInputSelectionTextColorOnSelected:"#ffffff",itemOverlayBackgroundColor:"hsl(0, 0%, 0%, 4.3%)",itemSelectedBackgroundColor:"#007aff",itemSelectedColor:"#ffffff"},moreMenu:{backgroundColor:"#ffffff",border:"1px solid #ebebeb",borderRadius:"12px",boxShadow:"0 0 3px rgba(0, 0, 0, 0.08)",buttonActiveBackgroundColor:"hsl(0, 0%, 0%, 8.6%)",buttonColor:"#000000",buttonHoverBackgroundColor:"hsl(0, 0%, 0%, 4.3%)",innerBorderRadius:"12px"},numericInput:{focusBorderColor:"#333333",borderColor:"#dbdbdb",borderRadius:"6px",hoverBorderColor:"#cccccc",inputBackground:"#ffffff",labelColor:"#666666",selectionBackground:"#007AFF",selectionColor:"#ffffff",spinnerActiveBackground:"hsl(0, 0%, 0%, 8.6%)",spinnerBackground:"transparent",spinnerBorderRadius:"5px",spinnerColor:"#333333",spinnerHoverBackground:"hsl(0, 0%, 0%, 4.3%)",textColor:"#333333"},opacitySlider:{activeColor:"#007AFF",thumbBorderColor:"#007AFF",thumbColor:"#ffffff",trackColor:"#e0e0e0"},settings:{contentHeadingColor:"#000000",contentTextColor:"#333333",descriptionColor:"#666666",labelColor:"#333333",shortcutItemBg:"#f8f8f8",shortcutKeyBg:"#ffffff",shortcutKeyBorder:"#e0e0e0",shortcutKeyColor:"#555555"},shapeFill:{hoverBackgroundColor:"#ebebeb",optionBackground:"#ffffff",selectedBackgroundColor:"#ebebeb"},shareDialog:{borderColor:"#e5e5e5",copyButtonBackground:"#ffffff",copyButtonColor:"#666666",copyButtonHoverBackground:"#e8e8e8",copyButtonHoverColor:"#333333",copySuccessBackground:"#d4edda",copySuccessColor:"#28a745",descriptionColor:"#666666",inputBackground:"#f5f5f5",inputBorderColor:"#e0e0e0",inputTextColor:"#333333",labelColor:"#333333",revokeButtonBorderColor:"#dc3545",revokeButtonColor:"#dc3545",revokeButtonHoverBackground:"#dc3545",revokeButtonHoverColor:"#ffffff",selectionColor:"#cce5ff"},slideToggle:{thumbColor:"#fff",thumbSize:"18px",trackCheckedColor:"#007AFF",trackColor:"#ccc"},splitButton:{backgroundColor:"#ffffff",border:"1px solid #ebebeb",boxShadow:"0 0 3px rgba(0, 0, 0, 0.08)",color:"#000000",dividerBackgroundColor:"#ebebeb",hoverBackgroundColor:"hsl(0, 0%, 0%, 4.3%)"},strokeSize:{hoverBackgroundColor:"#ebebeb",selectedBackgroundColor:"#ebebeb"},tooltip:{backgroundColor:"#ffffff",border:"1px solid #ebebeb",boxShadow:"0 1px 6px rgba(0, 0, 0, 0.12)",color:"#000000"},utilityPanel:{backgroundColor:"#e2e2e2",buttonColor:"#333333",buttonHoverBackgroundColor:"hsl(0, 0%, 0%, 4.3%)",separatorColor:"hsl(0, 0%, 0%, 8%)"}},r={name:"dark",global:{borderColor:"#3a3a3a",dividerColor:"#3a3a3a",focusColor:"#ffffff",focusRingColor:"#ffffff",iconColor:"currentColor",scrollbarThumbColor:"#555555",textPrimary:"#ffffff",textSecondary:"#e0e0e0"},pillTabs:{background:"#3a3a3a",tabBackground:"transparent",tabBackgroundHover:"rgba(255, 255, 255, 0.08)",tabBackgroundSelected:"#2a2a2a",tabShadowSelected:"0 1px 3px rgba(0, 0, 0, 0.3)",tabTextColor:"#999999",tabTextColorSelected:"#ffffff"},textInput:{background:"#1a1a1a",borderColor:"#4a4a4a",borderRadius:"6px",focusBorderColor:"#ffffff",hoverBorderColor:"#5a5a5a",labelColor:"#e0e0e0",placeholderColor:"#777777",selectionBackground:"#0A84FF",selectionColor:"#ffffff",suffixBackground:"#3a3a3a",suffixColor:"#aaaaaa",textColor:"#e0e0e0"},selection:{borderColor:"#0A84FF",boxBackgroundColor:"rgba(10, 132, 255, 0.2)",boxBorderColor:"rgba(10, 132, 255, 0.5)",handleColor:"#1a1a1a",handleStrokeColor:"#0A84FF"},checkerboard:{colorDark:"#4a4a4a",colorLight:"#3a3a3a"},backToContent:{activeBackgroundColor:"hsl(0, 0%, 100%, 12%)",backgroundColor:"#2a2a2a",border:"1px solid #3a3a3a",boxShadow:"0 0 6px rgba(0, 0, 0, 0.3)",color:"#ffffff",hoverBackgroundColor:"hsl(0, 0%, 100%, 8%)"},colorPalette:{circleBorderColor:"#4a4a4a",hoverBackgroundColor:"#3a3a3a",selectedBackgroundColor:"#3a3a3a"},contextMenu:{backgroundColor:"#2a2a2a",border:"1px solid #3a3a3a",boxShadow:"0 1px 8px rgba(0, 0, 0, 0.4)",dividerColor:"rgba(255, 255, 255, 0.1)",itemActiveBackgroundColor:"hsl(0, 0%, 100%, 12%)",itemColor:"#e0e0e0",itemDisabledColor:"#666666",itemHoverBackgroundColor:"hsl(0, 0%, 100%, 8%)"},controls:{backgroundColor:"#2a2a2a",border:"1px solid #3a3a3a",boxShadow:"0 0 6px rgba(0, 0, 0, 0.3)",controlActiveBackgroundColor:"hsl(0, 0%, 100%, 12%)",controlColor:"#ffffff",controlHoverBackgroundColor:"hsl(0, 0%, 100%, 8%)",controlSelectedBackgroundColor:"#0A84FF",controlSelectedColor:"#ffffff",separatorColor:"#3a3a3a"},currentUserDialog:{emailColor:"#999999",nameColor:"#ffffff"},dialog:{backdropColor:"rgba(0, 0, 0, 0.6)",backgroundColor:"#2a2a2a",border:"1px solid #3a3a3a",boxShadow:"0 4px 24px rgba(0, 0, 0, 0.5)",closeButtonActiveBackground:"hsl(0, 0%, 100%, 12%)",closeButtonBackground:"transparent",closeButtonColor:"#e0e0e0",closeButtonHoverBackground:"hsl(0, 0%, 100%, 8%)",closeButtonHoverColor:"#ffffff",footerBorder:"1px solid #3a3a3a",headerBorder:"1px solid #3a3a3a",titleColor:"#ffffff"},loginDialog:{buttonActiveBackground:"#444444",buttonBackground:"#2a2a2a",buttonBorderColor:"#4a4a4a",buttonHoverBackground:"#3a3a3a",buttonHoverBorderColor:"#5a5a5a",buttonTextColor:"#e0e0e0",spinnerActiveColor:"#ffffff",spinnerColor:"#555555",subtitleColor:"#999999"},dropdown:{accentColor:"#0A84FF",borderColor:"#4a4a4a",borderRadius:"6px",hoverBorderColor:"#5a5a5a",background:"#1a1a1a",hoverBackgroundColor:"#3a3a3a",menuBorderRadius:"6px",selectedBackgroundColor:"rgba(10, 132, 255, 0.2)",textColor:"#e0e0e0"},engine:{backgroundColor:"#1a1a1a",loadingOverlayBackground:"rgba(26, 26, 26, 0.85)",loadingOverlayColor:"#e0e0e0",loadingOverlaySpinnerActiveColor:"#e0e0e0",loadingOverlaySpinnerColor:"#555555"},snap:{indicatorFill:"rgba(10, 132, 255, 0.35)",indicatorStroke:"#0A84FF",lineStroke:"rgba(255, 255, 255, 0.35)"},fontSize:{hoverBackgroundColor:"#3a3a3a",selectedBackgroundColor:"#3a3a3a",textColor:"#e0e0e0"},lineEndings:{hoverBackgroundColor:"#3a3a3a",labelColor:"#999999",optionBackground:"#2a2a2a",selectedBackgroundColor:"#3a3a3a"},masterDetail:{backButtonColor:"#e0e0e0",backgroundColor:"#2a2a2a",detailBackgroundColor:"#2a2a2a",detailFocusOutline:"2px solid #ffffff",menuBackgroundColor:"#2a2a2a",menuBorderRight:"1px solid #3a3a3a",menuItemActiveBackgroundColor:"hsl(0, 0%, 100%, 12%)",menuItemBackgroundColor:"transparent",menuItemChevronColor:"#666666",menuItemColor:"#e0e0e0",menuItemDisabledColor:"#666666",menuItemFocusOutline:"2px solid #ffffff",menuItemHoverBackgroundColor:"hsl(0, 0%, 100%, 8%)",menuItemSelectedBackgroundColor:"#0A84FF",menuItemSelectedColor:"#ffffff",menuItemSelectedHoverBackgroundColor:"#0A84FF"},menu:{backgroundColor:"#2a2a2a",border:"1px solid #3a3a3a",boxShadow:"0 0 6px rgba(0, 0, 0, 0.3)",itemButtonHoverBackgroundColor:"hsl(0, 0%, 100%, 8%)",itemChildOpenBackgroundColor:"hsl(0, 0%, 100%, 6%)",itemColor:"#e0e0e0",itemEditingBackgroundColor:"#3a3a3a",itemInputBorder:"1px solid #ffffff",itemInputBorderColorOnSelected:"#ffffff",itemInputCaretColor:"#e0e0e0",itemInputCaretColorOnSelected:"#ffffff",itemInputSelectionColor:"#b0b0b0",itemInputSelectionColorOnSelected:"rgba(255, 255, 255, 0.35)",itemInputSelectionTextColor:"#ffffff",itemInputSelectionTextColorOnSelected:"#ffffff",itemOverlayBackgroundColor:"hsl(0, 0%, 100%, 8%)",itemSelectedBackgroundColor:"#0A84FF",itemSelectedColor:"#ffffff"},moreMenu:{backgroundColor:"#2a2a2a",border:"1px solid #3a3a3a",borderRadius:"12px",boxShadow:"0 0 6px rgba(0, 0, 0, 0.3)",buttonActiveBackgroundColor:"hsl(0, 0%, 100%, 12%)",buttonColor:"#ffffff",buttonHoverBackgroundColor:"hsl(0, 0%, 100%, 8%)",innerBorderRadius:"12px"},numericInput:{borderColor:"#4a4a4a",borderRadius:"6px",focusBorderColor:"#ffffff",hoverBorderColor:"#5a5a5a",inputBackground:"#1a1a1a",labelColor:"#999999",selectionBackground:"#0A84FF",selectionColor:"#ffffff",spinnerActiveBackground:"hsl(0, 0%, 100%, 12%)",spinnerBackground:"transparent",spinnerBorderRadius:"5px",spinnerColor:"#e0e0e0",spinnerHoverBackground:"hsl(0, 0%, 100%, 8%)",textColor:"#e0e0e0"},opacitySlider:{activeColor:"#0A84FF",thumbBorderColor:"#0A84FF",thumbColor:"#ffffff",trackColor:"#4a4a4a"},settings:{contentHeadingColor:"#ffffff",contentTextColor:"#e0e0e0",descriptionColor:"#999999",labelColor:"#e0e0e0",shortcutItemBg:"#3a3a3a",shortcutKeyBg:"#2a2a2a",shortcutKeyBorder:"#4a4a4a",shortcutKeyColor:"#e0e0e0"},shapeFill:{hoverBackgroundColor:"#3a3a3a",optionBackground:"#2a2a2a",selectedBackgroundColor:"#3a3a3a"},shareDialog:{labelColor:"#e0e0e0",descriptionColor:"#e0e0e0",inputBackground:"#1a1a1a",inputBorderColor:"#4a4a4a",inputTextColor:"#e0e0e0",selectionColor:"#0A84FF",copyButtonBackground:"#2a2a2a",copyButtonColor:"#e0e0e0",copyButtonHoverBackground:"#3a3a3a",copyButtonHoverColor:"#ffffff",copySuccessBackground:"#28a745",copySuccessColor:"#ffffff"},slideToggle:{thumbColor:"#ffffff",trackCheckedColor:"#0A84FF",trackColor:"#4a4a4a",transitionDuration:"0.2s"},splitButton:{backgroundColor:"#2a2a2a",border:"1px solid #3a3a3a",boxShadow:"0 0 6px rgba(0, 0, 0, 0.3)",color:"#ffffff",dividerBackgroundColor:"#3a3a3a",hoverBackgroundColor:"hsl(0, 0%, 100%, 8%)"},strokeSize:{hoverBackgroundColor:"#3a3a3a",selectedBackgroundColor:"#3a3a3a"},tooltip:{backgroundColor:"#2a2a2a",border:"1px solid #3a3a3a",boxShadow:"0 1px 8px rgba(0, 0, 0, 0.4)",color:"#ffffff"},utilityPanel:{backgroundColor:"#3a3a3a",buttonColor:"#e0e0e0",buttonHoverBackgroundColor:"hsl(0, 0%, 100%, 8%)",separatorColor:"hsl(0, 0%, 100%, 12%)"}};class a{static camelToKebab(o){return o.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}static flattenThemeToVariables(o,e="--kritzel"){const r=new Map,t=(o,e,l=!1)=>{for(const[n,f]of Object.entries(o)){if(l&&"name"===n)continue;const o=`${e}-${a.camelToKebab(n)}`;"object"==typeof f&&null!==f?t(f,o):"string"==typeof f&&r.set(o,f)}};return t(o,e,!0),r}static applyVariablesToElement(o,e){for(const[r,a]of e)o.style.setProperty(r,a)}static applyThemeToElement(o,e){const r=a.flattenThemeToVariables(e);a.applyVariablesToElement(o,r)}}const t="kritzel-settings",l="light";class n{_core;_currentTheme=l;_targetElement=null;_storageKey;_themeRegistry=new Map;constructor(o){this._core=o,this._storageKey=o.editorId?`${t}-${o.editorId}`:t,this._themeRegistry.set("light",e),this._themeRegistry.set("dark",r),this._currentTheme=this.getStoredTheme()}get currentTheme(){return this._currentTheme}setTargetElement(o){this._targetElement=o,this._targetElement&&this.applyTheme(this._currentTheme)}getTargetElement(){return this._targetElement}getThemeByName(o){return this._themeRegistry.get(o)??this._themeRegistry.values().next().value}registerThemes(o){0===o.length&&console.warn("[KritzelThemeManager] registerThemes called with an empty array. The theme registry will be empty."),this._themeRegistry.clear();for(const e of o)this._themeRegistry.set(e.name,e)}injectThemeEarly(o){let e=o;if(e||"undefined"==typeof document||(e=document.documentElement),!e)return;const r=this.getStoredTheme(),t=this.getThemeByName(r);a.applyThemeToElement(e,t)}getAllThemes(){return Array.from(this._themeRegistry.values())}getStoredTheme(){if("undefined"==typeof localStorage)return l;const o=localStorage.getItem(this._storageKey);if(!o)return l;try{const e=JSON.parse(o);if("string"==typeof e?.theme)return e.theme}catch{}return l}static getStoredTheme(){if("undefined"==typeof localStorage)return l;const o=localStorage.getItem(t);if(!o)return l;try{const e=JSON.parse(o);if("string"==typeof e?.theme)return e.theme}catch{}return l}setTheme(o){this._currentTheme=o,this._targetElement&&this.applyTheme(o)}isDarkTheme(){return"dark"===this._currentTheme}applyTheme(o){if(!this._targetElement)return;const e=this.getThemeByName(o);a.applyThemeToElement(this._targetElement,e)}cleanup(){this._targetElement=null}}class f{static resolveThemeColor(o,e){return o?function(o,e){return e in o&&o[e]?o[e]:o["dark"===e?"dark":"light"]}(o,e??n.getStoredTheme()):""}static applyOpacity(o,e,r){const a="string"==typeof o?o:this.resolveThemeColor(o,r);if(!a||e>=1)return a;const t=a.startsWith("#")?a.slice(1):a;let l,n,f;if(3===t.length)l=parseInt(t[0]+t[0],16),n=parseInt(t[1]+t[1],16),f=parseInt(t[2]+t[2],16);else{if(6!==t.length)return a;l=parseInt(t.substring(0,2),16),n=parseInt(t.substring(2,4),16),f=parseInt(t.substring(4,6),16)}return isNaN(l)||isNaN(n)||isNaN(f)?a:`rgba(${l}, ${n}, ${f}, ${e})`}static getContrastColor(o){const e=o.startsWith("#")?o.slice(1):o;let r,a,t;if(3===e.length)r=parseInt(e[0]+e[0],16),a=parseInt(e[1]+e[1],16),t=parseInt(e[2]+e[2],16);else{if(6!==e.length)return"#000000";r=parseInt(e.substring(0,2),16),a=parseInt(e.substring(2,4),16),t=parseInt(e.substring(4,6),16)}return isNaN(r)||isNaN(a)||isNaN(t)||.299*r+.587*a+.114*t>150?"#000000":"#ffffff"}static determineTextColor(o){const e="transparent"===o.light,r="transparent"===o.dark;return e&&r?{light:"#000000",dark:"#ffffff"}:{light:e?"#000000":this.getContrastColor(o.light),dark:r?"#ffffff":this.getContrastColor(o.dark)}}}export{o as D,n as K,a as T,f as a,r as d,e as l}
@@ -1 +0,0 @@
1
- import{p as e,H as s,c as t,h as r,d as i,t as o}from"./p-B43upypT.js";import{d as l}from"./p-skWUIStn.js";const a=e(class extends s{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.sizeChange=t(this,"sizeChange")}sizes=[4,6,8,12,16,24];selectedSize=null;sizeChange;handleSizeClick(e){this.selectedSize=e,this.sizeChange.emit(e)}render(){return r(i,{key:"514d87732c9b15cddd5a905407ff7ce9069c06d7"},r("div",{key:"170c9a8abfe8298116d8a269338da95fbc2aac7b",class:"size-grid"},this.sizes.map((e=>r("div",{tabIndex:0,class:{"size-container":!0,selected:this.selectedSize===e},onClick:()=>this.handleSizeClick(e)},r("kritzel-color",{value:"var(--kritzel-global-text-primary)",size:e}))))))}static get style(){return":host{display:flex;align-items:flex-start;gap:0;padding:0;width:100%;box-sizing:border-box}.size-grid{width:100%;display:grid;grid-template-columns:repeat(auto-fill, 32px);gap:8px;justify-items:center}.size-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:var(--kritzel-global-pointer-cursor, pointer);border:2px solid transparent;box-sizing:border-box}.size-container:hover{background-color:var(--kritzel-stroke-size-hover-background-color, #ebebeb)}.size-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-stroke-size-selected-background-color, #ebebeb)}"}},[513,"kritzel-stroke-size",{sizes:[16],selectedSize:[1026,"selected-size"]}]);function c(){"undefined"!=typeof customElements&&["kritzel-stroke-size","kritzel-color"].forEach((e=>{switch(e){case"kritzel-stroke-size":customElements.get(o(e))||customElements.define(o(e),a);break;case"kritzel-color":customElements.get(o(e))||l()}}))}export{a as K,c as d}
@@ -1 +0,0 @@
1
- import{p as e,H as t,c as s,h as i,d as o,t as r}from"./p-B43upypT.js";import{e as n,d as a}from"./p-CUPYGT8c.js";import{a as l}from"./p-2xYAGd0I.js";import{d as h}from"./p-skWUIStn.js";import{d as p}from"./p-BFoK4W--.js";import{d as c}from"./p-Df3BwVGy.js";import{d}from"./p-CmuNn1Tc.js";import{d as m}from"./p-JhOYwUOj.js";import{d as f}from"./p-FK7b3BGt.js";import{d as u}from"./p-DbB730vO.js";import{d as g}from"./p-CXpv9Rxe.js";import{d as z}from"./p-DEy7zJCe.js";import{d as y}from"./p-BFYtCsZu.js";import{d as k}from"./p-B2Os1ya_.js";class C{static getToolConfig(e){switch(e?.toolType){case"selection":return"getToolConfig"in e&&"function"==typeof e.getToolConfig?e.getToolConfig():null;case"brush":return{type:"brush",colorProperty:"color",sizeProperty:"size",opacityProperty:"opacity",paletteSource:"palette",sizesSource:"sizes",controls:[{type:"stroke-size",propertyName:"size"}]};case"line":return{type:"line",colorProperty:"color",sizeProperty:"size",opacityProperty:"opacity",paletteSource:"palette",sizesSource:"sizes",controls:[{type:"stroke-size",propertyName:"size"},{type:"line-endings",propertyName:"arrows",additionalProps:{}}]};case"shape":return{type:"shape",colorProperty:"strokeColor",sizeProperty:"strokeWidth",opacityProperty:"opacity",paletteSource:"palette",sizesSource:"sizes",controls:[{type:"stroke-size",propertyName:"strokeWidth"},{type:"shape-fill",propertyName:"fillColor",additionalProps:{}}]};case"text":return{type:"text",colorProperty:"fontColor",sizeProperty:"fontSize",opacityProperty:"opacity",paletteSource:"palette",sizesSource:"sizes",controls:[{type:"font-size",propertyName:"fontSize",additionalProps:{}},{type:"font-family",propertyName:"fontFamily"}]};default:return null}}}const x=e(class extends t{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.toolChange=s(this,"toolChange"),this.displayValuesChange=s(this,"displayValuesChange")}tool;handleToolChange(e,t){const s=C.getToolConfig(e);if(t&&e&&"shape"===s?.type){const i=C.getToolConfig(t);"shape"===i?.type&&[s.colorProperty,s.sizeProperty,s.opacityProperty,"fillColor"].forEach((s=>{s&&void 0!==t[s]&&(e[s]=t[s])}))}this.config=s,this.config&&(this.updatePalette(),this.updateSizes(),this.currentOpacity=e[this.config.opacityProperty]??1,this.emitDisplayValues())}isExpanded=!1;theme;engine;handleSelectionChangeBound=this.handleSelectionChange.bind(this);onThemeChange(){this.emitDisplayValues()}handleEngineChange(e,t){t&&t.removeEventListener("objectsSelectionChange",this.handleSelectionChangeBound),e&&e.addEventListener("objectsSelectionChange",this.handleSelectionChangeBound)}toolChange;displayValuesChange;config;palette=[];sizes=[];currentOpacity=1;updateTrigger=0;handleSelectionChange(){this.tool instanceof n&&(this.config=C.getToolConfig(this.tool),this.config&&(this.updatePalette(),this.updateSizes(),this.currentOpacity=this.tool[this.config.opacityProperty]??1,this.emitDisplayValues()))}disconnectedCallback(){this.engine&&this.engine.removeEventListener("objectsSelectionChange",this.handleSelectionChangeBound)}componentWillLoad(){this.config=C.getToolConfig(this.tool),this.config&&(this.updatePalette(),this.updateSizes(),this.currentOpacity=this.tool[this.config.opacityProperty]??1,this.emitDisplayValues()),this.engine&&this.engine.addEventListener("objectsSelectionChange",this.handleSelectionChangeBound)}emitDisplayValues(){if(!this.config)return;const e=this.tool[this.config.sizeProperty],t={color:l.applyOpacity(this.tool[this.config.colorProperty],this.currentOpacity,this.theme),size:e};this.tool instanceof a&&(t.fontFamily=this.tool.fontFamily),this.displayValuesChange.emit(t)}updatePalette(){this.config&&(this.palette="none"===this.config.paletteSource?[]:this.tool.palette||[])}updateSizes(){this.config&&(this.sizes="none"===this.config.sizesSource?[]:this.tool.sizes||[])}handleToggleExpand=()=>{this.isExpanded=!this.isExpanded};handleColorChange=e=>{if(this.tool[this.config.colorProperty]=e.detail,"shape"===this.config.type||"selection"===this.config.type){const t=this.tool;("string"==typeof t.fillColor?"transparent"===t.fillColor:"transparent"===t.fillColor.light&&"transparent"===t.fillColor.dark)||(t.fillColor=e.detail)}this.emitDisplayValues(),this.toolChange.emit(this.tool),this.updateTrigger++};handleSizeChange=e=>{this.tool[this.config.sizeProperty]=e.detail,this.emitDisplayValues(),this.toolChange.emit(this.tool),this.updateTrigger++};handleOpacityChange=e=>{this.tool[this.config.opacityProperty]=e.detail,this.currentOpacity=e.detail,this.emitDisplayValues(),this.toolChange.emit(this.tool)};handlePropertyChange=(e,t)=>{if("shape"!==this.config.type&&"selection"!==this.config.type||"fillColor"!==e)this.tool[e]=t,"fontFamily"===e&&this.emitDisplayValues();else{const e="filled"===t?this.tool[this.config.colorProperty]:{light:"transparent",dark:"transparent"};this.tool.fillColor=e,"filled"===t&&(this.tool[this.config.colorProperty]=e)}this.toolChange.emit(this.tool),this.updateTrigger++};getShapeFillValue(){const e=this.tool.fillColor;return("string"==typeof e?"transparent"===e:"transparent"===e.light&&"transparent"===e.dark)?"transparent":"filled"}renderControl(e){const t=this.tool[e.propertyName];switch(e.type){case"stroke-size":return i("kritzel-stroke-size",{key:e.type,sizes:this.sizes.length>0?this.sizes:void 0,selectedSize:t,onSizeChange:this.handleSizeChange});case"font-size":return i("kritzel-font-size",{key:e.type,sizes:this.sizes.length>0?this.sizes:void 0,selectedSize:t,fontFamily:this.tool.fontFamily,onSizeChange:this.handleSizeChange});case"line-endings":return i("kritzel-line-endings",{key:e.type,value:t,onValueChange:t=>this.handlePropertyChange(e.propertyName,t.detail)});case"shape-fill":return i("kritzel-shape-fill",{key:e.type,value:this.getShapeFillValue(),onValueChange:t=>this.handlePropertyChange(e.propertyName,t.detail)});case"font-family":return i("kritzel-font-family",{key:e.type,selectedFontFamily:t,onFontFamilyChange:t=>this.handlePropertyChange(e.propertyName,t.detail)});default:return null}}render(){if(!this.config)return null;const e=this.palette.length>6||"text"===this.config.type,t=this.palette.length>0,s=this.config.controls.find((e=>"stroke-size"===e.type||"font-size"===e.type)),r=this.config.controls.filter((e=>"stroke-size"!==e.type&&"font-size"!==e.type));return i(o,null,i("div",{style:{display:"flex",flexDirection:"row",gap:"8px",width:"100%"}},i("div",{style:{display:"flex",flexDirection:"column",gap:"12px",flex:"1"}},t&&i("kritzel-color-palette",{colors:this.palette,selectedColor:this.tool[this.config.colorProperty],isExpanded:this.isExpanded,isOpaque:!0,opacity:this.currentOpacity,theme:this.theme,onColorChange:this.handleColorChange}),s&&this.renderControl(s),i("kritzel-opacity-slider",{value:this.tool[this.config.opacityProperty],previewColor:this.tool[this.config.colorProperty],onValueChange:this.handleOpacityChange}),r.map((e=>[i("div",{class:"divider"}),this.renderControl(e)]))),e&&i("div",{style:{display:"flex",alignItems:"flex-start"}},i("button",{class:"expand-toggle",onClick:this.handleToggleExpand,title:this.isExpanded?"Collapse":"Expand"},i("kritzel-icon",{name:this.isExpanded?"chevron-up":"chevron-down"})))))}static get watchers(){return{tool:[{handleToolChange:0}],theme:[{onThemeChange:0}],engine:[{handleEngineChange:0}]}}static get style(){return".expand-toggle{background:none;border:none;cursor:var(--kritzel-global-pointer-cursor, pointer);padding:0;margin:0;display:flex;align-items:center;justify-content:center;width:32px;height:32px;color:var(--kritzel-icon-color, currentColor);transition:transform 0.2s ease}.expand-toggle:hover{opacity:0.7}.expand-toggle:focus{outline:none}.expand-toggle:focus-visible{outline:2px solid var(--kritzel-focus-color, #007acc);outline-offset:2px}.expand-toggle:active{transform:scale(0.95)}.divider{height:1px;background-color:var(--kritzel-divider-color, #e0e0e0);margin:4px 0;width:100%}"}},[513,"kritzel-tool-config",{tool:[1040],isExpanded:[1028,"is-expanded"],theme:[1],engine:[16],config:[32],palette:[32],sizes:[32],currentOpacity:[32],updateTrigger:[32]},void 0,{tool:[{handleToolChange:0}],theme:[{onThemeChange:0}],engine:[{handleEngineChange:0}]}]);function b(){"undefined"!=typeof customElements&&["kritzel-tool-config","kritzel-color","kritzel-color-palette","kritzel-dropdown","kritzel-font","kritzel-font-family","kritzel-font-size","kritzel-icon","kritzel-line-endings","kritzel-opacity-slider","kritzel-shape-fill","kritzel-stroke-size"].forEach((e=>{switch(e){case"kritzel-tool-config":customElements.get(r(e))||customElements.define(r(e),x);break;case"kritzel-color":customElements.get(r(e))||h();break;case"kritzel-color-palette":customElements.get(r(e))||p();break;case"kritzel-dropdown":customElements.get(r(e))||c();break;case"kritzel-font":customElements.get(r(e))||d();break;case"kritzel-font-family":customElements.get(r(e))||m();break;case"kritzel-font-size":customElements.get(r(e))||f();break;case"kritzel-icon":customElements.get(r(e))||u();break;case"kritzel-line-endings":customElements.get(r(e))||g();break;case"kritzel-opacity-slider":customElements.get(r(e))||z();break;case"kritzel-shape-fill":customElements.get(r(e))||y();break;case"kritzel-stroke-size":customElements.get(r(e))||k()}}))}export{C as K,x as a,b as d}
@@ -1 +0,0 @@
1
- import{p as e,H as t,c as i,h as s,d as n,t as l}from"./p-B43upypT.js";import{K as a}from"./p-DhMlShij.js";import{O as o}from"./p-BAN5dnHX.js";import{d as h}from"./p-DbB730vO.js";import{d as r,a as c}from"./p-SptaSMno.js";import{d as u}from"./p-BYmp9Ovv.js";import{d as m}from"./p-COLHjboZ.js";const d=e(class extends t{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.isWorkspaceManagerReady=i(this,"isWorkspaceManagerReady"),this.workspaceChange=i(this,"workspaceChange")}get host(){return this}visible=!1;activeWorkspace;workspaces=[];isWorkspaceManagerReady;workspaceChange;childMenuAnchor=null;openChildMenuItem=null;newWorkspace=null;editingItemId=null;handleWheel(e){e.ctrlKey&&e.preventDefault()}kritzelEngineRef=null;splitButtonRef;get sortedWorkspaces(){return[this.newWorkspace,...this.workspaces].filter((e=>null!=e)).sort(((e,t)=>t.createdAt.getTime()-e.createdAt.getTime()))}async componentWillLoad(){await this.initializeEngine(),this.isWorkspaceManagerReady.emit()}async initializeEngine(){await customElements.whenDefined("kritzel-engine");const e=this.host.closest("kritzel-editor");this.kritzelEngineRef=e?.querySelector("kritzel-engine")??null,this.kritzelEngineRef||console.warn("kritzel-engine not found in kritzel-editor.")}async select(e,t){this.editingItemId||(e.action?e.action(e,t):this.workspaceChange.emit(e.value))}async add(){await this.splitButtonRef.open(),this.newWorkspace=new a(o.generateUUID(),"New Workspace"),this.editingItemId=this.newWorkspace.id}edit(e){this.openChildMenuItem=null,this.childMenuAnchor=null,requestAnimationFrame((()=>{this.editingItemId=e.id}))}async save(e){if(this.newWorkspace)this.newWorkspace.name=e.label,await(this.kritzelEngineRef?.createWorkspace(this.newWorkspace)),this.workspaceChange.emit(this.newWorkspace);else{const t=e.value;t.name=e.label,await(this.kritzelEngineRef?.updateWorkspace(t))}this.editingItemId=null,this.newWorkspace=null}cancel(){this.newWorkspace=null,this.editingItemId=null}async delete(e){this.openChildMenuItem=null,this.childMenuAnchor=null,await(this.kritzelEngineRef?.deleteWorkspace(e.value)),e.value.id===this.activeWorkspace?.id&&(this.activeWorkspace=this.sortedWorkspaces.find((t=>t.id!==e.value.id))||null,this.workspaceChange.emit(this.activeWorkspace)),await this.splitButtonRef.focusMenu()}toggleChildMenu(e,t){this.openChildMenuItem=e,this.childMenuAnchor=t}closeChildMenu(){this.openChildMenuItem=null,this.childMenuAnchor=null}handleMenuOpen(){}handleMenuClose(){this.cancel(),this.closeChildMenu()}render(){const e=this.sortedWorkspaces.sort(((e,t)=>t.createdAt.getTime()-e.createdAt.getTime())).filter((e=>null!==e)).map((e=>({id:e.id,label:e.name,icon:e.isPublic?"users-round":void 0,iconTooltip:e.isPublic?"Shared workspace":void 0,value:e,isEditing:this.editingItemId===e.id,isSelected:this.activeWorkspace?.id===e.id,isNewItem:this.newWorkspace?.id===e.id,isChildMenuOpen:this.openChildMenuItem?.id===e.id,childMenuAnchor:this.openChildMenuItem?.id===e.id?this.childMenuAnchor:null,children:[{id:`${e.id}-rename`,label:"Rename",value:"rename",action:(e,t)=>this.edit(t)},{id:`${e.id}-delete`,label:"Delete",value:"delete",isDisabled:this.sortedWorkspaces.length<=1,action:(e,t)=>this.delete(t)}]})));return s(n,{style:{display:this.visible?"":"none"}},s("div",{class:{manager:!0,visible:this.visible}},s("kritzel-split-button",{ref:e=>this.splitButtonRef=e,items:e,mainButtonDisabled:null!=this.editingItemId,onMainButtonClick:()=>this.add(),onItemSelect:e=>this.select(e.detail.item,e.detail.parent),onItemToggleChildMenu:e=>this.toggleChildMenu(e.detail.item,e.detail.childMenuAnchor),onItemSave:e=>this.save(e.detail),onItemCancel:()=>this.cancel(),onItemCloseChildMenu:()=>this.closeChildMenu(),onMenuOpen:()=>this.handleMenuOpen(),onMenuClose:()=>this.handleMenuClose()})))}static get style(){return":host{display:flex;flex-direction:column;z-index:1}.manager{opacity:0;pointer-events:none;transition:opacity 0.2s ease-out}.manager.visible{opacity:1;pointer-events:auto}"}},[513,"kritzel-workspace-manager",{visible:[4],activeWorkspace:[1040],workspaces:[16],childMenuAnchor:[32],openChildMenuItem:[32],newWorkspace:[32],editingItemId:[32]},[[8,"wheel","handleWheel"]]]);function p(){"undefined"!=typeof customElements&&["kritzel-workspace-manager","kritzel-icon","kritzel-menu","kritzel-menu-item","kritzel-portal","kritzel-split-button"].forEach((e=>{switch(e){case"kritzel-workspace-manager":customElements.get(l(e))||customElements.define(l(e),d);break;case"kritzel-icon":customElements.get(l(e))||h();break;case"kritzel-menu":customElements.get(l(e))||c();break;case"kritzel-menu-item":customElements.get(l(e))||r();break;case"kritzel-portal":customElements.get(l(e))||u();break;case"kritzel-split-button":customElements.get(l(e))||m()}}))}export{d as K,p as d}