kritzel-stencil 0.2.10 → 0.2.12

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 (68) hide show
  1. package/dist/cjs/kritzel-active-users_42.cjs.entry.js +280 -33
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/stencil.cjs.js +1 -1
  4. package/dist/collection/classes/core/core.class.js +12 -7
  5. package/dist/collection/classes/core/viewport.class.js +65 -0
  6. package/dist/collection/classes/handlers/context-menu.handler.js +7 -6
  7. package/dist/collection/components/core/kritzel-editor/kritzel-editor.css +8 -1
  8. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +4 -4
  9. package/dist/collection/components/shared/kritzel-dialog/kritzel-dialog.css +29 -0
  10. package/dist/collection/components/shared/kritzel-dialog/kritzel-dialog.js +201 -5
  11. package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js +1 -1
  12. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.css +1 -1
  13. package/dist/collection/components/ui/kritzel-current-user-dialog/kritzel-current-user-dialog.js +1 -1
  14. package/dist/collection/components/ui/kritzel-export/kritzel-export.js +1 -1
  15. package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.js +1 -1
  16. package/dist/collection/components/ui/kritzel-more-menu/kritzel-more-menu.js +1 -1
  17. package/dist/collection/components/ui/kritzel-settings/kritzel-settings.js +1 -1
  18. package/dist/collection/components/ui/kritzel-share-dialog/kritzel-share-dialog.js +2 -2
  19. package/dist/collection/configs/default-engine-config.js +2 -0
  20. package/dist/collection/constants/version.js +1 -1
  21. package/dist/components/index.js +1 -1
  22. package/dist/components/kritzel-controls.js +1 -1
  23. package/dist/components/kritzel-current-user-dialog.js +1 -1
  24. package/dist/components/kritzel-current-user.js +1 -1
  25. package/dist/components/kritzel-dialog.js +1 -1
  26. package/dist/components/kritzel-editor.js +1 -1
  27. package/dist/components/kritzel-engine.js +1 -1
  28. package/dist/components/kritzel-export.js +1 -1
  29. package/dist/components/kritzel-login-dialog.js +1 -1
  30. package/dist/components/kritzel-menu-item.js +1 -1
  31. package/dist/components/kritzel-menu.js +1 -1
  32. package/dist/components/kritzel-more-menu.js +1 -1
  33. package/dist/components/kritzel-settings.js +1 -1
  34. package/dist/components/kritzel-share-dialog.js +1 -1
  35. package/dist/components/kritzel-split-button.js +1 -1
  36. package/dist/components/kritzel-workspace-manager.js +1 -1
  37. package/dist/components/p-BTSOqHMI.js +1 -0
  38. package/dist/components/{p-B_fA1LTU.js → p-BWB2UGxj.js} +1 -1
  39. package/dist/components/{p-BpRNLd4z.js → p-Bw1PPSFV.js} +1 -1
  40. package/dist/components/p-C51_twnc.js +1 -0
  41. package/dist/components/{p-DykzXVCs.js → p-CS3JA3yn.js} +1 -1
  42. package/dist/components/p-CrSLn46K.js +1 -0
  43. package/dist/components/p-CrmWVXea.js +1 -0
  44. package/dist/components/{p-DQ1fRE9J.js → p-CvCTQQcJ.js} +1 -1
  45. package/dist/components/{p-CRsnBR8O.js → p-D9BJCr8V.js} +1 -1
  46. package/dist/components/p-DMfU0hHe.js +1 -0
  47. package/dist/components/p-DsxW_miC.js +1 -0
  48. package/dist/components/p-DzxPDPED.js +1 -0
  49. package/dist/components/{p-nW05C2cx.js → p-Z9_amVdR.js} +1 -1
  50. package/dist/esm/kritzel-active-users_42.entry.js +280 -33
  51. package/dist/esm/loader.js +1 -1
  52. package/dist/esm/stencil.js +1 -1
  53. package/dist/stencil/p-ddd603ac.entry.js +9 -0
  54. package/dist/stencil/stencil.esm.js +1 -1
  55. package/dist/types/classes/core/viewport.class.d.ts +22 -0
  56. package/dist/types/components/shared/kritzel-dialog/kritzel-dialog.d.ts +21 -0
  57. package/dist/types/components.d.ts +11 -0
  58. package/dist/types/constants/version.d.ts +1 -1
  59. package/dist/types/interfaces/engine-state.interface.d.ts +2 -0
  60. package/package.json +1 -1
  61. package/dist/components/p-B1V6yEGY.js +0 -1
  62. package/dist/components/p-BuSOJ7Xd.js +0 -1
  63. package/dist/components/p-CzYgMB2N.js +0 -1
  64. package/dist/components/p-DBIK7z89.js +0 -1
  65. package/dist/components/p-DPxSr1wV.js +0 -1
  66. package/dist/components/p-Dpr_JQam.js +0 -1
  67. package/dist/components/p-xHh03blG.js +0 -1
  68. package/dist/stencil/p-bfff1c18.entry.js +0 -9
@@ -870,7 +870,7 @@ class KritzelToolConfigHelper {
870
870
  }
871
871
  }
872
872
 
873
- const kritzelControlsCss = () => `:host{display:flex;flex-direction:column;user-select:none;max-width:calc(100vw - 16px)}: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:10000;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}`;
873
+ const kritzelControlsCss = () => `:host{display:flex;flex-direction:column;user-select:none;max-width:100%}: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:10000;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}`;
874
874
 
875
875
  const KritzelControls = class {
876
876
  constructor(hostRef) {
@@ -1182,7 +1182,7 @@ const KritzelCurrentUserDialog = class {
1182
1182
  }
1183
1183
  render() {
1184
1184
  const displayName = this.getDisplayName();
1185
- return (h(Host, { key: 'e1dd44cdfdbaebfe886fed0d9feba2ef232b6615' }, h("kritzel-dialog", { key: '49dd037cca0741cc949f20d9d44cfd028492dc60', dialogTitle: "Account", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small" }, h("div", { key: 'ddcdfb82cc0c896025559888d475ab5c9ad59b4c', class: "user-info" }, h("kritzel-avatar", { key: '4d164b784cde6787d26ac164c7450c0352e6a7cb', user: this.user, size: 80 }), displayName && h("div", { key: '13ad719d8bd90cd608c78438fccbb38ed1d5e5ba', class: "user-name" }, displayName), this.user?.email && h("div", { key: 'df360afd434293d9c9d5fcf114713e0a6925a78e', class: "user-email" }, this.user.email)))));
1185
+ return (h(Host, { key: 'e1dd44cdfdbaebfe886fed0d9feba2ef232b6615' }, h("kritzel-dialog", { key: 'cd3daa7abd53c10852d63a2fe53d919414cd8904', dialogTitle: "Account", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, h("div", { key: '94d0a691ede73135e6cf4ef144c13e52e410ffbe', class: "user-info" }, h("kritzel-avatar", { key: 'e57592d2f3663b593534055be5aae1b224fa8906', user: this.user, size: 80 }), displayName && h("div", { key: '237db2d0608ee49ea70e5282b61a59077f0f4595', class: "user-name" }, displayName), this.user?.email && h("div", { key: 'd821e8171530b92ce6f1781c1145b611d3c533d0', class: "user-email" }, this.user.email)))));
1186
1186
  }
1187
1187
  };
1188
1188
  KritzelCurrentUserDialog.style = kritzelCurrentUserDialogCss();
@@ -1343,7 +1343,7 @@ class KritzelHTMLHelper {
1343
1343
  }
1344
1344
  }
1345
1345
 
1346
- const kritzelDialogCss = () => `:host{display:contents}.backdrop{position:fixed;top:0;left:0;right:0;bottom:0;z-index:10002;display:flex;align-items:center;justify-content:center;background-color:var(--kritzel-dialog-backdrop-color, rgba(0, 0, 0, 0.5));opacity:1;transition:opacity 150ms ease-out}.backdrop.is-animating{opacity:0}.dialog-content{position:relative;display:flex;flex-direction:column;background-color:var(--kritzel-dialog-background-color, #ffffff);border-radius:var(--kritzel-dialog-border-radius, 12px);box-shadow:var(--kritzel-dialog-box-shadow, 0 4px 20px rgba(0, 0, 0, 0.15));border:var(--kritzel-dialog-border, 1px solid #ebebeb);max-height:var(--kritzel-dialog-max-height, 90vh);max-width:var(--kritzel-dialog-max-width, 90vw);overflow:hidden;transform:scale(1);opacity:1;transition:transform 200ms ease-out, opacity 200ms ease-out;font-family:var(--kritzel-dialog-font-family, sans-serif)}.dialog-content.is-animating{transform:scale(0.95);opacity:0}.dialog-content.size-small{width:var(--kritzel-dialog-width-small, 320px);height:var(--kritzel-dialog-height-small, auto)}.dialog-content.size-medium{width:var(--kritzel-dialog-width-medium, 480px);height:var(--kritzel-dialog-height-medium, auto)}.dialog-content.size-large{width:var(--kritzel-dialog-width-large, 640px);height:var(--kritzel-dialog-height-large, auto)}.dialog-content.size-fullscreen{width:100vw;height:100vh;height:100dvh;max-width:100vw;max-height:100vh;max-height:100dvh;border-radius:0}@media (max-width: 576px), (max-height: 576px) and (orientation: landscape){.backdrop:has(.fullscreen-on-mobile){background-color:transparent}.dialog-content.fullscreen-on-mobile{width:100vw;height:100vh;height:100dvh;max-width:100vw;max-height:100vh;max-height:100dvh;border-radius:0}.dialog-content.fullscreen-on-mobile .dialog-body{display:flex;flex-direction:column}.dialog-content.fullscreen-on-mobile .dialog-body ::slotted(*){flex:1;min-height:0}}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:var(--kritzel-dialog-header-padding, 16px 20px);border-bottom:var(--kritzel-dialog-header-border, 1px solid #ebebeb);gap:12px}.dialog-title{margin:0;font-size:var(--kritzel-dialog-title-font-size, 18px);font-weight:var(--kritzel-dialog-title-font-weight, 600);color:var(--kritzel-dialog-title-color, #1a1a1a);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.close-button{display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:none;border-radius:var(--kritzel-dialog-close-button-border-radius, 6px);background-color:var(--kritzel-dialog-close-button-background, transparent);color:var(--kritzel-dialog-close-button-color, #666666);cursor:var(--kritzel-global-pointer-cursor, pointer);transition:background-color 150ms ease, color 150ms ease;flex-shrink:0;-webkit-tap-highlight-color:transparent}.close-button:hover{background-color:var(--kritzel-dialog-close-button-hover-background, #f5f5f5);color:var(--kritzel-dialog-close-button-hover-color, #1a1a1a)}.close-button:active{background-color:var(--kritzel-dialog-close-button-active-background, #ebebeb)}.close-button:focus-visible{outline:revert;outline-offset:revert}.dialog-body{padding:var(--kritzel-dialog-body-padding, 20px);overflow-y:auto;flex:1;min-height:0;scrollbar-color:var(--kritzel-global-scrollbar-thumb-color, #ebebeb) transparent;scrollbar-width:thin}.dialog-footer{display:flex;align-items:center;justify-content:flex-end;gap:var(--kritzel-dialog-footer-gap, 8px);padding:var(--kritzel-dialog-footer-padding, 16px 20px);border-top:var(--kritzel-dialog-footer-border, 1px solid #ebebeb)}::slotted([slot='header']){flex:1}::slotted([slot='footer']){display:contents}`;
1346
+ const kritzelDialogCss = () => `:host{display:contents}.dialog-content{text-align:start;line-height:normal}.backdrop{position:fixed;top:0;left:0;right:0;bottom:0;z-index:10002;display:flex;align-items:center;justify-content:center;background-color:var(--kritzel-dialog-backdrop-color, rgba(0, 0, 0, 0.5));opacity:1;transition:opacity 150ms ease-out}.backdrop.is-animating{opacity:0}.dialog-content{position:relative;display:flex;flex-direction:column;background-color:var(--kritzel-dialog-background-color, #ffffff);border-radius:var(--kritzel-dialog-border-radius, 12px);box-shadow:var(--kritzel-dialog-box-shadow, 0 4px 20px rgba(0, 0, 0, 0.15));border:var(--kritzel-dialog-border, 1px solid #ebebeb);max-height:var(--kritzel-dialog-max-height, 90vh);max-width:var(--kritzel-dialog-max-width, 90vw);overflow:hidden;transform:scale(1);opacity:1;transition:transform 200ms ease-out, opacity 200ms ease-out;font-family:var(--kritzel-dialog-font-family, sans-serif)}.dialog-content.is-animating{transform:scale(0.95);opacity:0}.dialog-content.size-small{width:var(--kritzel-dialog-width-small, 320px);height:var(--kritzel-dialog-height-small, auto)}.dialog-content.size-medium{width:var(--kritzel-dialog-width-medium, 480px);height:var(--kritzel-dialog-height-medium, auto)}.dialog-content.size-large{width:var(--kritzel-dialog-width-large, 640px);height:var(--kritzel-dialog-height-large, auto)}.dialog-content.size-fullscreen{width:100vw;height:100vh;height:100dvh;max-width:100vw;max-height:100vh;max-height:100dvh;border-radius:0}.backdrop.contained-fullscreen{background-color:transparent}.dialog-content.contained-fullscreen{border-radius:0}.dialog-content.contained-fullscreen .dialog-body{display:flex;flex-direction:column}.dialog-content.contained-fullscreen .dialog-body ::slotted(*){flex:1;min-height:0}@media (max-width: 576px), (max-height: 576px) and (orientation: landscape){.backdrop:has(.fullscreen-on-mobile){background-color:transparent}.dialog-content.fullscreen-on-mobile{width:100vw;height:100vh;height:100dvh;max-width:100vw;max-height:100vh;max-height:100dvh;border-radius:0}.dialog-content.fullscreen-on-mobile .dialog-body{display:flex;flex-direction:column}.dialog-content.fullscreen-on-mobile .dialog-body ::slotted(*){flex:1;min-height:0}}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:var(--kritzel-dialog-header-padding, 16px 20px);border-bottom:var(--kritzel-dialog-header-border, 1px solid #ebebeb);gap:12px}.dialog-title{margin:0;font-size:var(--kritzel-dialog-title-font-size, 18px);font-weight:var(--kritzel-dialog-title-font-weight, 600);color:var(--kritzel-dialog-title-color, #1a1a1a);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.close-button{display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:none;border-radius:var(--kritzel-dialog-close-button-border-radius, 6px);background-color:var(--kritzel-dialog-close-button-background, transparent);color:var(--kritzel-dialog-close-button-color, #666666);cursor:var(--kritzel-global-pointer-cursor, pointer);transition:background-color 150ms ease, color 150ms ease;flex-shrink:0;-webkit-tap-highlight-color:transparent}.close-button:hover{background-color:var(--kritzel-dialog-close-button-hover-background, #f5f5f5);color:var(--kritzel-dialog-close-button-hover-color, #1a1a1a)}.close-button:active{background-color:var(--kritzel-dialog-close-button-active-background, #ebebeb)}.close-button:focus-visible{outline:revert;outline-offset:revert}.dialog-body{padding:var(--kritzel-dialog-body-padding, 20px);overflow-y:auto;flex:1;min-height:0;scrollbar-color:var(--kritzel-global-scrollbar-thumb-color, #ebebeb) transparent;scrollbar-width:thin}.dialog-footer{display:flex;align-items:center;justify-content:flex-end;gap:var(--kritzel-dialog-footer-gap, 8px);padding:var(--kritzel-dialog-footer-padding, 16px 20px);border-top:var(--kritzel-dialog-footer-border, 1px solid #ebebeb)}::slotted([slot='header']){flex:1}::slotted([slot='footer']){display:contents}`;
1347
1347
 
1348
1348
  const KritzelDialog = class {
1349
1349
  constructor(hostRef) {
@@ -1370,8 +1370,12 @@ const KritzelDialog = class {
1370
1370
  size = 'medium';
1371
1371
  /** Whether to automatically go fullscreen on mobile viewports */
1372
1372
  fullscreenOnMobile = true;
1373
+ /** Constrain the dialog to its nearest editor/container ancestor instead of the viewport. */
1374
+ contained = false;
1373
1375
  isAnimating = false;
1374
1376
  mobileLockedHeight = null;
1377
+ containerRect = null;
1378
+ containerBorderRadius = null;
1375
1379
  /** Emitted when the dialog opens */
1376
1380
  dialogOpen;
1377
1381
  /** Emitted when the dialog closes */
@@ -1379,6 +1383,9 @@ const KritzelDialog = class {
1379
1383
  previousOverflow = '';
1380
1384
  previousActiveElement = null;
1381
1385
  visualViewportListenersAttached = false;
1386
+ containerElement = null;
1387
+ containerResizeObserver = null;
1388
+ containerTrackingFrame = null;
1382
1389
  handleIsOpenChange(newValue) {
1383
1390
  if (newValue) {
1384
1391
  this.openDialog();
@@ -1428,13 +1435,19 @@ const KritzelDialog = class {
1428
1435
  }
1429
1436
  disconnectedCallback() {
1430
1437
  this.removeVisualViewportListeners();
1438
+ this.stopContainerTracking();
1431
1439
  this.restoreBodyScroll();
1432
1440
  }
1433
1441
  openDialog() {
1434
1442
  this.isAnimating = true;
1435
1443
  this.previousActiveElement = document.activeElement;
1436
- this.lockBodyScroll();
1437
- this.addVisualViewportListeners();
1444
+ if (this.contained) {
1445
+ this.startContainerTracking();
1446
+ }
1447
+ else {
1448
+ this.lockBodyScroll();
1449
+ this.addVisualViewportListeners();
1450
+ }
1438
1451
  this.lockMobileViewportHeight();
1439
1452
  this.dialogOpen.emit();
1440
1453
  if (this.autoFocus) {
@@ -1449,9 +1462,106 @@ const KritzelDialog = class {
1449
1462
  closeDialog() {
1450
1463
  this.restoreBodyScroll();
1451
1464
  this.removeVisualViewportListeners();
1465
+ this.stopContainerTracking();
1452
1466
  this.mobileLockedHeight = null;
1453
1467
  this.returnFocusToPreviousElement();
1454
1468
  }
1469
+ findContainerElement() {
1470
+ // Walk up the composed DOM (crossing shadow roots) and return the first
1471
+ // ancestor that opts into containing dialogs. We accept either an explicit
1472
+ // [data-kritzel-dialog-container] marker or the kritzel-editor host so any
1473
+ // consumer can opt in without modifying the editor itself.
1474
+ let node = this.host;
1475
+ while (node) {
1476
+ if (node instanceof HTMLElement) {
1477
+ if (node.hasAttribute('data-kritzel-dialog-container') || node.tagName === 'KRITZEL-EDITOR') {
1478
+ return node;
1479
+ }
1480
+ }
1481
+ const parent = node.parentNode;
1482
+ if (parent) {
1483
+ node = parent;
1484
+ }
1485
+ else if (node instanceof ShadowRoot) {
1486
+ node = node.host;
1487
+ }
1488
+ else {
1489
+ node = null;
1490
+ }
1491
+ }
1492
+ return null;
1493
+ }
1494
+ startContainerTracking() {
1495
+ this.containerElement = this.findContainerElement();
1496
+ if (!this.containerElement) {
1497
+ // No container found — fall back to viewport behavior.
1498
+ this.containerRect = null;
1499
+ return;
1500
+ }
1501
+ this.updateContainerRect();
1502
+ if (typeof ResizeObserver !== 'undefined') {
1503
+ this.containerResizeObserver = new ResizeObserver(() => this.updateContainerRect());
1504
+ this.containerResizeObserver.observe(this.containerElement);
1505
+ }
1506
+ window.addEventListener('resize', this.handleContainerTrackingEvent, { passive: true });
1507
+ window.addEventListener('scroll', this.handleContainerTrackingEvent, { capture: true, passive: true });
1508
+ }
1509
+ stopContainerTracking() {
1510
+ if (this.containerResizeObserver) {
1511
+ this.containerResizeObserver.disconnect();
1512
+ this.containerResizeObserver = null;
1513
+ }
1514
+ window.removeEventListener('resize', this.handleContainerTrackingEvent);
1515
+ window.removeEventListener('scroll', this.handleContainerTrackingEvent, { capture: true });
1516
+ if (this.containerTrackingFrame !== null) {
1517
+ cancelAnimationFrame(this.containerTrackingFrame);
1518
+ this.containerTrackingFrame = null;
1519
+ }
1520
+ this.containerElement = null;
1521
+ this.containerRect = null;
1522
+ this.containerBorderRadius = null;
1523
+ }
1524
+ handleContainerTrackingEvent = () => {
1525
+ if (this.containerTrackingFrame !== null)
1526
+ return;
1527
+ this.containerTrackingFrame = requestAnimationFrame(() => {
1528
+ this.containerTrackingFrame = null;
1529
+ this.updateContainerRect();
1530
+ });
1531
+ };
1532
+ updateContainerRect() {
1533
+ if (!this.containerElement)
1534
+ return;
1535
+ const rect = this.containerElement.getBoundingClientRect();
1536
+ const next = { top: rect.top, left: rect.left, width: rect.width, height: rect.height };
1537
+ const prev = this.containerRect;
1538
+ if (!prev || prev.top !== next.top || prev.left !== next.left || prev.width !== next.width || prev.height !== next.height) {
1539
+ this.containerRect = next;
1540
+ }
1541
+ // Look for the nearest visually-rounded ancestor (the container itself or
1542
+ // any ancestor up to the document) so the backdrop matches wrappers that
1543
+ // round their corners around the editor.
1544
+ const radius = this.findVisualBorderRadius(this.containerElement);
1545
+ if (this.containerBorderRadius !== radius) {
1546
+ this.containerBorderRadius = radius;
1547
+ }
1548
+ }
1549
+ findVisualBorderRadius(start) {
1550
+ let node = start;
1551
+ while (node && node !== document.body && node !== document.documentElement) {
1552
+ const computed = window.getComputedStyle(node);
1553
+ const tl = computed.borderTopLeftRadius;
1554
+ const tr = computed.borderTopRightRadius;
1555
+ const br = computed.borderBottomRightRadius;
1556
+ const bl = computed.borderBottomLeftRadius;
1557
+ const isZero = (v) => !v || v === '0px' || v === '0%';
1558
+ if (!(isZero(tl) && isZero(tr) && isZero(br) && isZero(bl))) {
1559
+ return `${tl} ${tr} ${br} ${bl}`;
1560
+ }
1561
+ node = node.parentElement;
1562
+ }
1563
+ return null;
1564
+ }
1455
1565
  emitClose(reason) {
1456
1566
  this.dialogClose.emit({ reason });
1457
1567
  }
@@ -1460,6 +1570,12 @@ const KritzelDialog = class {
1460
1570
  document.body.style.overflow = 'hidden';
1461
1571
  }
1462
1572
  lockMobileViewportHeight() {
1573
+ // Skip mobile viewport height locking when contained — the dialog is sized
1574
+ // by its wrapper, not the viewport.
1575
+ if (this.contained) {
1576
+ this.mobileLockedHeight = null;
1577
+ return;
1578
+ }
1463
1579
  // Only lock height on mobile when fullscreenOnMobile is enabled.
1464
1580
  // Use the smaller dimension so landscape phones (wide but short) are also detected.
1465
1581
  const viewportWidth = this.getViewportWidth();
@@ -1594,15 +1710,73 @@ const KritzelDialog = class {
1594
1710
  return null;
1595
1711
  return (h("div", { class: "dialog-footer" }, h("slot", { name: "footer" })));
1596
1712
  }
1713
+ getBackdropStyle() {
1714
+ if (!this.contained || !this.containerRect)
1715
+ return undefined;
1716
+ const { top, left, width, height } = this.containerRect;
1717
+ const style = {
1718
+ top: `${top}px`,
1719
+ left: `${left}px`,
1720
+ right: 'auto',
1721
+ bottom: 'auto',
1722
+ width: `${width}px`,
1723
+ height: `${height}px`,
1724
+ };
1725
+ if (this.containerBorderRadius) {
1726
+ style.borderRadius = this.containerBorderRadius;
1727
+ // Ensure rounded corners actually clip the inner dialog content.
1728
+ style.overflow = 'hidden';
1729
+ }
1730
+ return style;
1731
+ }
1732
+ getDialogContentStyle() {
1733
+ const style = {};
1734
+ // In contained mode, cap the dialog dimensions to the container so the
1735
+ // declared widths/heights of size variants cannot overflow the wrapper.
1736
+ if (this.contained && this.containerRect) {
1737
+ const { width, height } = this.containerRect;
1738
+ if (this.isContainerMobile()) {
1739
+ // Mobile-sized container: behave like fullscreen-on-mobile but scoped
1740
+ // to the container instead of the viewport (works in any orientation).
1741
+ style.width = `${width}px`;
1742
+ style.height = `${height}px`;
1743
+ style.maxWidth = `${width}px`;
1744
+ style.maxHeight = `${height}px`;
1745
+ style.borderRadius = '0';
1746
+ }
1747
+ else {
1748
+ // Leave a small margin so the dialog visibly sits within the container.
1749
+ const maxWidth = Math.max(0, width - 32);
1750
+ const maxHeight = Math.max(0, height - 32);
1751
+ style.maxWidth = `${maxWidth}px`;
1752
+ style.maxHeight = `${maxHeight}px`;
1753
+ }
1754
+ }
1755
+ if (this.mobileLockedHeight) {
1756
+ style.height = this.mobileLockedHeight;
1757
+ style.maxHeight = this.mobileLockedHeight;
1758
+ }
1759
+ return Object.keys(style).length > 0 ? style : undefined;
1760
+ }
1761
+ isContainerMobile() {
1762
+ if (!this.fullscreenOnMobile || !this.containerRect)
1763
+ return false;
1764
+ // Match the existing viewport media-query threshold: container is "mobile"
1765
+ // when its smaller dimension is <= 576px. This handles both portrait and
1766
+ // landscape wrappers symmetrically.
1767
+ return Math.min(this.containerRect.width, this.containerRect.height) <= 576;
1768
+ }
1597
1769
  render() {
1598
1770
  if (!this.isOpen)
1599
1771
  return null;
1600
- return (h(Host, null, h("div", { class: { backdrop: true, 'is-animating': this.isAnimating }, onClick: this.handleBackdropClick }, h("div", { class: {
1772
+ const containerFullscreen = this.contained && this.isContainerMobile();
1773
+ return (h(Host, null, h("div", { class: { backdrop: true, 'is-animating': this.isAnimating, 'contained-fullscreen': containerFullscreen }, style: this.getBackdropStyle(), onClick: this.handleBackdropClick }, h("div", { class: {
1601
1774
  'dialog-content': true,
1602
1775
  'is-animating': this.isAnimating,
1603
1776
  [`size-${this.size}`]: true,
1604
1777
  'fullscreen-on-mobile': this.fullscreenOnMobile,
1605
- }, style: this.mobileLockedHeight ? { height: this.mobileLockedHeight, maxHeight: this.mobileLockedHeight } : undefined, role: "dialog", "aria-modal": "true", "aria-labelledby": this.dialogTitle ? 'dialog-title' : undefined, tabIndex: -1, onClick: this.handleContentClick }, this.renderHeader(), h("div", { class: "dialog-body" }, h("slot", null)), this.renderFooter()))));
1778
+ 'contained-fullscreen': containerFullscreen,
1779
+ }, style: this.getDialogContentStyle(), role: "dialog", "aria-modal": "true", "aria-labelledby": this.dialogTitle ? 'dialog-title' : undefined, tabIndex: -1, onClick: this.handleContentClick }, this.renderHeader(), h("div", { class: "dialog-body" }, h("slot", null)), this.renderFooter()))));
1606
1780
  }
1607
1781
  static get watchers() { return {
1608
1782
  "isOpen": [{
@@ -1895,7 +2069,7 @@ const DEFAULT_SYNC_CONFIG = {
1895
2069
  ],
1896
2070
  };
1897
2071
 
1898
- const kritzelEditorCss = () => `kritzel-editor{display:flex;margin:0;position:relative;overflow:hidden;width:100%;height:100%;align-items:center;justify-content:center;touch-action:manipulation;user-select:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}kritzel-controls{position:absolute;bottom:var(--kritzel-editor-controls-bottom, 14px);transition:transform var(--kritzel-editor-controls-transition-duration, 0.1s) var(--kritzel-editor-controls-transition, ease-in-out)}kritzel-controls.keyboard-open{transform:var(--kritzel-editor-controls-transform, translateY(300%))}.top-left-buttons{position:absolute;top:var(--kritzel-editor-top-left-buttons-top, 14px);left:var(--kritzel-editor-top-left-buttons-left, 14px);display:flex;align-items:flex-start;gap:8px;z-index:10000}.top-right-buttons{position:absolute;top:var(--kritzel-editor-top-right-buttons-top, 14px);right:var(--kritzel-editor-top-right-buttons-right, 14px);display:flex;align-items:center;gap:8px;z-index:10000}.top-right-button{display:flex;align-items:center;justify-content:center;width:50px;height:50px;padding:0;border:var(--kritzel-split-button-border, 1px solid #ebebeb);border-radius:var(--kritzel-split-button-border-radius, 12px);background-color:var(--kritzel-split-button-background-color, #ffffff);cursor:var(--kritzel-global-pointer-cursor, pointer);box-shadow:var(--kritzel-split-button-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));transition:background-color 150ms ease;-webkit-tap-highlight-color:transparent}.top-right-button:hover{background-color:#f5f5f5}.top-right-button:active{background-color:#ebebeb}`;
2072
+ const kritzelEditorCss = () => `kritzel-editor{display:flex;margin:0;position:relative;overflow:hidden;width:100%;height:100%;align-items:center;justify-content:center;touch-action:manipulation;user-select:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-align:start;line-height:normal}kritzel-controls{position:absolute;left:0;right:0;margin-inline:auto;width:max-content;max-width:calc(100% - 16px);bottom:var(--kritzel-editor-controls-bottom, 14px);transition:transform var(--kritzel-editor-controls-transition-duration, 0.1s) var(--kritzel-editor-controls-transition, ease-in-out)}kritzel-controls.keyboard-open{transform:var(--kritzel-editor-controls-transform, translateY(300%))}.top-left-buttons{position:absolute;top:var(--kritzel-editor-top-left-buttons-top, 14px);left:var(--kritzel-editor-top-left-buttons-left, 14px);display:flex;align-items:flex-start;gap:8px;z-index:10000}.top-right-buttons{position:absolute;top:var(--kritzel-editor-top-right-buttons-top, 14px);right:var(--kritzel-editor-top-right-buttons-right, 14px);display:flex;align-items:center;gap:8px;z-index:10000}.top-right-button{display:flex;align-items:center;justify-content:center;width:50px;height:50px;padding:0;border:var(--kritzel-split-button-border, 1px solid #ebebeb);border-radius:var(--kritzel-split-button-border-radius, 12px);background-color:var(--kritzel-split-button-background-color, #ffffff);cursor:var(--kritzel-global-pointer-cursor, pointer);box-shadow:var(--kritzel-split-button-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));transition:background-color 150ms ease;-webkit-tap-highlight-color:transparent}.top-right-button:hover{background-color:#f5f5f5}.top-right-button:active{background-color:#ebebeb}`;
1899
2073
 
1900
2074
  const KritzelEditor = class {
1901
2075
  constructor(hostRef) {
@@ -20373,6 +20547,71 @@ class KritzelViewport {
20373
20547
  this._core.store.state.scale = clampedScale;
20374
20548
  this.centerInViewport(object);
20375
20549
  }
20550
+ /**
20551
+ * Centers the viewport on a given object and zooms out only if the object
20552
+ * does not fit at the current scale. Never zooms in — if the object already
20553
+ * fits, the scale is left unchanged.
20554
+ * @param object - The object to fit in the viewport
20555
+ */
20556
+ centerFitInViewportIfNeeded(object) {
20557
+ const scaleX = this._core.store.state.viewportWidth / (object.rotatedBoundingBox.width * 1.1);
20558
+ const scaleY = this._core.store.state.viewportHeight / (object.rotatedBoundingBox.height * 1.1);
20559
+ const newScale = Math.min(scaleX, scaleY, this._core.store.state.scaleMax);
20560
+ const clampedScale = Math.max(newScale, this.getEffectiveMinScale());
20561
+ if (clampedScale < this._core.store.state.scale) {
20562
+ this._core.store.state.scale = clampedScale;
20563
+ }
20564
+ this.centerInViewport(object);
20565
+ }
20566
+ /**
20567
+ * Zooms out and centers the viewport on a given object only if the object
20568
+ * does not fit at the current scale. If the object already fits, the
20569
+ * viewport is left completely unchanged.
20570
+ * @param object - The object to check and fit in the viewport
20571
+ */
20572
+ fitInViewportIfNeeded(object) {
20573
+ const scaleX = this._core.store.state.viewportWidth / (object.rotatedBoundingBox.width * 1.1);
20574
+ const scaleY = this._core.store.state.viewportHeight / (object.rotatedBoundingBox.height * 1.1);
20575
+ const newScale = Math.min(scaleX, scaleY, this._core.store.state.scaleMax);
20576
+ const clampedScale = Math.max(newScale, this.getEffectiveMinScale());
20577
+ if (clampedScale < this._core.store.state.scale) {
20578
+ this._core.store.state.scale = clampedScale;
20579
+ this.centerInViewport(object);
20580
+ }
20581
+ }
20582
+ /**
20583
+ * Smoothly brings a given object into view if it is not fully visible within
20584
+ * the current viewport. Zooms out only if the object is too large to fit at
20585
+ * the current scale; never zooms in. If the object is already fully visible,
20586
+ * the viewport is left unchanged.
20587
+ * @param object - The object to bring into view
20588
+ */
20589
+ bringIntoViewIfNeeded(object) {
20590
+ const { scale, translateX, translateY, viewportWidth, viewportHeight } = this._core.store.state;
20591
+ const bounds = object.rotatedBoundingBox;
20592
+ // Compute the object's bounding box in screen-space coordinates
20593
+ const screenLeft = bounds.x * scale + translateX;
20594
+ const screenTop = bounds.y * scale + translateY;
20595
+ const screenRight = (bounds.x + bounds.width) * scale + translateX;
20596
+ const screenBottom = (bounds.y + bounds.height) * scale + translateY;
20597
+ // If fully visible, no adjustment needed
20598
+ if (screenLeft >= 0 && screenTop >= 0 && screenRight <= viewportWidth && screenBottom <= viewportHeight) {
20599
+ return;
20600
+ }
20601
+ // Calculate the scale needed to fit the object with padding; never zoom in
20602
+ const scaleX = viewportWidth / (bounds.width * 1.1);
20603
+ const scaleY = viewportHeight / (bounds.height * 1.1);
20604
+ const fitScale = Math.min(scaleX, scaleY, this._core.store.state.scaleMax);
20605
+ const clampedFitScale = Math.max(fitScale, this.getEffectiveMinScale());
20606
+ const targetScale = Math.min(clampedFitScale, scale);
20607
+ // Animate to center the object at the target scale
20608
+ const objectCenterX = bounds.x + bounds.width / 2;
20609
+ const objectCenterY = bounds.y + bounds.height / 2;
20610
+ const targetTranslateX = viewportWidth / 2 - objectCenterX * targetScale;
20611
+ const targetTranslateY = viewportHeight / 2 - objectCenterY * targetScale;
20612
+ const clamped = this.clampTranslate(targetTranslateX, targetTranslateY);
20613
+ this.animateViewportTo(clamped.translateX, clamped.translateY, targetScale);
20614
+ }
20376
20615
  /**
20377
20616
  * Handles zoom operations triggered by wheel events with Ctrl key.
20378
20617
  * Zooms around the cursor position, respecting scale limits.
@@ -20823,17 +21062,18 @@ class KritzelContextMenuHandler extends KritzelBaseHandler {
20823
21062
  this._core.rerender();
20824
21063
  }
20825
21064
  this._core.store.state.contextMenuItems = this._core.store.selectionGroup ? this.objectContextMenuItems : this.globalContextMenuItems;
20826
- let x = event.clientX - this._core.store.offsetX;
20827
- let y = event.clientY - this._core.store.offsetY;
21065
+ const clickX = event.clientX - this._core.store.offsetX;
21066
+ const clickY = event.clientY - this._core.store.offsetY;
21067
+ const { translateX, translateY, scale } = this._core.store.state;
21068
+ this._core.store.state.contextMenuWorldX = (clickX - translateX) / scale;
21069
+ this._core.store.state.contextMenuWorldY = (clickY - translateY) / scale;
21070
+ let x = clickX;
21071
+ let y = clickY;
20828
21072
  const menuWidthEstimate = 150;
20829
- const menuHeightEstimate = 200;
20830
21073
  const margin = 10;
20831
21074
  if (x + menuWidthEstimate > window.innerWidth - margin) {
20832
21075
  x = window.innerWidth - menuWidthEstimate - margin;
20833
21076
  }
20834
- if (y + menuHeightEstimate > window.innerHeight - margin) {
20835
- y = window.innerHeight - menuHeightEstimate - margin;
20836
- }
20837
21077
  x = Math.max(margin, x);
20838
21078
  y = Math.max(margin, y);
20839
21079
  this._core.store.state.contextMenuX = x;
@@ -21099,6 +21339,8 @@ const DEFAULT_ENGINE_CONFIG = {
21099
21339
  contextMenuItems: [],
21100
21340
  contextMenuX: 0,
21101
21341
  contextMenuY: 0,
21342
+ contextMenuWorldX: 0,
21343
+ contextMenuWorldY: 0,
21102
21344
  skipContextMenu: false,
21103
21345
  debugInfo: {
21104
21346
  showObjectInfo: false,
@@ -24106,21 +24348,26 @@ class KritzelCore {
24106
24348
  if (copiedObjects.length === 1) {
24107
24349
  selectionGroup.rotation = copiedObjects[0].rotation;
24108
24350
  }
24109
- // Add the selection group
24110
- this.addSelectionGroup(selectionGroup);
24111
- // Handle cross-workspace paste: center objects in viewport
24351
+ // For cross-workspace paste, set the selection group's position before inserting
24352
+ // it into the store. This mirrors the existing pattern where objects have
24353
+ // updatePosition called before addObject, so the correct position is captured
24354
+ // in the single initial insert with no separate Yjs update (and no extra undo step).
24112
24355
  if (isDifferentWorkspace) {
24113
24356
  if (x !== undefined && y !== undefined) {
24114
- // Position was explicitly provided, use it
24357
+ // Explicit cursor position provided (e.g. right-click paste)
24115
24358
  selectionGroup.updatePosition(x, y);
24116
24359
  }
24117
24360
  else {
24118
- // Center the selection group in the viewport
24361
+ // Ctrl+V paste: center objects in the current viewport
24119
24362
  selectionGroup.centerInViewport();
24120
24363
  }
24121
- // Fit the viewport to show the pasted objects
24122
- this.engine.viewport.centerFitInViewport(selectionGroup);
24123
24364
  }
24365
+ // Add the selection group (inserts with the already-adjusted position)
24366
+ this.addSelectionGroup(selectionGroup);
24367
+ // Bring pasted objects into view with a smooth animation if they are not
24368
+ // fully visible. These only mutate in-memory viewport state (scale, translateX/Y)
24369
+ // and do not produce any Yjs writes, so they have no impact on the undo history.
24370
+ this.engine.viewport.bringIntoViewIfNeeded(selectionGroup);
24124
24371
  this._store.state.isSelecting = false;
24125
24372
  // Defer creating copies for future pastes to next frame to avoid
24126
24373
  // doubling the object creation cost in the current paste frame
@@ -26185,9 +26432,9 @@ const KritzelEngine = class {
26185
26432
  if (isInsideDialog) {
26186
26433
  return false;
26187
26434
  }
26188
- const target = ev.target;
26435
+ const target = path[0];
26189
26436
  // Don't handle if target is an interactive element that needs keyboard input
26190
- if (target.matches?.('input, textarea, select, [contenteditable="true"], [contenteditable=""]')) {
26437
+ if (target instanceof HTMLElement && target.matches?.('input, textarea, select, [contenteditable="true"], [contenteditable=""]')) {
26191
26438
  return false;
26192
26439
  }
26193
26440
  // Handle global shortcuts when no interactive element has focus
@@ -27865,8 +28112,8 @@ const KritzelEngine = class {
27865
28112
  }, onActionSelected: event => {
27866
28113
  if (event.detail.action) {
27867
28114
  event.detail.action({
27868
- x: (-this.core.store.state.translateX + this.core.store.state.contextMenuX) / this.core.store.state.scale,
27869
- y: (-this.core.store.state.translateY + this.core.store.state.contextMenuY) / this.core.store.state.scale,
28115
+ x: this.core.store.state.contextMenuWorldX,
28116
+ y: this.core.store.state.contextMenuWorldY,
27870
28117
  }, this.core.store.selectionGroup?.objects || []);
27871
28118
  }
27872
28119
  this.hideContextMenu();
@@ -27999,7 +28246,7 @@ const KritzelExport = class {
27999
28246
  return (h("div", { class: "export-tab-content" }, h("kritzel-input", { label: "Filename", value: this.exportFilename, placeholder: "Enter filename", suffix: ".json", onValueChange: this.handleFilenameChange })));
28000
28247
  }
28001
28248
  render() {
28002
- return (h(Host, { key: '5178e66f75b94697c771e2dc6fe7ce317e21cd1a' }, h("kritzel-dialog", { key: '01aae6955be6828945b20e8a8a4d7c49eb92b2e2', isOpen: this.isDialogOpen, dialogTitle: "Export", closable: true, onDialogClose: this.closeDialog }, h("div", { key: '57c6f6de2917fb51201d737c4d0e1877f5671466', class: "export-content" }, h("kritzel-pill-tabs", { key: '800b8c058078ba1bba06b5edbaf370c4fa3c6806', tabs: this.tabs, value: this.activeTab, onValueChange: this.handleTabChange }), this.activeTab === 'viewport' && this.renderViewportExport(), this.activeTab === 'workspace' && this.renderWorkspaceExport(), h("button", { key: '99fb3b3d8dc42fdb47a3110e8403dde4e508e6cd', class: "export-primary-button", onClick: this.handleExport }, "Export")))));
28249
+ return (h(Host, { key: '5178e66f75b94697c771e2dc6fe7ce317e21cd1a' }, h("kritzel-dialog", { key: 'f80cbe3fa709ed7e046303034b7345ca1f94bc48', isOpen: this.isDialogOpen, dialogTitle: "Export", closable: true, contained: true, onDialogClose: this.closeDialog }, h("div", { key: 'e7968807c2b67ebfc800cb1694b4e34af245ffba', class: "export-content" }, h("kritzel-pill-tabs", { key: 'eac62225c4c42431296f330791a1fb2212f579f5', tabs: this.tabs, value: this.activeTab, onValueChange: this.handleTabChange }), this.activeTab === 'viewport' && this.renderViewportExport(), this.activeTab === 'workspace' && this.renderWorkspaceExport(), h("button", { key: '3489affca39a901c2ef05a0698cdf51c0a7f6d1a', class: "export-primary-button", onClick: this.handleExport }, "Export")))));
28003
28250
  }
28004
28251
  };
28005
28252
  KritzelExport.style = kritzelExportCss();
@@ -28296,7 +28543,7 @@ const KritzelLoginDialog = class {
28296
28543
  this.dialogClosed.emit();
28297
28544
  };
28298
28545
  render() {
28299
- return (h(Host, { key: '1a664868b840030a773f61c2a0f4388dfb014675' }, h("kritzel-dialog", { key: '09ece6fb5949fc8b204f29cd931c583e525590e1', dialogTitle: this.dialogTitle, isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small" }, h("div", { key: '57218d7762734929691b82700c31922f5a4991c8', class: "login-content" }, this.subtitle && (h("p", { key: '9ee071786f393857cd6a666e395526a139359d60', class: "login-subtitle" }, this.subtitle)), h("div", { key: 'a487687345aabcfb55976437ddc85feb464f0cae', class: "login-providers" }, this.providers.map(provider => (h("button", { key: provider.name, class: {
28546
+ return (h(Host, { key: '1a664868b840030a773f61c2a0f4388dfb014675' }, h("kritzel-dialog", { key: '54844ffa772a211515c1ef3e6834ec45f7f3d035', dialogTitle: this.dialogTitle, isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, h("div", { key: 'd9b981b6904c58bc39173ae37ee5c4c0ee329005', class: "login-content" }, this.subtitle && (h("p", { key: 'd4d200060507d2b8b755796d8313acdfc7e2f587', class: "login-subtitle" }, this.subtitle)), h("div", { key: '3dc1e3c070e62d026eb16ceb48eb63c94bc2bed0', class: "login-providers" }, this.providers.map(provider => (h("button", { key: provider.name, class: {
28300
28547
  'provider-button': true,
28301
28548
  'is-loading': this.loadingProvider === provider.name,
28302
28549
  'is-disabled': this.loadingProvider !== null && this.loadingProvider !== provider.name,
@@ -28483,7 +28730,7 @@ const KritzelMenu = class {
28483
28730
  this.itemCloseChildMenu.emit(event.detail);
28484
28731
  };
28485
28732
  render() {
28486
- return (h(Host, { key: 'a81ea8a1fe2dc6cb8d9f395cafbcadec3eb4aa45', tabIndex: 0, onClick: e => e.stopPropagation() }, this.openChildMenuItem && h("div", { key: 'bb27d7a923431d79567e79283e505ea4ae02ef36', class: "has-open-child-overlay", onClick: this.onOverlayClick }), this.items.map(item => (h("kritzel-menu-item", { key: item.id, 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 })))));
28733
+ return (h(Host, { key: 'a81ea8a1fe2dc6cb8d9f395cafbcadec3eb4aa45', tabIndex: 0, onClick: e => e.stopPropagation() }, this.openChildMenuItem && h("div", { key: 'bb27d7a923431d79567e79283e505ea4ae02ef36', class: "has-open-child-overlay", onClick: this.onOverlayClick }), this.items.map(item => (h("kritzel-menu-item", { key: item.id, "data-testid": `menu-item-${item.id}`, item: item, parent: this.parent, style: { pointerEvents: this.editingMenuItem && !item.isEditing ? 'none' : 'auto' }, onItemSelect: this.handleItemSelect, onItemSave: this.handleSave, onItemCancel: this.handleCancel, onItemToggleChildMenu: this.handleToggleChildMenu, onItemCloseChildMenu: this.handleCloseChildMenu })))));
28487
28734
  }
28488
28735
  };
28489
28736
  KritzelMenu.style = kritzelMenuCss();
@@ -28664,7 +28911,7 @@ const KritzelMoreMenu = class {
28664
28911
  this.closeMenu();
28665
28912
  };
28666
28913
  render() {
28667
- return (h(Host, { key: '0e12ffc8c72566ec92080e6a19bd1d929795bef9', class: { mobile: this.isTouchDevice } }, h("div", { key: 'cc73b51c5aa39522a7ab7ec23d5c0a2732ed7acc', class: { 'more-menu-wrapper': true, visible: this.visible } }, h("button", { key: 'c35b8c7aa56e5e0e2773fed9fbbbead0b6b01a71', class: "more-menu-button", onClick: this.toggleMenu }, h("kritzel-icon", { key: '8b3261da5a10371a17b2562b71fde48dd0ba8ccd', name: this.icon, size: this.iconSize })), h("kritzel-portal", { key: 'be4a42061f27bbca3d435dec8e4dd25fc78febb0', anchor: this.menuAnchor, offsetY: this.offsetY, onClose: this.closeMenu }, h("kritzel-menu", { key: '763043f4d02819097396ce1baa85f398695e38b5', items: this.visibleItems, onItemSelect: this.handleMenuItemSelect })))));
28914
+ return (h(Host, { key: '0e12ffc8c72566ec92080e6a19bd1d929795bef9', class: { mobile: this.isTouchDevice } }, h("div", { key: 'cc73b51c5aa39522a7ab7ec23d5c0a2732ed7acc', class: { 'more-menu-wrapper': true, visible: this.visible } }, h("button", { key: '6b4bda0bcfec9ef9a5506f844c835d8e270b636e', class: "more-menu-button", "data-testid": "more-menu-button", onClick: this.toggleMenu }, h("kritzel-icon", { key: '0de3f4404db14c92b8d81d41514c62eac3b3e0f0', name: this.icon, size: this.iconSize })), h("kritzel-portal", { key: '6aad3b6ac4161c195a15a49b67005e9605253dbc', anchor: this.menuAnchor, offsetY: this.offsetY, onClose: this.closeMenu }, h("kritzel-menu", { key: 'aee02f7da9cbd2b49ee430fedc1a0404991982ba', items: this.visibleItems, onItemSelect: this.handleMenuItemSelect })))));
28668
28915
  }
28669
28916
  };
28670
28917
  KritzelMoreMenu.style = kritzelMoreMenuCss();
@@ -29167,7 +29414,7 @@ const KritzelPortal = class {
29167
29414
  * This file is auto-generated by the version bump scripts.
29168
29415
  * Do not modify manually.
29169
29416
  */
29170
- const KRITZEL_VERSION = '0.2.10';
29417
+ const KRITZEL_VERSION = '0.2.12';
29171
29418
 
29172
29419
  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)}`;
29173
29420
 
@@ -29355,7 +29602,7 @@ const KritzelSettings = class {
29355
29602
  }
29356
29603
  }
29357
29604
  render() {
29358
- return (h(Host, { key: 'e86192a8ca49f8618d58ede4d04d321ea238d7d4' }, h("kritzel-dialog", { key: '111bc00bbf36c2a2f82179b1a8ba22fb3a9ed11b', isOpen: this.isDialogOpen, dialogTitle: "Settings", size: "large", onDialogClose: this.closeDialog }, h("kritzel-master-detail", { key: '02c49d50572678e2ffc9d0a02bece918fbaa14e2', items: SETTINGS_CATEGORIES, selectedItemId: this.selectedCategoryId, onItemSelect: this.handleCategorySelect }, this.renderCategoryContent()))));
29605
+ return (h(Host, { key: 'e86192a8ca49f8618d58ede4d04d321ea238d7d4' }, h("kritzel-dialog", { key: '23a47a8cd9281794bfd2aec7edd6a4ef4b931550', isOpen: this.isDialogOpen, dialogTitle: "Settings", size: "large", contained: true, onDialogClose: this.closeDialog }, h("kritzel-master-detail", { key: '007c8a1c04bd0d692b55d88988b0f8874f9242a4', items: SETTINGS_CATEGORIES, selectedItemId: this.selectedCategoryId, onItemSelect: this.handleCategorySelect }, this.renderCategoryContent()))));
29359
29606
  }
29360
29607
  static get watchers() { return {
29361
29608
  "settings": [{
@@ -29486,9 +29733,9 @@ const KritzelShareDialog = class {
29486
29733
  this.dialogClosed.emit();
29487
29734
  };
29488
29735
  render() {
29489
- return (h(Host, { key: 'bd58f146337b3eca96ca34408a3d30621f01765a' }, h("kritzel-dialog", { key: 'c152f4ec5739a18b265f9a8b161ec8501c1a053b', dialogTitle: "Share Workspace", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small" }, h("div", { key: '2810061b1c99e4f4644342453de693e1cddf9a27', class: "share-content" }, h("div", { key: 'bc56de53fd6136c6867018af24019383094cab0d', class: "share-section" }, h("div", { key: '43464ffd61e5a19653cc081e823f01c0eb17e454', class: "share-row" }, h("div", { key: 'ed83ea6684695d09dc6af82b3367fbbff6e4c7e2', class: "share-label-group" }, h("label", { key: 'fe2eaf501dd80ad0b8d83f93a2dcdd18bc093d3b', class: "share-label" }, "Link sharing"), h("p", { key: '738f1a6afc0421380164b9d270920631cefdfd78', class: "share-description" }, this.internalIsPublic
29736
+ return (h(Host, { key: 'bd58f146337b3eca96ca34408a3d30621f01765a' }, h("kritzel-dialog", { key: '0575ac82e19d07cf909556cae2ec433e0057fd5b', dialogTitle: "Share Workspace", size: "small", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, contained: true }, h("div", { key: 'c51d207e31255f45724103bfecbe858f13a721e6', class: "share-content" }, h("div", { key: 'ca6cb7721b9ba834c133b2cb953b208475e34fb5', class: "share-section" }, h("div", { key: '2c76845c903cc1c18cc26b9111d608e732ed12a5', class: "share-row" }, h("div", { key: '7700533f54372bc81d8d795414318a6bf0e93c47', class: "share-label-group" }, h("label", { key: 'a1d80009cb09cfe35bce35ce1151bf0754b052c1', class: "share-label" }, "Link sharing"), h("p", { key: '10c1963e95e658c7fb86174f1dba7565ce40d5a6', class: "share-description" }, this.internalIsPublic
29490
29737
  ? 'Anyone with the link can access this workspace.'
29491
- : 'Link sharing is disabled. Only you can access this workspace.')), h("kritzel-slide-toggle", { key: '60f0200ea8f9c207cd5ee76f5a86f82707bb724b', checked: this.internalIsPublic, onCheckedChange: this.handleToggleChange, label: "Enable link sharing" }))), this.internalIsPublic && (h("div", { key: '83212a2a996b85996eee119d5535203f77d3c8dd', class: "share-section" }, h("div", { key: '297031b5aef2018f7aa33c32fd0f8c82f1ddb4cb', class: "share-url-container" }, h("input", { key: '467cca4a8c31b75daa82670f64b562730c241f52', type: "text", class: "share-url-input", value: this.getShareUrl(), readOnly: true, onClick: (e) => e.target.select() }), h("button", { key: 'fdc0f490339cb7050fb020cb1e83e51f6374b183', class: { 'copy-button': true, 'copy-success': this.copySuccess }, onClick: this.handleCopyUrl, title: this.copySuccess ? 'Copied!' : 'Copy link' }, h("kritzel-icon", { key: '5ff1a76d7977c75ea7bc8c339bdf515ba102e511', name: this.copySuccess ? 'check' : 'copy', size: 18 })))))))));
29738
+ : 'Link sharing is disabled. Only you can access this workspace.')), h("kritzel-slide-toggle", { key: 'ec62a5ece12be0cea18a16c5d41db0a992309174', checked: this.internalIsPublic, onCheckedChange: this.handleToggleChange, label: "Enable link sharing" }))), this.internalIsPublic && (h("div", { key: '5e826d4c8c37792ba3a74a0189ad313a8ab482e2', class: "share-section" }, h("div", { key: 'f8e35cda32cb34ab21f56335aa27503fd6fe98c4', class: "share-url-container" }, h("input", { key: '47feb20a1843e1d3d8f7d146d71574b187002e8d', type: "text", class: "share-url-input", value: this.getShareUrl(), readOnly: true, onClick: (e) => e.target.select() }), h("button", { key: '052f56f35d057430cbc8fd03da5bef574b173791', class: { 'copy-button': true, 'copy-success': this.copySuccess }, onClick: this.handleCopyUrl, title: this.copySuccess ? 'Copied!' : 'Copy link' }, h("kritzel-icon", { key: '4e1de478f837a352185be2a06e15796dc1fb2f5e', name: this.copySuccess ? 'check' : 'copy', size: 18 })))))))));
29492
29739
  }
29493
29740
  static get watchers() { return {
29494
29741
  "isPublic": [{