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
@@ -892,7 +892,7 @@ class KritzelToolConfigHelper {
892
892
  }
893
893
  }
894
894
 
895
- 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}`;
895
+ 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}`;
896
896
 
897
897
  const KritzelControls = class {
898
898
  constructor(hostRef) {
@@ -1204,7 +1204,7 @@ const KritzelCurrentUserDialog = class {
1204
1204
  }
1205
1205
  render() {
1206
1206
  const displayName = this.getDisplayName();
1207
- return (index.h(index.Host, { key: 'e1dd44cdfdbaebfe886fed0d9feba2ef232b6615' }, index.h("kritzel-dialog", { key: '49dd037cca0741cc949f20d9d44cfd028492dc60', dialogTitle: "Account", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small" }, index.h("div", { key: 'ddcdfb82cc0c896025559888d475ab5c9ad59b4c', class: "user-info" }, index.h("kritzel-avatar", { key: '4d164b784cde6787d26ac164c7450c0352e6a7cb', user: this.user, size: 80 }), displayName && index.h("div", { key: '13ad719d8bd90cd608c78438fccbb38ed1d5e5ba', class: "user-name" }, displayName), this.user?.email && index.h("div", { key: 'df360afd434293d9c9d5fcf114713e0a6925a78e', class: "user-email" }, this.user.email)))));
1207
+ 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)))));
1208
1208
  }
1209
1209
  };
1210
1210
  KritzelCurrentUserDialog.style = kritzelCurrentUserDialogCss();
@@ -1365,7 +1365,7 @@ class KritzelHTMLHelper {
1365
1365
  }
1366
1366
  }
1367
1367
 
1368
- 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}`;
1368
+ 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}`;
1369
1369
 
1370
1370
  const KritzelDialog = class {
1371
1371
  constructor(hostRef) {
@@ -1392,8 +1392,12 @@ const KritzelDialog = class {
1392
1392
  size = 'medium';
1393
1393
  /** Whether to automatically go fullscreen on mobile viewports */
1394
1394
  fullscreenOnMobile = true;
1395
+ /** Constrain the dialog to its nearest editor/container ancestor instead of the viewport. */
1396
+ contained = false;
1395
1397
  isAnimating = false;
1396
1398
  mobileLockedHeight = null;
1399
+ containerRect = null;
1400
+ containerBorderRadius = null;
1397
1401
  /** Emitted when the dialog opens */
1398
1402
  dialogOpen;
1399
1403
  /** Emitted when the dialog closes */
@@ -1401,6 +1405,9 @@ const KritzelDialog = class {
1401
1405
  previousOverflow = '';
1402
1406
  previousActiveElement = null;
1403
1407
  visualViewportListenersAttached = false;
1408
+ containerElement = null;
1409
+ containerResizeObserver = null;
1410
+ containerTrackingFrame = null;
1404
1411
  handleIsOpenChange(newValue) {
1405
1412
  if (newValue) {
1406
1413
  this.openDialog();
@@ -1450,13 +1457,19 @@ const KritzelDialog = class {
1450
1457
  }
1451
1458
  disconnectedCallback() {
1452
1459
  this.removeVisualViewportListeners();
1460
+ this.stopContainerTracking();
1453
1461
  this.restoreBodyScroll();
1454
1462
  }
1455
1463
  openDialog() {
1456
1464
  this.isAnimating = true;
1457
1465
  this.previousActiveElement = document.activeElement;
1458
- this.lockBodyScroll();
1459
- this.addVisualViewportListeners();
1466
+ if (this.contained) {
1467
+ this.startContainerTracking();
1468
+ }
1469
+ else {
1470
+ this.lockBodyScroll();
1471
+ this.addVisualViewportListeners();
1472
+ }
1460
1473
  this.lockMobileViewportHeight();
1461
1474
  this.dialogOpen.emit();
1462
1475
  if (this.autoFocus) {
@@ -1471,9 +1484,106 @@ const KritzelDialog = class {
1471
1484
  closeDialog() {
1472
1485
  this.restoreBodyScroll();
1473
1486
  this.removeVisualViewportListeners();
1487
+ this.stopContainerTracking();
1474
1488
  this.mobileLockedHeight = null;
1475
1489
  this.returnFocusToPreviousElement();
1476
1490
  }
1491
+ findContainerElement() {
1492
+ // Walk up the composed DOM (crossing shadow roots) and return the first
1493
+ // ancestor that opts into containing dialogs. We accept either an explicit
1494
+ // [data-kritzel-dialog-container] marker or the kritzel-editor host so any
1495
+ // consumer can opt in without modifying the editor itself.
1496
+ let node = this.host;
1497
+ while (node) {
1498
+ if (node instanceof HTMLElement) {
1499
+ if (node.hasAttribute('data-kritzel-dialog-container') || node.tagName === 'KRITZEL-EDITOR') {
1500
+ return node;
1501
+ }
1502
+ }
1503
+ const parent = node.parentNode;
1504
+ if (parent) {
1505
+ node = parent;
1506
+ }
1507
+ else if (node instanceof ShadowRoot) {
1508
+ node = node.host;
1509
+ }
1510
+ else {
1511
+ node = null;
1512
+ }
1513
+ }
1514
+ return null;
1515
+ }
1516
+ startContainerTracking() {
1517
+ this.containerElement = this.findContainerElement();
1518
+ if (!this.containerElement) {
1519
+ // No container found — fall back to viewport behavior.
1520
+ this.containerRect = null;
1521
+ return;
1522
+ }
1523
+ this.updateContainerRect();
1524
+ if (typeof ResizeObserver !== 'undefined') {
1525
+ this.containerResizeObserver = new ResizeObserver(() => this.updateContainerRect());
1526
+ this.containerResizeObserver.observe(this.containerElement);
1527
+ }
1528
+ window.addEventListener('resize', this.handleContainerTrackingEvent, { passive: true });
1529
+ window.addEventListener('scroll', this.handleContainerTrackingEvent, { capture: true, passive: true });
1530
+ }
1531
+ stopContainerTracking() {
1532
+ if (this.containerResizeObserver) {
1533
+ this.containerResizeObserver.disconnect();
1534
+ this.containerResizeObserver = null;
1535
+ }
1536
+ window.removeEventListener('resize', this.handleContainerTrackingEvent);
1537
+ window.removeEventListener('scroll', this.handleContainerTrackingEvent, { capture: true });
1538
+ if (this.containerTrackingFrame !== null) {
1539
+ cancelAnimationFrame(this.containerTrackingFrame);
1540
+ this.containerTrackingFrame = null;
1541
+ }
1542
+ this.containerElement = null;
1543
+ this.containerRect = null;
1544
+ this.containerBorderRadius = null;
1545
+ }
1546
+ handleContainerTrackingEvent = () => {
1547
+ if (this.containerTrackingFrame !== null)
1548
+ return;
1549
+ this.containerTrackingFrame = requestAnimationFrame(() => {
1550
+ this.containerTrackingFrame = null;
1551
+ this.updateContainerRect();
1552
+ });
1553
+ };
1554
+ updateContainerRect() {
1555
+ if (!this.containerElement)
1556
+ return;
1557
+ const rect = this.containerElement.getBoundingClientRect();
1558
+ const next = { top: rect.top, left: rect.left, width: rect.width, height: rect.height };
1559
+ const prev = this.containerRect;
1560
+ if (!prev || prev.top !== next.top || prev.left !== next.left || prev.width !== next.width || prev.height !== next.height) {
1561
+ this.containerRect = next;
1562
+ }
1563
+ // Look for the nearest visually-rounded ancestor (the container itself or
1564
+ // any ancestor up to the document) so the backdrop matches wrappers that
1565
+ // round their corners around the editor.
1566
+ const radius = this.findVisualBorderRadius(this.containerElement);
1567
+ if (this.containerBorderRadius !== radius) {
1568
+ this.containerBorderRadius = radius;
1569
+ }
1570
+ }
1571
+ findVisualBorderRadius(start) {
1572
+ let node = start;
1573
+ while (node && node !== document.body && node !== document.documentElement) {
1574
+ const computed = window.getComputedStyle(node);
1575
+ const tl = computed.borderTopLeftRadius;
1576
+ const tr = computed.borderTopRightRadius;
1577
+ const br = computed.borderBottomRightRadius;
1578
+ const bl = computed.borderBottomLeftRadius;
1579
+ const isZero = (v) => !v || v === '0px' || v === '0%';
1580
+ if (!(isZero(tl) && isZero(tr) && isZero(br) && isZero(bl))) {
1581
+ return `${tl} ${tr} ${br} ${bl}`;
1582
+ }
1583
+ node = node.parentElement;
1584
+ }
1585
+ return null;
1586
+ }
1477
1587
  emitClose(reason) {
1478
1588
  this.dialogClose.emit({ reason });
1479
1589
  }
@@ -1482,6 +1592,12 @@ const KritzelDialog = class {
1482
1592
  document.body.style.overflow = 'hidden';
1483
1593
  }
1484
1594
  lockMobileViewportHeight() {
1595
+ // Skip mobile viewport height locking when contained — the dialog is sized
1596
+ // by its wrapper, not the viewport.
1597
+ if (this.contained) {
1598
+ this.mobileLockedHeight = null;
1599
+ return;
1600
+ }
1485
1601
  // Only lock height on mobile when fullscreenOnMobile is enabled.
1486
1602
  // Use the smaller dimension so landscape phones (wide but short) are also detected.
1487
1603
  const viewportWidth = this.getViewportWidth();
@@ -1616,15 +1732,73 @@ const KritzelDialog = class {
1616
1732
  return null;
1617
1733
  return (index.h("div", { class: "dialog-footer" }, index.h("slot", { name: "footer" })));
1618
1734
  }
1735
+ getBackdropStyle() {
1736
+ if (!this.contained || !this.containerRect)
1737
+ return undefined;
1738
+ const { top, left, width, height } = this.containerRect;
1739
+ const style = {
1740
+ top: `${top}px`,
1741
+ left: `${left}px`,
1742
+ right: 'auto',
1743
+ bottom: 'auto',
1744
+ width: `${width}px`,
1745
+ height: `${height}px`,
1746
+ };
1747
+ if (this.containerBorderRadius) {
1748
+ style.borderRadius = this.containerBorderRadius;
1749
+ // Ensure rounded corners actually clip the inner dialog content.
1750
+ style.overflow = 'hidden';
1751
+ }
1752
+ return style;
1753
+ }
1754
+ getDialogContentStyle() {
1755
+ const style = {};
1756
+ // In contained mode, cap the dialog dimensions to the container so the
1757
+ // declared widths/heights of size variants cannot overflow the wrapper.
1758
+ if (this.contained && this.containerRect) {
1759
+ const { width, height } = this.containerRect;
1760
+ if (this.isContainerMobile()) {
1761
+ // Mobile-sized container: behave like fullscreen-on-mobile but scoped
1762
+ // to the container instead of the viewport (works in any orientation).
1763
+ style.width = `${width}px`;
1764
+ style.height = `${height}px`;
1765
+ style.maxWidth = `${width}px`;
1766
+ style.maxHeight = `${height}px`;
1767
+ style.borderRadius = '0';
1768
+ }
1769
+ else {
1770
+ // Leave a small margin so the dialog visibly sits within the container.
1771
+ const maxWidth = Math.max(0, width - 32);
1772
+ const maxHeight = Math.max(0, height - 32);
1773
+ style.maxWidth = `${maxWidth}px`;
1774
+ style.maxHeight = `${maxHeight}px`;
1775
+ }
1776
+ }
1777
+ if (this.mobileLockedHeight) {
1778
+ style.height = this.mobileLockedHeight;
1779
+ style.maxHeight = this.mobileLockedHeight;
1780
+ }
1781
+ return Object.keys(style).length > 0 ? style : undefined;
1782
+ }
1783
+ isContainerMobile() {
1784
+ if (!this.fullscreenOnMobile || !this.containerRect)
1785
+ return false;
1786
+ // Match the existing viewport media-query threshold: container is "mobile"
1787
+ // when its smaller dimension is <= 576px. This handles both portrait and
1788
+ // landscape wrappers symmetrically.
1789
+ return Math.min(this.containerRect.width, this.containerRect.height) <= 576;
1790
+ }
1619
1791
  render() {
1620
1792
  if (!this.isOpen)
1621
1793
  return null;
1622
- return (index.h(index.Host, null, index.h("div", { class: { backdrop: true, 'is-animating': this.isAnimating }, onClick: this.handleBackdropClick }, index.h("div", { class: {
1794
+ const containerFullscreen = this.contained && this.isContainerMobile();
1795
+ return (index.h(index.Host, null, index.h("div", { class: { backdrop: true, 'is-animating': this.isAnimating, 'contained-fullscreen': containerFullscreen }, style: this.getBackdropStyle(), onClick: this.handleBackdropClick }, index.h("div", { class: {
1623
1796
  'dialog-content': true,
1624
1797
  'is-animating': this.isAnimating,
1625
1798
  [`size-${this.size}`]: true,
1626
1799
  'fullscreen-on-mobile': this.fullscreenOnMobile,
1627
- }, 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(), index.h("div", { class: "dialog-body" }, index.h("slot", null)), this.renderFooter()))));
1800
+ 'contained-fullscreen': containerFullscreen,
1801
+ }, style: this.getDialogContentStyle(), role: "dialog", "aria-modal": "true", "aria-labelledby": this.dialogTitle ? 'dialog-title' : undefined, tabIndex: -1, onClick: this.handleContentClick }, this.renderHeader(), index.h("div", { class: "dialog-body" }, index.h("slot", null)), this.renderFooter()))));
1628
1802
  }
1629
1803
  static get watchers() { return {
1630
1804
  "isOpen": [{
@@ -1917,7 +2091,7 @@ const DEFAULT_SYNC_CONFIG = {
1917
2091
  ],
1918
2092
  };
1919
2093
 
1920
- 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}`;
2094
+ 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}`;
1921
2095
 
1922
2096
  const KritzelEditor = class {
1923
2097
  constructor(hostRef) {
@@ -20395,6 +20569,71 @@ class KritzelViewport {
20395
20569
  this._core.store.state.scale = clampedScale;
20396
20570
  this.centerInViewport(object);
20397
20571
  }
20572
+ /**
20573
+ * Centers the viewport on a given object and zooms out only if the object
20574
+ * does not fit at the current scale. Never zooms in — if the object already
20575
+ * fits, the scale is left unchanged.
20576
+ * @param object - The object to fit in the viewport
20577
+ */
20578
+ centerFitInViewportIfNeeded(object) {
20579
+ const scaleX = this._core.store.state.viewportWidth / (object.rotatedBoundingBox.width * 1.1);
20580
+ const scaleY = this._core.store.state.viewportHeight / (object.rotatedBoundingBox.height * 1.1);
20581
+ const newScale = Math.min(scaleX, scaleY, this._core.store.state.scaleMax);
20582
+ const clampedScale = Math.max(newScale, this.getEffectiveMinScale());
20583
+ if (clampedScale < this._core.store.state.scale) {
20584
+ this._core.store.state.scale = clampedScale;
20585
+ }
20586
+ this.centerInViewport(object);
20587
+ }
20588
+ /**
20589
+ * Zooms out and centers the viewport on a given object only if the object
20590
+ * does not fit at the current scale. If the object already fits, the
20591
+ * viewport is left completely unchanged.
20592
+ * @param object - The object to check and fit in the viewport
20593
+ */
20594
+ fitInViewportIfNeeded(object) {
20595
+ const scaleX = this._core.store.state.viewportWidth / (object.rotatedBoundingBox.width * 1.1);
20596
+ const scaleY = this._core.store.state.viewportHeight / (object.rotatedBoundingBox.height * 1.1);
20597
+ const newScale = Math.min(scaleX, scaleY, this._core.store.state.scaleMax);
20598
+ const clampedScale = Math.max(newScale, this.getEffectiveMinScale());
20599
+ if (clampedScale < this._core.store.state.scale) {
20600
+ this._core.store.state.scale = clampedScale;
20601
+ this.centerInViewport(object);
20602
+ }
20603
+ }
20604
+ /**
20605
+ * Smoothly brings a given object into view if it is not fully visible within
20606
+ * the current viewport. Zooms out only if the object is too large to fit at
20607
+ * the current scale; never zooms in. If the object is already fully visible,
20608
+ * the viewport is left unchanged.
20609
+ * @param object - The object to bring into view
20610
+ */
20611
+ bringIntoViewIfNeeded(object) {
20612
+ const { scale, translateX, translateY, viewportWidth, viewportHeight } = this._core.store.state;
20613
+ const bounds = object.rotatedBoundingBox;
20614
+ // Compute the object's bounding box in screen-space coordinates
20615
+ const screenLeft = bounds.x * scale + translateX;
20616
+ const screenTop = bounds.y * scale + translateY;
20617
+ const screenRight = (bounds.x + bounds.width) * scale + translateX;
20618
+ const screenBottom = (bounds.y + bounds.height) * scale + translateY;
20619
+ // If fully visible, no adjustment needed
20620
+ if (screenLeft >= 0 && screenTop >= 0 && screenRight <= viewportWidth && screenBottom <= viewportHeight) {
20621
+ return;
20622
+ }
20623
+ // Calculate the scale needed to fit the object with padding; never zoom in
20624
+ const scaleX = viewportWidth / (bounds.width * 1.1);
20625
+ const scaleY = viewportHeight / (bounds.height * 1.1);
20626
+ const fitScale = Math.min(scaleX, scaleY, this._core.store.state.scaleMax);
20627
+ const clampedFitScale = Math.max(fitScale, this.getEffectiveMinScale());
20628
+ const targetScale = Math.min(clampedFitScale, scale);
20629
+ // Animate to center the object at the target scale
20630
+ const objectCenterX = bounds.x + bounds.width / 2;
20631
+ const objectCenterY = bounds.y + bounds.height / 2;
20632
+ const targetTranslateX = viewportWidth / 2 - objectCenterX * targetScale;
20633
+ const targetTranslateY = viewportHeight / 2 - objectCenterY * targetScale;
20634
+ const clamped = this.clampTranslate(targetTranslateX, targetTranslateY);
20635
+ this.animateViewportTo(clamped.translateX, clamped.translateY, targetScale);
20636
+ }
20398
20637
  /**
20399
20638
  * Handles zoom operations triggered by wheel events with Ctrl key.
20400
20639
  * Zooms around the cursor position, respecting scale limits.
@@ -20845,17 +21084,18 @@ class KritzelContextMenuHandler extends workspace_migrations.KritzelBaseHandler
20845
21084
  this._core.rerender();
20846
21085
  }
20847
21086
  this._core.store.state.contextMenuItems = this._core.store.selectionGroup ? this.objectContextMenuItems : this.globalContextMenuItems;
20848
- let x = event.clientX - this._core.store.offsetX;
20849
- let y = event.clientY - this._core.store.offsetY;
21087
+ const clickX = event.clientX - this._core.store.offsetX;
21088
+ const clickY = event.clientY - this._core.store.offsetY;
21089
+ const { translateX, translateY, scale } = this._core.store.state;
21090
+ this._core.store.state.contextMenuWorldX = (clickX - translateX) / scale;
21091
+ this._core.store.state.contextMenuWorldY = (clickY - translateY) / scale;
21092
+ let x = clickX;
21093
+ let y = clickY;
20850
21094
  const menuWidthEstimate = 150;
20851
- const menuHeightEstimate = 200;
20852
21095
  const margin = 10;
20853
21096
  if (x + menuWidthEstimate > window.innerWidth - margin) {
20854
21097
  x = window.innerWidth - menuWidthEstimate - margin;
20855
21098
  }
20856
- if (y + menuHeightEstimate > window.innerHeight - margin) {
20857
- y = window.innerHeight - menuHeightEstimate - margin;
20858
- }
20859
21099
  x = Math.max(margin, x);
20860
21100
  y = Math.max(margin, y);
20861
21101
  this._core.store.state.contextMenuX = x;
@@ -21121,6 +21361,8 @@ const DEFAULT_ENGINE_CONFIG = {
21121
21361
  contextMenuItems: [],
21122
21362
  contextMenuX: 0,
21123
21363
  contextMenuY: 0,
21364
+ contextMenuWorldX: 0,
21365
+ contextMenuWorldY: 0,
21124
21366
  skipContextMenu: false,
21125
21367
  debugInfo: {
21126
21368
  showObjectInfo: false,
@@ -24128,21 +24370,26 @@ class KritzelCore {
24128
24370
  if (copiedObjects.length === 1) {
24129
24371
  selectionGroup.rotation = copiedObjects[0].rotation;
24130
24372
  }
24131
- // Add the selection group
24132
- this.addSelectionGroup(selectionGroup);
24133
- // Handle cross-workspace paste: center objects in viewport
24373
+ // For cross-workspace paste, set the selection group's position before inserting
24374
+ // it into the store. This mirrors the existing pattern where objects have
24375
+ // updatePosition called before addObject, so the correct position is captured
24376
+ // in the single initial insert with no separate Yjs update (and no extra undo step).
24134
24377
  if (isDifferentWorkspace) {
24135
24378
  if (x !== undefined && y !== undefined) {
24136
- // Position was explicitly provided, use it
24379
+ // Explicit cursor position provided (e.g. right-click paste)
24137
24380
  selectionGroup.updatePosition(x, y);
24138
24381
  }
24139
24382
  else {
24140
- // Center the selection group in the viewport
24383
+ // Ctrl+V paste: center objects in the current viewport
24141
24384
  selectionGroup.centerInViewport();
24142
24385
  }
24143
- // Fit the viewport to show the pasted objects
24144
- this.engine.viewport.centerFitInViewport(selectionGroup);
24145
24386
  }
24387
+ // Add the selection group (inserts with the already-adjusted position)
24388
+ this.addSelectionGroup(selectionGroup);
24389
+ // Bring pasted objects into view with a smooth animation if they are not
24390
+ // fully visible. These only mutate in-memory viewport state (scale, translateX/Y)
24391
+ // and do not produce any Yjs writes, so they have no impact on the undo history.
24392
+ this.engine.viewport.bringIntoViewIfNeeded(selectionGroup);
24146
24393
  this._store.state.isSelecting = false;
24147
24394
  // Defer creating copies for future pastes to next frame to avoid
24148
24395
  // doubling the object creation cost in the current paste frame
@@ -26207,9 +26454,9 @@ const KritzelEngine = class {
26207
26454
  if (isInsideDialog) {
26208
26455
  return false;
26209
26456
  }
26210
- const target = ev.target;
26457
+ const target = path[0];
26211
26458
  // Don't handle if target is an interactive element that needs keyboard input
26212
- if (target.matches?.('input, textarea, select, [contenteditable="true"], [contenteditable=""]')) {
26459
+ if (target instanceof HTMLElement && target.matches?.('input, textarea, select, [contenteditable="true"], [contenteditable=""]')) {
26213
26460
  return false;
26214
26461
  }
26215
26462
  // Handle global shortcuts when no interactive element has focus
@@ -27887,8 +28134,8 @@ const KritzelEngine = class {
27887
28134
  }, onActionSelected: event => {
27888
28135
  if (event.detail.action) {
27889
28136
  event.detail.action({
27890
- x: (-this.core.store.state.translateX + this.core.store.state.contextMenuX) / this.core.store.state.scale,
27891
- y: (-this.core.store.state.translateY + this.core.store.state.contextMenuY) / this.core.store.state.scale,
28137
+ x: this.core.store.state.contextMenuWorldX,
28138
+ y: this.core.store.state.contextMenuWorldY,
27892
28139
  }, this.core.store.selectionGroup?.objects || []);
27893
28140
  }
27894
28141
  this.hideContextMenu();
@@ -28021,7 +28268,7 @@ const KritzelExport = class {
28021
28268
  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 })));
28022
28269
  }
28023
28270
  render() {
28024
- return (index.h(index.Host, { key: '5178e66f75b94697c771e2dc6fe7ce317e21cd1a' }, index.h("kritzel-dialog", { key: '01aae6955be6828945b20e8a8a4d7c49eb92b2e2', isOpen: this.isDialogOpen, dialogTitle: "Export", closable: true, onDialogClose: this.closeDialog }, index.h("div", { key: '57c6f6de2917fb51201d737c4d0e1877f5671466', class: "export-content" }, index.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(), index.h("button", { key: '99fb3b3d8dc42fdb47a3110e8403dde4e508e6cd', class: "export-primary-button", onClick: this.handleExport }, "Export")))));
28271
+ 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")))));
28025
28272
  }
28026
28273
  };
28027
28274
  KritzelExport.style = kritzelExportCss();
@@ -28318,7 +28565,7 @@ const KritzelLoginDialog = class {
28318
28565
  this.dialogClosed.emit();
28319
28566
  };
28320
28567
  render() {
28321
- return (index.h(index.Host, { key: '1a664868b840030a773f61c2a0f4388dfb014675' }, index.h("kritzel-dialog", { key: '09ece6fb5949fc8b204f29cd931c583e525590e1', dialogTitle: this.dialogTitle, isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small" }, index.h("div", { key: '57218d7762734929691b82700c31922f5a4991c8', class: "login-content" }, this.subtitle && (index.h("p", { key: '9ee071786f393857cd6a666e395526a139359d60', class: "login-subtitle" }, this.subtitle)), index.h("div", { key: 'a487687345aabcfb55976437ddc85feb464f0cae', class: "login-providers" }, this.providers.map(provider => (index.h("button", { key: provider.name, class: {
28568
+ 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: {
28322
28569
  'provider-button': true,
28323
28570
  'is-loading': this.loadingProvider === provider.name,
28324
28571
  'is-disabled': this.loadingProvider !== null && this.loadingProvider !== provider.name,
@@ -28505,7 +28752,7 @@ const KritzelMenu = class {
28505
28752
  this.itemCloseChildMenu.emit(event.detail);
28506
28753
  };
28507
28754
  render() {
28508
- 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, 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 })))));
28755
+ 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 })))));
28509
28756
  }
28510
28757
  };
28511
28758
  KritzelMenu.style = kritzelMenuCss();
@@ -28686,7 +28933,7 @@ const KritzelMoreMenu = class {
28686
28933
  this.closeMenu();
28687
28934
  };
28688
28935
  render() {
28689
- return (index.h(index.Host, { key: '0e12ffc8c72566ec92080e6a19bd1d929795bef9', class: { mobile: this.isTouchDevice } }, index.h("div", { key: 'cc73b51c5aa39522a7ab7ec23d5c0a2732ed7acc', class: { 'more-menu-wrapper': true, visible: this.visible } }, index.h("button", { key: 'c35b8c7aa56e5e0e2773fed9fbbbead0b6b01a71', class: "more-menu-button", onClick: this.toggleMenu }, index.h("kritzel-icon", { key: '8b3261da5a10371a17b2562b71fde48dd0ba8ccd', name: this.icon, size: this.iconSize })), index.h("kritzel-portal", { key: 'be4a42061f27bbca3d435dec8e4dd25fc78febb0', anchor: this.menuAnchor, offsetY: this.offsetY, onClose: this.closeMenu }, index.h("kritzel-menu", { key: '763043f4d02819097396ce1baa85f398695e38b5', items: this.visibleItems, onItemSelect: this.handleMenuItemSelect })))));
28936
+ return (index.h(index.Host, { key: '0e12ffc8c72566ec92080e6a19bd1d929795bef9', class: { mobile: this.isTouchDevice } }, index.h("div", { key: 'cc73b51c5aa39522a7ab7ec23d5c0a2732ed7acc', class: { 'more-menu-wrapper': true, visible: this.visible } }, index.h("button", { key: '6b4bda0bcfec9ef9a5506f844c835d8e270b636e', class: "more-menu-button", "data-testid": "more-menu-button", onClick: this.toggleMenu }, index.h("kritzel-icon", { key: '0de3f4404db14c92b8d81d41514c62eac3b3e0f0', name: this.icon, size: this.iconSize })), index.h("kritzel-portal", { key: '6aad3b6ac4161c195a15a49b67005e9605253dbc', anchor: this.menuAnchor, offsetY: this.offsetY, onClose: this.closeMenu }, index.h("kritzel-menu", { key: 'aee02f7da9cbd2b49ee430fedc1a0404991982ba', items: this.visibleItems, onItemSelect: this.handleMenuItemSelect })))));
28690
28937
  }
28691
28938
  };
28692
28939
  KritzelMoreMenu.style = kritzelMoreMenuCss();
@@ -29189,7 +29436,7 @@ const KritzelPortal = class {
29189
29436
  * This file is auto-generated by the version bump scripts.
29190
29437
  * Do not modify manually.
29191
29438
  */
29192
- const KRITZEL_VERSION = '0.2.10';
29439
+ const KRITZEL_VERSION = '0.2.12';
29193
29440
 
29194
29441
  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)}`;
29195
29442
 
@@ -29377,7 +29624,7 @@ const KritzelSettings = class {
29377
29624
  }
29378
29625
  }
29379
29626
  render() {
29380
- return (index.h(index.Host, { key: 'e86192a8ca49f8618d58ede4d04d321ea238d7d4' }, index.h("kritzel-dialog", { key: '111bc00bbf36c2a2f82179b1a8ba22fb3a9ed11b', isOpen: this.isDialogOpen, dialogTitle: "Settings", size: "large", onDialogClose: this.closeDialog }, index.h("kritzel-master-detail", { key: '02c49d50572678e2ffc9d0a02bece918fbaa14e2', items: SETTINGS_CATEGORIES, selectedItemId: this.selectedCategoryId, onItemSelect: this.handleCategorySelect }, this.renderCategoryContent()))));
29627
+ 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()))));
29381
29628
  }
29382
29629
  static get watchers() { return {
29383
29630
  "settings": [{
@@ -29508,9 +29755,9 @@ const KritzelShareDialog = class {
29508
29755
  this.dialogClosed.emit();
29509
29756
  };
29510
29757
  render() {
29511
- return (index.h(index.Host, { key: 'bd58f146337b3eca96ca34408a3d30621f01765a' }, index.h("kritzel-dialog", { key: 'c152f4ec5739a18b265f9a8b161ec8501c1a053b', dialogTitle: "Share Workspace", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small" }, index.h("div", { key: '2810061b1c99e4f4644342453de693e1cddf9a27', class: "share-content" }, index.h("div", { key: 'bc56de53fd6136c6867018af24019383094cab0d', class: "share-section" }, index.h("div", { key: '43464ffd61e5a19653cc081e823f01c0eb17e454', class: "share-row" }, index.h("div", { key: 'ed83ea6684695d09dc6af82b3367fbbff6e4c7e2', class: "share-label-group" }, index.h("label", { key: 'fe2eaf501dd80ad0b8d83f93a2dcdd18bc093d3b', class: "share-label" }, "Link sharing"), index.h("p", { key: '738f1a6afc0421380164b9d270920631cefdfd78', class: "share-description" }, this.internalIsPublic
29758
+ 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
29512
29759
  ? 'Anyone with the link can access this workspace.'
29513
- : 'Link sharing is disabled. Only you can access this workspace.')), index.h("kritzel-slide-toggle", { key: '60f0200ea8f9c207cd5ee76f5a86f82707bb724b', checked: this.internalIsPublic, onCheckedChange: this.handleToggleChange, label: "Enable link sharing" }))), this.internalIsPublic && (index.h("div", { key: '83212a2a996b85996eee119d5535203f77d3c8dd', class: "share-section" }, index.h("div", { key: '297031b5aef2018f7aa33c32fd0f8c82f1ddb4cb', class: "share-url-container" }, index.h("input", { key: '467cca4a8c31b75daa82670f64b562730c241f52', type: "text", class: "share-url-input", value: this.getShareUrl(), readOnly: true, onClick: (e) => e.target.select() }), index.h("button", { key: 'fdc0f490339cb7050fb020cb1e83e51f6374b183', class: { 'copy-button': true, 'copy-success': this.copySuccess }, onClick: this.handleCopyUrl, title: this.copySuccess ? 'Copied!' : 'Copy link' }, index.h("kritzel-icon", { key: '5ff1a76d7977c75ea7bc8c339bdf515ba102e511', name: this.copySuccess ? 'check' : 'copy', size: 18 })))))))));
29760
+ : '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 })))))))));
29514
29761
  }
29515
29762
  static get watchers() { return {
29516
29763
  "isPublic": [{