kritzel-stencil 0.3.8 → 0.3.10

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 (182) hide show
  1. package/dist/cjs/index.cjs.js +2 -1
  2. package/dist/cjs/kritzel-active-users_42.cjs.entry.js +301 -126
  3. package/dist/cjs/kritzel-brush-style.cjs.entry.js +1 -1
  4. package/dist/cjs/loader.cjs.js +1 -1
  5. package/dist/cjs/{schema.constants-rCfWpcBV.js → schema.constants-BNMNpzvA.js} +77 -12
  6. package/dist/cjs/stencil.cjs.js +1 -1
  7. package/dist/collection/classes/core/core.class.js +3 -0
  8. package/dist/collection/classes/handlers/context-menu.handler.js +54 -0
  9. package/dist/collection/classes/managers/theme.manager.js +47 -5
  10. package/dist/collection/classes/objects/selection-box.class.js +2 -2
  11. package/dist/collection/classes/objects/selection-group.class.js +3 -3
  12. package/dist/collection/classes/objects/text.class.js +8 -0
  13. package/dist/collection/classes/registries/icon-registry.class.js +2 -1
  14. package/dist/collection/classes/tools/text-tool.class.js +2 -0
  15. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.js +1 -1
  16. package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.js +1 -1
  17. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +168 -17
  18. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +83 -1
  19. package/dist/collection/components/shared/kritzel-avatar/kritzel-avatar.js +3 -3
  20. package/dist/collection/components/shared/kritzel-brush-style/kritzel-brush-style.js +1 -1
  21. package/dist/collection/components/shared/kritzel-button/kritzel-button.js +2 -2
  22. package/dist/collection/components/shared/kritzel-color/kritzel-color.js +8 -8
  23. package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js +7 -7
  24. package/dist/collection/components/shared/kritzel-dropdown/kritzel-dropdown.js +7 -7
  25. package/dist/collection/components/shared/kritzel-font/kritzel-font.js +1 -1
  26. package/dist/collection/components/shared/kritzel-font-family/kritzel-font-family.js +1 -1
  27. package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js +1 -1
  28. package/dist/collection/components/shared/kritzel-input/kritzel-input.js +1 -1
  29. package/dist/collection/components/shared/kritzel-line-endings/kritzel-line-endings.js +2 -2
  30. package/dist/collection/components/shared/kritzel-master-detail/kritzel-master-detail.js +3 -3
  31. package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js +1 -1
  32. package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.js +2 -2
  33. package/dist/collection/components/shared/kritzel-numeric-input/kritzel-numeric-input.js +1 -1
  34. package/dist/collection/components/shared/kritzel-opacity-slider/kritzel-opacity-slider.js +2 -1
  35. package/dist/collection/components/shared/kritzel-pill-tabs/kritzel-pill-tabs.js +1 -1
  36. package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js +1 -1
  37. package/dist/collection/components/shared/kritzel-shape-fill/kritzel-shape-fill.js +2 -2
  38. package/dist/collection/components/shared/kritzel-slide-toggle/kritzel-slide-toggle.js +1 -1
  39. package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js +1 -1
  40. package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js +1 -1
  41. package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.js +2 -2
  42. package/dist/collection/components/ui/kritzel-back-to-content/kritzel-back-to-content.js +1 -1
  43. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js +94 -48
  44. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.css +1 -1
  45. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +15 -14
  46. package/dist/collection/components/ui/kritzel-current-user/kritzel-current-user.js +1 -1
  47. package/dist/collection/components/ui/kritzel-current-user-dialog/kritzel-current-user-dialog.js +1 -1
  48. package/dist/collection/components/ui/kritzel-export/kritzel-export.js +1 -1
  49. package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.js +1 -1
  50. package/dist/collection/components/ui/kritzel-more-menu/kritzel-more-menu.js +1 -1
  51. package/dist/collection/components/ui/kritzel-settings/kritzel-settings.js +28 -9
  52. package/dist/collection/components/ui/kritzel-share-dialog/kritzel-share-dialog.js +2 -2
  53. package/dist/collection/components/ui/kritzel-tool-config/kritzel-tool-config.js +6 -6
  54. package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +1 -1
  55. package/dist/collection/constants/color-palette.constants.js +4 -1
  56. package/dist/collection/constants/version.js +1 -1
  57. package/dist/collection/index.js +2 -0
  58. package/dist/collection/themes/dark-theme.js +4 -0
  59. package/dist/collection/themes/light-theme.js +4 -0
  60. package/dist/components/index.js +1 -1
  61. package/dist/components/kritzel-active-users.js +1 -1
  62. package/dist/components/kritzel-avatar.js +1 -1
  63. package/dist/components/kritzel-awareness-cursors.js +1 -1
  64. package/dist/components/kritzel-back-to-content.js +1 -1
  65. package/dist/components/kritzel-brush-style.js +1 -1
  66. package/dist/components/kritzel-button.js +1 -1
  67. package/dist/components/kritzel-color-palette.js +1 -1
  68. package/dist/components/kritzel-color.js +1 -1
  69. package/dist/components/kritzel-context-menu.js +1 -1
  70. package/dist/components/kritzel-controls.js +1 -1
  71. package/dist/components/kritzel-current-user-dialog.js +1 -1
  72. package/dist/components/kritzel-current-user.js +1 -1
  73. package/dist/components/kritzel-cursor-trail.js +1 -1
  74. package/dist/components/kritzel-dropdown.js +1 -1
  75. package/dist/components/kritzel-editor.js +1 -1
  76. package/dist/components/kritzel-engine.js +1 -1
  77. package/dist/components/kritzel-export.js +1 -1
  78. package/dist/components/kritzel-font-family.js +1 -1
  79. package/dist/components/kritzel-font-size.js +1 -1
  80. package/dist/components/kritzel-font.js +1 -1
  81. package/dist/components/kritzel-icon.js +1 -1
  82. package/dist/components/kritzel-input.js +1 -1
  83. package/dist/components/kritzel-line-endings.js +1 -1
  84. package/dist/components/kritzel-login-dialog.js +1 -1
  85. package/dist/components/kritzel-master-detail.js +1 -1
  86. package/dist/components/kritzel-menu-item.js +1 -1
  87. package/dist/components/kritzel-menu.js +1 -1
  88. package/dist/components/kritzel-more-menu.js +1 -1
  89. package/dist/components/kritzel-numeric-input.js +1 -1
  90. package/dist/components/kritzel-opacity-slider.js +1 -1
  91. package/dist/components/kritzel-pill-tabs.js +1 -1
  92. package/dist/components/kritzel-portal.js +1 -1
  93. package/dist/components/kritzel-settings.js +1 -1
  94. package/dist/components/kritzel-shape-fill.js +1 -1
  95. package/dist/components/kritzel-share-dialog.js +1 -1
  96. package/dist/components/kritzel-slide-toggle.js +1 -1
  97. package/dist/components/kritzel-split-button.js +1 -1
  98. package/dist/components/kritzel-stroke-size.js +1 -1
  99. package/dist/components/kritzel-tool-config.js +1 -1
  100. package/dist/components/kritzel-tooltip.js +1 -1
  101. package/dist/components/kritzel-utility-panel.js +1 -1
  102. package/dist/components/kritzel-workspace-manager.js +1 -1
  103. package/dist/components/{p-CJjwjpMH.js → p-BFgWBbpu.js} +1 -1
  104. package/dist/components/{p-CqAkznU_.js → p-BI_UUiTr.js} +1 -1
  105. package/dist/components/p-BPEn0_hr.js +1 -0
  106. package/dist/components/{p-Cz2gQKbL.js → p-B_JH91jB.js} +1 -1
  107. package/dist/components/{p-BV3EJRtU.js → p-Bp3kdH4l.js} +1 -1
  108. package/dist/components/p-C0wFAtT_.js +1 -0
  109. package/dist/components/p-C8ggg-5h.js +1 -0
  110. package/dist/components/{p-B638ZH7S.js → p-CARNM9pf.js} +1 -1
  111. package/dist/components/p-CB7ynHtI.js +1 -0
  112. package/dist/components/{p-DDBaFNFi.js → p-CJ2V42sz.js} +1 -1
  113. package/dist/components/{p-A7Ult9iv.js → p-CJERvHdy.js} +1 -1
  114. package/dist/components/{p-CrSLn46K.js → p-CKY7AvGR.js} +1 -1
  115. package/dist/components/{p-C4vg_-vg.js → p-COIxq81R.js} +1 -1
  116. package/dist/components/p-CT2IjyIk.js +1 -0
  117. package/dist/components/{p-B5a3arJg.js → p-CWgI1dA0.js} +1 -1
  118. package/dist/components/{p-0cs6zQLB.js → p-CYR9wbJg.js} +1 -1
  119. package/dist/components/{p-CrmWVXea.js → p-Cr7xOsIZ.js} +1 -1
  120. package/dist/components/{p-qBqQhAmh.js → p-CxtTuKCy.js} +1 -1
  121. package/dist/components/{p-DEd2L0e3.js → p-D0aom7Yu.js} +1 -1
  122. package/dist/components/{p-DwHZN643.js → p-D15NO5kE.js} +1 -1
  123. package/dist/components/p-DH-H7om7.js +1 -0
  124. package/dist/components/{p-PMiFTdm6.js → p-DJLJfKY2.js} +1 -1
  125. package/dist/components/{p-W0nK9EQJ.js → p-DLlIaDNn.js} +2 -2
  126. package/dist/components/{p-DXO_ppUK.js → p-DRB3TZzI.js} +1 -1
  127. package/dist/components/{p-CaKSDRid.js → p-DXgUuzXW.js} +1 -1
  128. package/dist/components/{p-ihbmwmHg.js → p-DdmJquQr.js} +1 -1
  129. package/dist/components/{p-Czaea0WP.js → p-DfH7YY2C.js} +1 -1
  130. package/dist/components/{p-CTj2UdbS.js → p-DgtrNOWm.js} +1 -1
  131. package/dist/components/{p-D6KNaj_Y.js → p-DhAM4qeQ.js} +1 -1
  132. package/dist/components/{p-DMfU0hHe.js → p-DmTG0Y5h.js} +1 -1
  133. package/dist/components/{p-BMsKd6TF.js → p-Dov3qOAR.js} +1 -1
  134. package/dist/components/{p-CvCTQQcJ.js → p-Dw9sKOsb.js} +1 -1
  135. package/dist/components/{p-CSODtZrV.js → p-Dx_xz_El.js} +1 -1
  136. package/dist/components/{p-BVEYAGm1.js → p-IiG44Unz.js} +1 -1
  137. package/dist/components/{p-DsxW_miC.js → p-K7ySy791.js} +1 -1
  138. package/dist/components/{p-Bda1I4pR.js → p-KVG5rztB.js} +1 -1
  139. package/dist/components/{p-C_OSXZqJ.js → p-KjtNlFTl.js} +1 -1
  140. package/dist/components/{p-DVEfOb8T.js → p-RnuCSIt-.js} +1 -1
  141. package/dist/components/{p-Z9_amVdR.js → p-ZgZqbJ58.js} +1 -1
  142. package/dist/components/{p-C4bAtxyk.js → p-guqEWGgV.js} +1 -1
  143. package/dist/components/{p-DemKKw9U.js → p-u0b2RJAn.js} +1 -1
  144. package/dist/components/{p-BLjdzUzs.js → p-x38RbGJA.js} +1 -1
  145. package/dist/esm/index.js +2 -2
  146. package/dist/esm/kritzel-active-users_42.entry.js +301 -126
  147. package/dist/esm/kritzel-brush-style.entry.js +1 -1
  148. package/dist/esm/loader.js +1 -1
  149. package/dist/esm/{schema.constants-cuIrI5X8.js → schema.constants-CqBoZbmA.js} +77 -13
  150. package/dist/esm/stencil.js +1 -1
  151. package/dist/stencil/index.esm.js +1 -1
  152. package/dist/stencil/p-3372fb1e.entry.js +9 -0
  153. package/dist/stencil/{p-10c2b77c.entry.js → p-69298b5f.entry.js} +1 -1
  154. package/dist/stencil/p-CqBoZbmA.js +1 -0
  155. package/dist/stencil/stencil.esm.js +1 -1
  156. package/dist/types/classes/handlers/context-menu.handler.d.ts +14 -0
  157. package/dist/types/classes/managers/theme.manager.d.ts +22 -2
  158. package/dist/types/classes/objects/text.class.d.ts +1 -0
  159. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +14 -2
  160. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +18 -1
  161. package/dist/types/components/shared/kritzel-color/kritzel-color.d.ts +3 -2
  162. package/dist/types/components/shared/kritzel-color-palette/kritzel-color-palette.d.ts +3 -2
  163. package/dist/types/components/ui/kritzel-context-menu/kritzel-context-menu.d.ts +9 -3
  164. package/dist/types/components/ui/kritzel-controls/kritzel-controls.d.ts +2 -2
  165. package/dist/types/components/ui/kritzel-settings/kritzel-settings.d.ts +2 -1
  166. package/dist/types/components/ui/kritzel-tool-config/kritzel-tool-config.d.ts +3 -2
  167. package/dist/types/components.d.ts +61 -18
  168. package/dist/types/constants/color-palette.constants.d.ts +4 -2
  169. package/dist/types/constants/version.d.ts +1 -1
  170. package/dist/types/helpers/color.helper.d.ts +4 -3
  171. package/dist/types/helpers/svg-export.helper.d.ts +3 -3
  172. package/dist/types/index.d.ts +2 -0
  173. package/dist/types/interfaces/theme.interface.d.ts +7 -3
  174. package/package.json +1 -1
  175. package/dist/components/p-B8wX0-3H.js +0 -1
  176. package/dist/components/p-BvgGpgKP.js +0 -1
  177. package/dist/components/p-C-sJ1r3g.js +0 -1
  178. package/dist/components/p-CBTqCoUx.js +0 -1
  179. package/dist/components/p-DdlK75Kx.js +0 -1
  180. package/dist/components/p-DjAiIBXv.js +0 -1
  181. package/dist/stencil/p-9ce67a14.entry.js +0 -9
  182. package/dist/stencil/p-cuIrI5X8.js +0 -1
@@ -1,5 +1,5 @@
1
1
  import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-D9HaikfQ.js';
2
- import { b as KritzelPath, d as KritzelLine, G as KritzelColorHelper, n as KritzelSelectionTool, g as KritzelBrushTool, h as KritzelLineTool, l as KritzelShapeTool, k as KritzelTextTool, J as KritzelDevicesHelper, L as KritzelMouseButton, M as DEFAULT_STROKE_SIZES, N as DEFAULT_COLOR_PALETTE, S as ShapeType, I as IndexedDBSyncProvider, D as DEFAULT_BRUSH_CONFIG, i as KritzelEraserTool, u as DEFAULT_LINE_TOOL_CONFIG, t as DEFAULT_TEXT_CONFIG, j as KritzelImageTool, y as KritzelAlignment, v as DEFAULT_ASSET_STORAGE_CONFIG, O as KritzelSelectionGroup, P as KritzelSelectionBox, Q as KritzelIconRegistry, R as KritzelKeyboardHelper, T as KritzelBaseHandler, U as KritzelBaseObject, q as KritzelWorkspace, e as KritzelGroup, c as KritzelImage, f as KritzelShape, K as KritzelText, z as runMigrations, F as CURRENT_WORKSPACE_SCHEMA_VERSION, C as WORKSPACE_MIGRATIONS, E as CURRENT_APP_STATE_SCHEMA_VERSION, B as APP_STATE_MIGRATIONS, V as ObjectHelper, m as KritzelCursorHelper, r as KritzelAnchorManager, s as KritzelThemeManager, o as KritzelAssetResolver, X as KritzelClassHelper, Y as KritzelEventHelper, W as WORKSPACE_EXPORT_VERSION } from './schema.constants-cuIrI5X8.js';
2
+ import { c as KritzelPath, e as KritzelLine, J as KritzelColorHelper, o as KritzelSelectionTool, h as KritzelBrushTool, i as KritzelLineTool, m as KritzelShapeTool, l as KritzelTextTool, L as KritzelDevicesHelper, M as KritzelMouseButton, N as DEFAULT_STROKE_SIZES, O as DEFAULT_COLOR_PALETTE, S as ShapeType, I as IndexedDBSyncProvider, D as DEFAULT_BRUSH_CONFIG, j as KritzelEraserTool, v as DEFAULT_LINE_TOOL_CONFIG, u as DEFAULT_TEXT_CONFIG, k as KritzelImageTool, z as KritzelAlignment, w as DEFAULT_ASSET_STORAGE_CONFIG, T as ThemeHelper, y as darkTheme, x as lightTheme, P as KritzelSelectionGroup, Q as KritzelSelectionBox, R as KritzelIconRegistry, U as KritzelKeyboardHelper, V as KritzelBaseHandler, K as KritzelBaseObject, r as KritzelWorkspace, f as KritzelGroup, d as KritzelImage, g as KritzelShape, b as KritzelText, B as runMigrations, G as CURRENT_WORKSPACE_SCHEMA_VERSION, E as WORKSPACE_MIGRATIONS, F as CURRENT_APP_STATE_SCHEMA_VERSION, C as APP_STATE_MIGRATIONS, X as ObjectHelper, n as KritzelCursorHelper, s as KritzelAnchorManager, t as KritzelThemeManager, p as KritzelAssetResolver, Y as KritzelClassHelper, Z as KritzelEventHelper, W as WORKSPACE_EXPORT_VERSION } from './schema.constants-CqBoZbmA.js';
3
3
  import * as Y from 'yjs';
4
4
  import 'y-indexeddb';
5
5
  import 'y-websocket';
@@ -132,16 +132,16 @@ const KritzelAvatar = class {
132
132
  height: `${this.size}px`,
133
133
  fontSize: `${Math.round(this.size * 0.4)}px`,
134
134
  };
135
- return (h(Host, { key: '2067605684a743be45059efd562697ff21fefbcb', style: containerStyles, class: {
135
+ return (h(Host, { key: '571bd5b92adc7c65b96ded37b8daf5ed79905361', style: containerStyles, class: {
136
136
  'has-image': !!showImage,
137
137
  'has-initials': !!showInitials,
138
138
  'has-default': !!showDefaultIcon,
139
- }, role: "img", "aria-label": this.getDisplayName() || 'User avatar' }, showImage && (h("img", { key: '1ed322318335deb011087494a2c437849b5a23a0', src: imageUrl, alt: "", class: "avatar-image", ref: (el) => {
139
+ }, role: "img", "aria-label": this.getDisplayName() || 'User avatar' }, showImage && (h("img", { key: '1065850b4575fda4637ab61ce07c6dfc97f14a90', src: imageUrl, alt: "", class: "avatar-image", ref: (el) => {
140
140
  if (el) {
141
141
  el.referrerPolicy = 'no-referrer';
142
142
  el.crossOrigin = 'anonymous';
143
143
  }
144
- }, onError: this.handleImageError })), showInitials && (h("span", { key: 'ff99dded4cb17d6c25880b54e3875c262dfc0440', class: "avatar-initials", style: { backgroundColor: this.getBackgroundColor() } }, initials)), showDefaultIcon && (h("span", { key: '5a217c6a1366dea3ceee8bfa03a38917cad7a9f9', class: "avatar-default" }, h("svg", { key: 'f4537e21772e6e6f1bb60835ad7a56123a200dd7', viewBox: "0 0 24 24", fill: "currentColor" }, h("path", { key: '29649695038a506e1caeba3a8b6c066860fb5a1d', d: "M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" }))))));
144
+ }, onError: this.handleImageError })), showInitials && (h("span", { key: 'a6d9c9dd2eac6e44c731a878e2460017da7fb0b7', class: "avatar-initials", style: { backgroundColor: this.getBackgroundColor() } }, initials)), showDefaultIcon && (h("span", { key: '9e9d33cdd213649071b76cb0875008562b30f6a1', class: "avatar-default" }, h("svg", { key: '5d0be5c503a8944b45de239f08e6f40378c2dc5e', viewBox: "0 0 24 24", fill: "currentColor" }, h("path", { key: '9264549c9b8abbdea74cd707d6f77bcfdde6459d', d: "M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" }))))));
145
145
  }
146
146
  static get watchers() { return {
147
147
  "user": [{
@@ -344,7 +344,7 @@ const KritzelAwarenessCursors = class {
344
344
  }
345
345
  render() {
346
346
  const cursors = Array.from(this.remoteCursors.values());
347
- return (h(Host, { key: '0f8678b0a96d80e12d2aa75f85af74a8737f836d' }, cursors.map(remoteCursor => {
347
+ return (h(Host, { key: '5c695e3c5a012767b31bb1b756ef03e2a174f46e' }, cursors.map(remoteCursor => {
348
348
  if (!remoteCursor.cursor)
349
349
  return null;
350
350
  // When a remote user is actively drawing, derive cursor position from
@@ -451,7 +451,7 @@ const KritzelBackToContent = class {
451
451
  this.backToContent.emit();
452
452
  };
453
453
  render() {
454
- return (h(Host, { key: '7d33e599832eb5e4f65b9fdbb9239cfe157733af' }, h("button", { key: '905b50a8a90a0ca66a4fa9421457b78a0f650de5', class: { 'back-to-content-button': true, visible: this.visible }, onClick: this.handleClick, "aria-label": this.text }, h("kritzel-icon", { key: 'eaa718ab29fad870464c6b67d5ad27c4300dfd54', name: "chevrons-left" }))));
454
+ return (h(Host, { key: 'b623a9a4e4b8fce50346771488a59c3a646c289e' }, h("button", { key: 'b2f6b257975639d33362f1038b61e5147963f189', class: { 'back-to-content-button': true, visible: this.visible }, onClick: this.handleClick, "aria-label": this.text }, h("kritzel-icon", { key: '22f34fc201a865b6d9b21775a349d0e185727d48', name: "chevrons-left" }))));
455
455
  }
456
456
  };
457
457
  KritzelBackToContent.style = kritzelBackToContentCss();
@@ -478,11 +478,11 @@ const KritzelButton = class {
478
478
  this.buttonClick.emit();
479
479
  };
480
480
  render() {
481
- return (h(Host, { key: 'aa82a9e0c6c39b0b2bce597ac2e864049543d474' }, h("button", { key: '5bda14f9fef89abacb9cd04e5aaa8ae7ae25048a', type: this.type, class: {
481
+ return (h(Host, { key: 'c915db75630392741de404f07265a391330e54ca' }, h("button", { key: '50248ee1ed5862c9ea72b4f7cf7d564d03b5b14e', type: this.type, class: {
482
482
  'kritzel-button': true,
483
483
  [this.variant]: true,
484
484
  'disabled': this.disabled,
485
- }, disabled: this.disabled, onClick: this.handleClick }, h("slot", { key: '8585675eec39345ddfbf3f6dbb705035f7a5d099' }))));
485
+ }, disabled: this.disabled, onClick: this.handleClick }, h("slot", { key: 'd595cd819c7c0a3550e468ce65d4e2c28cc02164' }))));
486
486
  }
487
487
  };
488
488
  KritzelButton.style = kritzelButtonCss();
@@ -530,13 +530,13 @@ const KritzelColorComponent = class {
530
530
  render() {
531
531
  const resolvedColor = this.resolveColor();
532
532
  const isColorVeryLight = this.isLightColor(resolvedColor);
533
- return (h(Host, { key: 'a740b94f2baacb978b26deae1ea1057c7faf9036' }, h("div", { key: 'e82f83a23e44a2ff23b5efbfac28e4c47cd5b749', class: "checkerboard-bg", style: {
533
+ return (h(Host, { key: 'c4c1fe2559aca61557ff2e8154f4d46ce3511b30' }, h("div", { key: '158c243018763a9609e0a056229263864a5e4d13', class: "checkerboard-bg", style: {
534
534
  width: `${this.size}px`,
535
535
  height: `${this.size}px`,
536
536
  borderRadius: '50%',
537
537
  display: 'inline-block',
538
538
  position: 'relative',
539
- } }, h("div", { key: 'd83e2be171f89ee4cd53e8cf83ab6591f585129f', class: {
539
+ } }, h("div", { key: 'afa21c72b17ab5fb4b16521b91dbe7e9162d05f8', class: {
540
540
  'color-circle': true,
541
541
  'white': isColorVeryLight,
542
542
  }, style: {
@@ -592,7 +592,7 @@ const KritzelColorPalette = class {
592
592
  render() {
593
593
  const displayedColors = this.isExpanded ? this.colors : this.colors.slice(0, 6);
594
594
  const expandedHeight = this.isExpanded ? this.calculateHeight() : '32px';
595
- return (h(Host, { key: 'a2c996d16a44f66471f6f76e08129142fc9f5ddb' }, h("div", { key: '245f4b9ff50412b84ede221d22b0894a104a6895', class: {
595
+ return (h(Host, { key: 'fc57d77d7c4cfd2aa2a02a70b8991858bb8cf61b' }, h("div", { key: '4fd10783609882f453ce95f5114acf799f21ec52', class: {
596
596
  'color-grid': true,
597
597
  'expanded': this.isExpanded,
598
598
  }, style: {
@@ -627,8 +627,9 @@ const KritzelContextMenu = class {
627
627
  actionSelected;
628
628
  close;
629
629
  processedItems = [];
630
- openSubmenuIndex = null;
631
- submenuPosition = 'right';
630
+ /** Current open submenu path (e.g. '0.2.1'). Empty if none. */
631
+ openSubmenuPath = '';
632
+ submenuPositions = {};
632
633
  submenuTimer = null;
633
634
  submenuRefs = new Map();
634
635
  menuItemWrapperRefs = new Map();
@@ -646,7 +647,8 @@ const KritzelContextMenu = class {
646
647
  }
647
648
  componentDidUpdate() {
648
649
  this.adjustPositionToViewport();
649
- this.adjustSubmenuPosition();
650
+ this.adjustSubmenuPositions();
651
+ this.pruneStaleRefs();
650
652
  }
651
653
  disconnectedCallback() {
652
654
  if (this.submenuTimer) {
@@ -683,60 +685,102 @@ const KritzelContextMenu = class {
683
685
  this.host.style.top = `${newTop}px`;
684
686
  }
685
687
  }
686
- adjustSubmenuPosition() {
687
- if (this.openSubmenuIndex === null)
688
+ adjustSubmenuPositions() {
689
+ if (!this.openSubmenuPath)
688
690
  return;
689
- const submenuEl = this.submenuRefs.get(this.openSubmenuIndex);
690
- if (!submenuEl)
691
- return;
692
- const submenuRect = submenuEl.getBoundingClientRect();
693
691
  const viewportHeight = window.innerHeight;
694
- // Adjust vertical position if needed (horizontal is pre-calculated)
695
- if (submenuRect.bottom > viewportHeight - VIEWPORT_PADDING) {
696
- const overflow = submenuRect.bottom - (viewportHeight - VIEWPORT_PADDING);
697
- submenuEl.style.top = `${-overflow}px`;
692
+ // Adjust every open submenu in the chain (every prefix of openSubmenuPath).
693
+ for (const path of this.getOpenSubmenuPaths()) {
694
+ const submenuEl = this.submenuRefs.get(path);
695
+ const wrapperEl = this.menuItemWrapperRefs.get(path);
696
+ if (!submenuEl || !wrapperEl)
697
+ continue;
698
+ const wrapperRect = wrapperEl.getBoundingClientRect();
699
+ const submenuHeight = submenuEl.offsetHeight; // Constant regardless of current top shift
700
+ const naturalBottom = wrapperRect.top + submenuHeight;
701
+ if (naturalBottom > viewportHeight - VIEWPORT_PADDING) {
702
+ let overflow = naturalBottom - (viewportHeight - VIEWPORT_PADDING);
703
+ // Don't shift up so far that the top goes above the viewport
704
+ if (wrapperRect.top - overflow < VIEWPORT_PADDING) {
705
+ overflow = wrapperRect.top - VIEWPORT_PADDING;
706
+ }
707
+ submenuEl.style.top = `${-overflow}px`;
708
+ }
709
+ else {
710
+ submenuEl.style.top = '0px';
711
+ }
698
712
  }
699
- else {
700
- submenuEl.style.top = '0px';
713
+ }
714
+ getOpenSubmenuPaths() {
715
+ if (!this.openSubmenuPath)
716
+ return [];
717
+ const parts = this.openSubmenuPath.split('.');
718
+ const paths = [];
719
+ for (let i = 1; i <= parts.length; i++) {
720
+ paths.push(parts.slice(0, i).join('.'));
721
+ }
722
+ return paths;
723
+ }
724
+ isSubmenuOpen(path) {
725
+ return this.openSubmenuPath === path || this.openSubmenuPath.startsWith(path + '.');
726
+ }
727
+ getParentPath(path) {
728
+ const idx = path.lastIndexOf('.');
729
+ return idx === -1 ? '' : path.substring(0, idx);
730
+ }
731
+ pruneStaleRefs() {
732
+ const openPaths = new Set(this.getOpenSubmenuPaths());
733
+ for (const key of Array.from(this.submenuRefs.keys())) {
734
+ if (!openPaths.has(key)) {
735
+ this.submenuRefs.delete(key);
736
+ }
737
+ }
738
+ // Keep root-level wrapper refs (single-segment paths) always rendered; prune deeper
739
+ // wrappers whose parent submenu is no longer open.
740
+ for (const key of Array.from(this.menuItemWrapperRefs.keys())) {
741
+ const parent = this.getParentPath(key);
742
+ if (parent !== '' && !openPaths.has(parent)) {
743
+ this.menuItemWrapperRefs.delete(key);
744
+ }
701
745
  }
702
746
  }
703
747
  handleItemClick(item, isDisabled, hasChildren) {
704
748
  if (isDisabled)
705
749
  return;
706
750
  if (hasChildren) {
707
- // Toggle submenu on click for touch devices
751
+ // Hover handles open/close; click on a parent is a no-op.
708
752
  return;
709
753
  }
710
754
  if (item.action) {
711
755
  this.actionSelected.emit(item);
712
756
  }
713
757
  }
714
- handleItemMouseEnter(index, hasChildren) {
758
+ handleItemMouseEnter(path, hasChildren) {
715
759
  if (this.submenuTimer) {
716
760
  clearTimeout(this.submenuTimer);
717
761
  this.submenuTimer = null;
718
762
  }
763
+ const parentPath = this.getParentPath(path);
719
764
  if (hasChildren) {
720
765
  this.submenuTimer = setTimeout(() => {
721
- // Pre-calculate position before opening to avoid flicker
722
- const wrapperEl = this.menuItemWrapperRefs.get(index);
766
+ // Pre-calculate horizontal position before opening to avoid flicker.
767
+ const wrapperEl = this.menuItemWrapperRefs.get(path);
768
+ let position = 'right';
723
769
  if (wrapperEl) {
724
770
  const rect = wrapperEl.getBoundingClientRect();
725
771
  const viewportWidth = window.innerWidth;
726
- // Check if opening to the right would overflow
727
772
  const wouldOverflowRight = rect.right + ESTIMATED_SUBMENU_WIDTH > viewportWidth - VIEWPORT_PADDING;
728
- this.submenuPosition = wouldOverflowRight ? 'left' : 'right';
773
+ position = wouldOverflowRight ? 'left' : 'right';
729
774
  }
730
- else {
731
- this.submenuPosition = 'right';
732
- }
733
- this.openSubmenuIndex = index;
775
+ this.submenuPositions = { ...this.submenuPositions, [path]: position };
776
+ this.openSubmenuPath = path;
734
777
  }, SUBMENU_DELAY);
735
778
  }
736
779
  else {
737
- // Close any open submenu when hovering a non-parent item
780
+ // Hovering a sibling without children: collapse to the parent chain so any
781
+ // sibling-rooted submenu closes, but the ancestor chain stays open.
738
782
  this.submenuTimer = setTimeout(() => {
739
- this.openSubmenuIndex = null;
783
+ this.openSubmenuPath = parentPath;
740
784
  }, SUBMENU_DELAY);
741
785
  }
742
786
  }
@@ -746,9 +790,11 @@ const KritzelContextMenu = class {
746
790
  this.submenuTimer = null;
747
791
  }
748
792
  }
749
- handleSubmenuMouseLeave() {
793
+ handleSubmenuMouseLeave(path) {
794
+ // Close this submenu (and any deeper levels) but keep the ancestor chain open.
795
+ const parentPath = this.getParentPath(path);
750
796
  this.submenuTimer = setTimeout(() => {
751
- this.openSubmenuIndex = null;
797
+ this.openSubmenuPath = parentPath;
752
798
  }, SUBMENU_DELAY);
753
799
  }
754
800
  async updateMenuItems() {
@@ -778,28 +824,28 @@ const KritzelContextMenu = class {
778
824
  }
779
825
  return defaultValue;
780
826
  }
781
- renderSubmenu(processedChildren, parentIndex) {
782
- return (h("div", { class: { 'submenu-container': true, 'position-left': this.submenuPosition === 'left' }, ref: el => el && this.submenuRefs.set(parentIndex, el), onMouseEnter: () => this.handleSubmenuMouseEnter(), onMouseLeave: () => this.handleSubmenuMouseLeave() }, processedChildren.map(({ item, isDisabled, processedChildren: nestedChildren }, index) => {
783
- const prevItem = index > 0 ? processedChildren[index - 1].item : null;
827
+ renderItems(items, parentPath) {
828
+ return items.map(({ item, isDisabled, processedChildren }, index) => {
829
+ const path = parentPath === '' ? String(index) : `${parentPath}.${index}`;
830
+ const prevItem = index > 0 ? items[index - 1].item : null;
784
831
  const showDivider = prevItem && prevItem.group !== item.group;
785
- const hasChildren = nestedChildren && nestedChildren.length > 0;
832
+ const hasChildren = !!processedChildren && processedChildren.length > 0;
833
+ const submenuOpen = hasChildren && this.isSubmenuOpen(path);
786
834
  return [
787
- showDivider && h("div", { class: "menu-divider", key: `submenu-divider-${index}` }),
788
- h("button", { key: `submenu-${item.label}-${index}`, class: { 'menu-item': true, 'disabled': isDisabled, 'has-children': hasChildren }, onClick: () => this.handleItemClick(item, isDisabled, hasChildren), disabled: isDisabled }, item.icon && h("kritzel-icon", { name: item.icon, size: 16 }), h("span", { class: "label" }, item.label), hasChildren && h("kritzel-icon", { name: "chevron-right", size: 12, class: "submenu-arrow" }))
835
+ showDivider && h("div", { class: "menu-divider", key: `divider-${path}` }),
836
+ h("div", { class: "menu-item-wrapper", key: `wrapper-${path}`, ref: el => el && this.menuItemWrapperRefs.set(path, el), onMouseEnter: () => this.handleItemMouseEnter(path, hasChildren) }, h("button", { key: `${item.label}-${path}`, class: { 'menu-item': true, 'disabled': isDisabled, 'has-children': hasChildren, 'submenu-open': submenuOpen }, onClick: () => this.handleItemClick(item, isDisabled, hasChildren), disabled: isDisabled && !hasChildren }, item.icon && h("kritzel-icon", { name: item.icon, size: 16 }), h("span", { class: "label" }, item.label), hasChildren && h("kritzel-icon", { name: "chevron-right", size: 12, class: "submenu-arrow" })), hasChildren && submenuOpen && this.renderSubmenu(processedChildren, path)),
789
837
  ];
790
- })));
838
+ });
839
+ }
840
+ renderSubmenu(processedChildren, path) {
841
+ const position = this.submenuPositions[path] === 'left' ? 'left' : 'right';
842
+ return (h("div", { class: { 'submenu-container': true, 'position-left': position === 'left' }, key: `submenu-${path}`, ref: el => el && this.submenuRefs.set(path, el), onMouseEnter: () => this.handleSubmenuMouseEnter(), onMouseLeave: () => this.handleSubmenuMouseLeave(path) }, this.renderItems(processedChildren, path)));
791
843
  }
792
844
  render() {
793
- return (h(Host, { key: '100ec82feefbc285f8e50fca3f23f853c33aa215' }, h("div", { key: '9305a0190bdcf7a9e4b5ae7473651a0261dbfd7c', class: "menu-container" }, this.processedItems.map(({ item, isDisabled, processedChildren }, index) => {
794
- const prevItem = index > 0 ? this.processedItems[index - 1].item : null;
795
- const showDivider = prevItem && prevItem.group !== item.group;
796
- const hasChildren = processedChildren && processedChildren.length > 0;
797
- const isSubmenuOpen = this.openSubmenuIndex === index;
798
- return [
799
- showDivider && h("div", { class: "menu-divider", key: `divider-${index}` }),
800
- h("div", { class: "menu-item-wrapper", ref: el => el && this.menuItemWrapperRefs.set(index, el), onMouseEnter: () => this.handleItemMouseEnter(index, hasChildren) }, h("button", { key: `${item.label}-${index}`, class: { 'menu-item': true, 'disabled': isDisabled, 'has-children': hasChildren, 'submenu-open': isSubmenuOpen }, onClick: () => this.handleItemClick(item, isDisabled, hasChildren), disabled: isDisabled && !hasChildren }, item.icon && h("kritzel-icon", { name: item.icon, size: 16 }), h("span", { class: "label" }, item.label), hasChildren && h("kritzel-icon", { name: "chevron-right", size: 12, class: "submenu-arrow" })), hasChildren && isSubmenuOpen && this.renderSubmenu(processedChildren, index))
801
- ];
802
- }))));
845
+ if (!this.processedItems || this.processedItems.length === 0) {
846
+ return null;
847
+ }
848
+ return (h(Host, null, h("div", { class: "menu-container" }, this.renderItems(this.processedItems, ''))));
803
849
  }
804
850
  static get watchers() { return {
805
851
  "items": [{
@@ -875,7 +921,7 @@ class KritzelToolConfigHelper {
875
921
  }
876
922
  }
877
923
 
878
- const kritzelControlsCss = () => `:host{display:flex;flex-direction:column;user-select:none;max-width:100%;z-index:1}:host(.mobile){--kritzel-controls-control-hover-background-color:transparent;--kritzel-controls-control-active-background-color:transparent}.kritzel-controls{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:var(--kritzel-controls-gap, 8px);height:100%;padding:var(--kritzel-controls-padding, 8px);background-color:var(--kritzel-controls-background-color, #ffffff);border-radius:var(--kritzel-controls-border-radius, 16px);box-shadow:var(--kritzel-controls-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-controls-border, 1px solid #ebebeb);z-index:1;position:relative;max-width:100%;overflow:hidden}.kritzel-tools-scroll{display:flex;flex-direction:row;align-items:center;gap:var(--kritzel-controls-gap, 8px);overflow-x:auto;overflow-y:hidden;flex:1 1 auto;min-width:0;padding:4px;margin:-4px;scrollbar-width:none;-ms-overflow-style:none}.kritzel-tools-scroll::-webkit-scrollbar{display:none}.scroll-indicator-left,.scroll-indicator-right{position:absolute;top:0;bottom:0;width:32px;pointer-events:none;opacity:0;transition:opacity 0.2s ease-out;z-index:1}.scroll-indicator-left{left:0;background:linear-gradient(to right, var(--kritzel-controls-background-color, #ffffff), transparent);border-radius:var(--kritzel-controls-border-radius, 16px) 0 0 var(--kritzel-controls-border-radius, 16px)}.scroll-indicator-right{right:0;background:linear-gradient(to left, var(--kritzel-controls-background-color, #ffffff), transparent);border-radius:0 var(--kritzel-controls-border-radius, 16px) var(--kritzel-controls-border-radius, 16px) 0}.scroll-indicator-left.visible,.scroll-indicator-right.visible{opacity:1}.kritzel-control{display:flex;justify-content:center;align-items:center;color:var(--kritzel-controls-control-color, #000000);border-radius:var(--kritzel-controls-control-border-radius, 12px);padding:var(--kritzel-controls-control-padding, 8px);border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);-webkit-tap-highlight-color:transparent;font-weight:bold}.kritzel-control:focus,.kritzel-control:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-control:active{background-color:var(--kritzel-controls-control-active-background-color, hsl(0, 0%, 0%, 8.6%))}.kritzel-control.selected,.kritzel-control.selected:hover,.kritzel-control.selected:active{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF) !important;color:var(--kritzel-controls-control-selected-color, #ffffff) !important}.kritzel-control.selected:focus{background-color:var(--kritzel-controls-control-selected-background-color, #007bffe3) !important}.kritzel-control-separator{width:1px;height:24px;background-color:var(--kritzel-controls-border, #ebebeb);margin:0 4px}.kritzel-control-split{position:relative;display:flex;align-items:center;border-radius:var(--kritzel-controls-control-border-radius, 12px);color:var(--kritzel-controls-control-color, #000000)}.kritzel-control-split .kritzel-control-main{display:flex;justify-content:center;align-items:center;padding:var(--kritzel-controls-control-padding, 8px);border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);-webkit-tap-highlight-color:transparent;border-radius:var(--kritzel-controls-control-border-radius, 12px);color:inherit}.kritzel-control-split.selected .kritzel-control-main{border-radius:var(--kritzel-controls-control-border-radius, 12px) 0 0 var(--kritzel-controls-control-border-radius, 12px)}.kritzel-control-split .kritzel-control-dropdown{display:flex;justify-content:center;align-items:center;align-self:stretch;border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);-webkit-tap-highlight-color:transparent;border-radius:0 var(--kritzel-controls-control-border-radius, 12px) var(--kritzel-controls-control-border-radius, 12px) 0;color:inherit;width:0;padding:0;opacity:0;overflow:hidden;pointer-events:none;transition:width 0.15s ease-out, padding 0.15s ease-out, opacity 0.15s ease-out}.kritzel-control-split .kritzel-control-dropdown.visible{width:auto;padding:0 6px;opacity:1;pointer-events:auto}.kritzel-control-split .kritzel-control-main:focus,.kritzel-control-split .kritzel-control-main:hover,.kritzel-control-split .kritzel-control-dropdown:focus,.kritzel-control-split .kritzel-control-dropdown:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-control-split .kritzel-control-main:active,.kritzel-control-split .kritzel-control-dropdown:active{background-color:var(--kritzel-controls-control-active-background-color, hsl(0, 0%, 0%, 8.6%))}.kritzel-control-split.selected{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF) !important;color:var(--kritzel-controls-control-selected-color, #ffffff) !important}.kritzel-control-split.selected .kritzel-control-main:hover,.kritzel-control-split.selected .kritzel-control-dropdown:hover{background-color:rgba(255, 255, 255, 0.15)}.kritzel-submenu-content{display:flex;flex-direction:column;gap:var(--kritzel-submenu-gap, 4px);min-width:140px}.kritzel-submenu-item{display:flex;align-items:center;gap:10px;padding:10px 12px;border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);border-radius:8px;color:var(--kritzel-controls-control-color, #000000);font-size:14px;text-align:left;white-space:nowrap;-webkit-tap-highlight-color:transparent}.kritzel-submenu-item:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-submenu-item.active{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF);color:var(--kritzel-controls-control-selected-color, #ffffff)}.kritzel-submenu-item.active:hover{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF)}.kritzel-config-container{position:relative;display:flex;justify-content:center;align-items:center;height:40px;box-sizing:border-box;-webkit-tap-highlight-color:transparent;flex-shrink:0;width:0;opacity:0;overflow:hidden;pointer-events:none;margin-left:calc(-1 * var(--kritzel-controls-gap, 8px));transition:width 0.2s ease-out, opacity 0.2s ease-out, margin-left 0.2s ease-out}.kritzel-config-container.visible{width:40px;opacity:1;pointer-events:auto;margin-left:0;overflow:visible}.config-gradient-left{position:absolute;top:0;bottom:0;left:-32px;width:32px;background:linear-gradient(to right, transparent, var(--kritzel-controls-background-color, #ffffff));pointer-events:none;z-index:1;opacity:0;transition:opacity 0.2s ease-out}.config-gradient-left.visible{opacity:1}.kritzel-config{display:flex;justify-content:center;align-items:center;cursor:var(--kritzel-global-pointer-cursor, pointer);border-radius:50%}.color-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;background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.font-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;background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.no-config{height:24px;width:24px;border-radius:50%;border:1px dashed gray}kritzel-tooltip{z-index:10001}`;
924
+ const kritzelControlsCss = () => `:host{display:flex;flex-direction:column;user-select:none;max-width:100%;z-index:1}:host(.mobile){--kritzel-controls-control-hover-background-color:transparent;--kritzel-controls-control-active-background-color:transparent}.kritzel-controls{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:var(--kritzel-controls-gap, 8px);height:100%;padding:var(--kritzel-controls-padding, 8px);background-color:var(--kritzel-controls-background-color, #ffffff);border-radius:var(--kritzel-controls-border-radius, 16px);box-shadow:var(--kritzel-controls-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-controls-border, 1px solid #ebebeb);z-index:1;position:relative;max-width:100%;overflow:hidden}.kritzel-tools-scroll{display:flex;flex-direction:row;align-items:center;gap:var(--kritzel-controls-gap, 8px);overflow-x:auto;overflow-y:hidden;flex:1 1 auto;min-width:0;padding:4px;margin:-4px;scrollbar-width:none;-ms-overflow-style:none}.kritzel-tools-scroll::-webkit-scrollbar{display:none}.scroll-indicator-left,.scroll-indicator-right{position:absolute;top:0;bottom:0;width:32px;pointer-events:none;opacity:0;transition:opacity 0.2s ease-out;z-index:1}.scroll-indicator-left{left:0;background:linear-gradient(to right, var(--kritzel-controls-background-color, #ffffff), transparent);border-radius:var(--kritzel-controls-border-radius, 16px) 0 0 var(--kritzel-controls-border-radius, 16px)}.scroll-indicator-right{right:0;background:linear-gradient(to left, var(--kritzel-controls-background-color, #ffffff), transparent);border-radius:0 var(--kritzel-controls-border-radius, 16px) var(--kritzel-controls-border-radius, 16px) 0}.scroll-indicator-left.visible,.scroll-indicator-right.visible{opacity:1}.kritzel-control{display:flex;justify-content:center;align-items:center;color:var(--kritzel-controls-control-color, #000000);border-radius:var(--kritzel-controls-control-border-radius, 12px);padding:var(--kritzel-controls-control-padding, 8px);border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);-webkit-tap-highlight-color:transparent;font-weight:bold}.kritzel-control:focus,.kritzel-control:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-control:active{background-color:var(--kritzel-controls-control-active-background-color, hsl(0, 0%, 0%, 8.6%))}.kritzel-control.selected,.kritzel-control.selected:hover,.kritzel-control.selected:active{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF) !important;color:var(--kritzel-controls-control-selected-color, #ffffff) !important}.kritzel-control.selected:focus{background-color:var(--kritzel-controls-control-selected-background-color, #007bffe3) !important}.kritzel-control-separator{width:1px;height:24px;background-color:var(--kritzel-controls-separator-color, #ebebeb);margin:0 4px}.kritzel-control-split{position:relative;display:flex;align-items:center;border-radius:var(--kritzel-controls-control-border-radius, 12px);color:var(--kritzel-controls-control-color, #000000)}.kritzel-control-split .kritzel-control-main{display:flex;justify-content:center;align-items:center;padding:var(--kritzel-controls-control-padding, 8px);border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);-webkit-tap-highlight-color:transparent;border-radius:var(--kritzel-controls-control-border-radius, 12px);color:inherit}.kritzel-control-split.selected .kritzel-control-main{border-radius:var(--kritzel-controls-control-border-radius, 12px) 0 0 var(--kritzel-controls-control-border-radius, 12px)}.kritzel-control-split .kritzel-control-dropdown{display:flex;justify-content:center;align-items:center;align-self:stretch;border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);-webkit-tap-highlight-color:transparent;border-radius:0 var(--kritzel-controls-control-border-radius, 12px) var(--kritzel-controls-control-border-radius, 12px) 0;color:inherit;width:0;padding:0;opacity:0;overflow:hidden;pointer-events:none;transition:width 0.15s ease-out, padding 0.15s ease-out, opacity 0.15s ease-out}.kritzel-control-split .kritzel-control-dropdown.visible{width:auto;padding:0 6px;opacity:1;pointer-events:auto}.kritzel-control-split .kritzel-control-main:focus,.kritzel-control-split .kritzel-control-main:hover,.kritzel-control-split .kritzel-control-dropdown:focus,.kritzel-control-split .kritzel-control-dropdown:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-control-split .kritzel-control-main:active,.kritzel-control-split .kritzel-control-dropdown:active{background-color:var(--kritzel-controls-control-active-background-color, hsl(0, 0%, 0%, 8.6%))}.kritzel-control-split.selected{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF) !important;color:var(--kritzel-controls-control-selected-color, #ffffff) !important}.kritzel-control-split.selected .kritzel-control-main:hover,.kritzel-control-split.selected .kritzel-control-dropdown:hover{background-color:rgba(255, 255, 255, 0.15)}.kritzel-submenu-content{display:flex;flex-direction:column;gap:var(--kritzel-submenu-gap, 4px);min-width:140px}.kritzel-submenu-item{display:flex;align-items:center;gap:10px;padding:10px 12px;border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);border-radius:8px;color:var(--kritzel-controls-control-color, #000000);font-size:14px;text-align:left;white-space:nowrap;-webkit-tap-highlight-color:transparent}.kritzel-submenu-item:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-submenu-item.active{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF);color:var(--kritzel-controls-control-selected-color, #ffffff)}.kritzel-submenu-item.active:hover{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF)}.kritzel-config-container{position:relative;display:flex;justify-content:center;align-items:center;height:40px;box-sizing:border-box;-webkit-tap-highlight-color:transparent;flex-shrink:0;width:0;opacity:0;overflow:hidden;pointer-events:none;margin-left:calc(-1 * var(--kritzel-controls-gap, 8px));transition:width 0.2s ease-out, opacity 0.2s ease-out, margin-left 0.2s ease-out}.kritzel-config-container.visible{width:40px;opacity:1;pointer-events:auto;margin-left:0;overflow:visible}.config-gradient-left{position:absolute;top:0;bottom:0;left:-32px;width:32px;background:linear-gradient(to right, transparent, var(--kritzel-controls-background-color, #ffffff));pointer-events:none;z-index:1;opacity:0;transition:opacity 0.2s ease-out}.config-gradient-left.visible{opacity:1}.kritzel-config{display:flex;justify-content:center;align-items:center;cursor:var(--kritzel-global-pointer-cursor, pointer);border-radius:50%}.color-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;background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.font-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;background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.no-config{height:24px;width:24px;border-radius:50%;border:1px dashed gray}kritzel-tooltip{z-index:10001}`;
879
925
 
880
926
  const KritzelControls = class {
881
927
  constructor(hostRef) {
@@ -887,7 +933,7 @@ const KritzelControls = class {
887
933
  activeControl = null;
888
934
  isUtilityPanelVisible = true;
889
935
  undoState = null;
890
- theme;
936
+ theme = 'light';
891
937
  isControlsReady;
892
938
  firstConfig = null;
893
939
  isTouchDevice = KritzelDevicesHelper.isTouchDevice();
@@ -1107,13 +1153,13 @@ const KritzelControls = class {
1107
1153
  // Separate tool controls from config control
1108
1154
  const toolControls = this.internalControls.filter(c => c.type === 'tool' || c.type === 'separator');
1109
1155
  const configControl = this.internalControls.find(c => c.type === 'config' && c.name === this.firstConfig?.name);
1110
- return (h(Host, { key: '7f2a5fed45ac89b34a86b87552ffaa1b94f44d8b', class: {
1156
+ return (h(Host, { key: 'b567aac7bca12cc5ffb0ee1eb9e6978636aa3c31', class: {
1111
1157
  mobile: this.isTouchDevice,
1112
- } }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: '2dcbbe498bce0b59fbd225d103f2e322d3b7ff85', style: {
1158
+ } }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: '88e8ae9ae7429987724df70895b02a3f59216364', style: {
1113
1159
  position: 'absolute',
1114
1160
  bottom: '56px',
1115
1161
  left: '12px',
1116
- }, undoState: this.undoState, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), h("div", { key: '6431079040502a78f021c612a7e953b1349f319a', class: "kritzel-controls" }, h("div", { key: '6e0d6dce107cf6b54fb904809fd525ce3b2ae4f0', class: { 'scroll-indicator-left': true, 'visible': this.canScrollLeft } }), h("div", { key: '2686304ad10deac2d022e1deba19195587659d64', class: "kritzel-tools-scroll", ref: el => (this.toolsScrollRef = el), onScroll: this.handleToolsScroll }, toolControls.map(control => {
1162
+ }, undoState: this.undoState, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), h("div", { key: '658e3d7b94e49a002d5057c1fb4fc199a371c48d', class: "kritzel-controls" }, h("div", { key: 'b54bb52a43e4a94ae1148cd4e75528bcaad681ef', class: { 'scroll-indicator-left': true, 'visible': this.canScrollLeft } }), h("div", { key: '36ce760357d3228141281a45c0ac7b0024b04795', class: "kritzel-tools-scroll", ref: el => (this.toolsScrollRef = el), onScroll: this.handleToolsScroll }, toolControls.map(control => {
1117
1163
  // Check if this control has sub-options (split-button)
1118
1164
  if (control.subOptions?.length) {
1119
1165
  const selectedSubOption = this.getSelectedSubOption(control);
@@ -1143,10 +1189,10 @@ const KritzelControls = class {
1143
1189
  'kritzel-control': true,
1144
1190
  'selected': this.activeControl?.name === control?.name,
1145
1191
  }, key: control.name, "data-testid": `tool-${control.name}`, onClick: _event => this.handleControlClick?.(control), "aria-label": control.name.charAt(0).toUpperCase() + control.name.slice(1) }, h("kritzel-icon", { name: control.icon })));
1146
- })), h("div", { key: 'f4bcbc856f6e027cdb579356faf54288b43aa080', class: { 'scroll-indicator-right': true, 'visible': this.canScrollRight && !(configControl && this.activeControl && hasConfigUI) } }), configControl && this.activeControl && (h("div", { class: {
1192
+ })), h("div", { key: 'f0b1e0f74fe197f4d39e307e7dd8dd4819c4b183', class: { 'scroll-indicator-right': true, 'visible': this.canScrollRight && !(configControl && this.activeControl && hasConfigUI) } }), configControl && this.activeControl && (h("div", { class: {
1147
1193
  'kritzel-config-container': true,
1148
1194
  'visible': hasConfigUI,
1149
- }, key: configControl.name }, h("div", { key: '0646c98b32047f51841f75dd5fb57813ebb153f5', class: { 'config-gradient-left': true, 'visible': this.needsScrolling } }), h("kritzel-tooltip", { key: '0816b8d7ca55add3c6a81de788be3c61a8a814f2', anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), triggerElement: this.configTriggerRef }, h("kritzel-tool-config", { key: '8f299593454e7855d83ad5d79b528940b2dcb202', tool: this.activeControl.tool, theme: this.theme, engine: this.kritzelEngine, onToolChange: event => this.handleToolChange?.(event), onDisplayValuesChange: this.handleDisplayValuesChange, style: { width: '100%', height: '100%' } })), h("div", { key: '8b2dc1dcc61df93a92cea8ba2aeb776e57965ab3', tabIndex: hasConfigUI ? 0 : -1, class: "kritzel-config", "data-testid": "tool-config", ref: el => {
1195
+ }, key: configControl.name }, h("div", { key: '51cc3ebf13092e710048441ff64856edd4f53dfc', class: { 'config-gradient-left': true, 'visible': this.needsScrolling } }), h("kritzel-tooltip", { key: 'dcace186ae3ece1d7e943f51b48ed5094d847284', anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), triggerElement: this.configTriggerRef }, h("kritzel-tool-config", { key: '9b16ac90f335fec3c043545fa0c5b363ab99924e', tool: this.activeControl.tool, theme: this.theme, engine: this.kritzelEngine, onToolChange: event => this.handleToolChange?.(event), onDisplayValuesChange: this.handleDisplayValuesChange, style: { width: '100%', height: '100%' } })), h("div", { key: '2425507968e27a01b66c1d7be79a40ebe77cd27d', tabIndex: hasConfigUI ? 0 : -1, class: "kritzel-config", "data-testid": "tool-config", ref: el => {
1150
1196
  if (el)
1151
1197
  this.configTriggerRef = el;
1152
1198
  }, onKeyDown: event => {
@@ -1155,7 +1201,7 @@ const KritzelControls = class {
1155
1201
  }
1156
1202
  }, style: {
1157
1203
  cursor: 'pointer',
1158
- } }, this.displayValues && (h("div", { key: '1074fc05048aed92ec9d62e347822df0a57a80e4', class: "color-container" }, h("kritzel-color", { key: '222efa6883ccbc6c97d10360039a1315de7d6273', value: this.displayValues.color, theme: this.theme, size: 18, style: {
1204
+ } }, this.displayValues && (h("div", { key: 'd2499df3c0a90c101957f55664452739e0f1692b', class: "color-container" }, h("kritzel-color", { key: 'b7cfcd3a8579c63f508c2786eecace1223e88974', value: this.displayValues.color, theme: this.theme, size: 18, style: {
1159
1205
  borderRadius: '50%',
1160
1206
  border: 'none',
1161
1207
  } })))))))));
@@ -1193,7 +1239,7 @@ const KritzelCurrentUser = class {
1193
1239
  this.dialogRef?.open();
1194
1240
  };
1195
1241
  render() {
1196
- return (h(Host, { key: 'c392caf731f8352fd8e2a95918fe48a2f00dd9e5' }, h("kritzel-avatar", { key: 'b3bdce0efa0c0610aa028303386c643d53bc8300', user: this.user, size: this.avatarSize, onClick: this.handleAvatarClick }), h("kritzel-current-user-dialog", { key: '5e7af1aea468028e091ad8f461e4352cb9f9636b', ref: el => (this.dialogRef = el), user: this.user })));
1242
+ return (h(Host, { key: 'a735cb9f16f4898fde0b52573affa2d270a8f1de' }, h("kritzel-avatar", { key: 'd449a515182718ab4ef3b26b2277696bbc7ab46f', user: this.user, size: this.avatarSize, onClick: this.handleAvatarClick }), h("kritzel-current-user-dialog", { key: '3542f6df43c9924218e344f70bdc398c74a8eae6', ref: el => (this.dialogRef = el), user: this.user })));
1197
1243
  }
1198
1244
  };
1199
1245
  KritzelCurrentUser.style = kritzelCurrentUserCss();
@@ -1225,7 +1271,7 @@ const KritzelCurrentUserDialog = class {
1225
1271
  }
1226
1272
  render() {
1227
1273
  const displayName = this.getDisplayName();
1228
- return (h(Host, { key: 'e1dd44cdfdbaebfe886fed0d9feba2ef232b6615' }, h("kritzel-dialog", { key: 'cd3daa7abd53c10852d63a2fe53d919414cd8904', dialogTitle: "Account", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, h("div", { key: '94d0a691ede73135e6cf4ef144c13e52e410ffbe', class: "user-info" }, h("kritzel-avatar", { key: 'e57592d2f3663b593534055be5aae1b224fa8906', user: this.user, size: 80 }), displayName && h("div", { key: '237db2d0608ee49ea70e5282b61a59077f0f4595', class: "user-name" }, displayName), this.user?.email && h("div", { key: 'd821e8171530b92ce6f1781c1145b611d3c533d0', class: "user-email" }, this.user.email)))));
1274
+ return (h(Host, { key: '40c1a1bed0ddf02f9835199b5f7d2363e4d1902b' }, h("kritzel-dialog", { key: 'a83c09eac66ddf51155591a32245e3f15e34943e', dialogTitle: "Account", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, h("div", { key: '14f7100a881ee3c5ba6b672d509bf3a9161ccd62', class: "user-info" }, h("kritzel-avatar", { key: 'e3552a80db81db4c26f81c6cc699363afa6153ea', user: this.user, size: 80 }), displayName && h("div", { key: 'c54164be605ac2bd2fc8bac6bb4481f820119028', class: "user-name" }, displayName), this.user?.email && h("div", { key: 'e6af7c44e45443eb24be0777768de96b0e3d249e', class: "user-email" }, this.user.email)))));
1229
1275
  }
1230
1276
  };
1231
1277
  KritzelCurrentUserDialog.style = kritzelCurrentUserDialogCss();
@@ -1298,7 +1344,7 @@ const KritzelCursorTrail = class {
1298
1344
  }
1299
1345
  }
1300
1346
  render() {
1301
- return (h(Host, { key: '2e40e68375f4b8b4531181d249c1638a01d9dac5' }, this.cursorTrailPoints.length > 1 && (h("svg", { key: 'c015f003cc5f4c5c532803846fa5201edf4c211a', class: "cursor-trail-svg", xmlns: "http://www.w3.org/2000/svg", style: {
1347
+ return (h(Host, { key: 'b427550b19a3e172cb25d05e34635121b82a61c5' }, this.cursorTrailPoints.length > 1 && (h("svg", { key: '9685b563497e110f36c0feffbfde04ebeb38024b', class: "cursor-trail-svg", xmlns: "http://www.w3.org/2000/svg", style: {
1302
1348
  position: 'absolute',
1303
1349
  left: '0',
1304
1350
  top: '0',
@@ -1889,13 +1935,13 @@ const KritzelDropdown = class {
1889
1935
  }
1890
1936
  updateInternalValue(proposedValue, emitChange) {
1891
1937
  let finalValue = proposedValue;
1892
- if (this.options && this.options.length > 0) {
1893
- const isValidValue = this.options.some(opt => opt.value === finalValue);
1894
- if (!finalValue || !isValidValue) {
1895
- finalValue = this.options[0].value;
1896
- }
1938
+ // Only fall back to an option if the proposed value is completely missing.
1939
+ // We intentionally don't sanitize invalid values here, to allow for values
1940
+ // that might be added to options asynchronously later (preventing race conditions).
1941
+ if (!finalValue && this.options && this.options.length > 0) {
1942
+ finalValue = this.options[0].value;
1897
1943
  }
1898
- else {
1944
+ else if (!finalValue) {
1899
1945
  finalValue = undefined;
1900
1946
  }
1901
1947
  if (this.internalValue !== finalValue) {
@@ -2067,7 +2113,7 @@ const KritzelDropdown = class {
2067
2113
  'open-up': this.openDirection === 'up',
2068
2114
  'open-down': this.openDirection === 'down',
2069
2115
  };
2070
- return (h(Host, { key: 'ac4dc8a445f79fa68555756a4ac26ba174a13eaa' }, h("div", { key: '1c73835be42e6a289657920ef33c2a53c183913d', class: "dropdown-wrapper", ref: el => (this.wrapperElement = el) }, h("slot", { key: 'ac73d76b5e24e2f2740113523524bc00d1c98d02', name: "prefix", ref: el => (this.prefixSlotElement = el), onSlotchange: this.evaluatePrefixContent }), h("div", { key: 'e1e71c68a8abb2cf0dc2b9314e05d1170c0bb5b3', class: "dropdown-container", style: { width: this.width } }, h("button", { key: '74588e1ff661f8f86318a2ed9bb53192ad96bacd', type: "button", class: triggerClasses, style: { ...this.selectStyles, ...this.getSelectedStyle() }, onClick: this.toggleMenu, onKeyDown: this.handleTriggerKeyDown, "aria-haspopup": "listbox", "aria-expanded": this.isOpen ? 'true' : 'false', ref: el => (this.triggerElement = el) }, h("span", { key: '432f694526e20e1e6abb6721f12aa246471d830d', class: "dropdown-trigger-label" }, this.getSelectedLabel()), h("span", { key: '81f7d98f78201910f4427a7c442172d0283de45b', class: "dropdown-trigger-arrow", "aria-hidden": "true" }, h("svg", { key: '18db309dc145718fbb3d51e44058e3bfa96b0d27', xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polyline", { key: '32af6ce9a1f045c2ce3b205b1b1dc1fe1a80e227', points: "6 9 12 15 18 9" }))))), h("slot", { key: 'b37cd43daa06424ea7b7951929352154f7d1ea0f', name: "suffix", ref: el => (this.suffixSlotElement = el), onSlotchange: this.evaluateSuffixContent }), h("ul", { key: '0e673d4e09e007a4c93ed6a992dddeb8eba33e91', class: menuClasses, role: "listbox", tabindex: "-1", onKeyDown: this.handleMenuKeyDown, ref: el => (this.menuElement = el) }, this.options.map((option, index) => {
2116
+ return (h(Host, { key: 'c606b338e55dc66396105fa7b4fbdf372f3866e6' }, h("div", { key: 'aa32b73cac337fa4142ecc124cf039a59e3b3118', class: "dropdown-wrapper", ref: el => (this.wrapperElement = el) }, h("slot", { key: '2cd8e9ef246a24c49d58f76f227f36aed4786178', name: "prefix", ref: el => (this.prefixSlotElement = el), onSlotchange: this.evaluatePrefixContent }), h("div", { key: '80df8155e1907017d508e92f155bab5ae12dffab', class: "dropdown-container", style: { width: this.width } }, h("button", { key: 'd86463de7ec58248f1611d6b5d46f0eafc117f36', type: "button", class: triggerClasses, style: { ...this.selectStyles, ...this.getSelectedStyle() }, onClick: this.toggleMenu, onKeyDown: this.handleTriggerKeyDown, "aria-haspopup": "listbox", "aria-expanded": this.isOpen ? 'true' : 'false', ref: el => (this.triggerElement = el) }, h("span", { key: '4ef6a997f7a781fb409e97ed5bd6843d0eaff0bb', class: "dropdown-trigger-label" }, this.getSelectedLabel()), h("span", { key: '6601efcd69d84af1f022d14ede628bac743cc1f1', class: "dropdown-trigger-arrow", "aria-hidden": "true" }, h("svg", { key: '6cb2efe7b4ca890562c10b0e24eb1dfdad90ec24', xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polyline", { key: 'a340af5a61dccf5bc29c8a473726b58055c2e9db', points: "6 9 12 15 18 9" }))))), h("slot", { key: '5bd4e5ad4cc4642c7769ecac2106ba82bae626f2', name: "suffix", ref: el => (this.suffixSlotElement = el), onSlotchange: this.evaluateSuffixContent }), h("ul", { key: 'e7a2be8ac261bc5fa1450940e2a57090d6be3315', class: menuClasses, role: "listbox", tabindex: "-1", onKeyDown: this.handleMenuKeyDown, ref: el => (this.menuElement = el) }, this.options.map((option, index) => {
2071
2117
  const isSelected = option.value === this.internalValue;
2072
2118
  const isFocused = index === this.focusedIndex;
2073
2119
  const optionClasses = {
@@ -2289,6 +2335,8 @@ const KritzelEditor = class {
2289
2335
  },
2290
2336
  { label: 'Delete', icon: 'delete', group: 'edit', action: () => this.engineRef.delete() },
2291
2337
  ];
2338
+ themes;
2339
+ theme = 'light';
2292
2340
  customSvgIcons = {};
2293
2341
  isControlsVisible = true;
2294
2342
  isUtilityPanelVisible = true;
@@ -2335,9 +2383,9 @@ const KritzelEditor = class {
2335
2383
  isVirtualKeyboardOpen = false;
2336
2384
  undoState = null;
2337
2385
  isBackToContentButtonVisible = false;
2338
- currentTheme = 'light';
2339
2386
  shortcuts = [];
2340
2387
  currentIsPublic = false;
2388
+ isEditorVisible = false;
2341
2389
  onIsEngineReady(newValue) {
2342
2390
  if (newValue && this.isControlsReady) {
2343
2391
  this.checkIsReady();
@@ -2389,11 +2437,15 @@ const KritzelEditor = class {
2389
2437
  }
2390
2438
  }
2391
2439
  onCurrentThemeChange() {
2440
+ this.applyTheme();
2392
2441
  setTimeout(() => this.setOsSpecificCssVariables(), 0);
2393
2442
  if (this.engineRef) {
2394
2443
  this.engineRef.saveSettings(this.currentSettingsConfig);
2395
2444
  }
2396
2445
  }
2446
+ onThemesChange() {
2447
+ this.applyTheme();
2448
+ }
2397
2449
  onTouchStart(event) {
2398
2450
  if (event.cancelable) {
2399
2451
  event.preventDefault();
@@ -2535,6 +2587,12 @@ const KritzelEditor = class {
2535
2587
  async exportViewportAsSvg() {
2536
2588
  return this.engineRef.exportViewportAsSvg();
2537
2589
  }
2590
+ async exportSelectedObjectsAsPng() {
2591
+ return this.engineRef.exportSelectedObjectsAsPng();
2592
+ }
2593
+ async exportSelectedObjectsAsSvg() {
2594
+ return this.engineRef.exportSelectedObjectsAsSvg();
2595
+ }
2538
2596
  async downloadAsJson(filename) {
2539
2597
  return this.engineRef.downloadAsJson(filename);
2540
2598
  }
@@ -2562,6 +2620,9 @@ const KritzelEditor = class {
2562
2620
  async hideContextMenu() {
2563
2621
  return this.engineRef.hideContextMenu();
2564
2622
  }
2623
+ async openContextMenu(options) {
2624
+ return this.engineRef.openContextMenu(options);
2625
+ }
2565
2626
  async triggerSelectionChange() {
2566
2627
  return this.engineRef.triggerSelectionChange();
2567
2628
  }
@@ -2577,6 +2638,15 @@ const KritzelEditor = class {
2577
2638
  loginDialogRef;
2578
2639
  componentWillLoad() {
2579
2640
  this.loadSettingsFromStorage();
2641
+ this.applyTheme();
2642
+ }
2643
+ applyTheme() {
2644
+ const themeObj = this.resolveThemeObject();
2645
+ ThemeHelper.applyThemeToElement(this.host, themeObj);
2646
+ }
2647
+ resolveThemeObject() {
2648
+ return this.themes?.find(t => t.name === this.theme)
2649
+ ?? (this.theme === 'dark' ? darkTheme : lightTheme);
2580
2650
  }
2581
2651
  componentDidLoad() {
2582
2652
  this.registerCustomSvgIcons();
@@ -2591,6 +2661,7 @@ const KritzelEditor = class {
2591
2661
  if (!this.isEngineReady || !this.isControlsReady || !this.isWorkspaceManagerReady || !this.activeWorkspace) {
2592
2662
  return;
2593
2663
  }
2664
+ this.isEditorVisible = true;
2594
2665
  const { id, name, isPublic, createdAt, updatedAt } = this.activeWorkspace;
2595
2666
  this.isReady.emit({
2596
2667
  host: this.host,
@@ -2604,6 +2675,7 @@ const KritzelEditor = class {
2604
2675
  syncConfig: this.syncConfig,
2605
2676
  assetStorageConfig: this.assetStorageConfig,
2606
2677
  loginConfig: this.loginConfig,
2678
+ theme: this.theme
2607
2679
  });
2608
2680
  }
2609
2681
  async onEngineReady(event) {
@@ -2617,6 +2689,7 @@ const KritzelEditor = class {
2617
2689
  this.loadShortcuts();
2618
2690
  }
2619
2691
  handleWorkspacesChange(event) {
2692
+ event.stopPropagation();
2620
2693
  this.workspaces = event.detail;
2621
2694
  }
2622
2695
  handleActiveWorkspaceChange(event) {
@@ -2635,46 +2708,54 @@ const KritzelEditor = class {
2635
2708
  });
2636
2709
  }
2637
2710
  handleObjectsChange(event) {
2711
+ event.stopPropagation();
2638
2712
  this.objectsChange.emit(event.detail);
2639
2713
  }
2640
2714
  handleObjectsAdded(event) {
2715
+ event.stopPropagation();
2641
2716
  this.objectsAdded.emit(event.detail);
2642
2717
  }
2643
2718
  handleObjectsRemoved(event) {
2719
+ event.stopPropagation();
2644
2720
  this.objectsRemoved.emit(event.detail);
2645
2721
  }
2646
2722
  handleObjectsUpdated(event) {
2723
+ event.stopPropagation();
2647
2724
  this.objectsUpdated.emit(event.detail);
2648
2725
  }
2649
2726
  handleUndoStateChange(event) {
2727
+ event.stopPropagation();
2650
2728
  this.undoStateChange.emit(event.detail);
2651
2729
  this.undoState = event.detail;
2652
2730
  }
2653
2731
  async handleObjectsInViewportChange(event) {
2732
+ event.stopPropagation();
2654
2733
  const hasVisibleObjects = this.getContentObjects(event.detail).length > 0;
2655
2734
  const hasAnyObjectsAtAll = this.getContentObjects(await this.engineRef.getAllObjects()).length > 0;
2656
2735
  this.isBackToContentButtonVisible = !hasVisibleObjects && hasAnyObjectsAtAll;
2657
2736
  }
2658
2737
  handleViewportChange(event) {
2738
+ event.stopPropagation();
2659
2739
  this.viewportChange.emit(event.detail);
2660
2740
  }
2661
2741
  handleAwarenessChange(event) {
2742
+ event.stopPropagation();
2662
2743
  this.awarenessChange.emit(event.detail);
2663
2744
  }
2664
2745
  handleSettingsChange(event) {
2665
2746
  this.scaleMin = event.detail.scaleMin;
2666
2747
  this.scaleMax = event.detail.scaleMax;
2667
2748
  this.lockDrawingScale = event.detail.lockDrawingScale;
2668
- this.currentTheme = event.detail.theme;
2749
+ this.theme = event.detail.theme;
2669
2750
  this.viewportBoundaryLeft = event.detail.viewportBoundaryLeft ?? -Infinity;
2670
2751
  this.viewportBoundaryRight = event.detail.viewportBoundaryRight ?? Infinity;
2671
2752
  this.viewportBoundaryTop = event.detail.viewportBoundaryTop ?? -Infinity;
2672
2753
  this.viewportBoundaryBottom = event.detail.viewportBoundaryBottom ?? Infinity;
2673
2754
  this.debugInfo = event.detail.debugInfo;
2674
- this.themeChange.emit(event.detail.theme);
2675
2755
  if (this.engineRef) {
2676
2756
  this.engineRef.saveSettings(event.detail);
2677
2757
  }
2758
+ this.themeChange.emit(event.detail.theme);
2678
2759
  }
2679
2760
  get moreMenuItems() {
2680
2761
  return [
@@ -2770,8 +2851,8 @@ const KritzelEditor = class {
2770
2851
  if (typeof parsed.lockDrawingScale === 'boolean') {
2771
2852
  this.lockDrawingScale = parsed.lockDrawingScale;
2772
2853
  }
2773
- if (parsed.theme === 'light' || parsed.theme === 'dark') {
2774
- this.currentTheme = parsed.theme;
2854
+ if (typeof parsed.theme === 'string') {
2855
+ this.theme = parsed.theme;
2775
2856
  }
2776
2857
  if (typeof parsed.viewportBoundaryLeft === 'number') {
2777
2858
  this.viewportBoundaryLeft = parsed.viewportBoundaryLeft;
@@ -2802,7 +2883,7 @@ const KritzelEditor = class {
2802
2883
  scaleMin: this.scaleMin,
2803
2884
  scaleMax: this.scaleMax,
2804
2885
  lockDrawingScale: this.lockDrawingScale,
2805
- theme: this.currentTheme,
2886
+ theme: this.theme,
2806
2887
  viewportBoundaryLeft: this.viewportBoundaryLeft,
2807
2888
  viewportBoundaryRight: this.viewportBoundaryRight,
2808
2889
  viewportBoundaryTop: this.viewportBoundaryTop,
@@ -2855,28 +2936,32 @@ const KritzelEditor = class {
2855
2936
  render() {
2856
2937
  const isLoggedIn = this.isLoggedIn;
2857
2938
  const shouldShowCurrentUser = isLoggedIn;
2858
- const shouldShowLoginButton = !!this.loginConfig && !isLoggedIn;
2859
- return (h(Host, { key: '2856db9fa6a0926df078d5d6eedb19d2b4de98a5' }, h("div", { key: '7ffad0fd28904b740af43e20addfef701bbcead9', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: '0639e3d0f1a91935d42c10d5dfa793fd595cc234', 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: '0039bc16615c26ab239ceeac418a7d47ff2ad40a', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), h("kritzel-engine", { key: '4815e1c4dfc6a04e68894b795c02dd678fec108d', ref: el => {
2939
+ const shouldShowLoginButton = this.isReady && !!this.loginConfig && !isLoggedIn;
2940
+ return (h(Host, { key: '3606d2318e6811f2f4b647f1531ff8bda409a401', style: {
2941
+ opacity: this.isEditorVisible ? '1' : '0',
2942
+ visibility: this.isEditorVisible ? 'visible' : 'hidden',
2943
+ transition: 'opacity 0.2s ease-in-out, visibility 0.2s ease-in-out',
2944
+ } }, h("div", { key: '094e66c69a829a3d150cd672f66f3f092cf19623', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: 'b31a64b26f0f13a24bc07f2a5db8230ebc0377e2', 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: '9768ead0daf60292c649a0ccdb4dcd92d8ce342a', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), h("kritzel-engine", { key: 'cf4cf487da19cd10352a31dab4e50db4aaabfd7a', ref: el => {
2860
2945
  if (el) {
2861
2946
  this.engineRef = el;
2862
2947
  }
2863
- }, workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, assetStorageConfig: this.assetStorageConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, 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.currentTheme, 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: 'fc44c417ee17a98f2b5d8eecffac6a86e43fda2a', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => {
2948
+ }, workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, assetStorageConfig: this.assetStorageConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, 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: 'eb0839b834e688f15461ebd7391c87b331a5b328', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => {
2864
2949
  if (el) {
2865
2950
  this.controlsRef = el;
2866
2951
  }
2867
- }, controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.currentTheme, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'f333d2b31d456d4e35dbd41c93492329939a7c4d', class: "top-right-buttons" }, h("kritzel-settings", { key: '7900c9b1c3fd35e07e0d2a2aa0b797f455f52e1d', ref: el => {
2952
+ }, controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'e5c14a118d245ef0ec1c5863eb21022a5e5d7c77', class: "top-right-buttons" }, h("kritzel-settings", { key: 'bad9ebae5bc91efaf388e525375ba263f0344374', ref: el => {
2868
2953
  if (el) {
2869
2954
  this.settingsRef = el;
2870
2955
  }
2871
- }, shortcuts: this.shortcuts, settings: this.currentSettingsConfig, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: 'c6ad8ae5255c9d90d854b7a26e81b65cfdc6236d', ref: el => {
2956
+ }, 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: 'ca28cd1057181b347af75ea51950114272bf33ec', ref: el => {
2872
2957
  if (el) {
2873
2958
  this.exportRef = el;
2874
2959
  }
2875
- }, 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: '3d6d3c460e5954b4d477c6bcc9992e503f781a81', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '33a72ce69276082ca7cc2815a93ad14de8dcf5a0', user: this.user }), shouldShowLoginButton && h("kritzel-button", { key: '809dedeacbf89674e42ab3e5850e67aadfe1111c', onButtonClick: () => this.loginDialogRef?.open() }, "Sign in"), h("kritzel-more-menu", { key: '7521045a24e32e6aa69a5a8c41a4edea5d657d93', items: this.moreMenuItems, visible: this.isMoreMenuVisible }), h("kritzel-share-dialog", { key: 'a4e778dee23b3dba94109c141e3628f22b740355', ref: el => {
2960
+ }, 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: '1b667e832c1f231ecdd9ea0cca0504c6f4a82ce1', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: 'ec0a1827625f79435d20b8d53374eb29e7174f7e', user: this.user }), shouldShowLoginButton && (h("kritzel-button", { key: '0ddec61cc09b96797c33ae18c225ec967efed3e8', onButtonClick: () => this.loginDialogRef?.open() }, "Sign in")), h("kritzel-more-menu", { key: 'e9d41eff38bbd4e9420f8586559597f8ec9d6802', items: this.moreMenuItems, visible: this.isMoreMenuVisible }), h("kritzel-share-dialog", { key: 'f3fd8a06f5cf0ac89c02d535ee30dec05c9e536f', ref: el => {
2876
2961
  if (el) {
2877
2962
  this.shareDialogRef = el;
2878
2963
  }
2879
- }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: '3394d489bdbc92c572208c8f65601bf91568f0c4', ref: el => {
2964
+ }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: '49bd9f85d4cb7ee0f8dc7d2b7248169848c36b9f', ref: el => {
2880
2965
  if (el) {
2881
2966
  this.loginDialogRef = el;
2882
2967
  }
@@ -2898,8 +2983,11 @@ const KritzelEditor = class {
2898
2983
  "activeWorkspaceId": [{
2899
2984
  "onActiveWorkspaceIdChange": 0
2900
2985
  }],
2901
- "currentTheme": [{
2986
+ "theme": [{
2902
2987
  "onCurrentThemeChange": 0
2988
+ }],
2989
+ "themes": [{
2990
+ "onThemesChange": 0
2903
2991
  }]
2904
2992
  }; }
2905
2993
  };
@@ -21129,6 +21217,60 @@ class KritzelContextMenuHandler extends KritzelBaseHandler {
21129
21217
  this._core.store.state.isEnabled = false;
21130
21218
  this._core.rerender();
21131
21219
  }
21220
+ /**
21221
+ * Programmatically opens the context menu at a specified world-coordinate position.
21222
+ * If an objectId is provided and found, the object context menu is shown for that object.
21223
+ * If no objectId is provided but a selection group exists, the object context menu is shown.
21224
+ * Otherwise, the global context menu is shown.
21225
+ * @param options.x - The X position in world (canvas) coordinates.
21226
+ * @param options.y - The Y position in world (canvas) coordinates.
21227
+ * @param options.objectId - Optional ID of an object to select and show the object context menu for.
21228
+ */
21229
+ open(options) {
21230
+ const { x, y, objectId } = options;
21231
+ if (this._core.store.state.activeTool instanceof KritzelSelectionTool) {
21232
+ const selectionTool = this._core.store.state.activeTool;
21233
+ selectionTool?.moveHandler?.cancelPendingDrag();
21234
+ }
21235
+ if (this._core.store.selectionBox) {
21236
+ this._core.store.objects.remove(object => object instanceof KritzelSelectionBox);
21237
+ this._core.store.setSelectionBox(null);
21238
+ this._core.store.state.isSelecting = false;
21239
+ }
21240
+ if (objectId) {
21241
+ const targetObject = this._core.store.allObjects.find(obj => obj.id === objectId);
21242
+ if (targetObject && !(targetObject instanceof KritzelSelectionGroup) && !(targetObject instanceof KritzelSelectionBox)) {
21243
+ const selectionGroup = KritzelSelectionGroup.create(this._core);
21244
+ selectionGroup.addOrRemove(targetObject);
21245
+ selectionGroup.isSelected = true;
21246
+ selectionGroup.rotation = targetObject.rotation;
21247
+ this._core.store.state.isSelecting = false;
21248
+ const currentSelectionGroup = this._core.store.selectionGroup;
21249
+ if (currentSelectionGroup) {
21250
+ this._core.removeSelectionGroup();
21251
+ }
21252
+ this._core.addSelectionGroup(selectionGroup);
21253
+ }
21254
+ }
21255
+ this._core.store.state.contextMenuItems = this._core.store.selectionGroup ? this.objectContextMenuItems : this.globalContextMenuItems;
21256
+ this._core.store.state.contextMenuWorldX = x;
21257
+ this._core.store.state.contextMenuWorldY = y;
21258
+ const { translateX, translateY, scale } = this._core.store.state;
21259
+ let screenX = x * scale + translateX;
21260
+ let screenY = y * scale + translateY;
21261
+ const menuWidthEstimate = 150;
21262
+ const margin = 10;
21263
+ if (screenX + menuWidthEstimate > this._core.store.state.viewportWidth - margin) {
21264
+ screenX = this._core.store.state.viewportWidth - menuWidthEstimate - margin;
21265
+ }
21266
+ screenX = Math.max(margin, screenX);
21267
+ screenY = Math.max(margin, screenY);
21268
+ this._core.store.state.contextMenuX = screenX;
21269
+ this._core.store.state.contextMenuY = screenY;
21270
+ this._core.store.state.isContextMenuVisible = true;
21271
+ this._core.store.state.isEnabled = false;
21272
+ this._core.rerender();
21273
+ }
21132
21274
  }
21133
21275
 
21134
21276
  /**
@@ -24436,6 +24578,7 @@ class KritzelCore {
24436
24578
  });
24437
24579
  group.finalize();
24438
24580
  };
24581
+ const newlyAddedObjects = [];
24439
24582
  // First add all copied objects to the objectsMap with updated positions
24440
24583
  copiedObjects.forEach((obj, i) => {
24441
24584
  // Update workspace if pasting to a different workspace
@@ -24452,9 +24595,11 @@ class KritzelCore {
24452
24595
  }
24453
24596
  // Add to objectsMap
24454
24597
  this.addObject(obj);
24598
+ newlyAddedObjects.push(obj);
24455
24599
  // Add to selection group
24456
24600
  selectionGroup.addOrRemove(obj);
24457
24601
  });
24602
+ this.engine.emitObjectsAdded(newlyAddedObjects);
24458
24603
  // Update line anchors to point to the newly pasted objects
24459
24604
  // Only remap if the anchor target was also part of the copied selection
24460
24605
  copiedObjects.forEach(obj => {
@@ -26362,6 +26507,14 @@ const KritzelEngine = class {
26362
26507
  onThemeChange(newValue) {
26363
26508
  this.core.themeManager.setTheme(newValue);
26364
26509
  }
26510
+ /** An array of available themes for the editor. */
26511
+ themes;
26512
+ onThemesChange(newValue) {
26513
+ if (newValue && newValue.length > 0) {
26514
+ this.core.themeManager.registerThemes(newValue);
26515
+ this.core.themeManager.applyTheme(this.core.themeManager.currentTheme);
26516
+ }
26517
+ }
26365
26518
  /** Left boundary of the viewport in world coordinates. Objects beyond this X position cannot be panned to. */
26366
26519
  viewportBoundaryLeft = -Infinity;
26367
26520
  onViewportBoundaryLeftChange(newValue) {
@@ -26724,6 +26877,18 @@ const KritzelEngine = class {
26724
26877
  this.core.store.state.isEnabled = true;
26725
26878
  this.core.rerender();
26726
26879
  }
26880
+ /**
26881
+ * Programmatically opens the context menu at a specified world-coordinate position.
26882
+ * If `objectId` is provided and found, the object context menu is shown for that object.
26883
+ * If no `objectId` is provided but a selection group already exists, the object context menu is shown.
26884
+ * Otherwise, the global context menu is shown.
26885
+ * @param options.x - The X position in world (canvas) coordinates.
26886
+ * @param options.y - The Y position in world (canvas) coordinates.
26887
+ * @param options.objectId - Optional ID of an object to select and show the object context menu for.
26888
+ */
26889
+ async openContextMenu(options) {
26890
+ this.contextMenuHandler.open(options);
26891
+ }
26727
26892
  /**
26728
26893
  * Retrieves a canvas object by its unique ID.
26729
26894
  * @param id - The object's unique identifier.
@@ -27593,6 +27758,11 @@ const KritzelEngine = class {
27593
27758
  }
27594
27759
  componentWillLoad() {
27595
27760
  this.core.setEditorId(this.editorId);
27761
+ if (this.themes && this.themes.length > 0) {
27762
+ this.core.themeManager.registerThemes(this.themes);
27763
+ }
27764
+ const editorElement = this.host.closest('kritzel-editor');
27765
+ this.core.themeManager.injectThemeEarly(editorElement || this.host);
27596
27766
  this.core.setUser(this.user);
27597
27767
  this.validateScaleMax(this.scaleMax);
27598
27768
  this.validateScaleMin(this.scaleMin);
@@ -28325,6 +28495,9 @@ const KritzelEngine = class {
28325
28495
  "theme": [{
28326
28496
  "onThemeChange": 0
28327
28497
  }],
28498
+ "themes": [{
28499
+ "onThemesChange": 0
28500
+ }],
28328
28501
  "viewportBoundaryLeft": [{
28329
28502
  "onViewportBoundaryLeftChange": 0
28330
28503
  }],
@@ -28421,7 +28594,7 @@ const KritzelExport = class {
28421
28594
  return (h("div", { class: "export-tab-content" }, h("kritzel-input", { label: "Filename", value: this.exportFilename, placeholder: "Enter filename", suffix: ".json", onValueChange: this.handleFilenameChange })));
28422
28595
  }
28423
28596
  render() {
28424
- return (h(Host, { key: '5178e66f75b94697c771e2dc6fe7ce317e21cd1a' }, h("kritzel-dialog", { key: 'f80cbe3fa709ed7e046303034b7345ca1f94bc48', isOpen: this.isDialogOpen, dialogTitle: "Export", closable: true, contained: true, onDialogClose: this.closeDialog }, h("div", { key: 'e7968807c2b67ebfc800cb1694b4e34af245ffba', class: "export-content" }, h("kritzel-pill-tabs", { key: 'eac62225c4c42431296f330791a1fb2212f579f5', tabs: this.tabs, value: this.activeTab, onValueChange: this.handleTabChange }), this.activeTab === 'viewport' && this.renderViewportExport(), this.activeTab === 'workspace' && this.renderWorkspaceExport(), h("button", { key: '3489affca39a901c2ef05a0698cdf51c0a7f6d1a', class: "export-primary-button", onClick: this.handleExport }, "Export")))));
28597
+ return (h(Host, { key: 'efeea781325e672e3f4c1579a50da1c928dc88b5' }, h("kritzel-dialog", { key: '60e27233f484e70fd12bcc0f8a72b89d2f72d596', isOpen: this.isDialogOpen, dialogTitle: "Export", closable: true, contained: true, onDialogClose: this.closeDialog }, h("div", { key: 'e58e1d9804fdc8cb3d4c053ead641e2301b99ea5', class: "export-content" }, h("kritzel-pill-tabs", { key: '409f4c2d64f5477dc57c72a8e32ae0a12dfb7eda', tabs: this.tabs, value: this.activeTab, onValueChange: this.handleTabChange }), this.activeTab === 'viewport' && this.renderViewportExport(), this.activeTab === 'workspace' && this.renderWorkspaceExport(), h("button", { key: '7166aee26e0dbbdf6e7348428f7a740614948e5e', class: "export-primary-button", onClick: this.handleExport }, "Export")))));
28425
28598
  }
28426
28599
  };
28427
28600
  KritzelExport.style = kritzelExportCss();
@@ -28436,7 +28609,7 @@ const KritzelFont = class {
28436
28609
  size = 24;
28437
28610
  color = '#000000';
28438
28611
  render() {
28439
- return (h(Host, { key: 'bcff1827a61df6896e49fe1df4819bf27b3610ef' }, h("div", { key: '53a03532afde5fca6e8ec1cc78e6cd41ab1444cd', class: "font-preview", style: {
28612
+ return (h(Host, { key: '6eef9e7df004469faeeaf458d9b9967f94f8536d' }, h("div", { key: '9926c54a57245c40d605077e191f62cebf3700b1', class: "font-preview", style: {
28440
28613
  fontFamily: this.fontFamily,
28441
28614
  fontSize: `${this.size}px`,
28442
28615
  color: this.color
@@ -28483,7 +28656,7 @@ const KritzelFontFamily = class {
28483
28656
  label: option.label,
28484
28657
  style: { fontFamily: option.value },
28485
28658
  }));
28486
- return (h(Host, { key: '3d942116fc1019f1b2982395a08b14a9b0081040' }, h("kritzel-dropdown", { key: 'a042505de2d9b27c6f77ed929496a3921c3170cd', options: dropdownOptions, value: this.selectedFontFamily, onValueChanged: this.handleDropdownValueChange, selectStyles: { fontFamily: this.selectedFontFamily } })));
28659
+ return (h(Host, { key: '0123dbdff9b7051d2ebc9dcf8d1f9c7c4c161dc4' }, h("kritzel-dropdown", { key: '5d4e289161502ecc60cef3d0c6d546a64817a12a', options: dropdownOptions, value: this.selectedFontFamily, onValueChanged: this.handleDropdownValueChange, selectStyles: { fontFamily: this.selectedFontFamily } })));
28487
28660
  }
28488
28661
  };
28489
28662
  KritzelFontFamily.style = kritzelFontFamilyCss();
@@ -28511,7 +28684,7 @@ const KritzelFontSize = class {
28511
28684
  }
28512
28685
  render() {
28513
28686
  const color = 'var(--kritzel-global-text-primary)';
28514
- return (h(Host, { key: 'c409d73ff06966fd3861a16c7de32d41db85c12a' }, this.sizes.map(size => (h("div", { tabIndex: 0, class: {
28687
+ return (h(Host, { key: 'efb5ad516a0ebfea0fee5c78a1d3b4d0af4a6bc9' }, this.sizes.map(size => (h("div", { tabIndex: 0, class: {
28515
28688
  'size-container': true,
28516
28689
  'selected': this.selectedSize === size,
28517
28690
  }, onClick: () => this.handleSizeClick(size), onKeyDown: event => this.handleKeyDown(event, size) }, h("kritzel-font", { fontFamily: this.fontFamily, size: size, color: color }))))));
@@ -28578,7 +28751,7 @@ const KritzelInput = class {
28578
28751
  this.valueChange.emit(input.value);
28579
28752
  };
28580
28753
  render() {
28581
- return (h(Host, { key: 'e482edcbaf7cee8c35effbce0428c2b4dea84bd4' }, h("div", { key: 'a71f5e3eeba5e34470227ea3be4dd6731a94a52e', class: "input-container" }, this.label && h("label", { key: '757a32997f09558412952fe948fa234d1baecb3f', class: "input-label" }, this.label), h("div", { key: 'cfb13fe0041efdd9fe4a7bf2a098ff321b545b79', class: { 'input-wrapper': true, 'has-suffix': !!this.suffix } }, h("input", { key: 'b8bf209f14f15f4ad8eb0cf1be1afb1bfc958f79', type: this.type, class: "text-input", value: this.inputValue, placeholder: this.placeholder, disabled: this.disabled, onInput: this.handleInput }), this.suffix && h("span", { key: 'b5d4444609ad93c10d86978a488252b673979c94', class: "input-suffix" }, this.suffix)))));
28754
+ return (h(Host, { key: '3fd1f42a3ad5edfac752c05f70558ef73bbfebc3' }, h("div", { key: '78468652ce95508090495fefa9381af175415be8', class: "input-container" }, this.label && h("label", { key: 'f368e0370df4848fa9448ed53382152ad8cc8816', class: "input-label" }, this.label), h("div", { key: 'c775c0c0a9f4b6c78ba83ced6237a744b7d3cf20', class: { 'input-wrapper': true, 'has-suffix': !!this.suffix } }, h("input", { key: 'aa5ce0bb5e3c56755bc6134a4328ce6294bda1ff', type: this.type, class: "text-input", value: this.inputValue, placeholder: this.placeholder, disabled: this.disabled, onInput: this.handleInput }), this.suffix && h("span", { key: '687cec4294e4cd10247db88caf157b33a3f16290', class: "input-suffix" }, this.suffix)))));
28582
28755
  }
28583
28756
  static get watchers() { return {
28584
28757
  "value": [{
@@ -28660,10 +28833,10 @@ const KritzelLineEndings = class {
28660
28833
  render() {
28661
28834
  const startEnding = this.getStartEnding();
28662
28835
  const endEnding = this.getEndEnding();
28663
- return (h(Host, { key: '38bcd0b0e56c0d0fc7fd57346b718054faa0ba06' }, h("div", { key: '5ae52039756334299a86d7301b15f6874d5689ff', class: "endings-section" }, h("div", { key: '8a0dd7792498248203f2db8c346828fe7f57534d', class: "endings-row" }, this.styles.map(type => (h("button", { class: {
28836
+ return (h(Host, { key: '60115b8a2840ffe21e0846fdc2678c6ba24b22c0' }, h("div", { key: '3b63aa05ca78699172c645fdd404efdc55bc4536', class: "endings-section" }, h("div", { key: '9538369e8d2bb26600d6054ddbbc13d6c960bd56', class: "endings-row" }, this.styles.map(type => (h("button", { class: {
28664
28837
  'ending-option': true,
28665
28838
  'selected': startEnding === type,
28666
- }, onClick: () => this.handleStartChange(type), title: type === 'none' ? 'No start arrow' : `${type} start arrow` }, this.renderEndingIcon(type, true)))))), h("div", { key: '001c6cc50af45e1461ef15e2c43df4efdd83b48f', class: "endings-section" }, h("div", { key: '96cc57da4bed38aa42207d40a6a21cd39fa18cad', class: "endings-row" }, this.styles.map(type => (h("button", { class: {
28839
+ }, onClick: () => this.handleStartChange(type), title: type === 'none' ? 'No start arrow' : `${type} start arrow` }, this.renderEndingIcon(type, true)))))), h("div", { key: 'ecec29740c09a61190938bab4955ccde6b84cfa2', class: "endings-section" }, h("div", { key: 'ea054597c3e3566e7921f2c04c07d74e4f4331a1', class: "endings-row" }, this.styles.map(type => (h("button", { class: {
28667
28840
  'ending-option': true,
28668
28841
  'selected': endEnding === type,
28669
28842
  }, onClick: () => this.handleEndChange(type), title: type === 'none' ? 'No end arrow' : `${type} end arrow` }, this.renderEndingIcon(type, false))))))));
@@ -28718,7 +28891,7 @@ const KritzelLoginDialog = class {
28718
28891
  this.dialogClosed.emit();
28719
28892
  };
28720
28893
  render() {
28721
- return (h(Host, { key: '1a664868b840030a773f61c2a0f4388dfb014675' }, h("kritzel-dialog", { key: '54844ffa772a211515c1ef3e6834ec45f7f3d035', dialogTitle: this.dialogTitle, isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, h("div", { key: 'd9b981b6904c58bc39173ae37ee5c4c0ee329005', class: "login-content" }, this.subtitle && (h("p", { key: 'd4d200060507d2b8b755796d8313acdfc7e2f587', class: "login-subtitle" }, this.subtitle)), h("div", { key: '3dc1e3c070e62d026eb16ceb48eb63c94bc2bed0', class: "login-providers" }, this.providers.map(provider => (h("button", { key: provider.name, class: {
28894
+ return (h(Host, { key: '8cac83db48fef2531f1669c3f601526b1e5cdefa' }, h("kritzel-dialog", { key: '34e7208c8c34550292c2b7503759bf103cfb49a6', dialogTitle: this.dialogTitle, isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, h("div", { key: 'b0a0d8e0f38adc8d9b9545a02c5fc879f64a24de', class: "login-content" }, this.subtitle && (h("p", { key: 'a51b5f0a8b402aaf979d4bf47c6f9c3ba7e14bfe', class: "login-subtitle" }, this.subtitle)), h("div", { key: 'b6d8f8748eadf1462dd4161f089130b7ded31b59', class: "login-providers" }, this.providers.map(provider => (h("button", { key: provider.name, class: {
28722
28895
  'provider-button': true,
28723
28896
  'is-loading': this.loadingProvider === provider.name,
28724
28897
  'is-disabled': this.loadingProvider !== null && this.loadingProvider !== provider.name,
@@ -28824,15 +28997,15 @@ const KritzelMasterDetail = class {
28824
28997
  const selectedItem = this.items.find(item => item.id === this.selectedItemId);
28825
28998
  const panelId = 'master-detail-panel';
28826
28999
  const selectedTabId = selectedItem ? `tab-${selectedItem.id}` : undefined;
28827
- return (h(Host, { key: '7f1fd360f657fddcdb6ce2eea17e4e2daf426eb2' }, h("div", { key: '02f7f6dd141d057dbf395dd836f7841a649fa16d', class: {
29000
+ return (h(Host, { key: '59479b50a3e79ee854c75d78e1a41c1cb0551dab' }, h("div", { key: '0fdfa2d5a28c8f5800b2eeb80c545bdfcd252f6b', class: {
28828
29001
  'master-detail-container': true,
28829
29002
  'is-mobile-detail-visible': this.showMobileDetail,
28830
- } }, h("nav", { key: '397758627252c5e9573a61c457d4481df6d9b4f2', class: "master-menu", role: "tablist", "aria-orientation": "vertical", "aria-label": "Settings categories" }, this.items.map((item, index) => (h("button", { key: item.id, id: `tab-${item.id}`, ref: el => this.setTabRef(el, index), class: {
29003
+ } }, h("nav", { key: 'f055346bdaf528e27136dffc680a5e2c6ddb95a7', class: "master-menu", role: "tablist", "aria-orientation": "vertical", "aria-label": "Settings categories" }, this.items.map((item, index) => (h("button", { key: item.id, id: `tab-${item.id}`, ref: el => this.setTabRef(el, index), class: {
28831
29004
  'menu-item': true,
28832
29005
  'is-selected': item.id === this.selectedItemId,
28833
29006
  'is-disabled': !!item.disabled,
28834
29007
  'is-focused': index === this.focusedIndex,
28835
- }, role: "tab", "aria-selected": item.id === this.selectedItemId ? 'true' : 'false', "aria-controls": panelId, "aria-disabled": item.disabled ? 'true' : undefined, tabIndex: this.getTabIndex(item, index), disabled: item.disabled, onClick: () => this.handleItemClick(item), onKeyDown: e => this.handleKeyDown(e, item, index), onFocus: () => this.handleFocus(index), onBlur: this.handleBlur }, item.icon && (h("kritzel-icon", { name: item.icon, size: 20, class: "menu-item-icon" })), h("span", { class: "menu-item-label" }, item.label), h("span", { class: "menu-item-chevron", "aria-hidden": "true" }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { d: "m9 18 6-6-6-6" }))))))), h("div", { key: '65cc4601a39cb7780c52cc86075efd0b4a24646a', id: panelId, class: "detail-panel", role: "tabpanel", "aria-labelledby": selectedTabId }, h("button", { key: '6b6ae9ac689c757d71e2a42ecaf8aaceb3785154', class: "mobile-back-button", onClick: this.handleBackClick, "aria-label": "Back to menu" }, h("kritzel-icon", { key: '28d9b2f68030587d44505f691e8fed57d968e631', name: "chevron-left", size: 20, class: "mobile-back-icon" }), "Back"), h("slot", { key: '2a35ca82717713808ca12227ecca671b848d1f02' })))));
29008
+ }, role: "tab", "aria-selected": item.id === this.selectedItemId ? 'true' : 'false', "aria-controls": panelId, "aria-disabled": item.disabled ? 'true' : undefined, tabIndex: this.getTabIndex(item, index), disabled: item.disabled, onClick: () => this.handleItemClick(item), onKeyDown: e => this.handleKeyDown(e, item, index), onFocus: () => this.handleFocus(index), onBlur: this.handleBlur }, item.icon && (h("kritzel-icon", { name: item.icon, size: 20, class: "menu-item-icon" })), h("span", { class: "menu-item-label" }, item.label), h("span", { class: "menu-item-chevron", "aria-hidden": "true" }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { d: "m9 18 6-6-6-6" }))))))), h("div", { key: '296ff692092eae9b73c673def66539aa4eb36053', id: panelId, class: "detail-panel", role: "tabpanel", "aria-labelledby": selectedTabId }, h("button", { key: '72c65aa2825aa373daa3b1d6fd48d8dd84ab25f1', class: "mobile-back-button", onClick: this.handleBackClick, "aria-label": "Back to menu" }, h("kritzel-icon", { key: '2241991dc0da3f53f77dc415e61f026a5734ad48', name: "chevron-left", size: 20, class: "mobile-back-icon" }), "Back"), h("slot", { key: '6ecdc24e462faf0d95e295d5536b44ea2f9181c9' })))));
28836
29009
  }
28837
29010
  static get watchers() { return {
28838
29011
  "selectedItemId": [{
@@ -28905,7 +29078,7 @@ const KritzelMenu = class {
28905
29078
  this.itemCloseChildMenu.emit(event.detail);
28906
29079
  };
28907
29080
  render() {
28908
- return (h(Host, { key: 'a81ea8a1fe2dc6cb8d9f395cafbcadec3eb4aa45', tabIndex: 0, onClick: e => e.stopPropagation() }, this.openChildMenuItem && h("div", { key: 'bb27d7a923431d79567e79283e505ea4ae02ef36', class: "has-open-child-overlay", onClick: this.onOverlayClick }), this.items.map(item => (h("kritzel-menu-item", { key: item.id, "data-testid": `menu-item-${item.id}`, item: item, parent: this.parent, style: { pointerEvents: this.editingMenuItem && !item.isEditing ? 'none' : 'auto' }, onItemSelect: this.handleItemSelect, onItemSave: this.handleSave, onItemCancel: this.handleCancel, onItemToggleChildMenu: this.handleToggleChildMenu, onItemCloseChildMenu: this.handleCloseChildMenu })))));
29081
+ return (h(Host, { key: '2d6d46fc8135133ed3e42d65399c8549bc5f6bb5', tabIndex: 0, onClick: e => e.stopPropagation() }, this.openChildMenuItem && h("div", { key: 'b5b3910cc82f7cb451730792fe6e3b3a254036f3', class: "has-open-child-overlay", onClick: this.onOverlayClick }), this.items.map(item => (h("kritzel-menu-item", { key: item.id, "data-testid": `menu-item-${item.id}`, item: item, parent: this.parent, style: { pointerEvents: this.editingMenuItem && !item.isEditing ? 'none' : 'auto' }, onItemSelect: this.handleItemSelect, onItemSave: this.handleSave, onItemCancel: this.handleCancel, onItemToggleChildMenu: this.handleToggleChildMenu, onItemCloseChildMenu: this.handleCloseChildMenu })))));
28909
29082
  }
28910
29083
  };
28911
29084
  KritzelMenu.style = kritzelMenuCss();
@@ -29010,12 +29183,12 @@ const KritzelMenuItem = class {
29010
29183
  ];
29011
29184
  }
29012
29185
  render() {
29013
- return (h(Host, { key: '6fd639ff533e0b2c39febd369b4ba034661ec708', tabIndex: this.item.isDisabled ? -1 : 0, class: {
29186
+ return (h(Host, { key: 'ae5057ce9101dc08e2365455c544914715be468e', tabIndex: this.item.isDisabled ? -1 : 0, class: {
29014
29187
  'selected': this.item.isSelected,
29015
29188
  'editing': this.item.isEditing,
29016
29189
  'disabled': this.item.isDisabled,
29017
29190
  'child-open': this.item.isChildMenuOpen,
29018
- }, onClick: this.handleItemSelect }, h("div", { key: 'd7486e9f1614be1801268fa97947aaab4c12460d', class: "menu-item-overlay" }), this.item.isEditing ? this.renderEditMode() : this.renderViewMode()));
29191
+ }, onClick: this.handleItemSelect }, h("div", { key: '973fc68404ea95c2f0459565b8a3d124d31ae090', class: "menu-item-overlay" }), this.item.isEditing ? this.renderEditMode() : this.renderViewMode()));
29019
29192
  }
29020
29193
  static get watchers() { return {
29021
29194
  "item": [{
@@ -29086,7 +29259,7 @@ const KritzelMoreMenu = class {
29086
29259
  this.closeMenu();
29087
29260
  };
29088
29261
  render() {
29089
- return (h(Host, { key: '33d85e3b5ad51effdf2f61c8742dbe829ef43f15', class: { mobile: this.isTouchDevice }, style: { display: this.visible ? '' : 'none' } }, h("div", { key: '917ca25a14294f44a0428431a3ec08a84db2aff0', class: { 'more-menu-wrapper': true, visible: this.visible } }, h("button", { key: '61e145de48ac7aced1fcc03dde5d5d14f4448167', class: "more-menu-button", "data-testid": "more-menu-button", onClick: this.toggleMenu, "aria-label": "More options" }, h("kritzel-icon", { key: 'ba13d2117b28658c518c9721f348329d677683f9', name: this.icon, size: this.iconSize })), h("kritzel-portal", { key: '48d757891102ec2925366e0ca0542a6e75f2621f', anchor: this.menuAnchor, offsetY: this.offsetY, onClose: this.closeMenu }, h("kritzel-menu", { key: 'f04040f7122507642652839be4f75fbb157de20d', items: this.visibleItems, onItemSelect: this.handleMenuItemSelect })))));
29262
+ return (h(Host, { key: '93bee9fc14d532a74f1b077098fb0a470655d2fe', class: { mobile: this.isTouchDevice }, style: { display: this.visible ? '' : 'none' } }, h("div", { key: '1783013acb533de9580698f29a7c8ae212b583fc', class: { 'more-menu-wrapper': true, visible: this.visible } }, h("button", { key: '8dc2f098377e78db0bf6efc05daaf02496cef527', class: "more-menu-button", "data-testid": "more-menu-button", onClick: this.toggleMenu, "aria-label": "More options" }, h("kritzel-icon", { key: '876a229226b0f79f1d5ef5d0b7793f362b884923', name: this.icon, size: this.iconSize })), h("kritzel-portal", { key: '57f7a69408b00c1bb9e5a08d22e224c6e6bcdea4', anchor: this.menuAnchor, offsetY: this.offsetY, onClose: this.closeMenu }, h("kritzel-menu", { key: '73a2aacd1b7c0ec79d7fa1695fbc02b1a0bde1b5', items: this.visibleItems, onItemSelect: this.handleMenuItemSelect })))));
29090
29263
  }
29091
29264
  };
29092
29265
  KritzelMoreMenu.style = kritzelMoreMenuCss();
@@ -29184,7 +29357,7 @@ const KritzelNumericInput = class {
29184
29357
  this.valueChange.emit(newValue);
29185
29358
  };
29186
29359
  render() {
29187
- return (h(Host, { key: 'b27f16d562bc6c61b0a6a289e622e7e35159a782' }, h("div", { key: '7f5f2295a60b46dc05c003b10ff74e9da6822406', class: "input-container" }, this.label && h("label", { key: 'a5a10af06139312ef0b038ed8c3bb533afa6235c', class: "input-label" }, this.label), h("div", { key: 'b15b4a2d84ad1185a67cd748176c7585a0789f09', class: "input-wrapper" }, h("input", { key: '8da76a405713461ef4eb2f316af6b737493371dd', type: "number", class: "numeric-input", title: "", min: this.min === Number.MIN_SAFE_INTEGER ? undefined : this.min, max: this.max === Number.MAX_SAFE_INTEGER ? undefined : this.max, step: this.step, value: this.inputValue, placeholder: this.placeholder, onInput: this.handleInput, onBlur: this.handleBlur, onKeyDown: this.handleKeyDown, onInvalid: this.handleInvalid }), h("div", { key: '9813f61998a8902d9a1bc4100dbab744e91e98f8', class: "spinner-buttons" }, h("button", { key: 'ad688c3332b0dbdd6327c66aed778d3e0d036aab', type: "button", class: "spinner-button spinner-up", onClick: this.handleIncrement, tabIndex: -1, "aria-label": "Increase value" }, h("svg", { key: 'a21ec61f331a7b672d2ce56cd2d1b30e7f0b22c6', viewBox: "0 0 10 6", class: "spinner-icon" }, h("path", { key: 'f36b4f68ea3733851bebce1e9f45a1f36e62acdc', d: "M1 5L5 1L9 5", stroke: "currentColor", "stroke-width": "1.5", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }))), h("button", { key: '484373581f26b6cf71194bf545d67997ef7db79f', type: "button", class: "spinner-button spinner-down", onClick: this.handleDecrement, tabIndex: -1, "aria-label": "Decrease value" }, h("svg", { key: '5b9199c270ad270729b9f5c1c9246824e1d49cb8', viewBox: "0 0 10 6", class: "spinner-icon" }, h("path", { key: 'd96e78c311bbc941edfafcb02017da7c367aaf2e', d: "M1 1L5 5L9 1", stroke: "currentColor", "stroke-width": "1.5", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }))))))));
29360
+ return (h(Host, { key: '18cd66a764c334a78e2dccd444f448235b41c38c' }, h("div", { key: '73305950e3e840e51466d720a2ef4f834a16adc1', class: "input-container" }, this.label && h("label", { key: 'f9521cb0137f5f8c676ced5c76989d8d03256f68', class: "input-label" }, this.label), h("div", { key: '07581a242db247a833cfa879b90c6da5dd06b116', class: "input-wrapper" }, h("input", { key: '7faa7a9a2c8923e2b2a24c435bc47a03998ac8ad', type: "number", class: "numeric-input", title: "", min: this.min === Number.MIN_SAFE_INTEGER ? undefined : this.min, max: this.max === Number.MAX_SAFE_INTEGER ? undefined : this.max, step: this.step, value: this.inputValue, placeholder: this.placeholder, onInput: this.handleInput, onBlur: this.handleBlur, onKeyDown: this.handleKeyDown, onInvalid: this.handleInvalid }), h("div", { key: 'd3920c978a4d97032f5aec550e6ca7e74c9c2e94', class: "spinner-buttons" }, h("button", { key: 'ae27375f0ba66a9ca6cf53fe4a05fa219bf47711', type: "button", class: "spinner-button spinner-up", onClick: this.handleIncrement, tabIndex: -1, "aria-label": "Increase value" }, h("svg", { key: '8a6e40c12468bb44400c1ad015463c830d0af13e', viewBox: "0 0 10 6", class: "spinner-icon" }, h("path", { key: '70b8ee3cc3b00d7f83822078f73e0437e24a98aa', d: "M1 5L5 1L9 5", stroke: "currentColor", "stroke-width": "1.5", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }))), h("button", { key: 'e26968c85480cbf4cd0f3bd9d6db59f1d6ade88c', type: "button", class: "spinner-button spinner-down", onClick: this.handleDecrement, tabIndex: -1, "aria-label": "Decrease value" }, h("svg", { key: 'a8c72dd2909b89ceb3797d0a77e531d0b5374e1d', viewBox: "0 0 10 6", class: "spinner-icon" }, h("path", { key: '16c95c8cbc90c9d49d081745384c3920620591fb', d: "M1 1L5 5L9 1", stroke: "currentColor", "stroke-width": "1.5", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }))))))));
29188
29361
  }
29189
29362
  static get watchers() { return {
29190
29363
  "value": [{
@@ -29223,8 +29396,9 @@ const KritzelOpacitySlider = class {
29223
29396
  }
29224
29397
  render() {
29225
29398
  const percentage = this.getPercentage();
29226
- return (h(Host, { key: 'f6460d2d37ca76c69c62597b32f7567c8a2e1b77' }, h("div", { key: '09cb87f8e7e09639b4b794f9c9b30da024a4023f', class: "opacity-container" }, h("div", { key: '783cd792f0511945f685483a181b621f3c2551f8', class: "slider-wrapper" }, h("input", { key: 'd05be4ab1a2a2b19411b12358b7846bebac83a83', type: "range", class: "opacity-slider", min: this.min, max: this.max, step: this.step, value: this.value, onInput: (e) => this.handleInput(e), style: {
29399
+ return (h(Host, { key: '988ad7b9ee8d3825c8577d951c6f1d00efbb45eb' }, h("div", { key: '4dad6a7d422333fbcaff55b2b374550b496a3adc', class: "opacity-container" }, h("div", { key: '7a0ceedd10f2e939dbf189410cc7263c7df498db', class: "slider-wrapper" }, h("input", { key: '453e8fbae27023fcbf3c453445fcb8567cb5db00', type: "range", class: "opacity-slider", min: this.min, max: this.max, step: this.step, value: this.value, onInput: (e) => this.handleInput(e), style: {
29227
29400
  '--slider-progress': `${percentage}%`,
29401
+ '--kritzel-opacity-slider-thumb-border-color': this.previewColor,
29228
29402
  } })))));
29229
29403
  }
29230
29404
  };
@@ -29287,7 +29461,7 @@ const KritzelPillTabs = class {
29287
29461
  buttons?.[newIndex]?.focus();
29288
29462
  }
29289
29463
  render() {
29290
- return (h(Host, { key: 'cd6993107010e578b91af23101da27bd2ef943cd' }, h("div", { key: '509c023b5bf91de1f463c8e080b83216a94d7d64', class: "pill-tabs-container", role: "tablist" }, this.tabs.map((tab, index) => (h("button", { key: tab.id, class: {
29464
+ return (h(Host, { key: 'f02f93ada5ec002695b62f511c847de201a8cbe4' }, h("div", { key: 'bb08ae773f1b993cb330556a5778d71fc5e91ce1', class: "pill-tabs-container", role: "tablist" }, this.tabs.map((tab, index) => (h("button", { key: tab.id, class: {
29291
29465
  'pill-tab': true,
29292
29466
  'selected': this.value === tab.id,
29293
29467
  }, role: "tab", "aria-selected": this.value === tab.id ? 'true' : 'false', tabIndex: this.value === tab.id ? 0 : -1, onClick: () => this.handleTabClick(tab.id), onKeyDown: (e) => this.handleKeyDown(e, index) }, tab.icon && h("kritzel-icon", { name: tab.icon, size: 16 }), h("span", { class: "pill-tab-label" }, tab.label)))))));
@@ -29575,7 +29749,7 @@ const KritzelPortal = class {
29575
29749
  this.portal.style.visibility = 'visible';
29576
29750
  }
29577
29751
  render() {
29578
- return (h(Host, { key: 'dcd8e6f3787c713012aeb6436bf63f2f4930c39e', style: { display: this.anchor ? 'block' : 'none' } }, h("slot", { key: '830f51521a77f0a28471026494323e14ab4f9f9a' })));
29752
+ return (h(Host, { key: 'ea4b3c0bdaeb94a1aa03714537c3b68c972ad9c5', style: { display: this.anchor ? 'block' : 'none' } }, h("slot", { key: 'cd9060be1fbb801e3b72546d465576d5d79b3c82' })));
29579
29753
  }
29580
29754
  static get watchers() { return {
29581
29755
  "anchor": [{
@@ -29589,7 +29763,7 @@ const KritzelPortal = class {
29589
29763
  * This file is auto-generated by the version bump scripts.
29590
29764
  * Do not modify manually.
29591
29765
  */
29592
- const KRITZEL_VERSION = '0.3.8';
29766
+ const KRITZEL_VERSION = '0.3.10';
29593
29767
 
29594
29768
  const kritzelSettingsCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-body-padding:0;--kritzel-dialog-width-large:800px;--kritzel-dialog-height-large:500px}.footer-button{padding:8px 16px;border-radius:6px;cursor:pointer;font-size:14px}.cancel-button{border:1px solid #ebebeb;background:#fff;color:inherit}.cancel-button:hover{background:#f5f5f5}.settings-content{padding:0}.settings-content h3{margin:0 0 16px 0;font-size:18px;font-weight:600;color:var(--kritzel-settings-content-heading-color, #333333)}.settings-content p{margin:0;font-size:14px;color:var(--kritzel-settings-content-text-color, #666666);line-height:1.5}.settings-group{display:flex;flex-direction:column;gap:24px}.settings-item{display:flex;flex-direction:column;gap:8px}.settings-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.settings-label{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.settings-description{font-size:12px;color:var(--kritzel-settings-description-color, #888888);margin:0;line-height:1.4}.shortcuts-list{display:flex;flex-direction:column;gap:24px}.shortcuts-category{display:flex;flex-direction:column;gap:8px}.shortcuts-category-title{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.shortcuts-group{display:flex;flex-direction:column;gap:4px}.shortcut-item{display:flex;justify-content:space-between;align-items:center;padding:6px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-item-bg, rgba(0, 0, 0, 0.02))}.shortcut-label{font-size:14px;color:var(--kritzel-settings-content-text-color, #666666)}.shortcut-key{font-family:monospace;font-size:12px;padding:2px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-key-bg, #f0f0f0);color:var(--kritzel-settings-shortcut-key-color, #333333);border:1px solid var(--kritzel-settings-shortcut-key-border, #ddd)}`;
29595
29769
 
@@ -29620,6 +29794,7 @@ const KritzelSettings = class {
29620
29794
  }
29621
29795
  get host() { return getElement(this); }
29622
29796
  /** Keyboard shortcuts to display in the settings dialog */
29797
+ availableThemes = ['light', 'dark'];
29623
29798
  shortcuts = [];
29624
29799
  /** Current settings values. Used to initialize and sync the component's internal state. */
29625
29800
  settings;
@@ -29633,7 +29808,7 @@ const KritzelSettings = class {
29633
29808
  scaleMin = DEFAULT_SCALE_MIN;
29634
29809
  scaleMax = DEFAULT_SCALE_MAX;
29635
29810
  lockDrawingScale = DEFAULT_LOCK_DRAWING_SCALE;
29636
- currentTheme = 'light';
29811
+ theme = 'light';
29637
29812
  viewportBoundaryLeft = DEFAULT_VIEWPORT_BOUNDARY_LEFT;
29638
29813
  viewportBoundaryRight = DEFAULT_VIEWPORT_BOUNDARY_RIGHT;
29639
29814
  viewportBoundaryTop = DEFAULT_VIEWPORT_BOUNDARY_TOP;
@@ -29656,8 +29831,8 @@ const KritzelSettings = class {
29656
29831
  if (typeof settings.lockDrawingScale === 'boolean') {
29657
29832
  this.lockDrawingScale = settings.lockDrawingScale;
29658
29833
  }
29659
- if (settings.theme === 'light' || settings.theme === 'dark') {
29660
- this.currentTheme = settings.theme;
29834
+ if (typeof settings.theme === 'string') {
29835
+ this.theme = settings.theme;
29661
29836
  }
29662
29837
  if (typeof settings.viewportBoundaryLeft === 'number') {
29663
29838
  this.viewportBoundaryLeft = settings.viewportBoundaryLeft;
@@ -29680,7 +29855,7 @@ const KritzelSettings = class {
29680
29855
  scaleMin: this.scaleMin,
29681
29856
  scaleMax: this.scaleMax,
29682
29857
  lockDrawingScale: this.lockDrawingScale,
29683
- theme: this.currentTheme,
29858
+ theme: this.theme,
29684
29859
  viewportBoundaryLeft: this.viewportBoundaryLeft,
29685
29860
  viewportBoundaryRight: this.viewportBoundaryRight,
29686
29861
  viewportBoundaryTop: this.viewportBoundaryTop,
@@ -29702,7 +29877,7 @@ const KritzelSettings = class {
29702
29877
  this.emitSettings();
29703
29878
  };
29704
29879
  handleThemeChange = (event) => {
29705
- this.currentTheme = event.detail ? 'dark' : 'light';
29880
+ this.theme = event.detail;
29706
29881
  this.emitSettings();
29707
29882
  };
29708
29883
  handleViewportBoundaryLeftChange = (event) => {
@@ -29763,7 +29938,7 @@ const KritzelSettings = class {
29763
29938
  renderCategoryContent() {
29764
29939
  switch (this.selectedCategoryId) {
29765
29940
  case 'general':
29766
- return (h("div", { class: "settings-content" }, h("h3", null, "General Settings"), h("div", { class: "settings-group" }, h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, "Dark Mode"), h("p", { class: "settings-description" }, "Toggle between light and dark color themes for the editor interface."), h("kritzel-slide-toggle", { checked: this.currentTheme === 'dark', label: "Dark Mode", onCheckedChange: this.handleThemeChange })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, "Lock Drawing Scale"), h("p", { class: "settings-description" }, "When enabled, drawn objects maintain a fixed visual size regardless of the current zoom level."), h("kritzel-slide-toggle", { checked: this.lockDrawingScale, label: "Lock Drawing Scale", onCheckedChange: this.handleLockDrawingScaleChange })))));
29941
+ return (h("div", { class: "settings-content" }, h("h3", null, "General Settings"), h("div", { class: "settings-group" }, h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, "Theme"), h("p", { class: "settings-description" }, "Select a registered color theme for the editor interface."), h("kritzel-dropdown", { options: this.availableThemes.map(t => ({ value: t, label: t })), value: this.theme, onValueChanged: this.handleThemeChange })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, "Lock Drawing Scale"), h("p", { class: "settings-description" }, "When enabled, drawn objects maintain a fixed visual size regardless of the current zoom level."), h("kritzel-slide-toggle", { checked: this.lockDrawingScale, label: "Lock Drawing Scale", onCheckedChange: this.handleLockDrawingScaleChange })))));
29767
29942
  case 'viewport':
29768
29943
  return (h("div", { class: "settings-content" }, h("h3", null, "Viewport Settings"), h("div", { class: "settings-group" }, h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, "Minimum Zoom Level"), h("p", { class: "settings-description" }, "Sets the minimum zoom level. Lower values allow zooming out further to see more of the canvas."), h("kritzel-numeric-input", { value: this.scaleMin, min: 0.0001, max: 1, step: 0.0001, onValueChange: this.handleScaleMinChange })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, "Maximum Zoom Level"), h("p", { class: "settings-description" }, "Sets the maximum zoom level. Higher values allow zooming in closer for detailed work."), h("kritzel-numeric-input", { value: this.scaleMax, min: 1, max: 1000, step: 1, onValueChange: this.handleScaleMaxChange })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, "Viewport Boundary Left"), h("p", { class: "settings-description" }, "Left boundary in world coordinates. Set to limit how far left the viewport can pan."), h("kritzel-numeric-input", { value: this.viewportBoundaryLeft, step: 100, placeholder: "Infinite", onValueChange: this.handleViewportBoundaryLeftChange })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, "Viewport Boundary Right"), h("p", { class: "settings-description" }, "Right boundary in world coordinates. Set to limit how far right the viewport can pan."), h("kritzel-numeric-input", { value: this.viewportBoundaryRight, step: 100, placeholder: "Infinite", onValueChange: this.handleViewportBoundaryRightChange })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, "Viewport Boundary Top"), h("p", { class: "settings-description" }, "Top boundary in world coordinates. Set to limit how far up the viewport can pan."), h("kritzel-numeric-input", { value: this.viewportBoundaryTop, step: 100, placeholder: "Infinite", onValueChange: this.handleViewportBoundaryTopChange })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, "Viewport Boundary Bottom"), h("p", { class: "settings-description" }, "Bottom boundary in world coordinates. Set to limit how far down the viewport can pan."), h("kritzel-numeric-input", { value: this.viewportBoundaryBottom, step: 100, placeholder: "Infinite", onValueChange: this.handleViewportBoundaryBottomChange })))));
29769
29944
  case 'shortcuts':
@@ -29777,7 +29952,7 @@ const KritzelSettings = class {
29777
29952
  }
29778
29953
  }
29779
29954
  render() {
29780
- return (h(Host, { key: 'e86192a8ca49f8618d58ede4d04d321ea238d7d4' }, h("kritzel-dialog", { key: '23a47a8cd9281794bfd2aec7edd6a4ef4b931550', isOpen: this.isDialogOpen, dialogTitle: "Settings", size: "large", contained: true, onDialogClose: this.closeDialog }, h("kritzel-master-detail", { key: '007c8a1c04bd0d692b55d88988b0f8874f9242a4', items: SETTINGS_CATEGORIES, selectedItemId: this.selectedCategoryId, onItemSelect: this.handleCategorySelect }, this.renderCategoryContent()))));
29955
+ return (h(Host, { key: '46c6792ae9cdd932d3dc71526862c9281c0cefc1' }, h("kritzel-dialog", { key: '1cd288cdf8b26bea378665c54bfc14577597fe49', isOpen: this.isDialogOpen, dialogTitle: "Settings", size: "large", contained: true, onDialogClose: this.closeDialog }, h("kritzel-master-detail", { key: '4d07e94ebb09035807356bab4bc7eaca57c36c6c', items: SETTINGS_CATEGORIES, selectedItemId: this.selectedCategoryId, onItemSelect: this.handleCategorySelect }, this.renderCategoryContent()))));
29781
29956
  }
29782
29957
  static get watchers() { return {
29783
29958
  "settings": [{
@@ -29810,10 +29985,10 @@ const KritzelShapeFill = class {
29810
29985
  return (h("svg", { viewBox: "0 0 24 24", class: "fill-icon" }, h("rect", { x: "4", y: "4", width: "16", height: "16", rx: "2", fill: strokeColor, stroke: strokeColor, "stroke-width": "2" })));
29811
29986
  }
29812
29987
  render() {
29813
- return (h(Host, { key: '5f915acf7a98ac585f5aba494981cbbb38252c93' }, h("div", { key: 'e8a7fd9a1611d5cace9fbf73c1421b211a8b7d89', class: "fill-row" }, h("button", { key: 'cbd388e362c94e36220e93f55fd0140a774e0bd7', class: {
29988
+ return (h(Host, { key: '6d38a9af2e4c4c7f86ab994c63fc074007c86b48' }, h("div", { key: 'cf58f26cb0e56e274873d11024209c6908d317bb', class: "fill-row" }, h("button", { key: 'c75eed70fe0c2fcbf0fd136bb6fce75b2dbfb45d', class: {
29814
29989
  'fill-option': true,
29815
29990
  'selected': this.value === 'transparent',
29816
- }, onClick: () => this.handleFillChange('transparent'), title: "Transparent background" }, this.renderFillIcon('transparent')), h("button", { key: '532eec1936f973eb2fb44c15839400e53ac4f4f7', class: {
29991
+ }, onClick: () => this.handleFillChange('transparent'), title: "Transparent background" }, this.renderFillIcon('transparent')), h("button", { key: '5d6ede439b5d5e55598cd8c20b5851fb9f210463', class: {
29817
29992
  'fill-option': true,
29818
29993
  'selected': this.value === 'filled',
29819
29994
  }, onClick: () => this.handleFillChange('filled'), title: "Filled background" }, this.renderFillIcon('filled')))));
@@ -29908,9 +30083,9 @@ const KritzelShareDialog = class {
29908
30083
  this.dialogClosed.emit();
29909
30084
  };
29910
30085
  render() {
29911
- return (h(Host, { key: 'bd58f146337b3eca96ca34408a3d30621f01765a' }, h("kritzel-dialog", { key: '0575ac82e19d07cf909556cae2ec433e0057fd5b', dialogTitle: "Share Workspace", size: "small", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, contained: true }, h("div", { key: 'c51d207e31255f45724103bfecbe858f13a721e6', class: "share-content" }, h("div", { key: 'ca6cb7721b9ba834c133b2cb953b208475e34fb5', class: "share-section" }, h("div", { key: '2c76845c903cc1c18cc26b9111d608e732ed12a5', class: "share-row" }, h("div", { key: '7700533f54372bc81d8d795414318a6bf0e93c47', class: "share-label-group" }, h("label", { key: 'a1d80009cb09cfe35bce35ce1151bf0754b052c1', class: "share-label" }, "Link sharing"), h("p", { key: '10c1963e95e658c7fb86174f1dba7565ce40d5a6', class: "share-description" }, this.internalIsPublic
30086
+ return (h(Host, { key: 'a104c14b2492d97f3ada98c9eaaa845d63074063' }, h("kritzel-dialog", { key: '1b12b27504153e54aeb0cb4e6b1030a0d43b9735', dialogTitle: "Share Workspace", size: "small", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, contained: true }, h("div", { key: '652f23e37876be356beb6f93abf5930e91d82cea', class: "share-content" }, h("div", { key: 'aaf336f2ac86fe23cac79cef920a9d67681046e2', class: "share-section" }, h("div", { key: '8075a7b3fff47c4b924d3b2d92b1377641920939', class: "share-row" }, h("div", { key: '41e98a74a5d4aede50fd75a7de62cbef9b5a5a31', class: "share-label-group" }, h("label", { key: '8a4f53e13d5a81497dd31316a49971c7245d82a2', class: "share-label" }, "Link sharing"), h("p", { key: '907a59d50e595734f03067f70830cf96defdf8d8', class: "share-description" }, this.internalIsPublic
29912
30087
  ? 'Anyone with the link can access this workspace.'
29913
- : 'Link sharing is disabled. Only you can access this workspace.')), h("kritzel-slide-toggle", { key: 'ec62a5ece12be0cea18a16c5d41db0a992309174', checked: this.internalIsPublic, onCheckedChange: this.handleToggleChange, label: "Enable link sharing" }))), this.internalIsPublic && (h("div", { key: '5e826d4c8c37792ba3a74a0189ad313a8ab482e2', class: "share-section" }, h("div", { key: 'f8e35cda32cb34ab21f56335aa27503fd6fe98c4', class: "share-url-container" }, h("input", { key: '47feb20a1843e1d3d8f7d146d71574b187002e8d', type: "text", class: "share-url-input", value: this.getShareUrl(), readOnly: true, onClick: (e) => e.target.select() }), h("button", { key: '052f56f35d057430cbc8fd03da5bef574b173791', class: { 'copy-button': true, 'copy-success': this.copySuccess }, onClick: this.handleCopyUrl, title: this.copySuccess ? 'Copied!' : 'Copy link' }, h("kritzel-icon", { key: '4e1de478f837a352185be2a06e15796dc1fb2f5e', name: this.copySuccess ? 'check' : 'copy', size: 18 })))))))));
30088
+ : 'Link sharing is disabled. Only you can access this workspace.')), h("kritzel-slide-toggle", { key: '0d75cfeeb63c33d20380ffe9a7e4c27148548ef9', checked: this.internalIsPublic, onCheckedChange: this.handleToggleChange, label: "Enable link sharing" }))), this.internalIsPublic && (h("div", { key: 'a8a10c74fd326c5097e4a5f0ee165602c3606ade', class: "share-section" }, h("div", { key: '6261a9fc6cb2be2a50856fb8a990b9da3fee84bf', class: "share-url-container" }, h("input", { key: '26ee72eebfee88d06a50c338cccc9af296c8ba4c', type: "text", class: "share-url-input", value: this.getShareUrl(), readOnly: true, onClick: (e) => e.target.select() }), h("button", { key: '4b1ec06fa27c95d9d0bb93f8cbb851a02fdd52cc', class: { 'copy-button': true, 'copy-success': this.copySuccess }, onClick: this.handleCopyUrl, title: this.copySuccess ? 'Copied!' : 'Copy link' }, h("kritzel-icon", { key: 'd9eea56b3523fcc3557d9868f3da7f28449a9447', name: this.copySuccess ? 'check' : 'copy', size: 18 })))))))));
29914
30089
  }
29915
30090
  static get watchers() { return {
29916
30091
  "isPublic": [{
@@ -29948,7 +30123,7 @@ const KritzelSlideToggle = class {
29948
30123
  }
29949
30124
  };
29950
30125
  render() {
29951
- return (h(Host, { key: '376beaa4424858c3aaf1466797663024889c0f73', class: { checked: this.checked, disabled: this.disabled }, tabIndex: this.disabled ? -1 : 0, role: "switch", "aria-checked": this.checked ? 'true' : 'false', "aria-disabled": this.disabled ? 'true' : 'false', "aria-label": this.label, onClick: this.handleToggle, onKeyDown: this.handleKeyDown }, h("div", { key: '2108fe8de84e0b9a619667b5ab4f57215c185375', class: "toggle-track" }, h("div", { key: 'ff8253ce660ca62313dea3034ac4980135eaac88', class: "toggle-thumb" }))));
30126
+ return (h(Host, { key: '8a1f816240f815905cc7def7cac92eb7ddac0df2', class: { checked: this.checked, disabled: this.disabled }, tabIndex: this.disabled ? -1 : 0, role: "switch", "aria-checked": this.checked ? 'true' : 'false', "aria-disabled": this.disabled ? 'true' : 'false', "aria-label": this.label, onClick: this.handleToggle, onKeyDown: this.handleKeyDown }, h("div", { key: 'd5fa5091ad54032f81dad3879149c4d8ec7ea37b', class: "toggle-track" }, h("div", { key: 'cce0d61431ed65a26926b0a496a5c22eb4169577', class: "toggle-thumb" }))));
29952
30127
  }
29953
30128
  };
29954
30129
  KritzelSlideToggle.style = kritzelSlideToggleCss();
@@ -30048,7 +30223,7 @@ const KritzelSplitButton = class {
30048
30223
  this.menuScrollTop = event.target.scrollTop;
30049
30224
  };
30050
30225
  render() {
30051
- return (h(Host, { key: '1ec4c6806f5ff020d675b34f32efeecf6ddf40ab', class: { mobile: this.isTouchDevice } }, h("button", { key: '11deb29bfc899fb2aa4d98c5bc615a8e0dfc56f9', class: "split-main-button", tabIndex: 0, onClick: this.handleButtonClick, disabled: this.mainButtonDisabled, "aria-label": "Main action" }, this.buttonIcon && h("kritzel-icon", { key: '46b0a1cea4528d5565c5ab17a2966fc15e2c00cb', name: this.buttonIcon })), h("div", { key: '6efd2cc0c64c4af734d1071c98c59afdfcc49067', class: "split-divider" }), h("button", { key: 'ed0cb5af95404a18ec335348d7e3af9dc6565bca', ref: el => (this.splitMenuButtonRef = el), class: "split-menu-button", tabIndex: 0, onClick: this.toggleMenu, disabled: this.menuButtonDisabled, "aria-label": "Open menu" }, h("kritzel-icon", { key: '72a83a39b8dd60468800befe85763574e19c3e20', name: this.dropdownIcon })), h("kritzel-portal", { key: 'f014876c36faef4b59db720b645ed6d30615df77', anchor: this.anchorElement, offsetY: 4, onClose: this.closeMenu }, h("kritzel-menu", { key: '3c16b2828d68ec64d6fe571865dbfbd80d09b40e', ref: el => (this.menuRef = el), items: this.items, onItemSelect: this.handleItemSelect, onItemSave: this.handleItemSave, onItemCancel: this.handleItemCancel, onItemToggleChildMenu: this.handleItemToggleChildMenu, onItemCloseChildMenu: this.handleItemCloseChildMenu, onClose: this.closeMenu, onScroll: this.handleScroll }))));
30226
+ return (h(Host, { key: '794fdb5cb4d110d93b6b2cb060fe34241f29db57', class: { mobile: this.isTouchDevice } }, h("button", { key: '7202a40f05bf6fc256996a05db55bcfa3baba615', class: "split-main-button", tabIndex: 0, onClick: this.handleButtonClick, disabled: this.mainButtonDisabled, "aria-label": "Main action" }, this.buttonIcon && h("kritzel-icon", { key: '3156c6c4e757d9ebbd3f5e3719ee1bf9bf81f71b', name: this.buttonIcon })), h("div", { key: '4c5a3a9791ecfd00d36fc0eb885c1d227200cfc7', class: "split-divider" }), h("button", { key: 'fe0ee44d11ddb34f7719b986406905c47bc1f152', ref: el => (this.splitMenuButtonRef = el), class: "split-menu-button", tabIndex: 0, onClick: this.toggleMenu, disabled: this.menuButtonDisabled, "aria-label": "Open menu" }, h("kritzel-icon", { key: 'b3d84e4599dc408ccc8afe17e487b501cbde89a4', name: this.dropdownIcon })), h("kritzel-portal", { key: '6800329ebe3c94a661e9ad852b6bf256defc291f', anchor: this.anchorElement, offsetY: 4, onClose: this.closeMenu }, h("kritzel-menu", { key: '0c98abe2327e0cc3182a55caf50c89316b526049', ref: el => (this.menuRef = el), items: this.items, onItemSelect: this.handleItemSelect, onItemSave: this.handleItemSave, onItemCancel: this.handleItemCancel, onItemToggleChildMenu: this.handleItemToggleChildMenu, onItemCloseChildMenu: this.handleItemCloseChildMenu, onClose: this.closeMenu, onScroll: this.handleScroll }))));
30052
30227
  }
30053
30228
  };
30054
30229
  KritzelSplitButton.style = kritzelSplitButtonCss();
@@ -30068,7 +30243,7 @@ const KritzelStrokeSize = class {
30068
30243
  this.sizeChange.emit(size);
30069
30244
  }
30070
30245
  render() {
30071
- return (h(Host, { key: 'f964d37a6cbfa48898ac066859165df1492535a9' }, h("div", { key: 'fed8ec5ddbe07d64beb151b22211fecdc0a278d1', class: "size-grid" }, this.sizes.map(size => (h("div", { tabIndex: 0, class: {
30246
+ return (h(Host, { key: '514d87732c9b15cddd5a905407ff7ce9069c06d7' }, h("div", { key: '170c9a8abfe8298116d8a269338da95fbc2aac7b', class: "size-grid" }, this.sizes.map(size => (h("div", { tabIndex: 0, class: {
30072
30247
  'size-container': true,
30073
30248
  'selected': this.selectedSize === size,
30074
30249
  }, onClick: () => this.handleSizeClick(size) }, h("kritzel-color", { value: 'var(--kritzel-global-text-primary)', size: size })))))));
@@ -30447,14 +30622,14 @@ const KritzelTooltip = class {
30447
30622
  }
30448
30623
  }
30449
30624
  render() {
30450
- return (h(Host, { key: '647f4d837fc06a3b5dca8896383c1a92ef7c5a3d', style: {
30625
+ return (h(Host, { key: '10bff4d14ff1f724d59463afc059f254e9485175', style: {
30451
30626
  position: 'fixed',
30452
30627
  zIndex: '9999',
30453
30628
  transition: 'opacity 0.3s ease-in-out, transform 0.3s ease-in-out',
30454
30629
  visibility: this.isVisible ? 'visible' : 'hidden',
30455
30630
  left: `${this.positionX}px`,
30456
30631
  bottom: `${this.positionY}px`,
30457
- } }, h("div", { key: '41b32207d1e9f84c85c054a8aae4727b7df05d62', class: "tooltip-content", onClick: event => event.stopPropagation(), onPointerDown: event => event.stopPropagation(), onMouseDown: event => event.stopPropagation() }, h("slot", { key: 'c164d76762957e60d904458d7a34936944d02eae' }))));
30632
+ } }, h("div", { key: '6bfc8f2fe731d758c74319abeb82c4b84616f8b6', class: "tooltip-content", onClick: event => event.stopPropagation(), onPointerDown: event => event.stopPropagation(), onMouseDown: event => event.stopPropagation() }, h("slot", { key: '2a92ad23f4424b2d17035f86983be66a81fee81d' }))));
30458
30633
  }
30459
30634
  static get watchers() { return {
30460
30635
  "triggerElement": [{
@@ -30493,7 +30668,7 @@ const KritzelUtilityPanel = class {
30493
30668
  this.redo.emit();
30494
30669
  }
30495
30670
  render() {
30496
- return (h(Host, { key: 'f800ea5843cf73ae132b56396ad05d664043f789' }, h("button", { key: '8f2c35b9b774ba5662ad584ebaa3e98a21e2d4e5', class: "utility-button", "data-testid": "utility-undo", disabled: !this.undoState?.canUndo, onClick: event => this.handleUndo(event), "aria-label": "Undo" }, h("kritzel-icon", { key: 'ffba256fea2b2ba7c767601a2051c940e5865fd5', name: "undo" })), h("button", { key: '261a7759ec1e25000ed76d2cf5aaef908cea886c', class: "utility-button", "data-testid": "utility-redo", disabled: !this.undoState?.canRedo, onClick: event => this.handleRedo(event), "aria-label": "Redo" }, h("kritzel-icon", { key: '7483a8c23a1dcd77dc0bfdb3cc39c4998e48b193', name: "redo" })), h("div", { key: '7450540c285a6cf746d52b31eb2e7f88ec30c1ec', class: "utility-separator" }), h("button", { key: '62fa097474ede7de6018a76ec492a9d72bb0cb11', class: "utility-button", "data-testid": "utility-delete", onClick: () => this.delete.emit(), "aria-label": "Delete selected items" }, h("kritzel-icon", { key: 'a1cea0b8a5524fe5877ae2ce7939bcb5a66b4dcd', name: "delete" }))));
30671
+ return (h(Host, { key: 'b49f6db6c0e574dc8a5a733c749ecda6f24f9d25' }, h("button", { key: 'e6306e54c8f660c3e92d032527fad1ea45ca0cf8', class: "utility-button", "data-testid": "utility-undo", disabled: !this.undoState?.canUndo, onClick: event => this.handleUndo(event), "aria-label": "Undo" }, h("kritzel-icon", { key: '5bb1293049a1e3004504289d92ccc79958786f3f', name: "undo" })), h("button", { key: '8102b0403d7f328ce4bfeb79767d5bd99d879013', class: "utility-button", "data-testid": "utility-redo", disabled: !this.undoState?.canRedo, onClick: event => this.handleRedo(event), "aria-label": "Redo" }, h("kritzel-icon", { key: '5db3047bec5d8ab695a2dc67780a5dbecbae64d2', name: "redo" })), h("div", { key: 'e894d9f2aaa2cad7aa980d3b839eca05a8d9c9df', class: "utility-separator" }), h("button", { key: 'f0a7de5ab91f82a2e5e8df75cc1903ec647abdac', class: "utility-button", "data-testid": "utility-delete", onClick: () => this.delete.emit(), "aria-label": "Delete selected items" }, h("kritzel-icon", { key: '5b146375394299bae946a95545c3c42c2bf36766', name: "delete" }))));
30497
30672
  }
30498
30673
  };
30499
30674
  KritzelUtilityPanel.style = kritzelUtilityPanelCss();