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,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-CFnj_FXt.js');
4
- var schema_constants = require('./schema.constants-rCfWpcBV.js');
4
+ var schema_constants = require('./schema.constants-BNMNpzvA.js');
5
5
  var Y = require('yjs');
6
6
  require('y-indexeddb');
7
7
  require('y-websocket');
@@ -154,16 +154,16 @@ const KritzelAvatar = class {
154
154
  height: `${this.size}px`,
155
155
  fontSize: `${Math.round(this.size * 0.4)}px`,
156
156
  };
157
- return (index.h(index.Host, { key: '2067605684a743be45059efd562697ff21fefbcb', style: containerStyles, class: {
157
+ return (index.h(index.Host, { key: '571bd5b92adc7c65b96ded37b8daf5ed79905361', style: containerStyles, class: {
158
158
  'has-image': !!showImage,
159
159
  'has-initials': !!showInitials,
160
160
  'has-default': !!showDefaultIcon,
161
- }, role: "img", "aria-label": this.getDisplayName() || 'User avatar' }, showImage && (index.h("img", { key: '1ed322318335deb011087494a2c437849b5a23a0', src: imageUrl, alt: "", class: "avatar-image", ref: (el) => {
161
+ }, role: "img", "aria-label": this.getDisplayName() || 'User avatar' }, showImage && (index.h("img", { key: '1065850b4575fda4637ab61ce07c6dfc97f14a90', src: imageUrl, alt: "", class: "avatar-image", ref: (el) => {
162
162
  if (el) {
163
163
  el.referrerPolicy = 'no-referrer';
164
164
  el.crossOrigin = 'anonymous';
165
165
  }
166
- }, onError: this.handleImageError })), showInitials && (index.h("span", { key: 'ff99dded4cb17d6c25880b54e3875c262dfc0440', class: "avatar-initials", style: { backgroundColor: this.getBackgroundColor() } }, initials)), showDefaultIcon && (index.h("span", { key: '5a217c6a1366dea3ceee8bfa03a38917cad7a9f9', class: "avatar-default" }, index.h("svg", { key: 'f4537e21772e6e6f1bb60835ad7a56123a200dd7', viewBox: "0 0 24 24", fill: "currentColor" }, index.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" }))))));
166
+ }, onError: this.handleImageError })), showInitials && (index.h("span", { key: 'a6d9c9dd2eac6e44c731a878e2460017da7fb0b7', class: "avatar-initials", style: { backgroundColor: this.getBackgroundColor() } }, initials)), showDefaultIcon && (index.h("span", { key: '9e9d33cdd213649071b76cb0875008562b30f6a1', class: "avatar-default" }, index.h("svg", { key: '5d0be5c503a8944b45de239f08e6f40378c2dc5e', viewBox: "0 0 24 24", fill: "currentColor" }, index.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" }))))));
167
167
  }
168
168
  static get watchers() { return {
169
169
  "user": [{
@@ -366,7 +366,7 @@ const KritzelAwarenessCursors = class {
366
366
  }
367
367
  render() {
368
368
  const cursors = Array.from(this.remoteCursors.values());
369
- return (index.h(index.Host, { key: '0f8678b0a96d80e12d2aa75f85af74a8737f836d' }, cursors.map(remoteCursor => {
369
+ return (index.h(index.Host, { key: '5c695e3c5a012767b31bb1b756ef03e2a174f46e' }, cursors.map(remoteCursor => {
370
370
  if (!remoteCursor.cursor)
371
371
  return null;
372
372
  // When a remote user is actively drawing, derive cursor position from
@@ -473,7 +473,7 @@ const KritzelBackToContent = class {
473
473
  this.backToContent.emit();
474
474
  };
475
475
  render() {
476
- return (index.h(index.Host, { key: '7d33e599832eb5e4f65b9fdbb9239cfe157733af' }, index.h("button", { key: '905b50a8a90a0ca66a4fa9421457b78a0f650de5', class: { 'back-to-content-button': true, visible: this.visible }, onClick: this.handleClick, "aria-label": this.text }, index.h("kritzel-icon", { key: 'eaa718ab29fad870464c6b67d5ad27c4300dfd54', name: "chevrons-left" }))));
476
+ return (index.h(index.Host, { key: 'b623a9a4e4b8fce50346771488a59c3a646c289e' }, index.h("button", { key: 'b2f6b257975639d33362f1038b61e5147963f189', class: { 'back-to-content-button': true, visible: this.visible }, onClick: this.handleClick, "aria-label": this.text }, index.h("kritzel-icon", { key: '22f34fc201a865b6d9b21775a349d0e185727d48', name: "chevrons-left" }))));
477
477
  }
478
478
  };
479
479
  KritzelBackToContent.style = kritzelBackToContentCss();
@@ -500,11 +500,11 @@ const KritzelButton = class {
500
500
  this.buttonClick.emit();
501
501
  };
502
502
  render() {
503
- return (index.h(index.Host, { key: 'aa82a9e0c6c39b0b2bce597ac2e864049543d474' }, index.h("button", { key: '5bda14f9fef89abacb9cd04e5aaa8ae7ae25048a', type: this.type, class: {
503
+ return (index.h(index.Host, { key: 'c915db75630392741de404f07265a391330e54ca' }, index.h("button", { key: '50248ee1ed5862c9ea72b4f7cf7d564d03b5b14e', type: this.type, class: {
504
504
  'kritzel-button': true,
505
505
  [this.variant]: true,
506
506
  'disabled': this.disabled,
507
- }, disabled: this.disabled, onClick: this.handleClick }, index.h("slot", { key: '8585675eec39345ddfbf3f6dbb705035f7a5d099' }))));
507
+ }, disabled: this.disabled, onClick: this.handleClick }, index.h("slot", { key: 'd595cd819c7c0a3550e468ce65d4e2c28cc02164' }))));
508
508
  }
509
509
  };
510
510
  KritzelButton.style = kritzelButtonCss();
@@ -552,13 +552,13 @@ const KritzelColorComponent = class {
552
552
  render() {
553
553
  const resolvedColor = this.resolveColor();
554
554
  const isColorVeryLight = this.isLightColor(resolvedColor);
555
- return (index.h(index.Host, { key: 'a740b94f2baacb978b26deae1ea1057c7faf9036' }, index.h("div", { key: 'e82f83a23e44a2ff23b5efbfac28e4c47cd5b749', class: "checkerboard-bg", style: {
555
+ return (index.h(index.Host, { key: 'c4c1fe2559aca61557ff2e8154f4d46ce3511b30' }, index.h("div", { key: '158c243018763a9609e0a056229263864a5e4d13', class: "checkerboard-bg", style: {
556
556
  width: `${this.size}px`,
557
557
  height: `${this.size}px`,
558
558
  borderRadius: '50%',
559
559
  display: 'inline-block',
560
560
  position: 'relative',
561
- } }, index.h("div", { key: 'd83e2be171f89ee4cd53e8cf83ab6591f585129f', class: {
561
+ } }, index.h("div", { key: 'afa21c72b17ab5fb4b16521b91dbe7e9162d05f8', class: {
562
562
  'color-circle': true,
563
563
  'white': isColorVeryLight,
564
564
  }, style: {
@@ -614,7 +614,7 @@ const KritzelColorPalette = class {
614
614
  render() {
615
615
  const displayedColors = this.isExpanded ? this.colors : this.colors.slice(0, 6);
616
616
  const expandedHeight = this.isExpanded ? this.calculateHeight() : '32px';
617
- return (index.h(index.Host, { key: 'a2c996d16a44f66471f6f76e08129142fc9f5ddb' }, index.h("div", { key: '245f4b9ff50412b84ede221d22b0894a104a6895', class: {
617
+ return (index.h(index.Host, { key: 'fc57d77d7c4cfd2aa2a02a70b8991858bb8cf61b' }, index.h("div", { key: '4fd10783609882f453ce95f5114acf799f21ec52', class: {
618
618
  'color-grid': true,
619
619
  'expanded': this.isExpanded,
620
620
  }, style: {
@@ -649,8 +649,9 @@ const KritzelContextMenu = class {
649
649
  actionSelected;
650
650
  close;
651
651
  processedItems = [];
652
- openSubmenuIndex = null;
653
- submenuPosition = 'right';
652
+ /** Current open submenu path (e.g. '0.2.1'). Empty if none. */
653
+ openSubmenuPath = '';
654
+ submenuPositions = {};
654
655
  submenuTimer = null;
655
656
  submenuRefs = new Map();
656
657
  menuItemWrapperRefs = new Map();
@@ -668,7 +669,8 @@ const KritzelContextMenu = class {
668
669
  }
669
670
  componentDidUpdate() {
670
671
  this.adjustPositionToViewport();
671
- this.adjustSubmenuPosition();
672
+ this.adjustSubmenuPositions();
673
+ this.pruneStaleRefs();
672
674
  }
673
675
  disconnectedCallback() {
674
676
  if (this.submenuTimer) {
@@ -705,60 +707,102 @@ const KritzelContextMenu = class {
705
707
  this.host.style.top = `${newTop}px`;
706
708
  }
707
709
  }
708
- adjustSubmenuPosition() {
709
- if (this.openSubmenuIndex === null)
710
+ adjustSubmenuPositions() {
711
+ if (!this.openSubmenuPath)
710
712
  return;
711
- const submenuEl = this.submenuRefs.get(this.openSubmenuIndex);
712
- if (!submenuEl)
713
- return;
714
- const submenuRect = submenuEl.getBoundingClientRect();
715
713
  const viewportHeight = window.innerHeight;
716
- // Adjust vertical position if needed (horizontal is pre-calculated)
717
- if (submenuRect.bottom > viewportHeight - VIEWPORT_PADDING) {
718
- const overflow = submenuRect.bottom - (viewportHeight - VIEWPORT_PADDING);
719
- submenuEl.style.top = `${-overflow}px`;
714
+ // Adjust every open submenu in the chain (every prefix of openSubmenuPath).
715
+ for (const path of this.getOpenSubmenuPaths()) {
716
+ const submenuEl = this.submenuRefs.get(path);
717
+ const wrapperEl = this.menuItemWrapperRefs.get(path);
718
+ if (!submenuEl || !wrapperEl)
719
+ continue;
720
+ const wrapperRect = wrapperEl.getBoundingClientRect();
721
+ const submenuHeight = submenuEl.offsetHeight; // Constant regardless of current top shift
722
+ const naturalBottom = wrapperRect.top + submenuHeight;
723
+ if (naturalBottom > viewportHeight - VIEWPORT_PADDING) {
724
+ let overflow = naturalBottom - (viewportHeight - VIEWPORT_PADDING);
725
+ // Don't shift up so far that the top goes above the viewport
726
+ if (wrapperRect.top - overflow < VIEWPORT_PADDING) {
727
+ overflow = wrapperRect.top - VIEWPORT_PADDING;
728
+ }
729
+ submenuEl.style.top = `${-overflow}px`;
730
+ }
731
+ else {
732
+ submenuEl.style.top = '0px';
733
+ }
720
734
  }
721
- else {
722
- submenuEl.style.top = '0px';
735
+ }
736
+ getOpenSubmenuPaths() {
737
+ if (!this.openSubmenuPath)
738
+ return [];
739
+ const parts = this.openSubmenuPath.split('.');
740
+ const paths = [];
741
+ for (let i = 1; i <= parts.length; i++) {
742
+ paths.push(parts.slice(0, i).join('.'));
743
+ }
744
+ return paths;
745
+ }
746
+ isSubmenuOpen(path) {
747
+ return this.openSubmenuPath === path || this.openSubmenuPath.startsWith(path + '.');
748
+ }
749
+ getParentPath(path) {
750
+ const idx = path.lastIndexOf('.');
751
+ return idx === -1 ? '' : path.substring(0, idx);
752
+ }
753
+ pruneStaleRefs() {
754
+ const openPaths = new Set(this.getOpenSubmenuPaths());
755
+ for (const key of Array.from(this.submenuRefs.keys())) {
756
+ if (!openPaths.has(key)) {
757
+ this.submenuRefs.delete(key);
758
+ }
759
+ }
760
+ // Keep root-level wrapper refs (single-segment paths) always rendered; prune deeper
761
+ // wrappers whose parent submenu is no longer open.
762
+ for (const key of Array.from(this.menuItemWrapperRefs.keys())) {
763
+ const parent = this.getParentPath(key);
764
+ if (parent !== '' && !openPaths.has(parent)) {
765
+ this.menuItemWrapperRefs.delete(key);
766
+ }
723
767
  }
724
768
  }
725
769
  handleItemClick(item, isDisabled, hasChildren) {
726
770
  if (isDisabled)
727
771
  return;
728
772
  if (hasChildren) {
729
- // Toggle submenu on click for touch devices
773
+ // Hover handles open/close; click on a parent is a no-op.
730
774
  return;
731
775
  }
732
776
  if (item.action) {
733
777
  this.actionSelected.emit(item);
734
778
  }
735
779
  }
736
- handleItemMouseEnter(index, hasChildren) {
780
+ handleItemMouseEnter(path, hasChildren) {
737
781
  if (this.submenuTimer) {
738
782
  clearTimeout(this.submenuTimer);
739
783
  this.submenuTimer = null;
740
784
  }
785
+ const parentPath = this.getParentPath(path);
741
786
  if (hasChildren) {
742
787
  this.submenuTimer = setTimeout(() => {
743
- // Pre-calculate position before opening to avoid flicker
744
- const wrapperEl = this.menuItemWrapperRefs.get(index);
788
+ // Pre-calculate horizontal position before opening to avoid flicker.
789
+ const wrapperEl = this.menuItemWrapperRefs.get(path);
790
+ let position = 'right';
745
791
  if (wrapperEl) {
746
792
  const rect = wrapperEl.getBoundingClientRect();
747
793
  const viewportWidth = window.innerWidth;
748
- // Check if opening to the right would overflow
749
794
  const wouldOverflowRight = rect.right + ESTIMATED_SUBMENU_WIDTH > viewportWidth - VIEWPORT_PADDING;
750
- this.submenuPosition = wouldOverflowRight ? 'left' : 'right';
795
+ position = wouldOverflowRight ? 'left' : 'right';
751
796
  }
752
- else {
753
- this.submenuPosition = 'right';
754
- }
755
- this.openSubmenuIndex = index;
797
+ this.submenuPositions = { ...this.submenuPositions, [path]: position };
798
+ this.openSubmenuPath = path;
756
799
  }, SUBMENU_DELAY);
757
800
  }
758
801
  else {
759
- // Close any open submenu when hovering a non-parent item
802
+ // Hovering a sibling without children: collapse to the parent chain so any
803
+ // sibling-rooted submenu closes, but the ancestor chain stays open.
760
804
  this.submenuTimer = setTimeout(() => {
761
- this.openSubmenuIndex = null;
805
+ this.openSubmenuPath = parentPath;
762
806
  }, SUBMENU_DELAY);
763
807
  }
764
808
  }
@@ -768,9 +812,11 @@ const KritzelContextMenu = class {
768
812
  this.submenuTimer = null;
769
813
  }
770
814
  }
771
- handleSubmenuMouseLeave() {
815
+ handleSubmenuMouseLeave(path) {
816
+ // Close this submenu (and any deeper levels) but keep the ancestor chain open.
817
+ const parentPath = this.getParentPath(path);
772
818
  this.submenuTimer = setTimeout(() => {
773
- this.openSubmenuIndex = null;
819
+ this.openSubmenuPath = parentPath;
774
820
  }, SUBMENU_DELAY);
775
821
  }
776
822
  async updateMenuItems() {
@@ -800,28 +846,28 @@ const KritzelContextMenu = class {
800
846
  }
801
847
  return defaultValue;
802
848
  }
803
- renderSubmenu(processedChildren, parentIndex) {
804
- return (index.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$1) => {
805
- const prevItem = index$1 > 0 ? processedChildren[index$1 - 1].item : null;
849
+ renderItems(items, parentPath) {
850
+ return items.map(({ item, isDisabled, processedChildren }, index$1) => {
851
+ const path = parentPath === '' ? String(index$1) : `${parentPath}.${index$1}`;
852
+ const prevItem = index$1 > 0 ? items[index$1 - 1].item : null;
806
853
  const showDivider = prevItem && prevItem.group !== item.group;
807
- const hasChildren = nestedChildren && nestedChildren.length > 0;
854
+ const hasChildren = !!processedChildren && processedChildren.length > 0;
855
+ const submenuOpen = hasChildren && this.isSubmenuOpen(path);
808
856
  return [
809
- showDivider && index.h("div", { class: "menu-divider", key: `submenu-divider-${index$1}` }),
810
- index.h("button", { key: `submenu-${item.label}-${index$1}`, class: { 'menu-item': true, 'disabled': isDisabled, 'has-children': hasChildren }, onClick: () => this.handleItemClick(item, isDisabled, hasChildren), disabled: isDisabled }, item.icon && index.h("kritzel-icon", { name: item.icon, size: 16 }), index.h("span", { class: "label" }, item.label), hasChildren && index.h("kritzel-icon", { name: "chevron-right", size: 12, class: "submenu-arrow" }))
857
+ showDivider && index.h("div", { class: "menu-divider", key: `divider-${path}` }),
858
+ index.h("div", { class: "menu-item-wrapper", key: `wrapper-${path}`, ref: el => el && this.menuItemWrapperRefs.set(path, el), onMouseEnter: () => this.handleItemMouseEnter(path, hasChildren) }, index.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 && index.h("kritzel-icon", { name: item.icon, size: 16 }), index.h("span", { class: "label" }, item.label), hasChildren && index.h("kritzel-icon", { name: "chevron-right", size: 12, class: "submenu-arrow" })), hasChildren && submenuOpen && this.renderSubmenu(processedChildren, path)),
811
859
  ];
812
- })));
860
+ });
861
+ }
862
+ renderSubmenu(processedChildren, path) {
863
+ const position = this.submenuPositions[path] === 'left' ? 'left' : 'right';
864
+ return (index.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)));
813
865
  }
814
866
  render() {
815
- return (index.h(index.Host, { key: '100ec82feefbc285f8e50fca3f23f853c33aa215' }, index.h("div", { key: '9305a0190bdcf7a9e4b5ae7473651a0261dbfd7c', class: "menu-container" }, this.processedItems.map(({ item, isDisabled, processedChildren }, index$1) => {
816
- const prevItem = index$1 > 0 ? this.processedItems[index$1 - 1].item : null;
817
- const showDivider = prevItem && prevItem.group !== item.group;
818
- const hasChildren = processedChildren && processedChildren.length > 0;
819
- const isSubmenuOpen = this.openSubmenuIndex === index$1;
820
- return [
821
- showDivider && index.h("div", { class: "menu-divider", key: `divider-${index$1}` }),
822
- index.h("div", { class: "menu-item-wrapper", ref: el => el && this.menuItemWrapperRefs.set(index$1, el), onMouseEnter: () => this.handleItemMouseEnter(index$1, hasChildren) }, index.h("button", { key: `${item.label}-${index$1}`, class: { 'menu-item': true, 'disabled': isDisabled, 'has-children': hasChildren, 'submenu-open': isSubmenuOpen }, onClick: () => this.handleItemClick(item, isDisabled, hasChildren), disabled: isDisabled && !hasChildren }, item.icon && index.h("kritzel-icon", { name: item.icon, size: 16 }), index.h("span", { class: "label" }, item.label), hasChildren && index.h("kritzel-icon", { name: "chevron-right", size: 12, class: "submenu-arrow" })), hasChildren && isSubmenuOpen && this.renderSubmenu(processedChildren, index$1))
823
- ];
824
- }))));
867
+ if (!this.processedItems || this.processedItems.length === 0) {
868
+ return null;
869
+ }
870
+ return (index.h(index.Host, null, index.h("div", { class: "menu-container" }, this.renderItems(this.processedItems, ''))));
825
871
  }
826
872
  static get watchers() { return {
827
873
  "items": [{
@@ -897,7 +943,7 @@ class KritzelToolConfigHelper {
897
943
  }
898
944
  }
899
945
 
900
- 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}`;
946
+ 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}`;
901
947
 
902
948
  const KritzelControls = class {
903
949
  constructor(hostRef) {
@@ -909,7 +955,7 @@ const KritzelControls = class {
909
955
  activeControl = null;
910
956
  isUtilityPanelVisible = true;
911
957
  undoState = null;
912
- theme;
958
+ theme = 'light';
913
959
  isControlsReady;
914
960
  firstConfig = null;
915
961
  isTouchDevice = schema_constants.KritzelDevicesHelper.isTouchDevice();
@@ -1129,13 +1175,13 @@ const KritzelControls = class {
1129
1175
  // Separate tool controls from config control
1130
1176
  const toolControls = this.internalControls.filter(c => c.type === 'tool' || c.type === 'separator');
1131
1177
  const configControl = this.internalControls.find(c => c.type === 'config' && c.name === this.firstConfig?.name);
1132
- return (index.h(index.Host, { key: '7f2a5fed45ac89b34a86b87552ffaa1b94f44d8b', class: {
1178
+ return (index.h(index.Host, { key: 'b567aac7bca12cc5ffb0ee1eb9e6978636aa3c31', class: {
1133
1179
  mobile: this.isTouchDevice,
1134
- } }, this.isUtilityPanelVisible && (index.h("kritzel-utility-panel", { key: '2dcbbe498bce0b59fbd225d103f2e322d3b7ff85', style: {
1180
+ } }, this.isUtilityPanelVisible && (index.h("kritzel-utility-panel", { key: '88e8ae9ae7429987724df70895b02a3f59216364', style: {
1135
1181
  position: 'absolute',
1136
1182
  bottom: '56px',
1137
1183
  left: '12px',
1138
- }, undoState: this.undoState, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), index.h("div", { key: '6431079040502a78f021c612a7e953b1349f319a', class: "kritzel-controls" }, index.h("div", { key: '6e0d6dce107cf6b54fb904809fd525ce3b2ae4f0', class: { 'scroll-indicator-left': true, 'visible': this.canScrollLeft } }), index.h("div", { key: '2686304ad10deac2d022e1deba19195587659d64', class: "kritzel-tools-scroll", ref: el => (this.toolsScrollRef = el), onScroll: this.handleToolsScroll }, toolControls.map(control => {
1184
+ }, undoState: this.undoState, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), index.h("div", { key: '658e3d7b94e49a002d5057c1fb4fc199a371c48d', class: "kritzel-controls" }, index.h("div", { key: 'b54bb52a43e4a94ae1148cd4e75528bcaad681ef', class: { 'scroll-indicator-left': true, 'visible': this.canScrollLeft } }), index.h("div", { key: '36ce760357d3228141281a45c0ac7b0024b04795', class: "kritzel-tools-scroll", ref: el => (this.toolsScrollRef = el), onScroll: this.handleToolsScroll }, toolControls.map(control => {
1139
1185
  // Check if this control has sub-options (split-button)
1140
1186
  if (control.subOptions?.length) {
1141
1187
  const selectedSubOption = this.getSelectedSubOption(control);
@@ -1165,10 +1211,10 @@ const KritzelControls = class {
1165
1211
  'kritzel-control': true,
1166
1212
  'selected': this.activeControl?.name === control?.name,
1167
1213
  }, key: control.name, "data-testid": `tool-${control.name}`, onClick: _event => this.handleControlClick?.(control), "aria-label": control.name.charAt(0).toUpperCase() + control.name.slice(1) }, index.h("kritzel-icon", { name: control.icon })));
1168
- })), index.h("div", { key: 'f4bcbc856f6e027cdb579356faf54288b43aa080', class: { 'scroll-indicator-right': true, 'visible': this.canScrollRight && !(configControl && this.activeControl && hasConfigUI) } }), configControl && this.activeControl && (index.h("div", { class: {
1214
+ })), index.h("div", { key: 'f0b1e0f74fe197f4d39e307e7dd8dd4819c4b183', class: { 'scroll-indicator-right': true, 'visible': this.canScrollRight && !(configControl && this.activeControl && hasConfigUI) } }), configControl && this.activeControl && (index.h("div", { class: {
1169
1215
  'kritzel-config-container': true,
1170
1216
  'visible': hasConfigUI,
1171
- }, key: configControl.name }, index.h("div", { key: '0646c98b32047f51841f75dd5fb57813ebb153f5', class: { 'config-gradient-left': true, 'visible': this.needsScrolling } }), index.h("kritzel-tooltip", { key: '0816b8d7ca55add3c6a81de788be3c61a8a814f2', anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), triggerElement: this.configTriggerRef }, index.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%' } })), index.h("div", { key: '8b2dc1dcc61df93a92cea8ba2aeb776e57965ab3', tabIndex: hasConfigUI ? 0 : -1, class: "kritzel-config", "data-testid": "tool-config", ref: el => {
1217
+ }, key: configControl.name }, index.h("div", { key: '51cc3ebf13092e710048441ff64856edd4f53dfc', class: { 'config-gradient-left': true, 'visible': this.needsScrolling } }), index.h("kritzel-tooltip", { key: 'dcace186ae3ece1d7e943f51b48ed5094d847284', anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), triggerElement: this.configTriggerRef }, index.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%' } })), index.h("div", { key: '2425507968e27a01b66c1d7be79a40ebe77cd27d', tabIndex: hasConfigUI ? 0 : -1, class: "kritzel-config", "data-testid": "tool-config", ref: el => {
1172
1218
  if (el)
1173
1219
  this.configTriggerRef = el;
1174
1220
  }, onKeyDown: event => {
@@ -1177,7 +1223,7 @@ const KritzelControls = class {
1177
1223
  }
1178
1224
  }, style: {
1179
1225
  cursor: 'pointer',
1180
- } }, this.displayValues && (index.h("div", { key: '1074fc05048aed92ec9d62e347822df0a57a80e4', class: "color-container" }, index.h("kritzel-color", { key: '222efa6883ccbc6c97d10360039a1315de7d6273', value: this.displayValues.color, theme: this.theme, size: 18, style: {
1226
+ } }, this.displayValues && (index.h("div", { key: 'd2499df3c0a90c101957f55664452739e0f1692b', class: "color-container" }, index.h("kritzel-color", { key: 'b7cfcd3a8579c63f508c2786eecace1223e88974', value: this.displayValues.color, theme: this.theme, size: 18, style: {
1181
1227
  borderRadius: '50%',
1182
1228
  border: 'none',
1183
1229
  } })))))))));
@@ -1215,7 +1261,7 @@ const KritzelCurrentUser = class {
1215
1261
  this.dialogRef?.open();
1216
1262
  };
1217
1263
  render() {
1218
- return (index.h(index.Host, { key: 'c392caf731f8352fd8e2a95918fe48a2f00dd9e5' }, index.h("kritzel-avatar", { key: 'b3bdce0efa0c0610aa028303386c643d53bc8300', user: this.user, size: this.avatarSize, onClick: this.handleAvatarClick }), index.h("kritzel-current-user-dialog", { key: '5e7af1aea468028e091ad8f461e4352cb9f9636b', ref: el => (this.dialogRef = el), user: this.user })));
1264
+ return (index.h(index.Host, { key: 'a735cb9f16f4898fde0b52573affa2d270a8f1de' }, index.h("kritzel-avatar", { key: 'd449a515182718ab4ef3b26b2277696bbc7ab46f', user: this.user, size: this.avatarSize, onClick: this.handleAvatarClick }), index.h("kritzel-current-user-dialog", { key: '3542f6df43c9924218e344f70bdc398c74a8eae6', ref: el => (this.dialogRef = el), user: this.user })));
1219
1265
  }
1220
1266
  };
1221
1267
  KritzelCurrentUser.style = kritzelCurrentUserCss();
@@ -1247,7 +1293,7 @@ const KritzelCurrentUserDialog = class {
1247
1293
  }
1248
1294
  render() {
1249
1295
  const displayName = this.getDisplayName();
1250
- return (index.h(index.Host, { key: 'e1dd44cdfdbaebfe886fed0d9feba2ef232b6615' }, index.h("kritzel-dialog", { key: 'cd3daa7abd53c10852d63a2fe53d919414cd8904', dialogTitle: "Account", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, index.h("div", { key: '94d0a691ede73135e6cf4ef144c13e52e410ffbe', class: "user-info" }, index.h("kritzel-avatar", { key: 'e57592d2f3663b593534055be5aae1b224fa8906', user: this.user, size: 80 }), displayName && index.h("div", { key: '237db2d0608ee49ea70e5282b61a59077f0f4595', class: "user-name" }, displayName), this.user?.email && index.h("div", { key: 'd821e8171530b92ce6f1781c1145b611d3c533d0', class: "user-email" }, this.user.email)))));
1296
+ return (index.h(index.Host, { key: '40c1a1bed0ddf02f9835199b5f7d2363e4d1902b' }, index.h("kritzel-dialog", { key: 'a83c09eac66ddf51155591a32245e3f15e34943e', dialogTitle: "Account", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, index.h("div", { key: '14f7100a881ee3c5ba6b672d509bf3a9161ccd62', class: "user-info" }, index.h("kritzel-avatar", { key: 'e3552a80db81db4c26f81c6cc699363afa6153ea', user: this.user, size: 80 }), displayName && index.h("div", { key: 'c54164be605ac2bd2fc8bac6bb4481f820119028', class: "user-name" }, displayName), this.user?.email && index.h("div", { key: 'e6af7c44e45443eb24be0777768de96b0e3d249e', class: "user-email" }, this.user.email)))));
1251
1297
  }
1252
1298
  };
1253
1299
  KritzelCurrentUserDialog.style = kritzelCurrentUserDialogCss();
@@ -1320,7 +1366,7 @@ const KritzelCursorTrail = class {
1320
1366
  }
1321
1367
  }
1322
1368
  render() {
1323
- return (index.h(index.Host, { key: '2e40e68375f4b8b4531181d249c1638a01d9dac5' }, this.cursorTrailPoints.length > 1 && (index.h("svg", { key: 'c015f003cc5f4c5c532803846fa5201edf4c211a', class: "cursor-trail-svg", xmlns: "http://www.w3.org/2000/svg", style: {
1369
+ return (index.h(index.Host, { key: 'b427550b19a3e172cb25d05e34635121b82a61c5' }, this.cursorTrailPoints.length > 1 && (index.h("svg", { key: '9685b563497e110f36c0feffbfde04ebeb38024b', class: "cursor-trail-svg", xmlns: "http://www.w3.org/2000/svg", style: {
1324
1370
  position: 'absolute',
1325
1371
  left: '0',
1326
1372
  top: '0',
@@ -1911,13 +1957,13 @@ const KritzelDropdown = class {
1911
1957
  }
1912
1958
  updateInternalValue(proposedValue, emitChange) {
1913
1959
  let finalValue = proposedValue;
1914
- if (this.options && this.options.length > 0) {
1915
- const isValidValue = this.options.some(opt => opt.value === finalValue);
1916
- if (!finalValue || !isValidValue) {
1917
- finalValue = this.options[0].value;
1918
- }
1960
+ // Only fall back to an option if the proposed value is completely missing.
1961
+ // We intentionally don't sanitize invalid values here, to allow for values
1962
+ // that might be added to options asynchronously later (preventing race conditions).
1963
+ if (!finalValue && this.options && this.options.length > 0) {
1964
+ finalValue = this.options[0].value;
1919
1965
  }
1920
- else {
1966
+ else if (!finalValue) {
1921
1967
  finalValue = undefined;
1922
1968
  }
1923
1969
  if (this.internalValue !== finalValue) {
@@ -2089,7 +2135,7 @@ const KritzelDropdown = class {
2089
2135
  'open-up': this.openDirection === 'up',
2090
2136
  'open-down': this.openDirection === 'down',
2091
2137
  };
2092
- return (index.h(index.Host, { key: 'ac4dc8a445f79fa68555756a4ac26ba174a13eaa' }, index.h("div", { key: '1c73835be42e6a289657920ef33c2a53c183913d', class: "dropdown-wrapper", ref: el => (this.wrapperElement = el) }, index.h("slot", { key: 'ac73d76b5e24e2f2740113523524bc00d1c98d02', name: "prefix", ref: el => (this.prefixSlotElement = el), onSlotchange: this.evaluatePrefixContent }), index.h("div", { key: 'e1e71c68a8abb2cf0dc2b9314e05d1170c0bb5b3', class: "dropdown-container", style: { width: this.width } }, index.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) }, index.h("span", { key: '432f694526e20e1e6abb6721f12aa246471d830d', class: "dropdown-trigger-label" }, this.getSelectedLabel()), index.h("span", { key: '81f7d98f78201910f4427a7c442172d0283de45b', class: "dropdown-trigger-arrow", "aria-hidden": "true" }, index.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" }, index.h("polyline", { key: '32af6ce9a1f045c2ce3b205b1b1dc1fe1a80e227', points: "6 9 12 15 18 9" }))))), index.h("slot", { key: 'b37cd43daa06424ea7b7951929352154f7d1ea0f', name: "suffix", ref: el => (this.suffixSlotElement = el), onSlotchange: this.evaluateSuffixContent }), index.h("ul", { key: '0e673d4e09e007a4c93ed6a992dddeb8eba33e91', class: menuClasses, role: "listbox", tabindex: "-1", onKeyDown: this.handleMenuKeyDown, ref: el => (this.menuElement = el) }, this.options.map((option, index$1) => {
2138
+ return (index.h(index.Host, { key: 'c606b338e55dc66396105fa7b4fbdf372f3866e6' }, index.h("div", { key: 'aa32b73cac337fa4142ecc124cf039a59e3b3118', class: "dropdown-wrapper", ref: el => (this.wrapperElement = el) }, index.h("slot", { key: '2cd8e9ef246a24c49d58f76f227f36aed4786178', name: "prefix", ref: el => (this.prefixSlotElement = el), onSlotchange: this.evaluatePrefixContent }), index.h("div", { key: '80df8155e1907017d508e92f155bab5ae12dffab', class: "dropdown-container", style: { width: this.width } }, index.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) }, index.h("span", { key: '4ef6a997f7a781fb409e97ed5bd6843d0eaff0bb', class: "dropdown-trigger-label" }, this.getSelectedLabel()), index.h("span", { key: '6601efcd69d84af1f022d14ede628bac743cc1f1', class: "dropdown-trigger-arrow", "aria-hidden": "true" }, index.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" }, index.h("polyline", { key: 'a340af5a61dccf5bc29c8a473726b58055c2e9db', points: "6 9 12 15 18 9" }))))), index.h("slot", { key: '5bd4e5ad4cc4642c7769ecac2106ba82bae626f2', name: "suffix", ref: el => (this.suffixSlotElement = el), onSlotchange: this.evaluateSuffixContent }), index.h("ul", { key: 'e7a2be8ac261bc5fa1450940e2a57090d6be3315', class: menuClasses, role: "listbox", tabindex: "-1", onKeyDown: this.handleMenuKeyDown, ref: el => (this.menuElement = el) }, this.options.map((option, index$1) => {
2093
2139
  const isSelected = option.value === this.internalValue;
2094
2140
  const isFocused = index$1 === this.focusedIndex;
2095
2141
  const optionClasses = {
@@ -2311,6 +2357,8 @@ const KritzelEditor = class {
2311
2357
  },
2312
2358
  { label: 'Delete', icon: 'delete', group: 'edit', action: () => this.engineRef.delete() },
2313
2359
  ];
2360
+ themes;
2361
+ theme = 'light';
2314
2362
  customSvgIcons = {};
2315
2363
  isControlsVisible = true;
2316
2364
  isUtilityPanelVisible = true;
@@ -2357,9 +2405,9 @@ const KritzelEditor = class {
2357
2405
  isVirtualKeyboardOpen = false;
2358
2406
  undoState = null;
2359
2407
  isBackToContentButtonVisible = false;
2360
- currentTheme = 'light';
2361
2408
  shortcuts = [];
2362
2409
  currentIsPublic = false;
2410
+ isEditorVisible = false;
2363
2411
  onIsEngineReady(newValue) {
2364
2412
  if (newValue && this.isControlsReady) {
2365
2413
  this.checkIsReady();
@@ -2411,11 +2459,15 @@ const KritzelEditor = class {
2411
2459
  }
2412
2460
  }
2413
2461
  onCurrentThemeChange() {
2462
+ this.applyTheme();
2414
2463
  setTimeout(() => this.setOsSpecificCssVariables(), 0);
2415
2464
  if (this.engineRef) {
2416
2465
  this.engineRef.saveSettings(this.currentSettingsConfig);
2417
2466
  }
2418
2467
  }
2468
+ onThemesChange() {
2469
+ this.applyTheme();
2470
+ }
2419
2471
  onTouchStart(event) {
2420
2472
  if (event.cancelable) {
2421
2473
  event.preventDefault();
@@ -2557,6 +2609,12 @@ const KritzelEditor = class {
2557
2609
  async exportViewportAsSvg() {
2558
2610
  return this.engineRef.exportViewportAsSvg();
2559
2611
  }
2612
+ async exportSelectedObjectsAsPng() {
2613
+ return this.engineRef.exportSelectedObjectsAsPng();
2614
+ }
2615
+ async exportSelectedObjectsAsSvg() {
2616
+ return this.engineRef.exportSelectedObjectsAsSvg();
2617
+ }
2560
2618
  async downloadAsJson(filename) {
2561
2619
  return this.engineRef.downloadAsJson(filename);
2562
2620
  }
@@ -2584,6 +2642,9 @@ const KritzelEditor = class {
2584
2642
  async hideContextMenu() {
2585
2643
  return this.engineRef.hideContextMenu();
2586
2644
  }
2645
+ async openContextMenu(options) {
2646
+ return this.engineRef.openContextMenu(options);
2647
+ }
2587
2648
  async triggerSelectionChange() {
2588
2649
  return this.engineRef.triggerSelectionChange();
2589
2650
  }
@@ -2599,6 +2660,15 @@ const KritzelEditor = class {
2599
2660
  loginDialogRef;
2600
2661
  componentWillLoad() {
2601
2662
  this.loadSettingsFromStorage();
2663
+ this.applyTheme();
2664
+ }
2665
+ applyTheme() {
2666
+ const themeObj = this.resolveThemeObject();
2667
+ schema_constants.ThemeHelper.applyThemeToElement(this.host, themeObj);
2668
+ }
2669
+ resolveThemeObject() {
2670
+ return this.themes?.find(t => t.name === this.theme)
2671
+ ?? (this.theme === 'dark' ? schema_constants.darkTheme : schema_constants.lightTheme);
2602
2672
  }
2603
2673
  componentDidLoad() {
2604
2674
  this.registerCustomSvgIcons();
@@ -2613,6 +2683,7 @@ const KritzelEditor = class {
2613
2683
  if (!this.isEngineReady || !this.isControlsReady || !this.isWorkspaceManagerReady || !this.activeWorkspace) {
2614
2684
  return;
2615
2685
  }
2686
+ this.isEditorVisible = true;
2616
2687
  const { id, name, isPublic, createdAt, updatedAt } = this.activeWorkspace;
2617
2688
  this.isReady.emit({
2618
2689
  host: this.host,
@@ -2626,6 +2697,7 @@ const KritzelEditor = class {
2626
2697
  syncConfig: this.syncConfig,
2627
2698
  assetStorageConfig: this.assetStorageConfig,
2628
2699
  loginConfig: this.loginConfig,
2700
+ theme: this.theme
2629
2701
  });
2630
2702
  }
2631
2703
  async onEngineReady(event) {
@@ -2639,6 +2711,7 @@ const KritzelEditor = class {
2639
2711
  this.loadShortcuts();
2640
2712
  }
2641
2713
  handleWorkspacesChange(event) {
2714
+ event.stopPropagation();
2642
2715
  this.workspaces = event.detail;
2643
2716
  }
2644
2717
  handleActiveWorkspaceChange(event) {
@@ -2657,46 +2730,54 @@ const KritzelEditor = class {
2657
2730
  });
2658
2731
  }
2659
2732
  handleObjectsChange(event) {
2733
+ event.stopPropagation();
2660
2734
  this.objectsChange.emit(event.detail);
2661
2735
  }
2662
2736
  handleObjectsAdded(event) {
2737
+ event.stopPropagation();
2663
2738
  this.objectsAdded.emit(event.detail);
2664
2739
  }
2665
2740
  handleObjectsRemoved(event) {
2741
+ event.stopPropagation();
2666
2742
  this.objectsRemoved.emit(event.detail);
2667
2743
  }
2668
2744
  handleObjectsUpdated(event) {
2745
+ event.stopPropagation();
2669
2746
  this.objectsUpdated.emit(event.detail);
2670
2747
  }
2671
2748
  handleUndoStateChange(event) {
2749
+ event.stopPropagation();
2672
2750
  this.undoStateChange.emit(event.detail);
2673
2751
  this.undoState = event.detail;
2674
2752
  }
2675
2753
  async handleObjectsInViewportChange(event) {
2754
+ event.stopPropagation();
2676
2755
  const hasVisibleObjects = this.getContentObjects(event.detail).length > 0;
2677
2756
  const hasAnyObjectsAtAll = this.getContentObjects(await this.engineRef.getAllObjects()).length > 0;
2678
2757
  this.isBackToContentButtonVisible = !hasVisibleObjects && hasAnyObjectsAtAll;
2679
2758
  }
2680
2759
  handleViewportChange(event) {
2760
+ event.stopPropagation();
2681
2761
  this.viewportChange.emit(event.detail);
2682
2762
  }
2683
2763
  handleAwarenessChange(event) {
2764
+ event.stopPropagation();
2684
2765
  this.awarenessChange.emit(event.detail);
2685
2766
  }
2686
2767
  handleSettingsChange(event) {
2687
2768
  this.scaleMin = event.detail.scaleMin;
2688
2769
  this.scaleMax = event.detail.scaleMax;
2689
2770
  this.lockDrawingScale = event.detail.lockDrawingScale;
2690
- this.currentTheme = event.detail.theme;
2771
+ this.theme = event.detail.theme;
2691
2772
  this.viewportBoundaryLeft = event.detail.viewportBoundaryLeft ?? -Infinity;
2692
2773
  this.viewportBoundaryRight = event.detail.viewportBoundaryRight ?? Infinity;
2693
2774
  this.viewportBoundaryTop = event.detail.viewportBoundaryTop ?? -Infinity;
2694
2775
  this.viewportBoundaryBottom = event.detail.viewportBoundaryBottom ?? Infinity;
2695
2776
  this.debugInfo = event.detail.debugInfo;
2696
- this.themeChange.emit(event.detail.theme);
2697
2777
  if (this.engineRef) {
2698
2778
  this.engineRef.saveSettings(event.detail);
2699
2779
  }
2780
+ this.themeChange.emit(event.detail.theme);
2700
2781
  }
2701
2782
  get moreMenuItems() {
2702
2783
  return [
@@ -2792,8 +2873,8 @@ const KritzelEditor = class {
2792
2873
  if (typeof parsed.lockDrawingScale === 'boolean') {
2793
2874
  this.lockDrawingScale = parsed.lockDrawingScale;
2794
2875
  }
2795
- if (parsed.theme === 'light' || parsed.theme === 'dark') {
2796
- this.currentTheme = parsed.theme;
2876
+ if (typeof parsed.theme === 'string') {
2877
+ this.theme = parsed.theme;
2797
2878
  }
2798
2879
  if (typeof parsed.viewportBoundaryLeft === 'number') {
2799
2880
  this.viewportBoundaryLeft = parsed.viewportBoundaryLeft;
@@ -2824,7 +2905,7 @@ const KritzelEditor = class {
2824
2905
  scaleMin: this.scaleMin,
2825
2906
  scaleMax: this.scaleMax,
2826
2907
  lockDrawingScale: this.lockDrawingScale,
2827
- theme: this.currentTheme,
2908
+ theme: this.theme,
2828
2909
  viewportBoundaryLeft: this.viewportBoundaryLeft,
2829
2910
  viewportBoundaryRight: this.viewportBoundaryRight,
2830
2911
  viewportBoundaryTop: this.viewportBoundaryTop,
@@ -2877,28 +2958,32 @@ const KritzelEditor = class {
2877
2958
  render() {
2878
2959
  const isLoggedIn = this.isLoggedIn;
2879
2960
  const shouldShowCurrentUser = isLoggedIn;
2880
- const shouldShowLoginButton = !!this.loginConfig && !isLoggedIn;
2881
- return (index.h(index.Host, { key: '2856db9fa6a0926df078d5d6eedb19d2b4de98a5' }, index.h("div", { key: '7ffad0fd28904b740af43e20addfef701bbcead9', class: "top-left-buttons" }, index.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) }), index.h("kritzel-back-to-content", { key: '0039bc16615c26ab239ceeac418a7d47ff2ad40a', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), index.h("kritzel-engine", { key: '4815e1c4dfc6a04e68894b795c02dd678fec108d', ref: el => {
2961
+ const shouldShowLoginButton = this.isReady && !!this.loginConfig && !isLoggedIn;
2962
+ return (index.h(index.Host, { key: '3606d2318e6811f2f4b647f1531ff8bda409a401', style: {
2963
+ opacity: this.isEditorVisible ? '1' : '0',
2964
+ visibility: this.isEditorVisible ? 'visible' : 'hidden',
2965
+ transition: 'opacity 0.2s ease-in-out, visibility 0.2s ease-in-out',
2966
+ } }, index.h("div", { key: '094e66c69a829a3d150cd672f66f3f092cf19623', class: "top-left-buttons" }, index.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) }), index.h("kritzel-back-to-content", { key: '9768ead0daf60292c649a0ccdb4dcd92d8ce342a', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), index.h("kritzel-engine", { key: 'cf4cf487da19cd10352a31dab4e50db4aaabfd7a', ref: el => {
2882
2967
  if (el) {
2883
2968
  this.engineRef = el;
2884
2969
  }
2885
- }, 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) }), index.h("kritzel-controls", { key: 'fc44c417ee17a98f2b5d8eecffac6a86e43fda2a', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => {
2970
+ }, 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) }), index.h("kritzel-controls", { key: 'eb0839b834e688f15461ebd7391c87b331a5b328', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => {
2886
2971
  if (el) {
2887
2972
  this.controlsRef = el;
2888
2973
  }
2889
- }, controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.currentTheme, onIsControlsReady: () => (this.isControlsReady = true) }), index.h("div", { key: 'f333d2b31d456d4e35dbd41c93492329939a7c4d', class: "top-right-buttons" }, index.h("kritzel-settings", { key: '7900c9b1c3fd35e07e0d2a2aa0b797f455f52e1d', ref: el => {
2974
+ }, controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, onIsControlsReady: () => (this.isControlsReady = true) }), index.h("div", { key: 'e5c14a118d245ef0ec1c5863eb21022a5e5d7c77', class: "top-right-buttons" }, index.h("kritzel-settings", { key: 'bad9ebae5bc91efaf388e525375ba263f0344374', ref: el => {
2890
2975
  if (el) {
2891
2976
  this.settingsRef = el;
2892
2977
  }
2893
- }, shortcuts: this.shortcuts, settings: this.currentSettingsConfig, onSettingsChange: event => this.handleSettingsChange(event) }), index.h("kritzel-export", { key: 'c6ad8ae5255c9d90d854b7a26e81b65cfdc6236d', ref: el => {
2978
+ }, 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) }), index.h("kritzel-export", { key: 'ca28cd1057181b347af75ea51950114272bf33ec', ref: el => {
2894
2979
  if (el) {
2895
2980
  this.exportRef = el;
2896
2981
  }
2897
- }, workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), index.h("kritzel-active-users", { key: '3d6d3c460e5954b4d477c6bcc9992e503f781a81', users: this.activeUsers }), shouldShowCurrentUser && index.h("kritzel-current-user", { key: '33a72ce69276082ca7cc2815a93ad14de8dcf5a0', user: this.user }), shouldShowLoginButton && index.h("kritzel-button", { key: '809dedeacbf89674e42ab3e5850e67aadfe1111c', onButtonClick: () => this.loginDialogRef?.open() }, "Sign in"), index.h("kritzel-more-menu", { key: '7521045a24e32e6aa69a5a8c41a4edea5d657d93', items: this.moreMenuItems, visible: this.isMoreMenuVisible }), index.h("kritzel-share-dialog", { key: 'a4e778dee23b3dba94109c141e3628f22b740355', ref: el => {
2982
+ }, workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), index.h("kritzel-active-users", { key: '1b667e832c1f231ecdd9ea0cca0504c6f4a82ce1', users: this.activeUsers }), shouldShowCurrentUser && index.h("kritzel-current-user", { key: 'ec0a1827625f79435d20b8d53374eb29e7174f7e', user: this.user }), shouldShowLoginButton && (index.h("kritzel-button", { key: '0ddec61cc09b96797c33ae18c225ec967efed3e8', onButtonClick: () => this.loginDialogRef?.open() }, "Sign in")), index.h("kritzel-more-menu", { key: 'e9d41eff38bbd4e9420f8586559597f8ec9d6802', items: this.moreMenuItems, visible: this.isMoreMenuVisible }), index.h("kritzel-share-dialog", { key: 'f3fd8a06f5cf0ac89c02d535ee30dec05c9e536f', ref: el => {
2898
2983
  if (el) {
2899
2984
  this.shareDialogRef = el;
2900
2985
  }
2901
- }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (index.h("kritzel-login-dialog", { key: '3394d489bdbc92c572208c8f65601bf91568f0c4', ref: el => {
2986
+ }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (index.h("kritzel-login-dialog", { key: '49bd9f85d4cb7ee0f8dc7d2b7248169848c36b9f', ref: el => {
2902
2987
  if (el) {
2903
2988
  this.loginDialogRef = el;
2904
2989
  }
@@ -2920,8 +3005,11 @@ const KritzelEditor = class {
2920
3005
  "activeWorkspaceId": [{
2921
3006
  "onActiveWorkspaceIdChange": 0
2922
3007
  }],
2923
- "currentTheme": [{
3008
+ "theme": [{
2924
3009
  "onCurrentThemeChange": 0
3010
+ }],
3011
+ "themes": [{
3012
+ "onThemesChange": 0
2925
3013
  }]
2926
3014
  }; }
2927
3015
  };
@@ -21151,6 +21239,60 @@ class KritzelContextMenuHandler extends schema_constants.KritzelBaseHandler {
21151
21239
  this._core.store.state.isEnabled = false;
21152
21240
  this._core.rerender();
21153
21241
  }
21242
+ /**
21243
+ * Programmatically opens the context menu at a specified world-coordinate position.
21244
+ * If an objectId is provided and found, the object context menu is shown for that object.
21245
+ * If no objectId is provided but a selection group exists, the object context menu is shown.
21246
+ * Otherwise, the global context menu is shown.
21247
+ * @param options.x - The X position in world (canvas) coordinates.
21248
+ * @param options.y - The Y position in world (canvas) coordinates.
21249
+ * @param options.objectId - Optional ID of an object to select and show the object context menu for.
21250
+ */
21251
+ open(options) {
21252
+ const { x, y, objectId } = options;
21253
+ if (this._core.store.state.activeTool instanceof schema_constants.KritzelSelectionTool) {
21254
+ const selectionTool = this._core.store.state.activeTool;
21255
+ selectionTool?.moveHandler?.cancelPendingDrag();
21256
+ }
21257
+ if (this._core.store.selectionBox) {
21258
+ this._core.store.objects.remove(object => object instanceof schema_constants.KritzelSelectionBox);
21259
+ this._core.store.setSelectionBox(null);
21260
+ this._core.store.state.isSelecting = false;
21261
+ }
21262
+ if (objectId) {
21263
+ const targetObject = this._core.store.allObjects.find(obj => obj.id === objectId);
21264
+ if (targetObject && !(targetObject instanceof schema_constants.KritzelSelectionGroup) && !(targetObject instanceof schema_constants.KritzelSelectionBox)) {
21265
+ const selectionGroup = schema_constants.KritzelSelectionGroup.create(this._core);
21266
+ selectionGroup.addOrRemove(targetObject);
21267
+ selectionGroup.isSelected = true;
21268
+ selectionGroup.rotation = targetObject.rotation;
21269
+ this._core.store.state.isSelecting = false;
21270
+ const currentSelectionGroup = this._core.store.selectionGroup;
21271
+ if (currentSelectionGroup) {
21272
+ this._core.removeSelectionGroup();
21273
+ }
21274
+ this._core.addSelectionGroup(selectionGroup);
21275
+ }
21276
+ }
21277
+ this._core.store.state.contextMenuItems = this._core.store.selectionGroup ? this.objectContextMenuItems : this.globalContextMenuItems;
21278
+ this._core.store.state.contextMenuWorldX = x;
21279
+ this._core.store.state.contextMenuWorldY = y;
21280
+ const { translateX, translateY, scale } = this._core.store.state;
21281
+ let screenX = x * scale + translateX;
21282
+ let screenY = y * scale + translateY;
21283
+ const menuWidthEstimate = 150;
21284
+ const margin = 10;
21285
+ if (screenX + menuWidthEstimate > this._core.store.state.viewportWidth - margin) {
21286
+ screenX = this._core.store.state.viewportWidth - menuWidthEstimate - margin;
21287
+ }
21288
+ screenX = Math.max(margin, screenX);
21289
+ screenY = Math.max(margin, screenY);
21290
+ this._core.store.state.contextMenuX = screenX;
21291
+ this._core.store.state.contextMenuY = screenY;
21292
+ this._core.store.state.isContextMenuVisible = true;
21293
+ this._core.store.state.isEnabled = false;
21294
+ this._core.rerender();
21295
+ }
21154
21296
  }
21155
21297
 
21156
21298
  /**
@@ -24458,6 +24600,7 @@ class KritzelCore {
24458
24600
  });
24459
24601
  group.finalize();
24460
24602
  };
24603
+ const newlyAddedObjects = [];
24461
24604
  // First add all copied objects to the objectsMap with updated positions
24462
24605
  copiedObjects.forEach((obj, i) => {
24463
24606
  // Update workspace if pasting to a different workspace
@@ -24474,9 +24617,11 @@ class KritzelCore {
24474
24617
  }
24475
24618
  // Add to objectsMap
24476
24619
  this.addObject(obj);
24620
+ newlyAddedObjects.push(obj);
24477
24621
  // Add to selection group
24478
24622
  selectionGroup.addOrRemove(obj);
24479
24623
  });
24624
+ this.engine.emitObjectsAdded(newlyAddedObjects);
24480
24625
  // Update line anchors to point to the newly pasted objects
24481
24626
  // Only remap if the anchor target was also part of the copied selection
24482
24627
  copiedObjects.forEach(obj => {
@@ -26384,6 +26529,14 @@ const KritzelEngine = class {
26384
26529
  onThemeChange(newValue) {
26385
26530
  this.core.themeManager.setTheme(newValue);
26386
26531
  }
26532
+ /** An array of available themes for the editor. */
26533
+ themes;
26534
+ onThemesChange(newValue) {
26535
+ if (newValue && newValue.length > 0) {
26536
+ this.core.themeManager.registerThemes(newValue);
26537
+ this.core.themeManager.applyTheme(this.core.themeManager.currentTheme);
26538
+ }
26539
+ }
26387
26540
  /** Left boundary of the viewport in world coordinates. Objects beyond this X position cannot be panned to. */
26388
26541
  viewportBoundaryLeft = -Infinity;
26389
26542
  onViewportBoundaryLeftChange(newValue) {
@@ -26746,6 +26899,18 @@ const KritzelEngine = class {
26746
26899
  this.core.store.state.isEnabled = true;
26747
26900
  this.core.rerender();
26748
26901
  }
26902
+ /**
26903
+ * Programmatically opens the context menu at a specified world-coordinate position.
26904
+ * If `objectId` is provided and found, the object context menu is shown for that object.
26905
+ * If no `objectId` is provided but a selection group already exists, the object context menu is shown.
26906
+ * Otherwise, the global context menu is shown.
26907
+ * @param options.x - The X position in world (canvas) coordinates.
26908
+ * @param options.y - The Y position in world (canvas) coordinates.
26909
+ * @param options.objectId - Optional ID of an object to select and show the object context menu for.
26910
+ */
26911
+ async openContextMenu(options) {
26912
+ this.contextMenuHandler.open(options);
26913
+ }
26749
26914
  /**
26750
26915
  * Retrieves a canvas object by its unique ID.
26751
26916
  * @param id - The object's unique identifier.
@@ -27615,6 +27780,11 @@ const KritzelEngine = class {
27615
27780
  }
27616
27781
  componentWillLoad() {
27617
27782
  this.core.setEditorId(this.editorId);
27783
+ if (this.themes && this.themes.length > 0) {
27784
+ this.core.themeManager.registerThemes(this.themes);
27785
+ }
27786
+ const editorElement = this.host.closest('kritzel-editor');
27787
+ this.core.themeManager.injectThemeEarly(editorElement || this.host);
27618
27788
  this.core.setUser(this.user);
27619
27789
  this.validateScaleMax(this.scaleMax);
27620
27790
  this.validateScaleMin(this.scaleMin);
@@ -28347,6 +28517,9 @@ const KritzelEngine = class {
28347
28517
  "theme": [{
28348
28518
  "onThemeChange": 0
28349
28519
  }],
28520
+ "themes": [{
28521
+ "onThemesChange": 0
28522
+ }],
28350
28523
  "viewportBoundaryLeft": [{
28351
28524
  "onViewportBoundaryLeftChange": 0
28352
28525
  }],
@@ -28443,7 +28616,7 @@ const KritzelExport = class {
28443
28616
  return (index.h("div", { class: "export-tab-content" }, index.h("kritzel-input", { label: "Filename", value: this.exportFilename, placeholder: "Enter filename", suffix: ".json", onValueChange: this.handleFilenameChange })));
28444
28617
  }
28445
28618
  render() {
28446
- return (index.h(index.Host, { key: '5178e66f75b94697c771e2dc6fe7ce317e21cd1a' }, index.h("kritzel-dialog", { key: 'f80cbe3fa709ed7e046303034b7345ca1f94bc48', isOpen: this.isDialogOpen, dialogTitle: "Export", closable: true, contained: true, onDialogClose: this.closeDialog }, index.h("div", { key: 'e7968807c2b67ebfc800cb1694b4e34af245ffba', class: "export-content" }, index.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(), index.h("button", { key: '3489affca39a901c2ef05a0698cdf51c0a7f6d1a', class: "export-primary-button", onClick: this.handleExport }, "Export")))));
28619
+ return (index.h(index.Host, { key: 'efeea781325e672e3f4c1579a50da1c928dc88b5' }, index.h("kritzel-dialog", { key: '60e27233f484e70fd12bcc0f8a72b89d2f72d596', isOpen: this.isDialogOpen, dialogTitle: "Export", closable: true, contained: true, onDialogClose: this.closeDialog }, index.h("div", { key: 'e58e1d9804fdc8cb3d4c053ead641e2301b99ea5', class: "export-content" }, index.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(), index.h("button", { key: '7166aee26e0dbbdf6e7348428f7a740614948e5e', class: "export-primary-button", onClick: this.handleExport }, "Export")))));
28447
28620
  }
28448
28621
  };
28449
28622
  KritzelExport.style = kritzelExportCss();
@@ -28458,7 +28631,7 @@ const KritzelFont = class {
28458
28631
  size = 24;
28459
28632
  color = '#000000';
28460
28633
  render() {
28461
- return (index.h(index.Host, { key: 'bcff1827a61df6896e49fe1df4819bf27b3610ef' }, index.h("div", { key: '53a03532afde5fca6e8ec1cc78e6cd41ab1444cd', class: "font-preview", style: {
28634
+ return (index.h(index.Host, { key: '6eef9e7df004469faeeaf458d9b9967f94f8536d' }, index.h("div", { key: '9926c54a57245c40d605077e191f62cebf3700b1', class: "font-preview", style: {
28462
28635
  fontFamily: this.fontFamily,
28463
28636
  fontSize: `${this.size}px`,
28464
28637
  color: this.color
@@ -28505,7 +28678,7 @@ const KritzelFontFamily = class {
28505
28678
  label: option.label,
28506
28679
  style: { fontFamily: option.value },
28507
28680
  }));
28508
- return (index.h(index.Host, { key: '3d942116fc1019f1b2982395a08b14a9b0081040' }, index.h("kritzel-dropdown", { key: 'a042505de2d9b27c6f77ed929496a3921c3170cd', options: dropdownOptions, value: this.selectedFontFamily, onValueChanged: this.handleDropdownValueChange, selectStyles: { fontFamily: this.selectedFontFamily } })));
28681
+ return (index.h(index.Host, { key: '0123dbdff9b7051d2ebc9dcf8d1f9c7c4c161dc4' }, index.h("kritzel-dropdown", { key: '5d4e289161502ecc60cef3d0c6d546a64817a12a', options: dropdownOptions, value: this.selectedFontFamily, onValueChanged: this.handleDropdownValueChange, selectStyles: { fontFamily: this.selectedFontFamily } })));
28509
28682
  }
28510
28683
  };
28511
28684
  KritzelFontFamily.style = kritzelFontFamilyCss();
@@ -28533,7 +28706,7 @@ const KritzelFontSize = class {
28533
28706
  }
28534
28707
  render() {
28535
28708
  const color = 'var(--kritzel-global-text-primary)';
28536
- return (index.h(index.Host, { key: 'c409d73ff06966fd3861a16c7de32d41db85c12a' }, this.sizes.map(size => (index.h("div", { tabIndex: 0, class: {
28709
+ return (index.h(index.Host, { key: 'efb5ad516a0ebfea0fee5c78a1d3b4d0af4a6bc9' }, this.sizes.map(size => (index.h("div", { tabIndex: 0, class: {
28537
28710
  'size-container': true,
28538
28711
  'selected': this.selectedSize === size,
28539
28712
  }, onClick: () => this.handleSizeClick(size), onKeyDown: event => this.handleKeyDown(event, size) }, index.h("kritzel-font", { fontFamily: this.fontFamily, size: size, color: color }))))));
@@ -28600,7 +28773,7 @@ const KritzelInput = class {
28600
28773
  this.valueChange.emit(input.value);
28601
28774
  };
28602
28775
  render() {
28603
- return (index.h(index.Host, { key: 'e482edcbaf7cee8c35effbce0428c2b4dea84bd4' }, index.h("div", { key: 'a71f5e3eeba5e34470227ea3be4dd6731a94a52e', class: "input-container" }, this.label && index.h("label", { key: '757a32997f09558412952fe948fa234d1baecb3f', class: "input-label" }, this.label), index.h("div", { key: 'cfb13fe0041efdd9fe4a7bf2a098ff321b545b79', class: { 'input-wrapper': true, 'has-suffix': !!this.suffix } }, index.h("input", { key: 'b8bf209f14f15f4ad8eb0cf1be1afb1bfc958f79', type: this.type, class: "text-input", value: this.inputValue, placeholder: this.placeholder, disabled: this.disabled, onInput: this.handleInput }), this.suffix && index.h("span", { key: 'b5d4444609ad93c10d86978a488252b673979c94', class: "input-suffix" }, this.suffix)))));
28776
+ return (index.h(index.Host, { key: '3fd1f42a3ad5edfac752c05f70558ef73bbfebc3' }, index.h("div", { key: '78468652ce95508090495fefa9381af175415be8', class: "input-container" }, this.label && index.h("label", { key: 'f368e0370df4848fa9448ed53382152ad8cc8816', class: "input-label" }, this.label), index.h("div", { key: 'c775c0c0a9f4b6c78ba83ced6237a744b7d3cf20', class: { 'input-wrapper': true, 'has-suffix': !!this.suffix } }, index.h("input", { key: 'aa5ce0bb5e3c56755bc6134a4328ce6294bda1ff', type: this.type, class: "text-input", value: this.inputValue, placeholder: this.placeholder, disabled: this.disabled, onInput: this.handleInput }), this.suffix && index.h("span", { key: '687cec4294e4cd10247db88caf157b33a3f16290', class: "input-suffix" }, this.suffix)))));
28604
28777
  }
28605
28778
  static get watchers() { return {
28606
28779
  "value": [{
@@ -28682,10 +28855,10 @@ const KritzelLineEndings = class {
28682
28855
  render() {
28683
28856
  const startEnding = this.getStartEnding();
28684
28857
  const endEnding = this.getEndEnding();
28685
- return (index.h(index.Host, { key: '38bcd0b0e56c0d0fc7fd57346b718054faa0ba06' }, index.h("div", { key: '5ae52039756334299a86d7301b15f6874d5689ff', class: "endings-section" }, index.h("div", { key: '8a0dd7792498248203f2db8c346828fe7f57534d', class: "endings-row" }, this.styles.map(type => (index.h("button", { class: {
28858
+ return (index.h(index.Host, { key: '60115b8a2840ffe21e0846fdc2678c6ba24b22c0' }, index.h("div", { key: '3b63aa05ca78699172c645fdd404efdc55bc4536', class: "endings-section" }, index.h("div", { key: '9538369e8d2bb26600d6054ddbbc13d6c960bd56', class: "endings-row" }, this.styles.map(type => (index.h("button", { class: {
28686
28859
  'ending-option': true,
28687
28860
  'selected': startEnding === type,
28688
- }, onClick: () => this.handleStartChange(type), title: type === 'none' ? 'No start arrow' : `${type} start arrow` }, this.renderEndingIcon(type, true)))))), index.h("div", { key: '001c6cc50af45e1461ef15e2c43df4efdd83b48f', class: "endings-section" }, index.h("div", { key: '96cc57da4bed38aa42207d40a6a21cd39fa18cad', class: "endings-row" }, this.styles.map(type => (index.h("button", { class: {
28861
+ }, onClick: () => this.handleStartChange(type), title: type === 'none' ? 'No start arrow' : `${type} start arrow` }, this.renderEndingIcon(type, true)))))), index.h("div", { key: 'ecec29740c09a61190938bab4955ccde6b84cfa2', class: "endings-section" }, index.h("div", { key: 'ea054597c3e3566e7921f2c04c07d74e4f4331a1', class: "endings-row" }, this.styles.map(type => (index.h("button", { class: {
28689
28862
  'ending-option': true,
28690
28863
  'selected': endEnding === type,
28691
28864
  }, onClick: () => this.handleEndChange(type), title: type === 'none' ? 'No end arrow' : `${type} end arrow` }, this.renderEndingIcon(type, false))))))));
@@ -28740,7 +28913,7 @@ const KritzelLoginDialog = class {
28740
28913
  this.dialogClosed.emit();
28741
28914
  };
28742
28915
  render() {
28743
- return (index.h(index.Host, { key: '1a664868b840030a773f61c2a0f4388dfb014675' }, index.h("kritzel-dialog", { key: '54844ffa772a211515c1ef3e6834ec45f7f3d035', dialogTitle: this.dialogTitle, isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, index.h("div", { key: 'd9b981b6904c58bc39173ae37ee5c4c0ee329005', class: "login-content" }, this.subtitle && (index.h("p", { key: 'd4d200060507d2b8b755796d8313acdfc7e2f587', class: "login-subtitle" }, this.subtitle)), index.h("div", { key: '3dc1e3c070e62d026eb16ceb48eb63c94bc2bed0', class: "login-providers" }, this.providers.map(provider => (index.h("button", { key: provider.name, class: {
28916
+ return (index.h(index.Host, { key: '8cac83db48fef2531f1669c3f601526b1e5cdefa' }, index.h("kritzel-dialog", { key: '34e7208c8c34550292c2b7503759bf103cfb49a6', dialogTitle: this.dialogTitle, isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, index.h("div", { key: 'b0a0d8e0f38adc8d9b9545a02c5fc879f64a24de', class: "login-content" }, this.subtitle && (index.h("p", { key: 'a51b5f0a8b402aaf979d4bf47c6f9c3ba7e14bfe', class: "login-subtitle" }, this.subtitle)), index.h("div", { key: 'b6d8f8748eadf1462dd4161f089130b7ded31b59', class: "login-providers" }, this.providers.map(provider => (index.h("button", { key: provider.name, class: {
28744
28917
  'provider-button': true,
28745
28918
  'is-loading': this.loadingProvider === provider.name,
28746
28919
  'is-disabled': this.loadingProvider !== null && this.loadingProvider !== provider.name,
@@ -28846,15 +29019,15 @@ const KritzelMasterDetail = class {
28846
29019
  const selectedItem = this.items.find(item => item.id === this.selectedItemId);
28847
29020
  const panelId = 'master-detail-panel';
28848
29021
  const selectedTabId = selectedItem ? `tab-${selectedItem.id}` : undefined;
28849
- return (index.h(index.Host, { key: '7f1fd360f657fddcdb6ce2eea17e4e2daf426eb2' }, index.h("div", { key: '02f7f6dd141d057dbf395dd836f7841a649fa16d', class: {
29022
+ return (index.h(index.Host, { key: '59479b50a3e79ee854c75d78e1a41c1cb0551dab' }, index.h("div", { key: '0fdfa2d5a28c8f5800b2eeb80c545bdfcd252f6b', class: {
28850
29023
  'master-detail-container': true,
28851
29024
  'is-mobile-detail-visible': this.showMobileDetail,
28852
- } }, index.h("nav", { key: '397758627252c5e9573a61c457d4481df6d9b4f2', class: "master-menu", role: "tablist", "aria-orientation": "vertical", "aria-label": "Settings categories" }, this.items.map((item, index$1) => (index.h("button", { key: item.id, id: `tab-${item.id}`, ref: el => this.setTabRef(el, index$1), class: {
29025
+ } }, index.h("nav", { key: 'f055346bdaf528e27136dffc680a5e2c6ddb95a7', class: "master-menu", role: "tablist", "aria-orientation": "vertical", "aria-label": "Settings categories" }, this.items.map((item, index$1) => (index.h("button", { key: item.id, id: `tab-${item.id}`, ref: el => this.setTabRef(el, index$1), class: {
28853
29026
  'menu-item': true,
28854
29027
  'is-selected': item.id === this.selectedItemId,
28855
29028
  'is-disabled': !!item.disabled,
28856
29029
  'is-focused': index$1 === this.focusedIndex,
28857
- }, role: "tab", "aria-selected": item.id === this.selectedItemId ? 'true' : 'false', "aria-controls": panelId, "aria-disabled": item.disabled ? 'true' : undefined, tabIndex: this.getTabIndex(item, index$1), disabled: item.disabled, onClick: () => this.handleItemClick(item), onKeyDown: e => this.handleKeyDown(e, item, index$1), onFocus: () => this.handleFocus(index$1), onBlur: this.handleBlur }, item.icon && (index.h("kritzel-icon", { name: item.icon, size: 20, class: "menu-item-icon" })), index.h("span", { class: "menu-item-label" }, item.label), index.h("span", { class: "menu-item-chevron", "aria-hidden": "true" }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }, index.h("path", { d: "m9 18 6-6-6-6" }))))))), index.h("div", { key: '65cc4601a39cb7780c52cc86075efd0b4a24646a', id: panelId, class: "detail-panel", role: "tabpanel", "aria-labelledby": selectedTabId }, index.h("button", { key: '6b6ae9ac689c757d71e2a42ecaf8aaceb3785154', class: "mobile-back-button", onClick: this.handleBackClick, "aria-label": "Back to menu" }, index.h("kritzel-icon", { key: '28d9b2f68030587d44505f691e8fed57d968e631', name: "chevron-left", size: 20, class: "mobile-back-icon" }), "Back"), index.h("slot", { key: '2a35ca82717713808ca12227ecca671b848d1f02' })))));
29030
+ }, role: "tab", "aria-selected": item.id === this.selectedItemId ? 'true' : 'false', "aria-controls": panelId, "aria-disabled": item.disabled ? 'true' : undefined, tabIndex: this.getTabIndex(item, index$1), disabled: item.disabled, onClick: () => this.handleItemClick(item), onKeyDown: e => this.handleKeyDown(e, item, index$1), onFocus: () => this.handleFocus(index$1), onBlur: this.handleBlur }, item.icon && (index.h("kritzel-icon", { name: item.icon, size: 20, class: "menu-item-icon" })), index.h("span", { class: "menu-item-label" }, item.label), index.h("span", { class: "menu-item-chevron", "aria-hidden": "true" }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }, index.h("path", { d: "m9 18 6-6-6-6" }))))))), index.h("div", { key: '296ff692092eae9b73c673def66539aa4eb36053', id: panelId, class: "detail-panel", role: "tabpanel", "aria-labelledby": selectedTabId }, index.h("button", { key: '72c65aa2825aa373daa3b1d6fd48d8dd84ab25f1', class: "mobile-back-button", onClick: this.handleBackClick, "aria-label": "Back to menu" }, index.h("kritzel-icon", { key: '2241991dc0da3f53f77dc415e61f026a5734ad48', name: "chevron-left", size: 20, class: "mobile-back-icon" }), "Back"), index.h("slot", { key: '6ecdc24e462faf0d95e295d5536b44ea2f9181c9' })))));
28858
29031
  }
28859
29032
  static get watchers() { return {
28860
29033
  "selectedItemId": [{
@@ -28927,7 +29100,7 @@ const KritzelMenu = class {
28927
29100
  this.itemCloseChildMenu.emit(event.detail);
28928
29101
  };
28929
29102
  render() {
28930
- return (index.h(index.Host, { key: 'a81ea8a1fe2dc6cb8d9f395cafbcadec3eb4aa45', tabIndex: 0, onClick: e => e.stopPropagation() }, this.openChildMenuItem && index.h("div", { key: 'bb27d7a923431d79567e79283e505ea4ae02ef36', class: "has-open-child-overlay", onClick: this.onOverlayClick }), this.items.map(item => (index.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 })))));
29103
+ return (index.h(index.Host, { key: '2d6d46fc8135133ed3e42d65399c8549bc5f6bb5', tabIndex: 0, onClick: e => e.stopPropagation() }, this.openChildMenuItem && index.h("div", { key: 'b5b3910cc82f7cb451730792fe6e3b3a254036f3', class: "has-open-child-overlay", onClick: this.onOverlayClick }), this.items.map(item => (index.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 })))));
28931
29104
  }
28932
29105
  };
28933
29106
  KritzelMenu.style = kritzelMenuCss();
@@ -29032,12 +29205,12 @@ const KritzelMenuItem = class {
29032
29205
  ];
29033
29206
  }
29034
29207
  render() {
29035
- return (index.h(index.Host, { key: '6fd639ff533e0b2c39febd369b4ba034661ec708', tabIndex: this.item.isDisabled ? -1 : 0, class: {
29208
+ return (index.h(index.Host, { key: 'ae5057ce9101dc08e2365455c544914715be468e', tabIndex: this.item.isDisabled ? -1 : 0, class: {
29036
29209
  'selected': this.item.isSelected,
29037
29210
  'editing': this.item.isEditing,
29038
29211
  'disabled': this.item.isDisabled,
29039
29212
  'child-open': this.item.isChildMenuOpen,
29040
- }, onClick: this.handleItemSelect }, index.h("div", { key: 'd7486e9f1614be1801268fa97947aaab4c12460d', class: "menu-item-overlay" }), this.item.isEditing ? this.renderEditMode() : this.renderViewMode()));
29213
+ }, onClick: this.handleItemSelect }, index.h("div", { key: '973fc68404ea95c2f0459565b8a3d124d31ae090', class: "menu-item-overlay" }), this.item.isEditing ? this.renderEditMode() : this.renderViewMode()));
29041
29214
  }
29042
29215
  static get watchers() { return {
29043
29216
  "item": [{
@@ -29108,7 +29281,7 @@ const KritzelMoreMenu = class {
29108
29281
  this.closeMenu();
29109
29282
  };
29110
29283
  render() {
29111
- return (index.h(index.Host, { key: '33d85e3b5ad51effdf2f61c8742dbe829ef43f15', class: { mobile: this.isTouchDevice }, style: { display: this.visible ? '' : 'none' } }, index.h("div", { key: '917ca25a14294f44a0428431a3ec08a84db2aff0', class: { 'more-menu-wrapper': true, visible: this.visible } }, index.h("button", { key: '61e145de48ac7aced1fcc03dde5d5d14f4448167', class: "more-menu-button", "data-testid": "more-menu-button", onClick: this.toggleMenu, "aria-label": "More options" }, index.h("kritzel-icon", { key: 'ba13d2117b28658c518c9721f348329d677683f9', name: this.icon, size: this.iconSize })), index.h("kritzel-portal", { key: '48d757891102ec2925366e0ca0542a6e75f2621f', anchor: this.menuAnchor, offsetY: this.offsetY, onClose: this.closeMenu }, index.h("kritzel-menu", { key: 'f04040f7122507642652839be4f75fbb157de20d', items: this.visibleItems, onItemSelect: this.handleMenuItemSelect })))));
29284
+ return (index.h(index.Host, { key: '93bee9fc14d532a74f1b077098fb0a470655d2fe', class: { mobile: this.isTouchDevice }, style: { display: this.visible ? '' : 'none' } }, index.h("div", { key: '1783013acb533de9580698f29a7c8ae212b583fc', class: { 'more-menu-wrapper': true, visible: this.visible } }, index.h("button", { key: '8dc2f098377e78db0bf6efc05daaf02496cef527', class: "more-menu-button", "data-testid": "more-menu-button", onClick: this.toggleMenu, "aria-label": "More options" }, index.h("kritzel-icon", { key: '876a229226b0f79f1d5ef5d0b7793f362b884923', name: this.icon, size: this.iconSize })), index.h("kritzel-portal", { key: '57f7a69408b00c1bb9e5a08d22e224c6e6bcdea4', anchor: this.menuAnchor, offsetY: this.offsetY, onClose: this.closeMenu }, index.h("kritzel-menu", { key: '73a2aacd1b7c0ec79d7fa1695fbc02b1a0bde1b5', items: this.visibleItems, onItemSelect: this.handleMenuItemSelect })))));
29112
29285
  }
29113
29286
  };
29114
29287
  KritzelMoreMenu.style = kritzelMoreMenuCss();
@@ -29206,7 +29379,7 @@ const KritzelNumericInput = class {
29206
29379
  this.valueChange.emit(newValue);
29207
29380
  };
29208
29381
  render() {
29209
- return (index.h(index.Host, { key: 'b27f16d562bc6c61b0a6a289e622e7e35159a782' }, index.h("div", { key: '7f5f2295a60b46dc05c003b10ff74e9da6822406', class: "input-container" }, this.label && index.h("label", { key: 'a5a10af06139312ef0b038ed8c3bb533afa6235c', class: "input-label" }, this.label), index.h("div", { key: 'b15b4a2d84ad1185a67cd748176c7585a0789f09', class: "input-wrapper" }, index.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 }), index.h("div", { key: '9813f61998a8902d9a1bc4100dbab744e91e98f8', class: "spinner-buttons" }, index.h("button", { key: 'ad688c3332b0dbdd6327c66aed778d3e0d036aab', type: "button", class: "spinner-button spinner-up", onClick: this.handleIncrement, tabIndex: -1, "aria-label": "Increase value" }, index.h("svg", { key: 'a21ec61f331a7b672d2ce56cd2d1b30e7f0b22c6', viewBox: "0 0 10 6", class: "spinner-icon" }, index.h("path", { key: 'f36b4f68ea3733851bebce1e9f45a1f36e62acdc', d: "M1 5L5 1L9 5", stroke: "currentColor", "stroke-width": "1.5", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }))), index.h("button", { key: '484373581f26b6cf71194bf545d67997ef7db79f', type: "button", class: "spinner-button spinner-down", onClick: this.handleDecrement, tabIndex: -1, "aria-label": "Decrease value" }, index.h("svg", { key: '5b9199c270ad270729b9f5c1c9246824e1d49cb8', viewBox: "0 0 10 6", class: "spinner-icon" }, index.h("path", { key: 'd96e78c311bbc941edfafcb02017da7c367aaf2e', d: "M1 1L5 5L9 1", stroke: "currentColor", "stroke-width": "1.5", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }))))))));
29382
+ return (index.h(index.Host, { key: '18cd66a764c334a78e2dccd444f448235b41c38c' }, index.h("div", { key: '73305950e3e840e51466d720a2ef4f834a16adc1', class: "input-container" }, this.label && index.h("label", { key: 'f9521cb0137f5f8c676ced5c76989d8d03256f68', class: "input-label" }, this.label), index.h("div", { key: '07581a242db247a833cfa879b90c6da5dd06b116', class: "input-wrapper" }, index.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 }), index.h("div", { key: 'd3920c978a4d97032f5aec550e6ca7e74c9c2e94', class: "spinner-buttons" }, index.h("button", { key: 'ae27375f0ba66a9ca6cf53fe4a05fa219bf47711', type: "button", class: "spinner-button spinner-up", onClick: this.handleIncrement, tabIndex: -1, "aria-label": "Increase value" }, index.h("svg", { key: '8a6e40c12468bb44400c1ad015463c830d0af13e', viewBox: "0 0 10 6", class: "spinner-icon" }, index.h("path", { key: '70b8ee3cc3b00d7f83822078f73e0437e24a98aa', d: "M1 5L5 1L9 5", stroke: "currentColor", "stroke-width": "1.5", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }))), index.h("button", { key: 'e26968c85480cbf4cd0f3bd9d6db59f1d6ade88c', type: "button", class: "spinner-button spinner-down", onClick: this.handleDecrement, tabIndex: -1, "aria-label": "Decrease value" }, index.h("svg", { key: 'a8c72dd2909b89ceb3797d0a77e531d0b5374e1d', viewBox: "0 0 10 6", class: "spinner-icon" }, index.h("path", { key: '16c95c8cbc90c9d49d081745384c3920620591fb', d: "M1 1L5 5L9 1", stroke: "currentColor", "stroke-width": "1.5", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }))))))));
29210
29383
  }
29211
29384
  static get watchers() { return {
29212
29385
  "value": [{
@@ -29245,8 +29418,9 @@ const KritzelOpacitySlider = class {
29245
29418
  }
29246
29419
  render() {
29247
29420
  const percentage = this.getPercentage();
29248
- return (index.h(index.Host, { key: 'f6460d2d37ca76c69c62597b32f7567c8a2e1b77' }, index.h("div", { key: '09cb87f8e7e09639b4b794f9c9b30da024a4023f', class: "opacity-container" }, index.h("div", { key: '783cd792f0511945f685483a181b621f3c2551f8', class: "slider-wrapper" }, index.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: {
29421
+ return (index.h(index.Host, { key: '988ad7b9ee8d3825c8577d951c6f1d00efbb45eb' }, index.h("div", { key: '4dad6a7d422333fbcaff55b2b374550b496a3adc', class: "opacity-container" }, index.h("div", { key: '7a0ceedd10f2e939dbf189410cc7263c7df498db', class: "slider-wrapper" }, index.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: {
29249
29422
  '--slider-progress': `${percentage}%`,
29423
+ '--kritzel-opacity-slider-thumb-border-color': this.previewColor,
29250
29424
  } })))));
29251
29425
  }
29252
29426
  };
@@ -29309,7 +29483,7 @@ const KritzelPillTabs = class {
29309
29483
  buttons?.[newIndex]?.focus();
29310
29484
  }
29311
29485
  render() {
29312
- return (index.h(index.Host, { key: 'cd6993107010e578b91af23101da27bd2ef943cd' }, index.h("div", { key: '509c023b5bf91de1f463c8e080b83216a94d7d64', class: "pill-tabs-container", role: "tablist" }, this.tabs.map((tab, index$1) => (index.h("button", { key: tab.id, class: {
29486
+ return (index.h(index.Host, { key: 'f02f93ada5ec002695b62f511c847de201a8cbe4' }, index.h("div", { key: 'bb08ae773f1b993cb330556a5778d71fc5e91ce1', class: "pill-tabs-container", role: "tablist" }, this.tabs.map((tab, index$1) => (index.h("button", { key: tab.id, class: {
29313
29487
  'pill-tab': true,
29314
29488
  'selected': this.value === tab.id,
29315
29489
  }, 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$1) }, tab.icon && index.h("kritzel-icon", { name: tab.icon, size: 16 }), index.h("span", { class: "pill-tab-label" }, tab.label)))))));
@@ -29597,7 +29771,7 @@ const KritzelPortal = class {
29597
29771
  this.portal.style.visibility = 'visible';
29598
29772
  }
29599
29773
  render() {
29600
- return (index.h(index.Host, { key: 'dcd8e6f3787c713012aeb6436bf63f2f4930c39e', style: { display: this.anchor ? 'block' : 'none' } }, index.h("slot", { key: '830f51521a77f0a28471026494323e14ab4f9f9a' })));
29774
+ return (index.h(index.Host, { key: 'ea4b3c0bdaeb94a1aa03714537c3b68c972ad9c5', style: { display: this.anchor ? 'block' : 'none' } }, index.h("slot", { key: 'cd9060be1fbb801e3b72546d465576d5d79b3c82' })));
29601
29775
  }
29602
29776
  static get watchers() { return {
29603
29777
  "anchor": [{
@@ -29611,7 +29785,7 @@ const KritzelPortal = class {
29611
29785
  * This file is auto-generated by the version bump scripts.
29612
29786
  * Do not modify manually.
29613
29787
  */
29614
- const KRITZEL_VERSION = '0.3.8';
29788
+ const KRITZEL_VERSION = '0.3.10';
29615
29789
 
29616
29790
  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)}`;
29617
29791
 
@@ -29642,6 +29816,7 @@ const KritzelSettings = class {
29642
29816
  }
29643
29817
  get host() { return index.getElement(this); }
29644
29818
  /** Keyboard shortcuts to display in the settings dialog */
29819
+ availableThemes = ['light', 'dark'];
29645
29820
  shortcuts = [];
29646
29821
  /** Current settings values. Used to initialize and sync the component's internal state. */
29647
29822
  settings;
@@ -29655,7 +29830,7 @@ const KritzelSettings = class {
29655
29830
  scaleMin = DEFAULT_SCALE_MIN;
29656
29831
  scaleMax = DEFAULT_SCALE_MAX;
29657
29832
  lockDrawingScale = DEFAULT_LOCK_DRAWING_SCALE;
29658
- currentTheme = 'light';
29833
+ theme = 'light';
29659
29834
  viewportBoundaryLeft = DEFAULT_VIEWPORT_BOUNDARY_LEFT;
29660
29835
  viewportBoundaryRight = DEFAULT_VIEWPORT_BOUNDARY_RIGHT;
29661
29836
  viewportBoundaryTop = DEFAULT_VIEWPORT_BOUNDARY_TOP;
@@ -29678,8 +29853,8 @@ const KritzelSettings = class {
29678
29853
  if (typeof settings.lockDrawingScale === 'boolean') {
29679
29854
  this.lockDrawingScale = settings.lockDrawingScale;
29680
29855
  }
29681
- if (settings.theme === 'light' || settings.theme === 'dark') {
29682
- this.currentTheme = settings.theme;
29856
+ if (typeof settings.theme === 'string') {
29857
+ this.theme = settings.theme;
29683
29858
  }
29684
29859
  if (typeof settings.viewportBoundaryLeft === 'number') {
29685
29860
  this.viewportBoundaryLeft = settings.viewportBoundaryLeft;
@@ -29702,7 +29877,7 @@ const KritzelSettings = class {
29702
29877
  scaleMin: this.scaleMin,
29703
29878
  scaleMax: this.scaleMax,
29704
29879
  lockDrawingScale: this.lockDrawingScale,
29705
- theme: this.currentTheme,
29880
+ theme: this.theme,
29706
29881
  viewportBoundaryLeft: this.viewportBoundaryLeft,
29707
29882
  viewportBoundaryRight: this.viewportBoundaryRight,
29708
29883
  viewportBoundaryTop: this.viewportBoundaryTop,
@@ -29724,7 +29899,7 @@ const KritzelSettings = class {
29724
29899
  this.emitSettings();
29725
29900
  };
29726
29901
  handleThemeChange = (event) => {
29727
- this.currentTheme = event.detail ? 'dark' : 'light';
29902
+ this.theme = event.detail;
29728
29903
  this.emitSettings();
29729
29904
  };
29730
29905
  handleViewportBoundaryLeftChange = (event) => {
@@ -29785,7 +29960,7 @@ const KritzelSettings = class {
29785
29960
  renderCategoryContent() {
29786
29961
  switch (this.selectedCategoryId) {
29787
29962
  case 'general':
29788
- return (index.h("div", { class: "settings-content" }, index.h("h3", null, "General Settings"), index.h("div", { class: "settings-group" }, index.h("div", { class: "settings-item" }, index.h("label", { class: "settings-label" }, "Dark Mode"), index.h("p", { class: "settings-description" }, "Toggle between light and dark color themes for the editor interface."), index.h("kritzel-slide-toggle", { checked: this.currentTheme === 'dark', label: "Dark Mode", onCheckedChange: this.handleThemeChange })), index.h("div", { class: "settings-item" }, index.h("label", { class: "settings-label" }, "Lock Drawing Scale"), index.h("p", { class: "settings-description" }, "When enabled, drawn objects maintain a fixed visual size regardless of the current zoom level."), index.h("kritzel-slide-toggle", { checked: this.lockDrawingScale, label: "Lock Drawing Scale", onCheckedChange: this.handleLockDrawingScaleChange })))));
29963
+ return (index.h("div", { class: "settings-content" }, index.h("h3", null, "General Settings"), index.h("div", { class: "settings-group" }, index.h("div", { class: "settings-item" }, index.h("label", { class: "settings-label" }, "Theme"), index.h("p", { class: "settings-description" }, "Select a registered color theme for the editor interface."), index.h("kritzel-dropdown", { options: this.availableThemes.map(t => ({ value: t, label: t })), value: this.theme, onValueChanged: this.handleThemeChange })), index.h("div", { class: "settings-item" }, index.h("label", { class: "settings-label" }, "Lock Drawing Scale"), index.h("p", { class: "settings-description" }, "When enabled, drawn objects maintain a fixed visual size regardless of the current zoom level."), index.h("kritzel-slide-toggle", { checked: this.lockDrawingScale, label: "Lock Drawing Scale", onCheckedChange: this.handleLockDrawingScaleChange })))));
29789
29964
  case 'viewport':
29790
29965
  return (index.h("div", { class: "settings-content" }, index.h("h3", null, "Viewport Settings"), index.h("div", { class: "settings-group" }, index.h("div", { class: "settings-item" }, index.h("label", { class: "settings-label" }, "Minimum Zoom Level"), index.h("p", { class: "settings-description" }, "Sets the minimum zoom level. Lower values allow zooming out further to see more of the canvas."), index.h("kritzel-numeric-input", { value: this.scaleMin, min: 0.0001, max: 1, step: 0.0001, onValueChange: this.handleScaleMinChange })), index.h("div", { class: "settings-item" }, index.h("label", { class: "settings-label" }, "Maximum Zoom Level"), index.h("p", { class: "settings-description" }, "Sets the maximum zoom level. Higher values allow zooming in closer for detailed work."), index.h("kritzel-numeric-input", { value: this.scaleMax, min: 1, max: 1000, step: 1, onValueChange: this.handleScaleMaxChange })), index.h("div", { class: "settings-item" }, index.h("label", { class: "settings-label" }, "Viewport Boundary Left"), index.h("p", { class: "settings-description" }, "Left boundary in world coordinates. Set to limit how far left the viewport can pan."), index.h("kritzel-numeric-input", { value: this.viewportBoundaryLeft, step: 100, placeholder: "Infinite", onValueChange: this.handleViewportBoundaryLeftChange })), index.h("div", { class: "settings-item" }, index.h("label", { class: "settings-label" }, "Viewport Boundary Right"), index.h("p", { class: "settings-description" }, "Right boundary in world coordinates. Set to limit how far right the viewport can pan."), index.h("kritzel-numeric-input", { value: this.viewportBoundaryRight, step: 100, placeholder: "Infinite", onValueChange: this.handleViewportBoundaryRightChange })), index.h("div", { class: "settings-item" }, index.h("label", { class: "settings-label" }, "Viewport Boundary Top"), index.h("p", { class: "settings-description" }, "Top boundary in world coordinates. Set to limit how far up the viewport can pan."), index.h("kritzel-numeric-input", { value: this.viewportBoundaryTop, step: 100, placeholder: "Infinite", onValueChange: this.handleViewportBoundaryTopChange })), index.h("div", { class: "settings-item" }, index.h("label", { class: "settings-label" }, "Viewport Boundary Bottom"), index.h("p", { class: "settings-description" }, "Bottom boundary in world coordinates. Set to limit how far down the viewport can pan."), index.h("kritzel-numeric-input", { value: this.viewportBoundaryBottom, step: 100, placeholder: "Infinite", onValueChange: this.handleViewportBoundaryBottomChange })))));
29791
29966
  case 'shortcuts':
@@ -29799,7 +29974,7 @@ const KritzelSettings = class {
29799
29974
  }
29800
29975
  }
29801
29976
  render() {
29802
- return (index.h(index.Host, { key: 'e86192a8ca49f8618d58ede4d04d321ea238d7d4' }, index.h("kritzel-dialog", { key: '23a47a8cd9281794bfd2aec7edd6a4ef4b931550', isOpen: this.isDialogOpen, dialogTitle: "Settings", size: "large", contained: true, onDialogClose: this.closeDialog }, index.h("kritzel-master-detail", { key: '007c8a1c04bd0d692b55d88988b0f8874f9242a4', items: SETTINGS_CATEGORIES, selectedItemId: this.selectedCategoryId, onItemSelect: this.handleCategorySelect }, this.renderCategoryContent()))));
29977
+ return (index.h(index.Host, { key: '46c6792ae9cdd932d3dc71526862c9281c0cefc1' }, index.h("kritzel-dialog", { key: '1cd288cdf8b26bea378665c54bfc14577597fe49', isOpen: this.isDialogOpen, dialogTitle: "Settings", size: "large", contained: true, onDialogClose: this.closeDialog }, index.h("kritzel-master-detail", { key: '4d07e94ebb09035807356bab4bc7eaca57c36c6c', items: SETTINGS_CATEGORIES, selectedItemId: this.selectedCategoryId, onItemSelect: this.handleCategorySelect }, this.renderCategoryContent()))));
29803
29978
  }
29804
29979
  static get watchers() { return {
29805
29980
  "settings": [{
@@ -29832,10 +30007,10 @@ const KritzelShapeFill = class {
29832
30007
  return (index.h("svg", { viewBox: "0 0 24 24", class: "fill-icon" }, index.h("rect", { x: "4", y: "4", width: "16", height: "16", rx: "2", fill: strokeColor, stroke: strokeColor, "stroke-width": "2" })));
29833
30008
  }
29834
30009
  render() {
29835
- return (index.h(index.Host, { key: '5f915acf7a98ac585f5aba494981cbbb38252c93' }, index.h("div", { key: 'e8a7fd9a1611d5cace9fbf73c1421b211a8b7d89', class: "fill-row" }, index.h("button", { key: 'cbd388e362c94e36220e93f55fd0140a774e0bd7', class: {
30010
+ return (index.h(index.Host, { key: '6d38a9af2e4c4c7f86ab994c63fc074007c86b48' }, index.h("div", { key: 'cf58f26cb0e56e274873d11024209c6908d317bb', class: "fill-row" }, index.h("button", { key: 'c75eed70fe0c2fcbf0fd136bb6fce75b2dbfb45d', class: {
29836
30011
  'fill-option': true,
29837
30012
  'selected': this.value === 'transparent',
29838
- }, onClick: () => this.handleFillChange('transparent'), title: "Transparent background" }, this.renderFillIcon('transparent')), index.h("button", { key: '532eec1936f973eb2fb44c15839400e53ac4f4f7', class: {
30013
+ }, onClick: () => this.handleFillChange('transparent'), title: "Transparent background" }, this.renderFillIcon('transparent')), index.h("button", { key: '5d6ede439b5d5e55598cd8c20b5851fb9f210463', class: {
29839
30014
  'fill-option': true,
29840
30015
  'selected': this.value === 'filled',
29841
30016
  }, onClick: () => this.handleFillChange('filled'), title: "Filled background" }, this.renderFillIcon('filled')))));
@@ -29930,9 +30105,9 @@ const KritzelShareDialog = class {
29930
30105
  this.dialogClosed.emit();
29931
30106
  };
29932
30107
  render() {
29933
- return (index.h(index.Host, { key: 'bd58f146337b3eca96ca34408a3d30621f01765a' }, index.h("kritzel-dialog", { key: '0575ac82e19d07cf909556cae2ec433e0057fd5b', dialogTitle: "Share Workspace", size: "small", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, contained: true }, index.h("div", { key: 'c51d207e31255f45724103bfecbe858f13a721e6', class: "share-content" }, index.h("div", { key: 'ca6cb7721b9ba834c133b2cb953b208475e34fb5', class: "share-section" }, index.h("div", { key: '2c76845c903cc1c18cc26b9111d608e732ed12a5', class: "share-row" }, index.h("div", { key: '7700533f54372bc81d8d795414318a6bf0e93c47', class: "share-label-group" }, index.h("label", { key: 'a1d80009cb09cfe35bce35ce1151bf0754b052c1', class: "share-label" }, "Link sharing"), index.h("p", { key: '10c1963e95e658c7fb86174f1dba7565ce40d5a6', class: "share-description" }, this.internalIsPublic
30108
+ return (index.h(index.Host, { key: 'a104c14b2492d97f3ada98c9eaaa845d63074063' }, index.h("kritzel-dialog", { key: '1b12b27504153e54aeb0cb4e6b1030a0d43b9735', dialogTitle: "Share Workspace", size: "small", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, contained: true }, index.h("div", { key: '652f23e37876be356beb6f93abf5930e91d82cea', class: "share-content" }, index.h("div", { key: 'aaf336f2ac86fe23cac79cef920a9d67681046e2', class: "share-section" }, index.h("div", { key: '8075a7b3fff47c4b924d3b2d92b1377641920939', class: "share-row" }, index.h("div", { key: '41e98a74a5d4aede50fd75a7de62cbef9b5a5a31', class: "share-label-group" }, index.h("label", { key: '8a4f53e13d5a81497dd31316a49971c7245d82a2', class: "share-label" }, "Link sharing"), index.h("p", { key: '907a59d50e595734f03067f70830cf96defdf8d8', class: "share-description" }, this.internalIsPublic
29934
30109
  ? 'Anyone with the link can access this workspace.'
29935
- : 'Link sharing is disabled. Only you can access this workspace.')), index.h("kritzel-slide-toggle", { key: 'ec62a5ece12be0cea18a16c5d41db0a992309174', checked: this.internalIsPublic, onCheckedChange: this.handleToggleChange, label: "Enable link sharing" }))), this.internalIsPublic && (index.h("div", { key: '5e826d4c8c37792ba3a74a0189ad313a8ab482e2', class: "share-section" }, index.h("div", { key: 'f8e35cda32cb34ab21f56335aa27503fd6fe98c4', class: "share-url-container" }, index.h("input", { key: '47feb20a1843e1d3d8f7d146d71574b187002e8d', type: "text", class: "share-url-input", value: this.getShareUrl(), readOnly: true, onClick: (e) => e.target.select() }), index.h("button", { key: '052f56f35d057430cbc8fd03da5bef574b173791', class: { 'copy-button': true, 'copy-success': this.copySuccess }, onClick: this.handleCopyUrl, title: this.copySuccess ? 'Copied!' : 'Copy link' }, index.h("kritzel-icon", { key: '4e1de478f837a352185be2a06e15796dc1fb2f5e', name: this.copySuccess ? 'check' : 'copy', size: 18 })))))))));
30110
+ : 'Link sharing is disabled. Only you can access this workspace.')), index.h("kritzel-slide-toggle", { key: '0d75cfeeb63c33d20380ffe9a7e4c27148548ef9', checked: this.internalIsPublic, onCheckedChange: this.handleToggleChange, label: "Enable link sharing" }))), this.internalIsPublic && (index.h("div", { key: 'a8a10c74fd326c5097e4a5f0ee165602c3606ade', class: "share-section" }, index.h("div", { key: '6261a9fc6cb2be2a50856fb8a990b9da3fee84bf', class: "share-url-container" }, index.h("input", { key: '26ee72eebfee88d06a50c338cccc9af296c8ba4c', type: "text", class: "share-url-input", value: this.getShareUrl(), readOnly: true, onClick: (e) => e.target.select() }), index.h("button", { key: '4b1ec06fa27c95d9d0bb93f8cbb851a02fdd52cc', class: { 'copy-button': true, 'copy-success': this.copySuccess }, onClick: this.handleCopyUrl, title: this.copySuccess ? 'Copied!' : 'Copy link' }, index.h("kritzel-icon", { key: 'd9eea56b3523fcc3557d9868f3da7f28449a9447', name: this.copySuccess ? 'check' : 'copy', size: 18 })))))))));
29936
30111
  }
29937
30112
  static get watchers() { return {
29938
30113
  "isPublic": [{
@@ -29970,7 +30145,7 @@ const KritzelSlideToggle = class {
29970
30145
  }
29971
30146
  };
29972
30147
  render() {
29973
- return (index.h(index.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 }, index.h("div", { key: '2108fe8de84e0b9a619667b5ab4f57215c185375', class: "toggle-track" }, index.h("div", { key: 'ff8253ce660ca62313dea3034ac4980135eaac88', class: "toggle-thumb" }))));
30148
+ return (index.h(index.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 }, index.h("div", { key: 'd5fa5091ad54032f81dad3879149c4d8ec7ea37b', class: "toggle-track" }, index.h("div", { key: 'cce0d61431ed65a26926b0a496a5c22eb4169577', class: "toggle-thumb" }))));
29974
30149
  }
29975
30150
  };
29976
30151
  KritzelSlideToggle.style = kritzelSlideToggleCss();
@@ -30070,7 +30245,7 @@ const KritzelSplitButton = class {
30070
30245
  this.menuScrollTop = event.target.scrollTop;
30071
30246
  };
30072
30247
  render() {
30073
- return (index.h(index.Host, { key: '1ec4c6806f5ff020d675b34f32efeecf6ddf40ab', class: { mobile: this.isTouchDevice } }, index.h("button", { key: '11deb29bfc899fb2aa4d98c5bc615a8e0dfc56f9', class: "split-main-button", tabIndex: 0, onClick: this.handleButtonClick, disabled: this.mainButtonDisabled, "aria-label": "Main action" }, this.buttonIcon && index.h("kritzel-icon", { key: '46b0a1cea4528d5565c5ab17a2966fc15e2c00cb', name: this.buttonIcon })), index.h("div", { key: '6efd2cc0c64c4af734d1071c98c59afdfcc49067', class: "split-divider" }), index.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" }, index.h("kritzel-icon", { key: '72a83a39b8dd60468800befe85763574e19c3e20', name: this.dropdownIcon })), index.h("kritzel-portal", { key: 'f014876c36faef4b59db720b645ed6d30615df77', anchor: this.anchorElement, offsetY: 4, onClose: this.closeMenu }, index.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 }))));
30248
+ return (index.h(index.Host, { key: '794fdb5cb4d110d93b6b2cb060fe34241f29db57', class: { mobile: this.isTouchDevice } }, index.h("button", { key: '7202a40f05bf6fc256996a05db55bcfa3baba615', class: "split-main-button", tabIndex: 0, onClick: this.handleButtonClick, disabled: this.mainButtonDisabled, "aria-label": "Main action" }, this.buttonIcon && index.h("kritzel-icon", { key: '3156c6c4e757d9ebbd3f5e3719ee1bf9bf81f71b', name: this.buttonIcon })), index.h("div", { key: '4c5a3a9791ecfd00d36fc0eb885c1d227200cfc7', class: "split-divider" }), index.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" }, index.h("kritzel-icon", { key: 'b3d84e4599dc408ccc8afe17e487b501cbde89a4', name: this.dropdownIcon })), index.h("kritzel-portal", { key: '6800329ebe3c94a661e9ad852b6bf256defc291f', anchor: this.anchorElement, offsetY: 4, onClose: this.closeMenu }, index.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 }))));
30074
30249
  }
30075
30250
  };
30076
30251
  KritzelSplitButton.style = kritzelSplitButtonCss();
@@ -30090,7 +30265,7 @@ const KritzelStrokeSize = class {
30090
30265
  this.sizeChange.emit(size);
30091
30266
  }
30092
30267
  render() {
30093
- return (index.h(index.Host, { key: 'f964d37a6cbfa48898ac066859165df1492535a9' }, index.h("div", { key: 'fed8ec5ddbe07d64beb151b22211fecdc0a278d1', class: "size-grid" }, this.sizes.map(size => (index.h("div", { tabIndex: 0, class: {
30268
+ return (index.h(index.Host, { key: '514d87732c9b15cddd5a905407ff7ce9069c06d7' }, index.h("div", { key: '170c9a8abfe8298116d8a269338da95fbc2aac7b', class: "size-grid" }, this.sizes.map(size => (index.h("div", { tabIndex: 0, class: {
30094
30269
  'size-container': true,
30095
30270
  'selected': this.selectedSize === size,
30096
30271
  }, onClick: () => this.handleSizeClick(size) }, index.h("kritzel-color", { value: 'var(--kritzel-global-text-primary)', size: size })))))));
@@ -30469,14 +30644,14 @@ const KritzelTooltip = class {
30469
30644
  }
30470
30645
  }
30471
30646
  render() {
30472
- return (index.h(index.Host, { key: '647f4d837fc06a3b5dca8896383c1a92ef7c5a3d', style: {
30647
+ return (index.h(index.Host, { key: '10bff4d14ff1f724d59463afc059f254e9485175', style: {
30473
30648
  position: 'fixed',
30474
30649
  zIndex: '9999',
30475
30650
  transition: 'opacity 0.3s ease-in-out, transform 0.3s ease-in-out',
30476
30651
  visibility: this.isVisible ? 'visible' : 'hidden',
30477
30652
  left: `${this.positionX}px`,
30478
30653
  bottom: `${this.positionY}px`,
30479
- } }, index.h("div", { key: '41b32207d1e9f84c85c054a8aae4727b7df05d62', class: "tooltip-content", onClick: event => event.stopPropagation(), onPointerDown: event => event.stopPropagation(), onMouseDown: event => event.stopPropagation() }, index.h("slot", { key: 'c164d76762957e60d904458d7a34936944d02eae' }))));
30654
+ } }, index.h("div", { key: '6bfc8f2fe731d758c74319abeb82c4b84616f8b6', class: "tooltip-content", onClick: event => event.stopPropagation(), onPointerDown: event => event.stopPropagation(), onMouseDown: event => event.stopPropagation() }, index.h("slot", { key: '2a92ad23f4424b2d17035f86983be66a81fee81d' }))));
30480
30655
  }
30481
30656
  static get watchers() { return {
30482
30657
  "triggerElement": [{
@@ -30515,7 +30690,7 @@ const KritzelUtilityPanel = class {
30515
30690
  this.redo.emit();
30516
30691
  }
30517
30692
  render() {
30518
- return (index.h(index.Host, { key: 'f800ea5843cf73ae132b56396ad05d664043f789' }, index.h("button", { key: '8f2c35b9b774ba5662ad584ebaa3e98a21e2d4e5', class: "utility-button", "data-testid": "utility-undo", disabled: !this.undoState?.canUndo, onClick: event => this.handleUndo(event), "aria-label": "Undo" }, index.h("kritzel-icon", { key: 'ffba256fea2b2ba7c767601a2051c940e5865fd5', name: "undo" })), index.h("button", { key: '261a7759ec1e25000ed76d2cf5aaef908cea886c', class: "utility-button", "data-testid": "utility-redo", disabled: !this.undoState?.canRedo, onClick: event => this.handleRedo(event), "aria-label": "Redo" }, index.h("kritzel-icon", { key: '7483a8c23a1dcd77dc0bfdb3cc39c4998e48b193', name: "redo" })), index.h("div", { key: '7450540c285a6cf746d52b31eb2e7f88ec30c1ec', class: "utility-separator" }), index.h("button", { key: '62fa097474ede7de6018a76ec492a9d72bb0cb11', class: "utility-button", "data-testid": "utility-delete", onClick: () => this.delete.emit(), "aria-label": "Delete selected items" }, index.h("kritzel-icon", { key: 'a1cea0b8a5524fe5877ae2ce7939bcb5a66b4dcd', name: "delete" }))));
30693
+ return (index.h(index.Host, { key: 'b49f6db6c0e574dc8a5a733c749ecda6f24f9d25' }, index.h("button", { key: 'e6306e54c8f660c3e92d032527fad1ea45ca0cf8', class: "utility-button", "data-testid": "utility-undo", disabled: !this.undoState?.canUndo, onClick: event => this.handleUndo(event), "aria-label": "Undo" }, index.h("kritzel-icon", { key: '5bb1293049a1e3004504289d92ccc79958786f3f', name: "undo" })), index.h("button", { key: '8102b0403d7f328ce4bfeb79767d5bd99d879013', class: "utility-button", "data-testid": "utility-redo", disabled: !this.undoState?.canRedo, onClick: event => this.handleRedo(event), "aria-label": "Redo" }, index.h("kritzel-icon", { key: '5db3047bec5d8ab695a2dc67780a5dbecbae64d2', name: "redo" })), index.h("div", { key: 'e894d9f2aaa2cad7aa980d3b839eca05a8d9c9df', class: "utility-separator" }), index.h("button", { key: 'f0a7de5ab91f82a2e5e8df75cc1903ec647abdac', class: "utility-button", "data-testid": "utility-delete", onClick: () => this.delete.emit(), "aria-label": "Delete selected items" }, index.h("kritzel-icon", { key: '5b146375394299bae946a95545c3c42c2bf36766', name: "delete" }))));
30519
30694
  }
30520
30695
  };
30521
30696
  KritzelUtilityPanel.style = kritzelUtilityPanelCss();